stoichiograph

Spell words with elemental symbols from the periodic table.
git clone git://git.amin.space/stoichiograph.git
Log | Files | Refs | LICENSE

test_speller.py (8124B)


      1 from collections import defaultdict
      2 from stoichiograph import speller
      3 from stoichiograph.speller import Node
      4 
      5 ELEMENTS = {
      6     'H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al',
      7     'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe',
      8     'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y',
      9     'Zr', 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb',
     10     'Te', 'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd',
     11     'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir',
     12     'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac',
     13     'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Md', 'No',
     14     'Lr', 'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl',
     15     'Mc', 'Lv', 'Ts', 'Og'
     16 }
     17 
     18 
     19 def test_verify_data():
     20     """Assert that the set of elements in `speller.py` matches this
     21     canonical set.
     22     """
     23     assert speller.ELEMENTS == ELEMENTS
     24 
     25 
     26 def test_elemental_spelling():
     27     """Assert that we get the expected results when spelling various
     28     inputs.
     29     """
     30     assert speller.spell('amputation') == [
     31         ('Am', 'Pu', 'Ta', 'Ti', 'O', 'N'),
     32         ('Am', 'P', 'U', 'Ta', 'Ti', 'O', 'N')
     33     ]
     34     assert speller.spell('') == []
     35     assert speller.spell('o') == [('O',)]
     36 
     37 
     38 def test_find_all_paths():
     39     """Make simple graph with some branches, and assert that we find all
     40     the paths from the first node to the last.
     41     """
     42     parents_to_children = {
     43         'a': {'b'},
     44         'b': {'c'},
     45         'c': {'d'},
     46         'd': {'e', 'y', 'z'},
     47         'e': {'f', 'x'},
     48         'f': {'g', 'x'},
     49         'g': {'h'},
     50         'h': {'i'},
     51         'x': {'y'},
     52         'y': {'z'},
     53     }
     54 
     55     assert set(speller.find_all_paths(parents_to_children, 'a', 'z')) == set([
     56         ('a', 'b', 'c', 'd', 'z'),
     57         ('a', 'b', 'c', 'd', 'y', 'z'),
     58         ('a', 'b', 'c', 'd', 'e', 'x', 'y', 'z'),
     59         ('a', 'b', 'c', 'd', 'e', 'f', 'x', 'y', 'z'),
     60     ])
     61 
     62 
     63 def test_build_spelling_graph():
     64     """Make a `speller.Graph` object, then build it with a word and
     65     assert that it contains the proper node relationships.
     66     """
     67     g = speller.Graph()
     68     speller.build_spelling_graph('because', g)
     69 
     70     assert g._parents_of == defaultdict(
     71         set,
     72         {
     73             Node(value='c', position=2): {Node(value='be', position=0)},
     74             Node(value='au', position=3): {Node(value='c', position=2)},
     75             Node(value='s', position=5): {
     76                 Node(value='au', position=3),
     77                 Node(value='u', position=4)
     78             },
     79             Node(value='se', position=5): {
     80                 Node(value='au', position=3),
     81                 Node(value='u', position=4)
     82             },
     83             None: {Node(value='se', position=5)},
     84             Node(value='ca', position=2): {Node(value='be', position=0)},
     85             Node(value='u', position=4): {Node(value='ca', position=2)}
     86         }
     87     )
     88 
     89     assert g._children_of == defaultdict(
     90         set,
     91         {
     92             None: {Node(value='be', position=0), Node(value='b', position=0)},
     93             Node(value='be', position=0): {
     94                 Node(value='ca', position=2),
     95                 Node(value='c', position=2)
     96             },
     97             Node(value='c', position=2): {Node(value='au', position=3)},
     98             Node(value='au', position=3): {
     99                 Node(value='se', position=5),
    100                 Node(value='s', position=5)
    101             },
    102             Node(value='ca', position=2): {Node(value='u', position=4)},
    103             Node(value='u', position=4): {
    104                 Node(value='se', position=5),
    105                 Node(value='s', position=5)
    106             }
    107         }
    108     )
    109 
    110 
    111 class TestGraph:
    112     """Tests for the methods of the `speller.Graph` class."""
    113 
    114     def test_firsts(self, test_graph):
    115         """Assert that the graph properly identifies its first nodes."""
    116         assert test_graph.firsts() == {Node('be', 0), Node('b', 0)}
    117 
    118     def test_lasts(self, test_graph):
    119         """Assert that the graph properly identifies its last nodes."""
    120         assert test_graph.lasts() == {Node('se', 5)}
    121 
    122     def test_add_edge(self, test_graph):
    123         """Add an edge to the graph."""
    124         parent = Node('te', 0)
    125         child = Node('st', 2)
    126         test_graph.add_edge(parent, child)
    127         assert test_graph._children_of[parent] == {child}
    128         assert test_graph._parents_of[child] == {parent}
    129 
    130     def test_add_edge_with_no_parent(self, test_graph):
    131         """Add an edge with no parent to the graph. Assert that 'None'
    132         isn't added to `_parents_of[child]`.
    133         """
    134         parent = None
    135         child = Node('a', 0)
    136         test_graph.add_edge(parent, child)
    137         assert child in test_graph._children_of[parent]
    138         assert None not in test_graph._parents_of[child]
    139 
    140     def test_add_edge_with_no_child(self, test_graph):
    141         """Add an edge with no child to the graph. Assert that `None`
    142         isn't added to `_children_of[parent]`.
    143         """
    144         parent = Node('z', 25)
    145         child = None
    146         test_graph.add_edge(parent, child)
    147         assert None not in test_graph._children_of[parent]
    148         assert parent in test_graph._parents_of[child]
    149 
    150     def test_nodes(self, test_graph):
    151         """Assert that the graph properly lists its nodes."""
    152         assert set(test_graph.nodes(connected_only=True)) == set([
    153             Node(value='be', position=0),
    154             Node(value='c', position=2),
    155             Node(value='ca', position=2),
    156             Node(value='au', position=3),
    157             Node(value='u', position=4),
    158             Node(value='s', position=5),
    159             Node(value='se', position=5),
    160         ])
    161         assert set(test_graph.nodes(connected_only=False)) == set([
    162             Node(value='b', position=0),
    163             Node(value='be', position=0),
    164             Node(value='c', position=2),
    165             Node(value='ca', position=2),
    166             Node(value='au', position=3),
    167             Node(value='u', position=4),
    168             Node(value='s', position=5),
    169             Node(value='se', position=5),
    170         ])
    171 
    172     def test_edges(self, test_graph):
    173         """Assert that the graph properly lists its edges."""
    174         assert set(test_graph.edges()) == set([
    175             (None, Node(value='b', position=0)),
    176             (None, Node(value='be', position=0)),
    177             (Node(value='be', position=0), Node(value='c', position=2)),
    178             (Node(value='be', position=0), Node(value='ca', position=2)),
    179             (Node(value='c', position=2), Node(value='au', position=3)),
    180             (Node(value='au', position=3), Node(value='s', position=5)),
    181             (Node(value='au', position=3), Node(value='se', position=5)),
    182             (Node(value='ca', position=2), Node(value='u', position=4)),
    183             (Node(value='u', position=4), Node(value='s', position=5)),
    184             (Node(value='u', position=4), Node(value='se', position=5))
    185         ])
    186 
    187     def test_export(self, test_graph):
    188         """Assert that the graph exports the proper dot code."""
    189         assert test_graph.export() == (
    190             """digraph G {
    191     graph [rankdir=LR];
    192     node [width=0.75 shape=circle];
    193     "Node(value='au', position=3)" -> "Node(value='s', position=5)";
    194     "Node(value='au', position=3)" -> "Node(value='se', position=5)";
    195     "Node(value='be', position=0)" -> "Node(value='c', position=2)";
    196     "Node(value='be', position=0)" -> "Node(value='ca', position=2)";
    197     "Node(value='c', position=2)" -> "Node(value='au', position=3)";
    198     "Node(value='ca', position=2)" -> "Node(value='u', position=4)";
    199     "Node(value='u', position=4)" -> "Node(value='s', position=5)";
    200     "Node(value='u', position=4)" -> "Node(value='se', position=5)";
    201     "Node(value='au', position=3)" [label="Au"];
    202     "Node(value='be', position=0)" [label="Be"];
    203     "Node(value='c', position=2)" [label="C"];
    204     "Node(value='ca', position=2)" [label="Ca"];
    205     "Node(value='s', position=5)" [label="S"];
    206     "Node(value='se', position=5)" [label="Se"];
    207     "Node(value='u', position=4)" [label="U"];
    208 }"""
    209         )