class ParseTreeTesterDuplicateSingleKeys(unittest.TestCase): # Assumes that a null structure passed in should produce {None:None} def setUp(self): testInput = ["test", "test", "test"] self._parseTree = ParseTree(testInput) def test_not_none(self): assert self._parseTree != None def test_root_node_is_active_node(self): # Should be true after initialization assert self._parseTree._rootNode == self._parseTree._currentNode def test_is_one_level(self): assert len(self._parseTree._rootNode.keys()) == 1 assert "test" in self._parseTree._rootNode.keys() def test_after_one_level_terminates(self): assert self._parseTree._rootNode["test"] == {None:None} def test_match_found(self): assert self._parseTree.validate("test") == ValidityCode.found_match def test_no_match(self): assert self._parseTree.validate("John") == ValidityCode.no_match
def __init__(self): self.__current = 0 self.__instances = [] # Registered viewers for observer design pattern self.__views = [] self.__indexObject = Index(os.path.join("res", "index.xml")) self.__parse_tree = ParseTree(self.__indexObject.keys())
class ParseTreeTesterNull(unittest.TestCase): # Assumes that a null structure passed in should produce {None:None} def setUp(self): self._parseTree = ParseTree([]) def test_not_none(self): assert self._parseTree != None def test_root_node_is_active_node(self): # Should be true after initialization assert self._parseTree._rootNode == self._parseTree._currentNode def test_one_level_none(self): assert len(self._parseTree._rootNode.keys()) == 0 def test_match_found_one(self): assert self._parseTree.validate("John") == ValidityCode.no_match
def setUp(self): testInput = ["test", "test", "test"] self._parseTree = ParseTree(testInput)
def setUp(self): self._parseTree = ParseTree([])
def setUp(self): testInput = ["John Hoskins", "John Wick Buddy", "John"] self._parseTree = ParseTree(testInput)
class ParseTreeTesterSimple(unittest.TestCase): def setUp(self): testInput = ["John Hoskins", "John Wick Buddy", "John"] self._parseTree = ParseTree(testInput) def test_not_none(self): assert self._parseTree != None def test_root_node_is_active_node(self): # Should be true after initialization assert self._parseTree._rootNode == self._parseTree._currentNode def test_one_root_key(self): assert len(self._parseTree._rootNode.keys()) == 1 assert "John" in self._parseTree._rootNode.keys() def test_two_children(self): self._parseTree.validate("John") assert len(self._parseTree._currentNode) == 3 def test_correct_children(self): self._parseTree.validate("John") assert "Hoskins" in self._parseTree._currentNode.keys() assert "Wick" in self._parseTree._currentNode.keys() assert None in self._parseTree._currentNode.keys() def test_children_terminate_three(self): self._parseTree.validate("John") self._parseTree.validate("Wick") self._parseTree.validate("Buddy") assert len(self._parseTree._currentNode) == 1 assert None in self._parseTree._currentNode.keys() def test_children_terminate_one(self): self._parseTree.validate("John") assert len(self._parseTree._currentNode) == 3 assert None in self._parseTree._currentNode.keys() def test_children_terminate_two(self): self._parseTree.validate("John") self._parseTree.validate("Hoskins") assert None in self._parseTree._currentNode.keys() assert len(self._parseTree._currentNode) == 1 # Match code testing def test_no_match_root(self): assert self._parseTree.validate("test") == ValidityCode.no_match def test_no_match_child(self): self._parseTree.validate("John") assert self._parseTree.validate("test") == ValidityCode.no_match def test_potential_match(self): self._parseTree.validate("John") assert self._parseTree.validate("Wick") == ValidityCode.potential_match def test_match_found_one(self): assert self._parseTree.validate("John") == ValidityCode.found_match def test_match_found_two(self): self._parseTree.validate("John") assert self._parseTree.validate("Hoskins") == ValidityCode.found_match def test_match_found_three(self): self._parseTree.validate("John") self._parseTree.validate("Wick") assert self._parseTree.validate("Buddy") == ValidityCode.found_match
def setUp(self): testInput = ["test one two three", "test one two three", "test one two three"] self._parseTree = ParseTree(testInput)
class KeywordInstanceTable: def __init__(self): self.__current = 0 self.__instances = [] # Registered viewers for observer design pattern self.__views = [] self.__indexObject = Index(os.path.join("res", "index.xml")) self.__parse_tree = ParseTree(self.__indexObject.keys()) def get_current_entry(self): """Returns the currently selected KeywordInstance.""" if len(self.__instances) == 0: return None else: return self.__instances[self.__current] def get_current_index(self): return self.__current def get_viewers(self): return self.__views def get_index(self): return self.__indexObject def set_index_object(self, index): self.__indexObject = index def append(self, keyword_instance): assert type( keyword_instance ) is KeywordInstance, "Only KeywordInstances can be appended." self.__instances.append(keyword_instance) def lookup(self, start_index): """Returns the KeywordInstance that corrosponds to the given CHARECTOR index.""" # This could be a binary search. for index, instance in enumerate(self.__instances): if instance.get_start() <= start_index <= instance.get_stop(): if instance.is_ambiguous(): self.__current = index return instance else: return None return None def jump_to(self, tableIndex): """Skip to a certain keyword table index.""" # assert to prevent jumps to pronouns, etc. assert self.__instances[tableIndex].is_ambiguous() self.__current = tableIndex % len(self.__instances) self.notify_viewers_redraw() def make_index(self): """Instantiates an Index object. Needed for session loading.""" self.__indexObject = Index("../META/index.xml") def reset(self): """Dereferences the table, and resets the current cursor to 0.""" self.__instances = [] self.__current = 0 def next_valid_entry(self, event=None): """ Returns the next valid entry that is ambiguous, and set the cursor to that index.""" table_length = len(self.__instances) for i in range(1, table_length): new_index = (self.__current + i) % table_length if self.__instances[new_index].is_ambiguous(): break self.__current = new_index self.notify_viewers_redraw() def previous_valid_entry(self, event=None): """ Returns the previous valid entry that is ambiguous, and set the cursor to that index.""" table_length = len(self.__instances) for i in range(1, table_length): new_index = (self.__current - i) % table_length if self.__instances[new_index].is_ambiguous(): break print("new:", new_index) self.__current = new_index self.notify_viewers_redraw() def next_tag(self, event=None): """ Move to the next tag in the list of tag suggestions (entry list) """ # Don't allow changes to confirmed entries if self.get_current_entry().is_confirmed(): return # Some weird mod arithmetic here, but it is needed to move seamlessly # through the range, (-1, len(possibleTags) - 1) new_index = self.get_current_entry().get_selection_index() new_index += 2 new_index %= (len(self.get_current_entry().get_entries()) + 1) new_index -= 1 self.get_current_entry().set_selection_index(new_index) self.notify_viewers_redraw() def prev_tag(self, event=None): """ Move to the previous tag in the list of tag suggestions (entry list) """ # Don't allow changes to confirmed entries if self.get_current_entry().is_confirmed(): return # Some weird mod arithmetic here, but it is needed to move seamlessly # through the range, (-1, len(possibleTags) - 1) new_index = self.get_current_entry().get_selection_index() new_index %= (len(self.get_current_entry().get_entries()) + 1) new_index -= 1 self.get_current_entry().set_selection_index(new_index) self.notify_viewers_redraw() def toggle_confirm_current(self, event=None): self.get_current_entry().toggle_confirm() self.notify_viewers_redraw() def fill_table(self, string): """Build a sorted (by start index) table of all KeywordInstances.""" self.reset() # Ideally, make a generator for each relevant line iterator = re.finditer("\w+(-\w+)?", string) keyword = "" potential_instance = KeywordInstance() found_match = False word = next(iterator) try: while True: # Yes, it's an infinite loop. It's the solution the # docs suggested. # Kind of inefficient, but seems to be fast enough # inx = int(tk.Text.index("1.0+%sc" % word.start()).split(".")[0]) inx = string.count("\n", 0, word.start()) + 1 # Only run the next bit if it's an interviewee. use "if true" # to not skip any lines. # if True: if (inx % 4 - 1) != 0: validity_code = self.__parse_tree.validate( word.group().lower()) if validity_code == ValidityCode.no_match: # This is the point when an entry is actually # saved. When it finds a match, it waits until # it hits a zero to save it, in case there are a # couple keys like so: "фон", "фон триер". We # want the second, longer tag, not the shorter. if found_match: potential_instance.set_string(keyword) index_entries = self.__indexObject.lookup( keyword.lower()) potential_instance.set_entries(index_entries) # set to unambiguous. checks len is 1 to avoid # multiple definitions of word bugs by accident. if len(index_entries) == 1 and index_entries[ 0].get_value("unambiguous") == "true": potential_instance.toggle_ambiguous( ) # set to false (unambiguous) self.__instances.append(potential_instance) # Reset the saved values. keyword = "" potential_instance = KeywordInstance() found_match = False # Continue rechecks the same word with a re- # set multiTest, in case two keywords are # next to each other. continue keyword = "" potential_instance = KeywordInstance() elif validity_code == ValidityCode.potential_match: # If there is a word, add a space before the # next one. if keyword != "": keyword += " " else: potential_instance.set_start(word.start()) keyword += word.group() elif validity_code == ValidityCode.found_match: if keyword != "": keyword += " " else: potential_instance.set_start(word.start()) keyword += word.group() potential_instance.set_stop(word.end()) found_match = True word = next(iterator) except StopIteration: # May need to save the last information, in case the final # word is a keyword pass self.next_valid_entry() # start at the first value # ------- Methods to implement subject / observer design pattern -------- def notify_viewers_redraw(self): for view in self.__views: view.update() def register_viewer(self, newView): self.__views.append(newView) def delete_viewer(self, viewToDelete): self.__views.remove(viewToDelete) # ------------------------------------------------------------------------ def prepare_for_serialization(self): # These elements are not serializable, so they need to be deleted. self.__views = [] self.__indexObject = None def __next__(self): if self.__iter_current == len(self.__instances) - 1: raise StopIteration else: self.__iter_current += 1 return self.__instances[self.__iter_current] def __iter__(self): self.__iter_current = -1 return self def __reversed__(self): return reversed(self.__instances)