def test_auto_name_simple_op(self): for OpCls in AndOperation, OrOperation, UnknownOperation: with self.subTest("operation %r" % OpCls): tree = OpCls( Word("test"), Phrase('"test"'), ) auto_name(tree) self.assertEqual(get_name(tree), "0") self.assertEqual(get_name(tree.children[0]), "0_0") self.assertEqual(get_name(tree.children[1]), "0_1")
def test_or_operation(self): ltree = parser.parse("n_pages:360 OR edition:Lumos") names = auto_name(ltree) query = self.es_builder(ltree) # the one matching Lumos book, = list( self.search.filter(query).filter("term", ref="BB1").execute()) self.assertEqual(len(book.meta.matched_queries), 1) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ok"><span class="ko">n_pages:360 </span>OR edition:Lumos</span>', ) # the one matching n_pages book, = list( self.search.filter(query).filter("term", ref="HP8").execute()) self.assertEqual(len(book.meta.matched_queries), 1) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ok">n_pages:360 OR<span class="ko"> edition:Lumos</span></span>', ) # matching None book, = list( self.search.filter(Q(query) | Q("match_all")).filter( Q("term", ref="HP7")).execute()) self.assertFalse(hasattr(book.meta, "matched_queries"))
def _nested_test(self, query, html, ref, num_match=1): """scenario taking into account nested :param str matching_query: the query that match the book :param str ref: ref of expected matching book """ ltree = parser.parse(query) names = auto_name(ltree) query = self.es_builder(ltree) queries = [query] + extract_nested_queries(query) matched_queries = [] # we have to force book matching by adding condition for sub_query in queries: search = self.search.filter(Q(sub_query) | Q("term", ref=ref)).filter("term", ref=ref) book, = list(search.execute()) self.assertEqual(book.ref, ref) matched_queries.extend(getattr(book.meta, "matched_queries", [])) self.assertEqual(len(matched_queries), num_match) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), html, ) return matched_queries, html
def test_double_negation(self): ltree = parser.parse("NOT (n_pages:360 AND - edition:Lumos) AND ref:*") names = auto_name(ltree) query = self.es_builder(ltree) # matching Lumos double negation book, = list( self.search.filter(query).filter("term", ref="BB1").execute()) self.assertEqual(len(book.meta.matched_queries), 2) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ok">NOT' '<span class="ko"> (n_pages:360 AND -<span class="ok"> edition:Lumos</span>) </span>' 'AND ref:*</span>', ) # not matching Lumos double negation book, = list( self.search.filter(Q(query) | Q("term", ref="HP8")).filter( "term", ref="HP8").execute()) self.assertEqual(len(book.meta.matched_queries), 2) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ko">NOT' '<span class="ok"> (n_pages:360 AND -<span class="ko"> edition:Lumos</span>) </span>' 'AND<span class="ok"> ref:*</span></span>', )
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_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)
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_auto_name_one_term(self): tree = Word("test") names = auto_name(tree) self.assertEqual(get_name(tree), "a") self.assertEqual(names, {"a": ()}) tree = Phrase('"test"') names = auto_name(tree) self.assertEqual(get_name(tree), "a") self.assertEqual(names, {"a": ()}) tree = Range(Word("test"), Word("*")) names = auto_name(tree) self.assertEqual(get_name(tree), "a") self.assertEqual(names, {"a": ()}) tree = Regex("/test/") names = auto_name(tree) self.assertEqual(get_name(tree), "a") self.assertEqual(names, {"a": ()})
def test_auto_name_simple_op(self): for OpCls in AndOperation, OrOperation, UnknownOperation: with self.subTest("operation %r" % OpCls): tree = OpCls( Word("test"), Phrase('"test"'), ) names = auto_name(tree) self.assertEqual(get_name(tree), None) self.assertEqual(get_name(tree.children[0]), "a") self.assertEqual(get_name(tree.children[1]), "b") self.assertEqual(names, {"a": (0, ), "b": (1, )})
def test_and_operation_matching(self): ltree = parser.parse("n_pages:157 AND edition:Lumos") names = auto_name(ltree) query = self.es_builder(ltree) # matching Lumos and n_pages book, = list( self.search.filter(query).filter("term", ref="BB1").execute()) self.assertEqual(len(book.meta.matched_queries), 2) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ok">n_pages:157 AND edition:Lumos</span>', )
def _negation_test(self, operator): ltree = parser.parse(f"{operator} n_pages:360 AND edition:Lumos") names = auto_name(ltree) query = self.es_builder(ltree) # matching Lumos book, = list( self.search.filter(query).filter("term", ref="BB1").execute()) self.assertEqual(len(book.meta.matched_queries), 1) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), f'<span class="ok">{operator}<span class="ko"> n_pages:360 </span>AND' ' edition:Lumos</span>', ) # matching n_pages and not lumos search = self.search.filter(Q(query) | Q("term", ref="HP8")).filter( Q("term", ref="HP8")) book, = list(search.execute()) self.assertEqual(len(book.meta.matched_queries), 1) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), f'<span class="ko">{operator}<span class="ok"> n_pages:360 </span>' f'AND edition:Lumos</span>', ) # matching none search = self.search.filter(Q(query) | Q("term", ref="HP7")).filter( Q("term", ref="HP7")) book, = list(search.execute()) self.assertFalse(hasattr(book.meta, "matched_queries")) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names([], names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), f'<span class="ko"><span class="ok">{operator}' '<span class="ko"> n_pages:360 </span></span>' 'AND edition:Lumos</span>', )
def test_auto_name_one_term(self): tree = Word("test") auto_name(tree) self.assertEqual(get_name(tree), "0") tree = Phrase('"test"') auto_name(tree) self.assertEqual(get_name(tree), "0") tree = Range("test", "*") auto_name(tree) self.assertEqual(get_name(tree), "0")
def _simple_test(self, matching_query, ref, num_match=1): """simple scenario :param str matching_query: the query that match the book :param str ref: ref of expected matching book """ ltree = parser.parse(f"{matching_query} OR n_pages:1000") names = auto_name(ltree) query = self.es_builder(ltree) book, = list(self.search.filter(query).execute()) self.assertEqual(book.ref, ref) self.assertEqual(len(book.meta.matched_queries), num_match) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names)) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), f'<span class="ok">{matching_query} OR<span class="ko"> n_pages:1000</span></span>', )
def test_keyword_naming(self): ltree = parser.parse("illustrators.nationality:UK") names = auto_name(ltree) query = self.es_builder(ltree) results = list(self.search.filter(query).execute()) book = results[0] self.assertEqual(book.meta.matched_queries, ["a"]) self.assertEqual( element_from_name(ltree, book.meta.matched_queries[0], names), ltree, ) paths_ok, paths_ko = self.propagate_matching( ltree, *matching_from_names(book.meta.matched_queries, names), ) self.assertEqual( self.make_html(ltree, paths_ok, paths_ko), '<span class="ok">illustrators.nationality:UK</span>', )