/** * Copyright 2014 National University of Ireland, Galway. * * This file is part of the SIREn project. Project and contact information: * * https://github.com/rdelbru/SIREn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sindice.siren.search.node; import java.io.IOException; import org.apache.lucene.index.Term; import org.junit.Test; import org.sindice.siren.search.node.NodeBooleanClause.Occur; import org.sindice.siren.search.node.TwigQuery.EmptyRootQuery; import org.sindice.siren.util.SirenTestCase; public class TestTwigQuery extends SirenTestCase { @Test public void testSetLevelConstraint() { final TwigQuery tq1 = new TwigQuery(2); tq1.addDescendant(2, new NodeTermQuery(new Term("field", "value")), Occur.MUST); assertEquals(2, tq1.getLevelConstraint()); // Descendant node level must be relative to the twig level assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); tq1.setLevelConstraint(3); assertEquals(3, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(5, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq2 = new TwigQuery(); tq2.addChild(tq1, Occur.MUST); // level of tq1 must have been updated assertEquals(2, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq3 = new TwigQuery(3); tq3.addRoot(tq2); // level of tq2 must have been updated assertEquals(3, tq2.getLevelConstraint()); // level of tq1 must have been updated assertEquals(4, tq1.getLevelConstraint()); // level of descendant node must have been updated assertEquals(6, tq1.clauses().get(0).getQuery().getLevelConstraint()); } @Test public void testSetAncestorPointer() { final NodeTermQuery term = new NodeTermQuery(new Term("field", "value")); final TwigQuery tq1 = new TwigQuery(); tq1.addDescendant(2, term, Occur.MUST); // ancestor of term query must be the root of the twig assertSame(tq1.getRoot(), term.ancestor); // ancestor of the twig must be null assertNull(tq1.ancestor); final TwigQuery tq2 = new TwigQuery(); tq2.addChild(tq1, Occur.MUST); // ancestor of tq1 and of its root must have been updated assertSame(tq2.getRoot(), tq1.ancestor); assertSame(tq2.getRoot(), tq1.getRoot().ancestor); // ancestor of tq1's descendant must have not changed assertEquals(4, tq1.clauses().get(0).getQuery().getLevelConstraint()); final TwigQuery tq3 = new TwigQuery(3); tq3.addRoot(tq2); // ancestor of tq2 and of its root must be the ancestor of tq3 assertSame(tq3.ancestor, tq2.ancestor); assertSame(tq2.ancestor, tq2.getRoot().ancestor); } @Test public void testRewriteEmptyRoot() throws IOException { TwigQuery tq = new TwigQuery(2); tq.setBoost(0.5f); // with only one clause, it must be rewritten into an AncestorFilterQuery // wrapping the descendant query final NodeTermQuery ntq = new NodeTermQuery(new Term("field", "value")); tq.addDescendant(2, ntq, Occur.MUST); NodeQuery q = (NodeQuery) tq.rewrite(null); assertTrue(q instanceof AncestorFilterQuery); assertEquals(2, q.getLevelConstraint()); assertEquals(tq.getBoost(), q.getBoost(), 0); final NodeTermQuery nested = (NodeTermQuery) ((AncestorFilterQuery) q).getQuery(); assertEquals(ntq, nested); // ancestor of single clause should be its AncestorFilterQuery assertEquals(q, nested.ancestor); // ancestor of rewritten query should be the same, as the ancestor has not // been rewritten yet assertSame(tq.ancestor, q.ancestor); // if more than one clause, it must not be rewritten tq.addDescendant(2, new NodeTermQuery(new Term("field", "value")), Occur.MUST); q = (NodeQuery) tq.rewrite(null); assertSame(tq, q); // with only one clause and with node constraints, it must be rewritten tq = new TwigQuery(2); tq.setNodeConstraint(3); tq.addDescendant(2, new NodeTermQuery(new Term("field", "value")), Occur.MUST); q = (NodeQuery) tq.rewrite(null); assertTrue(q instanceof AncestorFilterQuery); assertEquals(3, q.lowerBound); assertEquals(3, q.upperBound); } @Test public void testRewriteEmptyRoot2() throws IOException { final TwigQuery tq = new TwigQuery(2); final NodeQuery q = (NodeQuery) tq.rewrite(null); assertTrue(q instanceof EmptyRootQuery); } @Test public void testRewriteEmptyClauses() throws IOException { final TwigQuery tq = new TwigQuery(2); tq.addRoot(new NodeTermQuery(new Term("field", "value"))); tq.setBoost(0.5f); // it must be rewritten into the root query final NodeQuery q = (NodeQuery) tq.rewrite(null); assertTrue(q instanceof NodeTermQuery); assertEquals(2, q.getLevelConstraint()); assertEquals(tq.getBoost(), q.getBoost(), 0); assertSame(tq.ancestor, q.ancestor); } @Test public void testRewriteTwigQueryRoot() throws IOException { // if the root node of a twig query is another twig query, then they must // be merged final TwigQuery tq2 = new TwigQuery(2); tq2.addRoot(new NodeTermQuery(new Term("root2", "root2"))); tq2.addChild(new NodeTermQuery(new Term("child2", "child2")), Occur.MUST); tq2.setBoost(0.5f); final TwigQuery tq1 = new TwigQuery(); tq1.addRoot(tq2); tq1.addChild(new NodeTermQuery(new Term("child1", "child1")), Occur.MUST); tq1.setBoost(0.5f); final NodeQuery q = (NodeQuery) tq1.rewrite(null); assertTrue(q instanceof TwigQuery); final TwigQuery tq = (TwigQuery) q; // level and boosst must be the same than for tq1 assertEquals(1, tq.getLevelConstraint()); assertEquals(tq.getBoost(), tq1.getBoost(), 0); // root must not be the same than for tq2 (it has been cloned) assertNotSame(tq.getRoot(), tq2.getRoot()); // root must be equal to the root of tq2 assertEquals(tq.getRoot(), tq2.getRoot()); // clauses must be merged assertEquals(2, tq.clauses().size()); for (final NodeBooleanClause clause : tq.clauses()) { assertEquals(2, clause.getQuery().getLevelConstraint()); assertSame(tq.getRoot(), clause.getQuery().ancestor); } } }