/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.lucene.queryparser.simple; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.PrefixQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.TestUtil; import org.apache.lucene.util.automaton.LevenshteinAutomata; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.AND_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.ESCAPE_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.FUZZY_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.NOT_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.OR_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.PHRASE_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.PRECEDENCE_OPERATORS; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.PREFIX_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.NEAR_OPERATOR; import static org.apache.lucene.queryparser.simple.SimpleQueryParser.WHITESPACE_OPERATOR; /** Tests for {@link SimpleQueryParser} */ public class TestSimpleQueryParser extends LuceneTestCase { /** * helper to parse a query with whitespace+lowercase analyzer across "field", * with default operator of MUST */ private Query parse(String text) { Analyzer analyzer = new MockAnalyzer(random()); SimpleQueryParser parser = new SimpleQueryParser(analyzer, "field"); parser.setDefaultOperator(Occur.MUST); return parser.parse(text); } /** * helper to parse a query with whitespace+lowercase analyzer across "field", * with default operator of MUST */ private Query parse(String text, int flags) { Analyzer analyzer = new MockAnalyzer(random()); SimpleQueryParser parser = new SimpleQueryParser(analyzer, Collections.singletonMap("field", 1f), flags); parser.setDefaultOperator(Occur.MUST); return parser.parse(text); } /** test a simple term */ public void testTerm() throws Exception { Query expected = new TermQuery(new Term("field", "foobar")); assertEquals(expected, parse("foobar")); } /** test a fuzzy query */ public void testFuzzy() throws Exception { Query regular = new TermQuery(new Term("field", "foobar")); Query expected = new FuzzyQuery(new Term("field", "foobar"), 2); assertEquals(expected, parse("foobar~2")); assertEquals(expected, parse("foobar~")); assertEquals(regular, parse("foobar~a")); assertEquals(regular, parse("foobar~1a")); BooleanQuery.Builder bool = new BooleanQuery.Builder(); FuzzyQuery fuzzy = new FuzzyQuery(new Term("field", "foo"), LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE); bool.add(fuzzy, Occur.MUST); bool.add(new TermQuery(new Term("field", "bar")), Occur.MUST); assertEquals(bool.build(), parse("foo~" + LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE + 1 + " bar")); } /** test a simple phrase */ public void testPhrase() throws Exception { PhraseQuery expected = new PhraseQuery("field", "foo", "bar"); assertEquals(expected, parse("\"foo bar\"")); } /** test a simple phrase with various slop settings */ public void testPhraseWithSlop() throws Exception { PhraseQuery expectedWithSlop = new PhraseQuery(2, "field", "foo", "bar"); assertEquals(expectedWithSlop, parse("\"foo bar\"~2")); PhraseQuery expectedWithMultiDigitSlop = new PhraseQuery(10, "field", "foo", "bar"); assertEquals(expectedWithMultiDigitSlop, parse("\"foo bar\"~10")); PhraseQuery expectedNoSlop = new PhraseQuery("field", "foo", "bar"); assertEquals("Ignore trailing tilde with no slop", expectedNoSlop, parse("\"foo bar\"~")); assertEquals("Ignore non-numeric trailing slop", expectedNoSlop, parse("\"foo bar\"~a")); assertEquals("Ignore non-numeric trailing slop", expectedNoSlop, parse("\"foo bar\"~1a")); assertEquals("Ignore negative trailing slop", expectedNoSlop, parse("\"foo bar\"~-1")); PhraseQuery pq = new PhraseQuery(12, "field", "foo", "bar"); BooleanQuery.Builder expectedBoolean = new BooleanQuery.Builder(); expectedBoolean.add(pq, Occur.MUST); expectedBoolean.add(new TermQuery(new Term("field", "baz")), Occur.MUST); assertEquals(expectedBoolean.build(), parse("\"foo bar\"~12 baz")); } /** test a simple prefix */ public void testPrefix() throws Exception { PrefixQuery expected = new PrefixQuery(new Term("field", "foobar")); assertEquals(expected, parse("foobar*")); } /** test some AND'd terms using '+' operator */ public void testAND() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "foo")), Occur.MUST); expected.add(new TermQuery(new Term("field", "bar")), Occur.MUST); assertEquals(expected.build(), parse("foo+bar")); } /** test some AND'd phrases using '+' operator */ public void testANDPhrase() throws Exception { PhraseQuery phrase1 = new PhraseQuery("field", "foo", "bar"); PhraseQuery phrase2 = new PhraseQuery("field", "star", "wars"); BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(phrase1, Occur.MUST); expected.add(phrase2, Occur.MUST); assertEquals(expected.build(), parse("\"foo bar\"+\"star wars\"")); } /** test some AND'd terms (just using whitespace) */ public void testANDImplicit() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "foo")), Occur.MUST); expected.add(new TermQuery(new Term("field", "bar")), Occur.MUST); assertEquals(expected.build(), parse("foo bar")); } /** test some OR'd terms */ public void testOR() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "foo")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "bar")), Occur.SHOULD); assertEquals(expected.build(), parse("foo|bar")); assertEquals(expected.build(), parse("foo||bar")); } /** test some OR'd terms (just using whitespace) */ public void testORImplicit() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "foo")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "bar")), Occur.SHOULD); SimpleQueryParser parser = new SimpleQueryParser(new MockAnalyzer(random()), "field"); assertEquals(expected.build(), parser.parse("foo bar")); } /** test some OR'd phrases using '|' operator */ public void testORPhrase() throws Exception { PhraseQuery phrase1 = new PhraseQuery("field", "foo", "bar"); PhraseQuery phrase2 = new PhraseQuery("field", "star", "wars"); BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(phrase1, Occur.SHOULD); expected.add(phrase2, Occur.SHOULD); assertEquals(expected.build(), parse("\"foo bar\"|\"star wars\"")); } /** test negated term */ public void testNOT() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "foo")), Occur.MUST_NOT); expected.add(new MatchAllDocsQuery(), Occur.SHOULD); assertEquals(expected.build(), parse("-foo")); assertEquals(expected.build(), parse("-(foo)")); assertEquals(expected.build(), parse("---foo")); } /** test crazy prefixes with multiple asterisks */ public void testCrazyPrefixes1() throws Exception { Query expected = new PrefixQuery(new Term("field", "st*ar")); assertEquals(expected, parse("st*ar*")); } /** test prefixes with some escaping */ public void testCrazyPrefixes2() throws Exception { Query expected = new PrefixQuery(new Term("field", "st*ar\\*")); assertEquals(expected, parse("st*ar\\\\**")); } /** not a prefix query! the prefix operator is escaped */ public void testTermInDisguise() throws Exception { Query expected = new TermQuery(new Term("field", "st*ar\\*")); assertEquals(expected, parse("sT*Ar\\\\\\*")); } // a number of test cases here have garbage/errors in // the syntax passed in to test that the query can // still be interpreted as a guess to what the human // input was trying to be public void testGarbageTerm() throws Exception { Query expected = new TermQuery(new Term("field", "star")); assertEquals(expected, parse("star")); assertEquals(expected, parse("star\n")); assertEquals(expected, parse("star\r")); assertEquals(expected, parse("star\t")); assertEquals(expected, parse("star(")); assertEquals(expected, parse("star)")); assertEquals(expected, parse("star\"")); assertEquals(expected, parse("\t \r\n\nstar \n \r \t ")); assertEquals(expected, parse("- + \"\" - star \\")); } public void testGarbageEmpty() throws Exception { MatchNoDocsQuery expected = new MatchNoDocsQuery(); assertEquals(expected, parse("")); assertEquals(expected, parse(" ")); assertEquals(expected, parse(" ")); assertEquals(expected, parse("\\ ")); assertEquals(expected, parse("\\ \\ ")); assertEquals(expected, parse("\"\"")); assertEquals(expected, parse("\" \"")); assertEquals(expected, parse("\" \"|\" \"")); assertEquals(expected, parse("(\" \"|\" \")")); assertEquals(expected, parse("\" \" \" \"")); assertEquals(expected, parse("(\" \" \" \")")); } public void testGarbageAND() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.MUST); expected.add(new TermQuery(new Term("field", "wars")), Occur.MUST); assertEquals(expected.build(), parse("star wars")); assertEquals(expected.build(), parse("star+wars")); assertEquals(expected.build(), parse(" star wars ")); assertEquals(expected.build(), parse(" star + wars ")); assertEquals(expected.build(), parse(" | star + + | wars ")); assertEquals(expected.build(), parse(" | star + + | wars \\")); } public void testGarbageOR() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "wars")), Occur.SHOULD); assertEquals(expected.build(), parse("star|wars")); assertEquals(expected.build(), parse(" star | wars ")); assertEquals(expected.build(), parse(" | star | + | wars ")); assertEquals(expected.build(), parse(" + star | + + wars \\")); } public void testGarbageNOT() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.MUST_NOT); expected.add(new MatchAllDocsQuery(), Occur.SHOULD); assertEquals(expected.build(), parse("-star")); assertEquals(expected.build(), parse("---star")); assertEquals(expected.build(), parse("- -star -")); } public void testGarbagePhrase() throws Exception { PhraseQuery expected = new PhraseQuery("field", "star", "wars"); assertEquals(expected, parse("\"star wars\"")); assertEquals(expected, parse("\"star wars\\ \"")); assertEquals(expected, parse("\"\" | \"star wars\"")); assertEquals(expected, parse(" \"star wars\" \"\"\\")); } public void testGarbageSubquery() throws Exception { Query expected = new TermQuery(new Term("field", "star")); assertEquals(expected, parse("(star)")); assertEquals(expected, parse("(star))")); assertEquals(expected, parse("((star)")); assertEquals(expected, parse(" -()(star) \n\n\r ")); assertEquals(expected, parse("| + - ( + - | star \n ) \n")); } public void testCompoundAnd() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.MUST); expected.add(new TermQuery(new Term("field", "wars")), Occur.MUST); expected.add(new TermQuery(new Term("field", "empire")), Occur.MUST); assertEquals(expected.build(), parse("star wars empire")); assertEquals(expected.build(), parse("star+wars + empire")); assertEquals(expected.build(), parse(" | --star wars empire \n\\")); } public void testCompoundOr() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "wars")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); assertEquals(expected.build(), parse("star|wars|empire")); assertEquals(expected.build(), parse("star|wars | empire")); assertEquals(expected.build(), parse(" | --star|wars|empire \n\\")); } public void testComplex00() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner = new BooleanQuery.Builder(); inner.add(new TermQuery(new Term("field", "star")), Occur.SHOULD); inner.add(new TermQuery(new Term("field", "wars")), Occur.SHOULD); expected.add(inner.build(), Occur.MUST); expected.add(new TermQuery(new Term("field", "empire")), Occur.MUST); assertEquals(expected.build(), parse("star|wars empire")); assertEquals(expected.build(), parse("star|wars + empire")); assertEquals(expected.build(), parse("star| + wars + ----empire |")); } public void testComplex01() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner = new BooleanQuery.Builder(); inner.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner.add(new TermQuery(new Term("field", "wars")), Occur.MUST); expected.add(inner.build(), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); assertEquals(expected.build(), parse("star wars | empire")); assertEquals(expected.build(), parse("star + wars|empire")); assertEquals(expected.build(), parse("star + | wars | ----empire +")); } public void testComplex02() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner = new BooleanQuery.Builder(); inner.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner.add(new TermQuery(new Term("field", "wars")), Occur.MUST); expected.add(inner.build(), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "strikes")), Occur.SHOULD); assertEquals(expected.build(), parse("star wars | empire | strikes")); assertEquals(expected.build(), parse("star + wars|empire | strikes")); assertEquals(expected.build(), parse("star + | wars | ----empire | + --strikes \\")); } public void testComplex03() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner = new BooleanQuery.Builder(); BooleanQuery.Builder inner2 = new BooleanQuery.Builder(); inner2.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner2.add(new TermQuery(new Term("field", "wars")), Occur.MUST); inner.add(inner2.build(), Occur.SHOULD); inner.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); inner.add(new TermQuery(new Term("field", "strikes")), Occur.SHOULD); expected.add(inner.build(), Occur.MUST); expected.add(new TermQuery(new Term("field", "back")), Occur.MUST); assertEquals(expected.build(), parse("star wars | empire | strikes back")); assertEquals(expected.build(), parse("star + wars|empire | strikes + back")); assertEquals(expected.build(), parse("star + | wars | ----empire | + --strikes + | --back \\")); } public void testComplex04() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner = new BooleanQuery.Builder(); BooleanQuery.Builder inner2 = new BooleanQuery.Builder(); inner.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner.add(new TermQuery(new Term("field", "wars")), Occur.MUST); inner2.add(new TermQuery(new Term("field", "strikes")), Occur.MUST); inner2.add(new TermQuery(new Term("field", "back")), Occur.MUST); expected.add(inner.build(), Occur.SHOULD); expected.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); expected.add(inner2.build(), Occur.SHOULD); assertEquals(expected.build(), parse("(star wars) | empire | (strikes back)")); assertEquals(expected.build(), parse("(star + wars) |empire | (strikes + back)")); assertEquals(expected.build(), parse("(star + | wars |) | ----empire | + --(strikes + | --back) \\")); } public void testComplex05() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner1 = new BooleanQuery.Builder(); BooleanQuery.Builder inner2 = new BooleanQuery.Builder(); BooleanQuery.Builder inner3 = new BooleanQuery.Builder(); BooleanQuery.Builder inner4 = new BooleanQuery.Builder(); inner1.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner1.add(new TermQuery(new Term("field", "wars")), Occur.MUST); inner2.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); inner3.add(new TermQuery(new Term("field", "strikes")), Occur.MUST); inner3.add(new TermQuery(new Term("field", "back")), Occur.MUST); inner4.add(new TermQuery(new Term("field", "jarjar")), Occur.MUST_NOT); inner4.add(new MatchAllDocsQuery(), Occur.SHOULD); inner3.add(inner4.build(), Occur.MUST); inner2.add(inner3.build(), Occur.SHOULD); expected.add(inner1.build(), Occur.SHOULD); expected.add(inner2.build(), Occur.SHOULD); assertEquals(expected.build(), parse("(star wars) | (empire | (strikes back -jarjar))")); assertEquals(expected.build(), parse("(star + wars) |(empire | (strikes + back -jarjar) () )")); assertEquals(expected.build(), parse("(star + | wars |) | --(--empire | + --(strikes + | --back + -jarjar) \"\" ) \"")); } public void testComplex06() throws Exception { BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder inner1 = new BooleanQuery.Builder(); BooleanQuery.Builder inner2 = new BooleanQuery.Builder(); BooleanQuery.Builder inner3 = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("field", "star")), Occur.MUST); inner1.add(new TermQuery(new Term("field", "wars")), Occur.SHOULD); inner3.add(new TermQuery(new Term("field", "empire")), Occur.SHOULD); inner3.add(new TermQuery(new Term("field", "strikes")), Occur.SHOULD); inner2.add(inner3.build(), Occur.MUST); inner2.add(new TermQuery(new Term("field", "back")), Occur.MUST); inner2.add(new TermQuery(new Term("field", "jar+|jar")), Occur.MUST); inner1.add(inner2.build(), Occur.SHOULD); expected.add(inner1.build(), Occur.MUST); assertEquals(expected.build(), parse("star (wars | (empire | strikes back jar\\+\\|jar))")); assertEquals(expected.build(), parse("star + (wars |(empire | strikes + back jar\\+\\|jar) () )")); assertEquals(expected.build(), parse("star + (| wars | | --(--empire | + --strikes + | --back + jar\\+\\|jar) \"\" ) \"")); } /** test a term with field weights */ public void testWeightedTerm() throws Exception { Map<String,Float> weights = new LinkedHashMap<>(); weights.put("field0", 5f); weights.put("field1", 10f); BooleanQuery.Builder expected = new BooleanQuery.Builder(); Query field0 = new TermQuery(new Term("field0", "foo")); field0 = new BoostQuery(field0, 5f); expected.add(field0, Occur.SHOULD); Query field1 = new TermQuery(new Term("field1", "foo")); field1 = new BoostQuery(field1, 10f); expected.add(field1, Occur.SHOULD); Analyzer analyzer = new MockAnalyzer(random()); SimpleQueryParser parser = new SimpleQueryParser(analyzer, weights); assertEquals(expected.build(), parser.parse("foo")); } /** test a more complex query with field weights */ public void testWeightedOR() throws Exception { Map<String,Float> weights = new LinkedHashMap<>(); weights.put("field0", 5f); weights.put("field1", 10f); BooleanQuery.Builder expected = new BooleanQuery.Builder(); BooleanQuery.Builder foo = new BooleanQuery.Builder(); Query field0 = new TermQuery(new Term("field0", "foo")); field0 = new BoostQuery(field0, 5f); foo.add(field0, Occur.SHOULD); Query field1 = new TermQuery(new Term("field1", "foo")); field1 = new BoostQuery(field1, 10f); foo.add(field1, Occur.SHOULD); expected.add(foo.build(), Occur.SHOULD); BooleanQuery.Builder bar = new BooleanQuery.Builder(); field0 = new TermQuery(new Term("field0", "bar")); field0 = new BoostQuery(field0, 5f); bar.add(field0, Occur.SHOULD); field1 = new TermQuery(new Term("field1", "bar")); field1 = new BoostQuery(field1, 10f); bar.add(field1, Occur.SHOULD); expected.add(bar.build(), Occur.SHOULD); Analyzer analyzer = new MockAnalyzer(random()); SimpleQueryParser parser = new SimpleQueryParser(analyzer, weights); assertEquals(expected.build(), parser.parse("foo|bar")); } /** helper to parse a query with keyword analyzer across "field" */ private Query parseKeyword(String text, int flags) { Analyzer analyzer = new MockAnalyzer(random(), MockTokenizer.KEYWORD, false); SimpleQueryParser parser = new SimpleQueryParser(analyzer, Collections.singletonMap("field", 1f), flags); return parser.parse(text); } /** test the ability to enable/disable phrase operator */ public void testDisablePhrase() { Query expected = new TermQuery(new Term("field", "\"test\"")); assertEquals(expected, parseKeyword("\"test\"", ~PHRASE_OPERATOR)); } /** test the ability to enable/disable prefix operator */ public void testDisablePrefix() { Query expected = new TermQuery(new Term("field", "test*")); assertEquals(expected, parseKeyword("test*", ~PREFIX_OPERATOR)); } /** test the ability to enable/disable AND operator */ public void testDisableAND() { Query expected = new TermQuery(new Term("field", "foo+bar")); assertEquals(expected, parseKeyword("foo+bar", ~AND_OPERATOR)); expected = new TermQuery(new Term("field", "+foo+bar")); assertEquals(expected, parseKeyword("+foo+bar", ~AND_OPERATOR)); } /** test the ability to enable/disable OR operator */ public void testDisableOR() { Query expected = new TermQuery(new Term("field", "foo|bar")); assertEquals(expected, parseKeyword("foo|bar", ~OR_OPERATOR)); expected = new TermQuery(new Term("field", "|foo|bar")); assertEquals(expected, parseKeyword("|foo|bar", ~OR_OPERATOR)); } /** test the ability to enable/disable NOT operator */ public void testDisableNOT() { Query expected = new TermQuery(new Term("field", "-foo")); assertEquals(expected, parseKeyword("-foo", ~NOT_OPERATOR)); } /** test the ability to enable/disable precedence operators */ public void testDisablePrecedence() { Query expected = new TermQuery(new Term("field", "(foo)")); assertEquals(expected, parseKeyword("(foo)", ~PRECEDENCE_OPERATORS)); expected = new TermQuery(new Term("field", ")foo(")); assertEquals(expected, parseKeyword(")foo(", ~PRECEDENCE_OPERATORS)); } /** test the ability to enable/disable escape operators */ public void testDisableEscape() { Query expected = new TermQuery(new Term("field", "foo\\bar")); assertEquals(expected, parseKeyword("foo\\bar", ~ESCAPE_OPERATOR)); assertEquals(expected, parseKeyword("(foo\\bar)", ~ESCAPE_OPERATOR)); assertEquals(expected, parseKeyword("\"foo\\bar\"", ~ESCAPE_OPERATOR)); } public void testDisableWhitespace() { Query expected = new TermQuery(new Term("field", "foo foo")); assertEquals(expected, parseKeyword("foo foo", ~WHITESPACE_OPERATOR)); expected = new TermQuery(new Term("field", " foo foo\n ")); assertEquals(expected, parseKeyword(" foo foo\n ", ~WHITESPACE_OPERATOR)); expected = new TermQuery(new Term("field", "\t\tfoo foo foo")); assertEquals(expected, parseKeyword("\t\tfoo foo foo", ~WHITESPACE_OPERATOR)); } public void testDisableFuzziness() { Query expected = new TermQuery(new Term("field", "foo~1")); assertEquals(expected, parseKeyword("foo~1", ~FUZZY_OPERATOR)); } public void testDisableSlop() { PhraseQuery expectedPhrase = new PhraseQuery("field", "foo", "bar"); BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(expectedPhrase, Occur.MUST); expected.add(new TermQuery(new Term("field", "~2")), Occur.MUST); assertEquals(expected.build(), parse("\"foo bar\"~2", ~NEAR_OPERATOR)); } // we aren't supposed to barf on any input... public void testRandomQueries() throws Exception { for (int i = 0; i < 1000; i++) { String query = TestUtil.randomUnicodeString(random()); parse(query); // no exception parseKeyword(query, TestUtil.nextInt(random(), 0, 1024)); // no exception } } public void testRandomQueries2() throws Exception { char chars[] = new char[] { 'a', '1', '|', '&', ' ', '(', ')', '"', '-', '~'}; StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.setLength(0); int queryLength = random().nextInt(20); for (int j = 0; j < queryLength; j++) { sb.append(chars[random().nextInt(chars.length)]); } parse(sb.toString()); // no exception parseKeyword(sb.toString(), TestUtil.nextInt(random(), 0, 1024)); // no exception } } public void testStarBecomesMatchAll() throws Exception { Query q = parse("*"); assertEquals(q, new MatchAllDocsQuery()); q = parse(" * "); assertEquals(q, new MatchAllDocsQuery()); } }