예제 #1
0
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())
예제 #3
0
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
예제 #4
0
 def setUp(self):
     testInput = ["test", "test", "test"]
     self._parseTree = ParseTree(testInput)
예제 #5
0
 def setUp(self):
     self._parseTree = ParseTree([])
예제 #6
0
 def setUp(self):
     testInput = ["John Hoskins",
                  "John Wick Buddy",
                  "John"]
     self._parseTree = ParseTree(testInput)
예제 #7
0
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
예제 #8
0
 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)