def test_set_children_raises(self): test = self._test_set_children_raises test(Word("foo"), [Word("foo")]) test(Phrase('"foo"'), [Word("foo")]) test(Regex("/foo/"), [Word("foo")]) test(SearchField("foo", Word("bar")), []) test(SearchField("foo", Word("bar")), [Word("bar"), Word("baz")]) test(Group(Word("foo")), []) test(Group(Word("foo")), [Word("foo"), Word("bar")]) test(FieldGroup(Word("foo")), []) test(FieldGroup(Word("foo")), [Word("foo"), Word("bar")]) test(Range(Word("20"), Word("30")), []) test(Range(Word("20"), Word("30")), [Word("20"), Word("30"), Word("40")]) test(Proximity(Word("foo")), []) test(Proximity(Word("foo")), [Word("foo"), Word("bar")]) test(Fuzzy(Word("foo")), []) test(Fuzzy(Word("foo")), [Word("foo"), Word("bar")]) test(Boost(Word("foo"), force=1), []) test(Boost(Word("foo"), force=1), [Word("foo"), Word("bar")]) test(Plus(Word("foo")), []) test(Plus(Word("foo")), [Word("foo"), Word("bar")]) test(Not(Word("foo")), []) test(Not(Word("foo")), [Word("foo"), Word("bar")]) test(Prohibit(Word("foo")), []) test(Prohibit(Word("foo")), [Word("foo"), Word("bar")])
def test_approx(self): tree = (UnknownOperation( Proximity(Phrase('"foo bar"'), 3, tail=" "), Proximity(Phrase('"foo baz"'), None, tail=" "), Fuzzy(Word('baz'), Decimal("0.3"), tail=" "), Fuzzy(Word('fou'), None))) parsed = parser.parse('"foo bar"~3 "foo baz"~ baz~0.3 fou~') self.assertEqual(str(parsed), str(tree)) self.assertEqual(parsed, tree)
def test_fuzzy(self): orig = Fuzzy(Word("bar"), degree=.3, pos=3, head="\n", tail="\t") copy = orig.clone_item() self.assert_equal_tail_head_pos(orig, copy) self.assertEqual(orig.degree, copy.degree) self.assertEqual(copy.term, NONE_ITEM) self.assertNotEqual(orig, copy) copy.children = [Word("bar")] self.assertEqual(orig, copy)
def test_equality_fuzzy(self): f1 = Fuzzy(term=Word('foo'), degree=5) f2 = Fuzzy(term=Word('bar'), degree=5) f3 = Fuzzy(term=Word('foo'), degree=5) f4 = Fuzzy(term=Word('foo'), degree=.5) f5 = Fuzzy(term=Word('foo'), degree=None) self.assertNotEqual(f1, f2) self.assertEqual(f1, f3) self.assertNotEqual(f1, f4) self.assertEqual(f4, f5)
def test_fuzzy(self): item = Fuzzy(Word("foo"), degree=None) self.assertEqual(str(item), "foo~") self.assertEqual(repr(item), "Fuzzy(Word('foo'), 0.5)") self.assertEqual(item.degree, Decimal(".5").normalize()) item = Fuzzy(Word("foo"), degree=".5") self.assertEqual(str(item), "foo~0.5") item = Fuzzy(Word("foo"), degree=str(1 / 3)) self.assertEqual(str(item), "foo~0.3333333333333333") # head tail item = Fuzzy(Word("foo", head="\t", tail="\n"), head="\r", tail=" ") self.assertEqual(str(item), "\tfoo\n~") self.assertEqual(item.__str__(head_tail=True), "\r\tfoo\n~ ")
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))
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)
def test_fuzzy(self): tree = parser.parse("\rfoo\t~2\n") self.assertEqual(tree, Fuzzy(Word("foo"), 2)) self.assertEqual(tree.head, "") self.assertEqual(tree.tail, "\n") self.assertEqual(tree.pos, 0) self.assertEqual(tree.size, 7) foo, = tree.children self.assertEqual(foo.head, "\r") self.assertEqual(foo.tail, "\t") self.assertEqual(foo.pos, 1) self.assertEqual(foo.size, 3) self.assertEqual(str(tree), "\rfoo\t~2") self.assertEqual(tree.__str__(head_tail=True), "\rfoo\t~2\n")
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, ))
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), [])
def test_named_queries_fuzzy(self): tree = SearchField("text", Fuzzy(Word('bar'))) set_name(tree.children[0], "a") result = self.transformer(tree) self.assertEqual( result, { "fuzzy": { "text": { "value": "bar", "_name": "a", 'fuzziness': 0.5 } } }, )
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/'), ])
def test_no_propagation(self): for tree in [ Range(Word("a"), Word("b")), Fuzzy(Word("foo")), Proximity('"bar baz"', 2) ]: with self.subTest("%r" % type(tree)): paths_ok, paths_ko = self.propagate_matching(tree, set(), {()}) # no down propagation self.assertEqual(paths_ok, set()) self.assertEqual(paths_ko, {()}) paths_ok, paths_ko = self.propagate_matching(tree, {()}, set()) self.assertEqual(paths_ok, {()}) self.assertEqual(paths_ko, set())
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")
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)', )
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")])
def test_fuzzy_negative_degree(self): check = LuceneCheck() query = Fuzzy(Word("foo"), "-4.1") self.assertFalse(check(query)) self.assertEqual(len(check.errors(query)), 1) self.assertIn("invalid degree", check.errors(query)[0])
def test_combination(self): tree = AndOperation( OrOperation( SearchField( "mine", FieldGroup( Plus(AndOperation( Word("foo"), Regex("/fizz/"), ), ), ), ), Boost( Group( AndOperation( Phrase('"ham"'), Word("spam"), Prohibit(Fuzzy(Word("fuzz"))), ), ), force=2, ), ), Not(OrOperation( Word('"bar"'), Word('"baz"'), ), ), ) to_path = simple_naming(tree) paths_ok, paths_ko = self.propagate_matching(tree, set()) self.assertEqual( paths_to_names(tree, paths_ok), {"prohibit", "not"}, ) self.assertEqual( paths_to_names(tree, paths_ko), { "and", "or", "searchfield", "fieldgroup", "plus", "and2", "foo", "fizz", "boost", "group", "and3", "ham", "spam", "fuzzy", "or2", "bar", "baz" }, ) # adding matching just enough positive expressions, so that complete expression matches paths_ok, paths_ko = self.propagate_matching( tree, {to_path["foo"], to_path["fizz"], to_path["ham"]}, ) self.assertEqual( paths_to_names(tree, paths_ok), { "and", "or", "searchfield", "fieldgroup", "plus", "and2", "foo", "fizz", "ham", "prohibit", "not" }, ) self.assertEqual( paths_to_names(tree, paths_ko), {"boost", "group", "and3", "spam", "fuzzy", "or2", "bar", "baz"}, ) # making everything match paths_ok, paths_ko = self.propagate_matching( tree, {to_path["foo"], to_path["fizz"], to_path["ham"], to_path["spam"]}, ) self.assertEqual( paths_to_names(tree, paths_ok), { "and", "or", "searchfield", "fieldgroup", "plus", "and2", "foo", "fizz", "ham", "prohibit", "boost", "group", "and3", "spam", "not" }) self.assertEqual(paths_to_names(tree, paths_ko), {"fuzzy", "or2", "bar", "baz"}) # making everything match, but some negative expression paths_ok, paths_ko = self.propagate_matching( tree, { to_path["foo"], to_path["fizz"], to_path["ham"], to_path["spam"], to_path["fuzzy"], to_path["bar"], }, ) self.assertEqual( paths_to_names(tree, paths_ok), { "or", "searchfield", "fieldgroup", "plus", "and2", "foo", "fizz", "ham", "spam", "fuzzy", "or2", "bar", }, ) self.assertEqual( paths_to_names(tree, paths_ko), { "and", "boost", "group", "and3", "prohibit", "boost", "group", "and3", "not", "baz", }, )
def test_fuzzy_non_word(self): check = LuceneCheck() query = Fuzzy(Phrase('"foo bar"'), "2") self.assertFalse(check(query)) self.assertEqual(len(check.errors(query)), 1) self.assertIn("single term", check.errors(query)[0])