package lux; import static org.junit.Assert.*; import lux.exception.LuxException; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.spans.SpanNearQuery; import org.apache.lucene.search.spans.SpanQuery; import org.apache.lucene.search.spans.SpanTermQuery; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @RunWith (MultiThreadedRunner.class) public class SearchTestNS extends BaseSearchTest { @BeforeClass public static void setup() throws Exception { setup ("lux/reader-test-ns.xml", "lux/reader-test.xml", "lux/empty-nodes.xml"); index.printAllTerms(); } @Test public void testSearchUnboundNS () throws Exception { try { assertSearch ("2", "count(lux:search('<x\\:title:test'))", null, 2); assertFalse ("Failed to raise exception", true); } catch (LuxException e) { assertEquals ("Cannot parse '<x\\:title:test': unbound namespace prefix 'x'", e.getMessage()); } // no namespace assertSearch ("2", "count(lux:search('<title:test'))", null, 2); } @Test public void testSearchNsUri () throws Exception { // namespace uri may be supplied explicitly // In Lucene 4.1, slashes must be escaped assertSearch ("2", "count(lux:search('<title\\{http\\:\\/\\/lux.net\\{test\\}\\}:test'))", null, 2); } @Test public void testSearchBoundNsPrefix() throws Exception { // Search string may use prefixes declared in surrounding context // This test should be run with a namespace-aware index assertSearch ("2", "declare namespace x='http://lux.net{test}'; count(lux:search('<x\\:title:test'))", null, 2); } @Test public void testSearchWildcardNamespace () throws Exception { // wildcarded namespace assertSearch ("4", "count(lux:search('<\\*\\:title:test'))", null, 4); } @Test public void testGeneratePathQuery () throws Exception { assertSearch ("2", "count(/entities)", null, 2); assertSearch ("0", "declare namespace x='x'; count(/x:title)", null, 0); // this actually has the correct namespace assertSearch ("1", "declare namespace x='http://lux.net{test}'; count(/x:title)", null, 1); assertSearch ("1", "declare namespace x='#2'; count(/x:entities)", null, 1); } @Test public void testAttributePredicateInPath1() throws Exception { // we were generating an incorrect query when an attribute appears in the middle of a path // in a predicate: in any case we don't optimize around the variable as we should // Note: the $id variable is magically bound to 'test' by assertSearch... assertSearch ("TEST", "declare variable $id as xs:string external; " + "let $test := collection()/test[@id=$id] " + "return $test/title/string()", null, 2); } @Test public void testAttributePredicateInPath2() throws Exception { // Variation on the above - this was generating SpanNear(Boolean(... which is an error assertSearch (null, "declare variable $id as xs:string external; " + "let $test := collection()/test[@id=$id] " + "return $test/title/other/string()", null, 0); } @Test public void testAttributePredicate() throws Exception { // Verifying that the Lucene query actually works: Query q1 = new TermQuery(new Term("lux_att_text", "id:test")); TopDocs results = index.searcher.search(q1, 10); assertEquals (2, results.totalHits); SpanNearQuery q2 = new SpanNearQuery (new SpanQuery[] { new SpanTermQuery(new Term("lux_path", "{}")), new SpanTermQuery(new Term("lux_path", "test")), new SpanTermQuery(new Term("lux_path", "title")) }, 0, true); results = index.searcher.search(q2, 10); assertEquals (2, results.totalHits); SpanNearQuery q3 = new SpanNearQuery (new SpanQuery[] { new SpanTermQuery(new Term("lux_path", "{}")), new SpanTermQuery(new Term("lux_path", "test")), new SpanTermQuery(new Term("lux_path", "@id")) }, 0, true); results = index.searcher.search(q3, 10); assertEquals (2, results.totalHits); BooleanQuery bq = new BooleanQuery (); BooleanQuery bqinner = new BooleanQuery (); bqinner.add(q1, Occur.MUST); bqinner.add(q3, Occur.MUST); bq.add(bqinner, Occur.MUST); bq.add(q2, Occur.MUST); results = index.searcher.search(bq, 10); assertEquals (1, results.totalHits); assertEquals (6, results.scoreDocs[0].doc); assertSearch ("2", "count (/test)", null, 2); assertSearch ("2", "count (/test/@id)", null, 2); assertSearch ("test", "/test/@id/string()", null, 2); // The actual test: // this was throwing a parsing exception assertSearch ("1", "count (/test[@id='test']/title)", null, 1); } @Test public void testSearchEmpty () throws Exception { // These queries aren't minimal since we don't index empty nodes assertSearch ("1", "count(//test[@id=''])", null, 2); assertSearch ("1", "count(/title[.=''])", null, 2); } } /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */