1use strict; 2# Before 'make install' is performed this script should be runnable with 3# 'make test'. After 'make install' it should work as 'perl test.pl' 4 5######################### 6 7# Make warnings fatal 8use warnings; 9BEGIN {$SIG{__WARN__} = sub { die "Terminating test due to warning: $_[0]" } }; 10 11use Test::More; 12use Devel::Peek; 13BEGIN { plan tests => 110 }; 14use Xapian qw(:standard); 15ok(1); # If we made it this far, we're ok. 16 17######################### 18 19# Insert your test code below, the Test module is use()ed here so read 20# its man page ( perldoc Test ) for help writing this test script. 21 22sub mset_expect_order (\@@) { 23 my ($m, @a) = @_; 24 my @m = map { $_->get_docid() } @{$m}; 25 is( scalar @m, scalar @a ); 26 for my $j (0 .. (scalar @a - 1)) { 27 is( $m[$j], $a[$j] ); 28 } 29} 30 31# first create database dir, if it doesn't exist; 32my $db_dir = 'testdb'; 33 34my $database; 35ok( $database = Xapian::Database->new( $db_dir ) ); 36 37my $qp = new Xapian::QueryParser( $database ); 38$qp = new Xapian::QueryParser(); 39 40$qp->set_stemmer( Xapian::Stem->new('english') ); 41$qp->set_stemming_strategy( STEM_ALL ); 42$qp->set_default_op( OP_AND ); 43 44my $query; 45ok( $query = $qp->parse_query( 'one or two', FLAG_BOOLEAN|FLAG_BOOLEAN_ANY_CASE|FLAG_SPELLING_CORRECTION ) ); 46ok( not $qp->get_corrected_query_string()); 47is( $query->get_description(), 'Query((one@1 OR two@2))' ); 48 49ok( $query = $qp->parse_query( 'one OR (two AND three)' ) ); 50is( $query->get_description(), 'Query((one@1 OR (two@2 AND three@3)))' ); 51 52ok( my $enq = $database->enquire( $query ) ); 53 54{ 55 is( $qp->set_stopper(sub { $_[0] eq 'bad' }), undef ); 56 is( $qp->parse_query("bad news")->get_description(), 'Query(news@2)' ); 57} 58 59{ 60 my @stopwords = qw(a the in on and); 61 my $stopper; 62 ok( $stopper = new Xapian::SimpleStopper(@stopwords) ); 63 foreach (@stopwords) { 64 ok( $stopper->stop_word($_) ); 65 } 66 foreach (qw(one two three four five)) { 67 ok( !$stopper->stop_word($_) ); 68 } 69 is( $qp->set_stopper($stopper), undef ); 70} 71ok( $qp->parse_query("one two many") ); 72 73$qp = new Xapian::QueryParser(); 74my $rp; 75ok( $rp = new Xapian::RangeProcessor(1) ); 76$qp->add_rangeprocessor($rp); 77$qp->add_boolean_prefix("test", "XTEST"); 78my $qpo = new Xapian::QueryParser(); 79my $vrp; 80ok( $vrp = new Xapian::StringValueRangeProcessor(1) ); 81$qpo->add_valuerangeprocessor($vrp); 82$qpo->add_boolean_prefix("test", "XTEST"); 83 84my $pair; 85foreach $pair ( 86 [ 'a..b', 'VALUE_RANGE 1 a b' ], 87 [ '$50..100', 'VALUE_RANGE 1 $50 100' ], 88 [ '$50..$99', 'VALUE_RANGE 1 $50 $99' ], 89 [ '$50..$100', '' ], 90 [ '02/03/1979..10/12/1980', 'VALUE_RANGE 1 02/03/1979 10/12/1980' ], 91 [ 'a..b hello', '(hello@1 FILTER VALUE_RANGE 1 a b)' ], 92 [ 'hello a..b', '(hello@1 FILTER VALUE_RANGE 1 a b)' ], 93 [ 'hello a..b world', '((hello@1 OR world@2) FILTER VALUE_RANGE 1 a b)' ], 94 [ 'hello a..b test:foo', '(hello@1 FILTER (VALUE_RANGE 1 a b AND XTESTfoo))' ], 95 [ '-5..7', 'VALUE_RANGE 1 -5 7' ], 96 [ 'hello -5..7', '(hello@1 FILTER VALUE_RANGE 1 -5 7)' ], 97 [ '-5..7 hello', '(hello@1 FILTER VALUE_RANGE 1 -5 7)' ], 98 [ '"time flies" 09:00..12:30', '((time@1 PHRASE 2 flies@2) FILTER VALUE_RANGE 1 09:00 12:30)' ] 99 ) { 100 my ($str, $res) = @{$pair}; 101 my $query = $qp->parse_query($str); 102 is( $query->get_description(), "Query($res)" ); 103 $query = $qpo->parse_query($str); 104 is( $query->get_description(), "Query($res)" ); 105} 106 107$qp = new Xapian::QueryParser(); 108 109my $rp1 = new Xapian::DateRangeProcessor(1); 110my $rp2 = new Xapian::NumberRangeProcessor(2); 111my $rp3 = new Xapian::RangeProcessor(3); 112my $rp4 = new Xapian::NumberRangeProcessor(4, '$', Xapian::RP_REPEATED); 113my $rp5 = new Xapian::NumberRangeProcessor(5, 'kg', Xapian::RP_REPEATED|Xapian::RP_SUFFIX); 114my $rp6 = new Xapian::RangeProcessor(6, 'country:'); 115my $rp7 = new Xapian::RangeProcessor(7, ':name', Xapian::RP_SUFFIX); 116$qp->add_rangeprocessor( $rp1 ); 117$qp->add_rangeprocessor( $rp2 ); 118$qp->add_rangeprocessor( $rp4 ); 119$qp->add_rangeprocessor( $rp5 ); 120$qp->add_rangeprocessor( $rp6 ); 121$qp->add_rangeprocessor( $rp7 ); 122$qp->add_rangeprocessor( $rp3 ); 123 124$qp->add_boolean_prefix("test", "XTEST"); 125 126$qpo = new Xapian::QueryParser(); 127 128my $vrp1 = new Xapian::DateValueRangeProcessor(1); 129my $vrp2 = new Xapian::NumberValueRangeProcessor(2); 130my $vrp3 = new Xapian::StringValueRangeProcessor(3); 131my $vrp4 = new Xapian::NumberValueRangeProcessor(4, '$'); 132my $vrp5 = new Xapian::NumberValueRangeProcessor(5, 'kg', 0); 133my $vrp6 = new Xapian::StringValueRangeProcessor(6, 'country:'); 134my $vrp7 = new Xapian::StringValueRangeProcessor(7, ':name', 0); 135$qpo->add_valuerangeprocessor( $vrp1 ); 136$qpo->add_valuerangeprocessor( $vrp2 ); 137$qpo->add_valuerangeprocessor( $vrp4 ); 138$qpo->add_valuerangeprocessor( $vrp5 ); 139$qpo->add_valuerangeprocessor( $vrp6 ); 140$qpo->add_valuerangeprocessor( $vrp7 ); 141$qpo->add_valuerangeprocessor( $vrp3 ); 142 143$qpo->add_boolean_prefix("test", "XTEST"); 144 145foreach $pair ( 146 [ 'a..b', 'VALUE_RANGE 3 a b' ], 147 [ '1..12', "VALUE_RANGE 2 \\xa0 \\xae" ], 148 [ '20070201..20070228', 'VALUE_RANGE 1 20070201 20070228' ], 149 [ '$10..20', "VALUE_RANGE 4 \\xad \\xb1" ], 150 [ '$10..$20', "VALUE_RANGE 4 \\xad \\xb1" ], 151 [ '12..42kg', "VALUE_RANGE 5 \\xae \\xb5\@" ], 152 [ '12kg..42kg', "VALUE_RANGE 5 \\xae \\xb5\@" ], 153 [ '12kg..42', 'VALUE_RANGE 3 12kg 42' ], 154 [ '10..$20', '' ], 155 [ '1999-03-12..2020-12-30', 'VALUE_RANGE 1 19990312 20201230' ], 156 [ '1999/03/12..2020/12/30', 'VALUE_RANGE 1 19990312 20201230' ], 157 [ '1999.03.12..2020.12.30', 'VALUE_RANGE 1 19990312 20201230' ], 158 [ '12/03/99..12/04/01', 'VALUE_RANGE 1 19990312 20010412' ], 159 [ '03-12-99..04-14-01', 'VALUE_RANGE 1 19990312 20010414' ], 160 [ '(test:a..test:b hello)', '(hello@1 FILTER VALUE_RANGE 3 test:a test:b)' ], 161 [ 'country:chile..denmark', 'VALUE_RANGE 6 chile denmark' ], 162 [ 'albert..xeni:name', 'VALUE_RANGE 7 albert xeni' ], 163 ) { 164 my ($str, $res) = @{$pair}; 165 my $query = $qp->parse_query($str); 166 is( $query->get_description(), "Query($res)" ); 167 $query = $qpo->parse_query($str); 168 is( $query->get_description(), "Query($res)" ); 169} 170 171$qp = new Xapian::QueryParser(); 172$qp->add_rangeprocessor( sub { Xapian::Query->new("spam") } ); 173foreach $pair ( 174 [ '123..345', '0 * spam' ], 175 ) { 176 my ($str, $res) = @{$pair}; 177 my $query = $qp->parse_query($str); 178 is( $query->get_description(), "Query($res)" ); 179} 180 181$qp = new Xapian::QueryParser(); 182{ 183 my $rpdate = new Xapian::DateRangeProcessor(1, Xapian::RP_DATE_PREFER_MDY, 1960); 184 $qp->add_rangeprocessor( $rpdate ); 185} 186 187$qpo = new Xapian::QueryParser(); 188 189{ 190 my $vrpdate = new Xapian::DateValueRangeProcessor(1, 1, 1960); 191 $qpo->add_valuerangeprocessor( $vrpdate ); 192} 193 194foreach $pair ( 195 [ '12/03/99..12/04/01', 'VALUE_RANGE 1 19991203 20011204' ], 196 [ '03-12-99..04-14-01', 'VALUE_RANGE 1 19990312 20010414' ], 197 [ '01/30/60..02/02/59', 'VALUE_RANGE 1 19600130 20590202' ], 198 ) { 199 my ($str, $res) = @{$pair}; 200 my $query = $qp->parse_query($str); 201 is( $query->get_description(), "Query($res)" ); 202 $query = $qpo->parse_query($str); 203 is( $query->get_description(), "Query($res)" ); 204} 205 206$qp = new Xapian::QueryParser(); 207$qp->add_prefix("foo", sub {return new Xapian::Query('foo')}); 208is( $qp->parse_query("foo:test")->get_description(), 'Query(foo)' ); 209 210# Regression test for Search::Xapian bug fixed in 1.0.5.0. In 1.0.0.0-1.0.4.0 211# we tried to catch const char * not Xapian::Error, so std::terminate got 212# called. 213$qp = Xapian::QueryParser->new; 214eval { 215 $qp->parse_query('other* AND', FLAG_BOOLEAN|FLAG_WILDCARD); 216}; 217ok($@); 218is(ref($@), "Xapian::QueryParserError", "correct class for exception"); 219ok($@->isa('Xapian::Error')); 220is($@->get_msg, "Syntax: <expression> AND <expression>", "get_msg works"); 221 222# Check FLAG_DEFAULT is wrapped (new in 1.0.11.0). 223ok( $qp->parse_query('hello world', FLAG_DEFAULT|FLAG_BOOLEAN_ANY_CASE) ); 224 225# Test OP_WILDCARD with limits. 226my ($q, @matches); 227ok( $enq = Xapian::Enquire->new($database) ); 228 229$qp->set_max_expansion(1, Xapian::WILDCARD_LIMIT_FIRST); 230ok( $q = $qp->parse_query('t*', FLAG_WILDCARD) ); 231$enq->set_query($q); 232@matches = $enq->matches(0, 10); 233mset_expect_order(@matches, (1, 2)); 234 235$qp->set_max_expansion(1, Xapian::WILDCARD_LIMIT_MOST_FREQUENT); 236ok( $q = $qp->parse_query('t*', FLAG_WILDCARD) ); 237$enq->set_query($q); 238@matches = $enq->matches(0, 10); 239mset_expect_order(@matches, (1, 2)); 240 241$qp->set_max_expansion(1, Xapian::WILDCARD_LIMIT_ERROR); 242ok( $q = $qp->parse_query('t*', FLAG_WILDCARD) ); 243$enq->set_query($q); 244eval { 245 @matches = $enq->matches(0, 10); 246}; 247ok( $@ ); 248is(ref($@), "Xapian::WildcardError", "correct class for exception"); 249 2501; 251