예제 #1
0
 def test_and_resolution(self):
     tree = (UnknownOperation(Word("a"), Word("b"),
                              OrOperation(Word("c"), Word("d"))))
     expected = (AndOperation(Word("a"), Word("b"),
                              OrOperation(Word("c"), Word("d"))))
     resolver = UnknownOperationResolver(resolve_to=AndOperation)
     self.assertEqual(resolver(tree), expected)
예제 #2
0
 def test_repeating_expression(self):
     # non regression test
     tree = AndOperation(
         Group(OrOperation(Word('bar'), Word('foo'))),
         Group(OrOperation(Word('bar'), Word('foo'), Word('spam'))),
     )
     # basic transformer should not change tree
     same_tree = TreeTransformer().visit(copy.deepcopy(tree))
     self.assertEqual(same_tree, tree)
예제 #3
0
    def test_mro(self):
        visitor = self.MROVisitor()

        tree = OrOperation(Word('a'), Word('b'))
        result = visitor.visit(tree)
        self.assertEquals(result, 'a OR b')

        tree = OrOperation(AndOperation(Word('a'), Word('b')), Word('c'))
        result = visitor.visit(tree)
        self.assertEquals(result, 'a BASE_OP b OR c')
예제 #4
0
 def test_groups(self):
     tree = (OrOperation(
         Word('test', tail=" "),
         Group(AndOperation(
             SearchField("subject",
                         FieldGroup(
                             OrOperation(Word('foo', tail=" "),
                                         Word('bar', head=" "))),
                         tail=" "), Word('baz', head=" ")),
               head=" ")))
     parsed = parser.parse('test OR (subject:(foo OR bar) AND baz)')
     self.assertEqual(str(parsed), str(tree))
     self.assertEqual(parsed, tree)
예제 #5
0
    def test_removal(self):
        tree = AndOperation(
            OrOperation(Word("spam"), Word("ham")),
            AndOperation(Word("foo"), Phrase('"bar"')),
            AndOperation(Phrase('"baz"'), Phrase('"biz"')),
        )

        transformer = self.BasicTransformer()
        new_tree = transformer.visit(tree)

        self.assertEqual(
            new_tree,
            AndOperation(OrOperation(Word("lol"), Word("lol")), Word("lol")),
        )
예제 #6
0
 def test_lucene_resolution_last_op_with_group(self):
     tree = (OrOperation(
         Word("a"), Word("b"),
         Group(
             AndOperation(Word("c"), UnknownOperation(Word("d"),
                                                      Word("e")))),
         UnknownOperation(Word("f"), Word("g")),
         Group(UnknownOperation(Word("h"), Word("i")))))
     expected = (OrOperation(
         Word("a"), Word("b"),
         Group(AndOperation(Word("c"), AndOperation(Word("d"), Word("e")))),
         OrOperation(Word("f"), Word("g")),
         Group(AndOperation(Word("h"), Word("i")))))
     resolver = UnknownOperationResolver(resolve_to=None)
     self.assertEqual(resolver(tree), expected)
예제 #7
0
    def test_or_operation(self):
        tree = OrOperation(Word("foo"), Phrase('"bar"'), Word("baz"))
        all_paths = {(0, ), (1, ), (2, )}

        matching = set()
        paths_ok, paths_ko = self.propagate_matching(tree, matching,
                                                     all_paths - matching)
        self.assertEqual(paths_ok, set())
        self.assertEqual(paths_ko, {
            (),
            (0, ),
            (1, ),
            (2, ),
        })

        matching = {(2, )}
        paths_ok, paths_ko = self.propagate_matching(tree, matching,
                                                     all_paths - matching)
        self.assertEqual(paths_ok, {(), (2, )})
        self.assertEqual(paths_ko, {(0, ), (1, )})

        matching = {(0, ), (2, )}
        paths_ok, paths_ko = self.propagate_matching(tree, matching,
                                                     all_paths - matching)
        self.assertEqual(paths_ok, {(), (0, ), (2, )})
        self.assertEqual(paths_ko, {(1, )})

        matching = {(0, ), (1, ), (2, )}
        paths_ok, paths_ko = self.propagate_matching(tree, matching,
                                                     all_paths - matching)
        self.assertEqual(paths_ok, {(), (0, ), (1, ), (2, )})
        self.assertEqual(paths_ko, set())
예제 #8
0
 def test_named_queries_or(self):
     tree = OrOperation(SearchField("text", Word("foo")),
                        SearchField("spam", Word("bar")))
     set_name(tree.operands[0], "a")
     set_name(tree.operands[1], "b")
     result = self.transformer(tree)
     self.assertEqual(
         result, {
             'bool': {
                 'should': [{
                     'term': {
                         'text': {
                             '_name': 'a',
                             'value': 'foo'
                         }
                     }
                 }, {
                     'match': {
                         'spam': {
                             '_name': 'b',
                             'query': 'bar',
                             'zero_terms_query': 'none'
                         }
                     }
                 }]
             }
         })
예제 #9
0
 def visit_phrase(self, node, parent):
     if (len(parent) > 0 and (isinstance(parent[-1], luqum.tree.SearchField)
                              or isinstance(parent[-1], luqum.tree.Range))):
         return node
     else:
         search_list = [SearchField(f, node) for f in self.fields]
         return Group(OrOperation(*search_list))
예제 #10
0
 def test_zealous_or_not(self):
     query = (OrOperation(Not(Word("foo")), Word("bar")))
     check_zealous = LuceneCheck(zeal=1)
     self.assertFalse(check_zealous(query))
     self.assertIn("inconsistent", check_zealous.errors(query)[0])
     check_easy_going = LuceneCheck()
     self.assertTrue(check_easy_going(query))
예제 #11
0
    def test_mro(self):
        visitor = self.MROVisitor()

        tree = OrOperation(Word('a'), Word('b'))
        result = visitor.visit(tree)
        self.assertEquals(list(result), ['a OR b', 'a', 'b'])

        tree = AndOperation(Word('a'), Word('b'))
        result = visitor.visit(tree)
        self.assertEquals(list(result), ['a BASE_OP b', 'a', 'b'])
예제 #12
0
 def test_auto_name_nested(self):
     tree = AndOperation(
         OrOperation(
             SearchField("bar", Word("test")),
             AndOperation(
                 Proximity(Phrase('"test"'), 2),
                 SearchField("baz", Word("test")),
             ),
         ),
         Group(UnknownOperation(
             Fuzzy(Word("test")),
             Phrase('"test"'),
         ), ),
     )
     names = auto_name(tree)
     self.assertEqual(sorted(names.keys()), list("abcdefgh"))
     # and
     and1 = tree
     self.assertEqual(get_name(and1), None)
     # - or
     or1 = and1.children[0]
     self.assertEqual(get_name(or1), "a")
     self.assertEqual(names["a"], (0, ))
     # -- search field
     sfield1 = or1.children[0]
     self.assertEqual(get_name(sfield1), "c")
     self.assertEqual(names["c"], (0, 0))
     self.assertEqual(get_name(sfield1.expr), None)
     # -- and
     and2 = or1.children[1]
     self.assertEqual(get_name(and2), "d")
     self.assertEqual(names["d"], (0, 1))
     # --- proximity phrase
     self.assertEqual(get_name(and2.children[0]), "e")
     self.assertEqual(names["e"], (0, 1, 0))
     self.assertEqual(get_name(and2.children[0].term), None)
     # --- search field
     sfield2 = and2.children[1]
     self.assertEqual(get_name(sfield2), "f")
     self.assertEqual(names["f"], (0, 1, 1))
     self.assertEqual(get_name(sfield2.expr), None)
     # - group
     group1 = and1.children[1]
     self.assertEqual(get_name(group1), "b")
     self.assertEqual(names["b"], (1, ))
     # -- unknown op
     unknownop1 = group1.children[0]
     self.assertEqual(get_name(unknownop1), None)
     # --- fuzzy word
     self.assertEqual(get_name(unknownop1.children[0]), "g")
     self.assertEqual(names["g"], (1, 0, 0))
     self.assertEqual(get_name(unknownop1.children[0].term), None)
     # --- phrase
     self.assertEqual(get_name(unknownop1.children[1]), "h")
     self.assertEqual(names["h"], (1, 0, 1))
예제 #13
0
 def test_visit_complex(self):
     tree = AndOperation(
         Group(
             OrOperation(Word("foo"), Word("bar"),
                         Boost(Fuzzy(Word("baz")), force=2))),
         Proximity(Phrase('"spam ham"')),
         SearchField("fizz", Regex("/fuzz/")),
     )
     transformed = self.transform(tree)
     expected = AndOperation(
         Group(
             OrOperation(
                 Word("foo@0-0-0"),
                 Word("bar@0-0-1"),
                 Boost(Fuzzy(Word("baz@0-0-2-0-0")), force=2),
             )),
         Proximity(Phrase('"spam ham@1-0"')),
         SearchField("fizz", Regex("/fuzz@2-0/")),
     )
     self.assertEqual(transformed, expected)
예제 #14
0
    def test_with_unknown_op_nested(self):
        prettify = Prettifier(indent=8, max_len=20)
        tree = OrOperation(
            UnknownOperation(Word("baaaaaaaaaar"), Word("baaaaaaaaaaaaaz")),
            Word("fooooooooooo"))
        self.assertEqual(
            "\n" + prettify(tree), """
        baaaaaaaaaar
        baaaaaaaaaaaaaz
OR
fooooooooooo""")
예제 #15
0
    def test_bad_fieldgroup(self):
        check = LuceneCheck()
        query = FieldGroup(Word("foo"))
        self.assertFalse(check(query))
        self.assertEqual(len(check.errors(query)), 1)
        self.assertIn("FieldGroup misuse", check.errors(query)[0])

        query = OrOperation(FieldGroup(Word("bar")), Word("foo"))
        self.assertFalse(check(query))
        self.assertEqual(len(check.errors(query)), 1)
        self.assertIn("FieldGroup misuse", check.errors(query)[0])
예제 #16
0
    def test_mro(self):
        visitor = self.MROVisitor()

        tree = OrOperation(Word('a'), Word('b'))
        result = visitor.visit(tree)
        self.assertEquals(list(result), ['a OR b', 'a', 'b'])

        # AndOperation has no specific method,
        # but inherists BaseOperation, hence uses visit_base_operation
        tree = AndOperation(Word('a'), Word('b'))
        result = visitor.visit(tree)
        self.assertEquals(list(result), ['a BASE_OP b', 'a', 'b'])
예제 #17
0
    def test_named_queries_complex(self):
        tree = (AndOperation(
            SearchField("text", Phrase('"foo bar"')),
            Group(OrOperation(
                Word("bar"),
                SearchField("spam", Word("baz")),
            ), ),
        ))
        and_op = tree
        search_text = and_op.operands[0]
        or_op = and_op.operands[1].children[0]
        bar = or_op.operands[0]
        search_spam = or_op.operands[1]
        set_name(search_text, "foo_bar")
        set_name(bar, "bar")
        set_name(search_spam, "baz")

        expected = {
            'bool': {
                'must': [{
                    'term': {
                        'text': {
                            '_name': 'foo_bar',
                            'value': 'foo bar'
                        }
                    }
                }, {
                    'bool': {
                        'should': [{
                            'term': {
                                'text': {
                                    '_name': 'bar',
                                    'value': 'bar'
                                }
                            }
                        }, {
                            'match': {
                                'spam': {
                                    '_name': 'baz',
                                    'query': 'baz',
                                    'zero_terms_query': 'none'
                                }
                            }
                        }]
                    }
                }]
            }
        }

        result = self.transformer(tree)
        self.assertEqual(result, expected)
예제 #18
0
 def test_check_ok(self):
     query = (AndOperation(
         SearchField(
             "f",
             FieldGroup(
                 AndOperation(
                     Boost(Proximity(Phrase('"foo bar"'), 4), "4.2"),
                     Prohibit(Range("100", "200"))))),
         Group(OrOperation(Fuzzy(Word("baz"), ".8"), Plus(Word("fizz"))))))
     check = LuceneCheck()
     self.assertTrue(check(query))
     self.assertEqual(check.errors(query), [])
     check = LuceneCheck(zeal=1)
     self.assertTrue(check(query))
     self.assertEqual(check.errors(query), [])
예제 #19
0
 def test_set_children(self):
     test = self._test_set_children
     test(Word("foo"), [])
     test(Phrase('"foo"'), [])
     test(Regex("/foo/"), [])
     test(SearchField("foo", Word("bar")), [Word("baz")])
     test(Group(Word("foo")), [Word("foo")])
     test(FieldGroup(Word("foo")), [Word("foo")])
     test(Range(Word("20"), Word("30")), [Word("40"), Word("50")])
     test(Proximity(Word("foo")), [Word("foo")])
     test(Fuzzy(Word("foo")), [Word("foo")])
     test(Boost(Word("foo"), force=1), [Word("foo")])
     many_terms = tuple(Word(f"foo_{i}") for i in range(5))
     test(UnknownOperation(Word("foo"), Word("bar")),
          (Word("foo"), Word("bar")))
     test(UnknownOperation(*many_terms), many_terms)
     test(AndOperation(Word("foo"), Word("bar")),
          (Word("foo"), Word("bar")))
     test(AndOperation(*many_terms), many_terms)
     test(OrOperation(Word("foo"), Word("bar")), (Word("foo"), Word("bar")))
     test(OrOperation(*many_terms), many_terms)
     test(Plus(Word("foo")), [Word("foo")])
     test(Not(Word("foo")), [Word("foo")])
     test(Prohibit(Word("foo")), [Word("foo")])
예제 #20
0
 def test_visit_complex(self):
     tree = AndOperation(
         Group(
             OrOperation(Word("foo"), Word("bar"),
                         Boost(Fuzzy(Word("baz")), force=2))),
         Proximity(Phrase('"spam ham"')),
         SearchField("fizz", Regex("/fuzz/")),
     )
     paths = self.visit(tree)
     self.assertEqual(sorted(paths), [
         ((0, 0, 0), "foo"),
         ((0, 0, 1), "bar"),
         ((0, 0, 2, 0, 0), "baz"),
         ((1, 0), '"spam ham"'),
         ((2, 0), '/fuzz/'),
     ])
예제 #21
0
    def test_auto_name_nested(self):
        tree = AndOperation(
            OrOperation(
                SearchField("bar", Word("test")),
                AndOperation(
                    Proximity(Phrase('"test"'), 2),
                    SearchField("baz", Word("test")),
                ),
            ),
            Group(
                UnknownOperation(
                    Fuzzy(Word("test")),
                    Phrase('"test"'),
                ),
            ),
        )

        auto_name(tree)
        # and
        and1 = tree
        self.assertEqual(get_name(and1), "0")
        # - or
        or1 = and1.children[0]
        self.assertEqual(get_name(or1), "0_0")
        # --- search field word
        sfield1 = or1.children[0]
        self.assertFalse(get_name(sfield1))
        self.assertEqual(get_name(sfield1.expr), "0_0_0")
        # --- and
        and2 = or1.children[1]
        self.assertEqual(get_name(and2), "0_0_1")
        # ----- proximity phrase
        self.assertEqual(get_name(and2.children[0].term), "0_0_1_0")
        # ----- search field word
        sfield2 = and2.children[1]
        self.assertFalse(get_name(sfield2))
        self.assertEqual(get_name(sfield2.expr), "0_0_1_1")
        # - group
        group1 = and1.children[1]
        self.assertEqual(get_name(group1), None)
        # --- unknown op
        unknownop1 = group1.children[0]
        self.assertEqual(get_name(unknownop1), "0_1")
        # ----- fuzzy word
        self.assertEqual(get_name(unknownop1.children[0].term), "0_1_0")
        # ----- phrase
        self.assertEqual(get_name(unknownop1.children[1]), "0_1_1")
예제 #22
0
 def test_lucene_resolution_last_op(self):
     tree = (OrOperation(
         Word("a"), Word("b"), UnknownOperation(Word("c"), Word("d")),
         AndOperation(Word("e"), UnknownOperation(Word("f"), Word("g"))),
         UnknownOperation(Word("i"), Word("j")),
         OrOperation(Word("k"), UnknownOperation(Word("l"), Word("m"))),
         UnknownOperation(Word("n"), Word("o"))))
     expected = (OrOperation(
         Word("a"), Word("b"), OrOperation(Word("c"), Word("d")),
         AndOperation(Word("e"), AndOperation(Word("f"), Word("g"))),
         AndOperation(Word("i"), Word("j")),
         OrOperation(Word("k"), OrOperation(Word("l"), Word("m"))),
         OrOperation(Word("n"), Word("o"))))
     resolver = UnknownOperationResolver(resolve_to=None)
     self.assertEqual(resolver(tree), expected)
예제 #23
0
    def test_combinations(self):
        # self.assertEqual(parser.parse("subject:test desc:(house OR car)").pval, "")
        tree = (UnknownOperation(
            SearchField("subject", Word("test"), tail=" "),
            AndOperation(
                SearchField("desc",
                            FieldGroup(
                                OrOperation(Word("house", tail=" "),
                                            Word("car", head=" "))),
                            tail=" "),
                Not(Proximity(Phrase('"approximatly this"'), 3, head=" "),
                    head=" "))))
        parsed = parser.parse(
            'subject:test desc:(house OR car) AND NOT "approximatly this"~3')

        self.assertEqual(str(parsed), str(tree))
        self.assertEqual(parsed, tree)
예제 #24
0
    def test_auto_name_integration(self):
        tree = (AndOperation(
            SearchField("text", Phrase('"foo bar"')),
            Group(OrOperation(
                Word("bar"),
                SearchField("spam", Word("baz")),
            ), ),
        ))
        auto_name(tree)

        expected = {
            'bool': {
                'must': [{
                    'term': {
                        'text': {
                            '_name': 'a',
                            'value': 'foo bar'
                        }
                    }
                }, {
                    'bool': {
                        'should': [{
                            'term': {
                                'text': {
                                    '_name': 'c',
                                    'value': 'bar'
                                }
                            }
                        }, {
                            'match': {
                                'spam': {
                                    '_name': 'd',
                                    'query': 'baz',
                                    'zero_terms_query': 'none'
                                }
                            }
                        }]
                    }
                }]
            }
        }

        result = self.transformer(tree)
        self.assertEqual(result, expected)
예제 #25
0
    def test_nested_negation(self):
        for NegClass in (Prohibit, Not):
            with self.subTest("%r" % NegClass):
                tree = AndOperation(
                    NegClass(
                        OrOperation(
                            NegClass(
                                AndOperation(
                                    NegClass(Word("a")),
                                    Word("b"),
                                )),
                            Word("c"),
                        )),
                    Word("d"),
                )
                a, b, c, d = (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 1), (0, 0,
                                                                   1), (1, )
                not_a, ab, not_ab = (0, 0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0)
                abc, not_abc, abcd = (0, 0), (0, ), ()

                paths_ok, paths_ko = self.propagate_matching(
                    tree, set(), {a, b, c, d})
                self.assertEqual(paths_ok, {not_a, not_ab, abc})
                self.assertEqual(paths_ko, {a, b, ab, c, not_abc, d, abcd})

                paths_ok, paths_ko = self.propagate_matching(
                    tree, {b, d}, {a, c})
                self.assertEqual(paths_ok, {not_a, b, ab, not_abc, d, abcd})
                self.assertEqual(paths_ko, {a, not_ab, c, abc})

                paths_ok, paths_ko = self.propagate_matching(
                    tree, {a, b, c}, {d})
                self.assertEqual(paths_ok, {a, b, not_ab, c, abc})
                self.assertEqual(paths_ko, {not_a, ab, not_abc, d, abcd})

                paths_ok, paths_ko = self.propagate_matching(
                    tree, {a, b, c, d}, set())
                self.assertEqual(paths_ok, {a, b, not_ab, c, abc, d})
                self.assertEqual(paths_ko, {not_a, ab, not_abc, abcd})
예제 #26
0
    def test_unknown_operation(self):
        tree = UnknownOperation(Word("foo"), Phrase('"bar"'), Word("baz"))

        tree_or = OrOperation(Word("foo"), Phrase('"bar"'), Word("baz"))
        tree_and = AndOperation(Word("foo"), Phrase('"bar"'), Word("baz"))
        propagate_or = self.propagate_matching
        propagate_and = MatchingPropagator(default_operation=AndOperation)
        all_paths = {(0, ), (1, ), (2, )}

        for matching in [
                set(), {(2, )}, {(0, ), (2, )}, {(0, ), (1, ), (2, )}
        ]:
            self.assertEqual(
                propagate_or(tree, matching),
                self.propagate_matching(tree_or, matching,
                                        matching - all_paths),
            )
            self.assertEqual(
                propagate_and(tree, matching),
                self.propagate_matching(tree_and, matching,
                                        matching - all_paths),
            )
예제 #27
0
 def test_complex(self):
     tree = Group(
         OrOperation(
             SearchField(
                 "foo",
                 FieldGroup(
                     UnknownOperation(Word("bar"),
                                      Range(Word("baz"), Word("spam")))),
             ),
             Not(Proximity(Phrase('"ham ham"'), 2)),
             Plus(Fuzzy(Word("hammer"), 3)),
         ))
     self.assertEqual(str(tree),
                      '(foo:(bar[bazTOspam])ORNOT"ham ham"~2OR+hammer~3)')
     self.assertEqual(
         str(auto_head_tail(tree)),
         '(foo:(bar [baz TO spam]) OR NOT "ham ham"~2 OR +hammer~3)',
     )
     # idem potent
     self.assertEqual(
         str(auto_head_tail(auto_head_tail(tree))),
         '(foo:(bar [baz TO spam]) OR NOT "ham ham"~2 OR +hammer~3)',
     )
예제 #28
0
 def test_element_from_path(self):
     tree = AndOperation(
         OrOperation(
             SearchField("bar", Word("test")),
             Group(
                 AndOperation(
                     Proximity(Phrase('"test"'), 2),
                     SearchField("baz", Word("test")),
                     Fuzzy(Word("test")),
                     Phrase('"test"'),
                 ), ),
         ), )
     names = {
         "a": (),
         "b": (0, 1),
         "c": (0, 1, 0, 2),
         "d": (0, 1, 0, 2, 0),
         "e": (0, 1, 0, 3)
     }
     self.assertEqual(element_from_path(tree, ()), tree)
     self.assertEqual(element_from_name(tree, "a", names), tree)
     self.assertEqual(element_from_path(tree, (0, 1)),
                      tree.children[0].children[1])
     self.assertEqual(element_from_name(tree, "b", names),
                      tree.children[0].children[1])
     self.assertEqual(element_from_path(tree, (0, 1, 0, 2)),
                      Fuzzy(Word("test")))
     self.assertEqual(element_from_name(tree, "c", names),
                      Fuzzy(Word("test")))
     self.assertEqual(element_from_path(tree, (0, 1, 0, 2, 0)),
                      Word("test"))
     self.assertEqual(element_from_name(tree, "d", names), Word("test"))
     self.assertEqual(element_from_path(tree, (0, 1, 0, 3)),
                      Phrase('"test"'))
     self.assertEqual(element_from_name(tree, "e", names), Phrase('"test"'))
     with self.assertRaises(IndexError):
         element_from_path(tree, (1, ))
예제 #29
0
 def test_or_operator(self):
     tree = parser.parse("\tfoo\nOR  bar\rOR\t\nbaz\r\r")
     self.assertEqual(tree,
                      OrOperation(Word("foo"), Word("bar"), Word("baz")))
     self.assertEqual(tree.head, "")
     self.assertEqual(tree.tail, "")
     self.assertEqual(tree.pos, 0)
     self.assertEqual(tree.size, 22)
     foo, bar, baz = tree.children
     self.assertEqual(foo.head, "\t")
     self.assertEqual(foo.tail, "\n")
     self.assertEqual(foo.pos, 1)
     self.assertEqual(foo.size, 3)
     self.assertEqual(bar.head, "  ")
     self.assertEqual(bar.tail, "\r")
     self.assertEqual(bar.pos, 9)
     self.assertEqual(bar.size, 3)
     self.assertEqual(baz.head, "\t\n")
     self.assertEqual(baz.tail, "\r\r")
     self.assertEqual(baz.pos, 17)
     self.assertEqual(baz.size, 3)
     self.assertEqual(str(tree), "\tfoo\nOR  bar\rOR\t\nbaz\r\r")
     self.assertEqual(tree.__str__(head_tail=True),
                      "\tfoo\nOR  bar\rOR\t\nbaz\r\r")
예제 #30
0
 def test_not_equality(self):
     # non regression test, adding a child should trigger non equality
     tree1 = OrOperation(Word("bar"))
     tree2 = OrOperation(Word("bar"), Word("foo"))
     self.assertNotEqual(tree1, tree2)