Files
bongo/import/clucene/test/queryParser/TestQueryParser.cpp
T
2007-01-22 23:37:12 +00:00

324 lines
12 KiB
C++

/*------------------------------------------------------------------------------
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
*
* Distributable under the terms of either the Apache License (Version 2.0) or
* the GNU Lesser General Public License, as specified in the COPYING file.
------------------------------------------------------------------------------*/
#include "test.h"
class QPTestFilter: public TokenFilter {
public:
bool inPhrase;
int32_t savedStart, savedEnd;
/**
* Filter which discards the token 'stop' and which expands the
* token 'phrase' into 'phrase1 phrase2'
*/
QPTestFilter(TokenStream* in):
TokenFilter(in,true),
inPhrase(false),
savedStart(0),
savedEnd(0)
{
}
bool next(Token* token) {
if (inPhrase) {
inPhrase = false;
token->set( _T("phrase2"), savedStart, savedEnd);
return true;
}else{
while( input->next(token) ){
if ( _tcscmp(token->termText(), _T("phrase")) == 0 ) {
inPhrase = true;
savedStart = token->startOffset();
savedEnd = token->endOffset();
token->set( _T("phrase1"), savedStart, savedEnd);
return true;
}else if ( _tcscmp(token->termText(), _T("stop") ) !=0 ){
return true;
}
}
}
return false;
}
};
class QPTestAnalyzer: public Analyzer {
public:
QPTestAnalyzer() {
}
/** Filters LowerCaseTokenizer with StopFilter. */
TokenStream* tokenStream(const TCHAR* fieldName, Reader* reader) {
return _CLNEW QPTestFilter(_CLNEW LowerCaseTokenizer(reader));
}
};
Query* getQuery(CuTest *tc,const TCHAR* query, Analyzer* a) {
try{
bool del = (a==NULL);
if (a == NULL)
a = _CLNEW SimpleAnalyzer();
QueryParser qp(_T("field"), a);
Query* ret = qp.parse(query);
if ( del )
_CLDELETE(a);
return ret;
}catch(CLuceneError& e){
CuFail(tc,_T("/%s/ threw an error: %s - "),query, e.twhat());
CuFail(tc,_T("%s\n"),e.twhat());
return NULL;
}catch(...){
CuFail(tc,_T("/%s/ threw an error.\n"),query);
return NULL;
}
}
void assertQueryEquals(CuTest *tc,const TCHAR* query, Analyzer* a, const TCHAR* result) {
Query* q = getQuery(tc,query, a);
if ( q == NULL )
return;
const TCHAR* s = q->toString(_T("field"));
if ( _tcscmp(s,result) != 0 ) {
CuFail(tc, _T("FAILED Query /%s/ yielded /%s/, expecting /%s/\n"), query, s,
result);
}
_CLDELETE_CARRAY(s);
_CLDELETE(q);
}
void assertTrue(CuTest *tc,const TCHAR* query, Analyzer* a, const TCHAR* inst, const TCHAR* msg){
Query* q = getQuery(tc,query,a);
bool success = q->instanceOf(inst);
_CLDELETE(q);
CuAssert(tc,msg,success);
}
void testSimple(CuTest *tc) {
StandardAnalyzer a;
assertQueryEquals(tc,_T("term term term"), NULL, _T("term term term"));
TCHAR tmp1[100];
#ifdef _UCS2
lucene_utf8towcs(tmp1,"t\xc3\xbcrm term term",100);
assertQueryEquals(tc,tmp1, NULL, tmp1);
assertQueryEquals(tc,tmp1, &a, tmp1);
lucene_utf8towcs(tmp1,"\xc3\xbcmlaut",100);
assertQueryEquals(tc,tmp1, NULL, tmp1);
assertQueryEquals(tc,tmp1, &a, tmp1);
#endif
assertQueryEquals(tc,_T("a AND b"), NULL, _T("+a +b"));
assertQueryEquals(tc,_T("(a AND b)"), NULL, _T("+a +b"));
assertQueryEquals(tc,_T("c OR (a AND b)"), NULL, _T("c (+a +b)"));
assertQueryEquals(tc,_T("a AND NOT b"), NULL, _T("+a -b"));
assertQueryEquals(tc,_T("a AND -b"), NULL, _T("+a -b"));
assertQueryEquals(tc,_T("a AND !b"), NULL, _T("+a -b"));
assertQueryEquals(tc,_T("a && b"), NULL, _T("+a +b"));
assertQueryEquals(tc,_T("a && ! b"), NULL, _T("+a -b"));
assertQueryEquals(tc,_T("a OR b"), NULL, _T("a b"));
assertQueryEquals(tc,_T("a || b"), NULL, _T("a b"));
assertQueryEquals(tc,_T("a OR !b"), NULL, _T("a -b"));
assertQueryEquals(tc,_T("a OR ! b"), NULL, _T("a -b"));
assertQueryEquals(tc,_T("a OR -b"), NULL, _T("a -b"));
assertQueryEquals(tc,_T("+term -term term"), NULL, _T("+term -term term"));
assertQueryEquals(tc,_T("foo:term AND field:anotherTerm"), NULL,
_T("+foo:term +anotherterm"));
assertQueryEquals(tc,_T("term AND \"phrase phrase\""), NULL,
_T("+term +\"phrase phrase\"") );
assertQueryEquals(tc,_T("\"hello there\""), NULL, _T("\"hello there\"") );
assertTrue(tc, _T("a AND b"), NULL,_T("BooleanQuery"),_T("a AND b") );
assertTrue(tc, _T("hello"), NULL,_T("TermQuery"), _T("hello"));
assertTrue(tc, _T("\"hello there\""), NULL,_T("PhraseQuery"), _T("\"hello there\""));
assertQueryEquals(tc,_T("germ term^2.0"), NULL, _T("germ term^2.0"));
assertQueryEquals(tc,_T("term^2.0"), NULL, _T("term^2.0"));
assertQueryEquals(tc,_T("term^2"), NULL, _T("term^2.0"));
assertQueryEquals(tc,_T("term^2.3"), NULL, _T("term^2.3"));
assertQueryEquals(tc,_T("\"germ term\"^2.0"), NULL, _T("\"germ term\"^2.0"));
assertQueryEquals(tc,_T("\"term germ\"^2"), NULL, _T("\"term germ\"^2.0") );
assertQueryEquals(tc,_T("(foo OR bar) AND (baz OR boo)"), NULL,
_T("+(foo bar) +(baz boo)"));
assertQueryEquals(tc,_T("((a OR b) AND NOT c) OR d"), NULL,
_T("(+(a b) -c) d"));
assertQueryEquals(tc,_T("+(apple \"steve jobs\") -(foo bar baz)"), NULL,
_T("+(apple \"steve jobs\") -(foo bar baz)") );
assertQueryEquals(tc,_T("+title:(dog OR cat) -author:\"bob dole\""), NULL,
_T("+(title:dog title:cat) -author:\"bob dole\"") );
}
void testPunct(CuTest *tc) {
WhitespaceAnalyzer a;
assertQueryEquals(tc,_T("a&b"), &a, _T("a&b"));
assertQueryEquals(tc,_T("a&&b"), &a, _T("a&&b"));
assertQueryEquals(tc,_T(".NET"), &a, _T(".NET"));
}
void testSlop(CuTest *tc) {
assertQueryEquals(tc,_T("\"term germ\"~2"), NULL, _T("\"term germ\"~2") );
assertQueryEquals(tc,_T("\"term germ\"~2 flork"), NULL, _T("\"term germ\"~2 flork") );
assertQueryEquals(tc,_T("\"term\"~2"), NULL, _T("term"));
assertQueryEquals(tc,_T("\" \"~2 germ"), NULL, _T("germ"));
assertQueryEquals(tc,_T("\"term germ\"~2^2"), NULL, _T("\"term germ\"~2^2.0") );
}
void testNumber(CuTest *tc) {
// The numbers go away because SimpleAnalzyer ignores them
assertQueryEquals(tc,_T("3"), NULL, _T(""));
assertQueryEquals(tc,_T("term 1.0 1 2"), NULL, _T("term"));
assertQueryEquals(tc,_T("term term1 term2"), NULL, _T("term term term"));
StandardAnalyzer a;
assertQueryEquals(tc,_T("3"), &a, _T("3"));
assertQueryEquals(tc,_T("term 1.0 1 2"), &a, _T("term 1.0 1 2"));
assertQueryEquals(tc,_T("term term1 term2"), &a, _T("term term1 term2"));
}
void testWildcard(CuTest *tc) {
assertQueryEquals(tc,_T("term*"), NULL, _T("term*"));
assertQueryEquals(tc,_T("term*^2"), NULL, _T("term*^2.0"));
#ifndef NO_FUZZY_QUERY
assertQueryEquals(tc,_T("term~"), NULL, _T("term~0.5"));
assertQueryEquals(tc,_T("term~^2"), NULL, _T("term^2.0~0.5"));
assertQueryEquals(tc,_T("term^2~"), NULL, _T("term^2.0~0.5"));
assertTrue(tc, _T("term~"), NULL,_T("FuzzyQuery"), _T("term~0.5"));
#endif
assertQueryEquals(tc,_T("term*germ"), NULL, _T("term*germ"));
assertQueryEquals(tc,_T("term*germ^3"), NULL, _T("term*germ^3.0"));
assertTrue(tc, _T("term*"), NULL,_T("PrefixQuery"), _T("term*"));
assertTrue(tc, _T("term*^2"), NULL,_T("PrefixQuery"), _T("term*^2.0"));
assertTrue(tc, _T("term*germ"), NULL,_T("WildcardQuery"), _T("term*germ"));
}
void testQPA(CuTest *tc) {
QPTestAnalyzer qpAnalyzer;
assertQueryEquals(tc,_T("term term term"), &qpAnalyzer, _T("term term term") );
assertQueryEquals(tc,_T("term +stop term"), &qpAnalyzer, _T("term term") );
assertQueryEquals(tc,_T("term -stop term"), &qpAnalyzer, _T("term term") );
assertQueryEquals(tc,_T("drop AND stop AND roll"), &qpAnalyzer, _T("+drop +roll") );
assertQueryEquals(tc,_T("term phrase term"), &qpAnalyzer,
_T("term \"phrase1 phrase2\" term") );
assertQueryEquals(tc,_T("term AND NOT phrase term"), &qpAnalyzer,
_T("+term -\"phrase1 phrase2\" term") );
assertQueryEquals(tc,_T("stop"), &qpAnalyzer, _T("") );
assertTrue(tc, _T("term term term"), &qpAnalyzer,_T("BooleanQuery"), _T("term term term"));
assertTrue(tc, _T("term +stop"), &qpAnalyzer,_T("TermQuery"), _T("term +stop"));
}
void testRange(CuTest *tc) {
StandardAnalyzer a;
assertQueryEquals(tc,_T("[ a z]"), NULL, _T("[a TO z]"));
assertTrue(tc, _T("[ a z]"), NULL, _T("RangeQuery"), _T("[ a z]") );
assertQueryEquals(tc,_T("[ a z ]"), NULL, _T("[a TO z]"));
assertQueryEquals(tc,_T("{ a z}"), NULL, _T("{a TO z}"));
assertQueryEquals(tc,_T("{ a z }"), NULL, _T("{a TO z}"));
assertQueryEquals(tc,_T("{ a z }^2.0"), NULL, _T("{a TO z}^2.0"));
assertQueryEquals(tc,_T("[ a z] OR bar"), NULL, _T("[a TO z] bar"));
assertQueryEquals(tc,_T("[ a z] AND bar"), NULL, _T("+[a TO z] +bar"));
assertQueryEquals(tc,_T("( bar blar { a z}) "), NULL, _T("bar blar {a TO z}"));
assertQueryEquals(tc,_T("gack ( bar blar { a z}) "), NULL, _T("gack (bar blar {a TO z})"));
assertQueryEquals(tc,_T("[050-070]"), &a, _T("[050 TO -070]"));
}
void testEscaped(CuTest *tc) {
WhitespaceAnalyzer a;
/*assertQueryEquals("\\[brackets"), &a, _T("\\[brackets") );
assertQueryEquals(tc,_T("\\[brackets"), null, _T("brackets") );
assertQueryEquals(tc,_T("\\\\"), &a, _T("\\\\") );
assertQueryEquals(tc,_T("\\+blah"), &a, _T("\\+blah") );
assertQueryEquals(tc,_T("\\(blah"), &a, _T("\\(blah") );
assertQueryEquals(tc,_T("\\-blah"), &a, _T("\\-blah") );
assertQueryEquals(tc,_T("\\!blah"), &a, _T("\\!blah") );
assertQueryEquals(tc,_T("\\{blah"), &a, _T("\\{blah") );
assertQueryEquals(tc,_T("\\}blah"), &a, _T("\\}blah") );
assertQueryEquals(tc,_T("\\:blah"), &a, _T("\\:blah") );
assertQueryEquals(tc,_T("\\^blah"), &a, _T("\\^blah") );
assertQueryEquals(tc,_T("\\[blah"), &a, _T("\\[blah") );
assertQueryEquals(tc,_T("\\]blah"), &a, _T("\\]blah") );
assertQueryEquals(tc,_T("\\\"blah"), &a, _T("\\\"blah") );
assertQueryEquals(tc,_T("\\(blah"), &a, _T("\\(blah") );
assertQueryEquals(tc,_T("\\)blah"), &a, _T("\\)blah") );
assertQueryEquals(tc,_T("\\~blah"), &a, _T("\\~blah") );
assertQueryEquals(tc,_T("\\*blah"), &a, _T("\\*blah") );
assertQueryEquals(tc,_T("\\?blah"), &a, _T("\\?blah") );
//assertQueryEquals(tc,_T("foo \\&\\& bar"), &a, _T("foo \\&\\& bar") );
//assertQueryEquals(tc,_T("foo \\|| bar"), &a, _T("foo \\|| bar") );
//assertQueryEquals(tc,_T("foo \\AND bar"), &a, _T("foo \\AND bar") );*/
assertQueryEquals(tc,_T("a\\-b:c"), &a, _T("a-b:c") );
assertQueryEquals(tc,_T("a\\+b:c"), &a, _T("a+b:c") );
assertQueryEquals(tc,_T("a\\:b:c"), &a, _T("a:b:c") );
assertQueryEquals(tc,_T("a\\\\b:c"), &a, _T("a\\b:c") );
assertQueryEquals(tc,_T("a:b\\-c"), &a, _T("a:b-c") );
assertQueryEquals(tc,_T("a:b\\+c"), &a, _T("a:b+c") );
assertQueryEquals(tc,_T("a:b\\:c"), &a, _T("a:b:c") );
assertQueryEquals(tc,_T("a:b\\\\c"), &a, _T("a:b\\c") );
assertQueryEquals(tc,_T("a:b\\-c*"), &a, _T("a:b-c*") );
assertQueryEquals(tc,_T("a:b\\+c*"), &a, _T("a:b+c*") );
assertQueryEquals(tc,_T("a:b\\:c*"), &a, _T("a:b:c*") );
assertQueryEquals(tc,_T("a:b\\\\c*"), &a, _T("a:b\\c*") );
assertQueryEquals(tc,_T("a:b\\-?c"), &a, _T("a:b-?c") );
assertQueryEquals(tc,_T("a:b\\+?c"), &a, _T("a:b+?c") );
assertQueryEquals(tc,_T("a:b\\:?c"), &a, _T("a:b:?c") );
assertQueryEquals(tc,_T("a:b\\\\?c"), &a, _T("a:b\\?c") );
assertQueryEquals(tc,_T("a:b\\-c~"), &a, _T("a:b-c~0.5") );
assertQueryEquals(tc,_T("a:b\\+c~"), &a, _T("a:b+c~0.5") );
assertQueryEquals(tc,_T("a:b\\:c~"), &a, _T("a:b:c~0.5") );
assertQueryEquals(tc,_T("a:b\\\\c~"), &a, _T("a:b\\c~0.5") );
assertQueryEquals(tc,_T("[ a\\- TO a\\+ ]"), &a, _T("[a- TO a+]") );
assertQueryEquals(tc,_T("[ a\\: TO a\\~ ]"), &a, _T("[a: TO a~]") );
assertQueryEquals(tc,_T("[ a\\\\ TO a\\* ]"), &a, _T("[a\\ TO a*]") );
}
CuSuite *testQueryParser(void)
{
CuSuite *suite = CuSuiteNew(_T("CLucene Query Parser Test"));
SUITE_ADD_TEST(suite, testSimple);
SUITE_ADD_TEST(suite, testQPA);
SUITE_ADD_TEST(suite, testEscaped);
SUITE_ADD_TEST(suite, testNumber);
SUITE_ADD_TEST(suite, testPunct);
#ifndef NO_FUZZY_QUERY
SUITE_ADD_TEST(suite, testSlop);
#endif
#ifndef NO_RANGE_QUERY
SUITE_ADD_TEST(suite, testRange);
#endif
#ifndef NO_WILDCARD_QUERY
SUITE_ADD_TEST(suite, testWildcard);
#endif
return suite;
}
// EOF