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 )