[omega] Compute date spans in days
[xapian.git] / xapian-bindings / perl / t / search.t
blob9ecd7db7a30fad666a2ccc94a3d9e7bc63846e23
1 use 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'
5 #########################
7 # change 'tests => 1' to 'tests => last_test_to_print';
9 # Make warnings fatal
10 use warnings;
11 BEGIN {$SIG{__WARN__} = sub { die "Terminating test due to warning: $_[0]" } };
13 use Test::More;
14 BEGIN { plan tests => 129 };
15 use Xapian qw(:ops);
17 #########################
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.
22 # None of the following tests can be expected to succeed without first
23 # creating a test database in the directory testdb.
25 my $db;
26 ok( $db = Xapian::Database->new( 'testdb' ), "test db opened ok" );
28 my $enq;
29 ok( $enq = $db->enquire(), "db enquirable" );
31 # Check Xapian::BAD_VALUENO is wrapped suitably.
32 $enq->set_collapse_key(Xapian::BAD_VALUENO);
34 # Test that the non-constant wrapping prior to 1.4.10 still works.
35 $enq->set_collapse_key($Xapian::BAD_VALUENO);
37 my @subqueries;
38 my $query;
39 ok( $subqueries[0] = Xapian::Query->new( 'test' ), "one-term queries ok" );
40 is( $subqueries[0]->get_description, "Query(test)", "query parsed correctly" );
42 # tests 5-14
43 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE) {
44   ok( $query = Xapian::Query->new( $op, @subqueries ), "$Xapian::OP_NAMES[$op] works with 1 object" );
45   ok( $query = Xapian::Query->new( $op, 'help' ), "$Xapian::OP_NAMES[$op] works with 1 term" );
47 is( $query->get_description, "Query(help)", "query parsed correctly" );
49 # tests 15-41
50 $subqueries[1] = Xapian::Query->new( 'help' );
51 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE,
52                 OP_AND_NOT, OP_XOR, OP_AND_MAYBE, OP_FILTER, OP_ELITE_SET) {
53   ok( $query = Xapian::Query->new( $op, @subqueries ), "$Xapian::OP_NAMES[$op] works with 2 objects" );
54   ok( $query = Xapian::Query->new( $op, $subqueries[0], 'test'), "$Xapian::OP_NAMES[$op] works with an object and a term" );
55   ok( $query = Xapian::Query->new( $op, 'test', 'help'), "$Xapian::OP_NAMES[$op] works with 2 terms" );
57 is( $query->get_description, "Query((test ELITE_SET 10 help))", "query parsed correctly" );
59 # tests 42-...
60 $subqueries[2] = Xapian::Query->new( 'one' );
61 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE ) {
62   ok( $query = Xapian::Query->new( $op, @subqueries ), "$Xapian::OP_NAMES[$op] works with 3 objects" );
63   ok( $query = Xapian::Query->new( $op, 'test', 'help', 'one' ), "$Xapian::OP_NAMES[$op] works with 3 terms" );
65 is( $query->get_description, "Query((test PHRASE 3 help PHRASE 3 one))", "query parsed correctly" );
67 ok( $enq = $db->enquire( $query ), "db queries return ok"  );
68 ok( $enq = $db->enquire( OP_OR, 'test', 'help' ), "in-line db queries return ok" );
69 is( $db->get_spelling_suggestion( 'tost' ), 'test', "spelling suggestion ok" );
71 ok( $query = Xapian::Query->new(OP_SCALE_WEIGHT, $query, 3.14), "OP_SCALE_WEIGHT understood" );
73 my $matches;
74 ok( $matches = $enq->get_mset( 0, 10 ), "match set returned ok" );
75 is( $matches->get_matches_estimated(), 2, "match set contains correct number of results" );
76 my $matches2;
77 ok( $matches2 = $enq->get_mset( 0, 1, 3 ), "match set with check_at_least returned ok" );
78 is( $matches2->get_matches_estimated(), 2, "match set contains correct number of results" );
80 my $match;
81 ok( $match = $matches->begin(), "match set iterator returned ok" );
82 is( $match, $matches->begin(), "match set returns consistent start point");
83 ok( $match++, "match set iterator can increment" );
84 isnt( $match, $matches->begin(), "match set iterator increments correctly" );
85 ok( $match->get_docid(), "document id returned ok" );
86 ok( $match->get_percent(), "percent relevance returned ok" );
87 is( $match->get_percent(), $matches->convert_to_percent($match->get_weight()),
88         "converting a weight to a percentage works" );
89 is( $match->get_percent(), $matches->convert_to_percent($match),
90         "converting an MSetIterator to a percentage works" );
92 my $doc;
93 ok( $doc = $match->get_document(), "documents retrievable" );
94 ok( $doc->get_data(), "data retrievable" );
96 ok( $match--, "match set iterator can decrement" );
97 is( $match, $matches->begin(), "match set iterator decrements correctly" );
98 $match->inc;
99 isnt( $match, $matches->begin(), "match set iterator increments correctly" );
100 $match->dec;
101 is( $match, $matches->begin(), "match set iterator decrements correctly" );
103 for (1 .. $matches->size()) { $match++; }
104 is( $match, $matches->end(), "match set returns correct endpoint");
106 my $rset;
107 ok( $rset = Xapian::RSet->new(), "relevance set created ok" );
108 $rset->add_document( 1 );
109 ok( $rset->contains( 1 ), "document added to relevance set successfully" );
110 ok( !$rset->contains( 2 ), "relevance set correctly fails to match document it does not contain" );
111 $rset->remove_document( 1 );
112 ok( !$rset->contains( 1 ), "document removed from relevance set successfully" );
113 $rset->add_document( 1 );
115 my $matches3;
116 ok( $matches3 = $enq->get_mset(0, 10, $rset), "get_mset with rset" );
117 is( $matches3->size, $matches->size, "rset doesn't change mset size" );
118 ok( $matches3 = $enq->get_mset(0, 10, 11, $rset), "get_mset with check_at_least and rset" );
119 is( $matches3->size, $matches->size, "rset and check_at_least don't change mset size" );
121 my $d;
122 # This was generating a warning converting "0" to an RSet object:
123 ok( $matches3 = $enq->get_mset(0, 10,
124                         sub { $d = scalar @_; return $_[0]->get_value(0) ne ""; }),
125         "get_mset with matchdecider" );
126 ok( defined $d, "matchdecider was called" );
127 ok( $d == 1, "matchdecider got an argument" );
129 $d = undef;
130 ok( $matches3 = $enq->get_mset(0, 10, 0, undef,
131                         sub { $d = scalar @_; return $_[0]->get_value(0) ne ""; }),
132         "get_mset with matchdecider and full args list" );
133 ok( defined $d, "matchdecider was called" );
134 ok( $d == 1, "matchdecider got an argument" );
136 sub mdecider {
137     $d = scalar @_;
138     return $_[0]->get_value(0) ne "";
141 $d = undef;
142 ok( $matches3 = $enq->get_mset(0, 10, \&mdecider),
143         "get_mset with named matchdecider function" );
144 ok( defined $d, "matchdecider was called" );
145 ok( $d == 1, "matchdecider got an argument" );
147 my $eset;
148 ok( $eset = $enq->get_eset( 10, $rset ), "can get expanded terms set" );
149 is( $eset->size(), 1, "expanded terms set of correct size" );
150 my $eit;
151 ok( $eit = $eset->begin(), "expanded terms set iterator retuns ok" );
152 is( $eit->get_termname(), 'one', "expanded terms set contains correct terms");
153 is( ++$eit, $eset->end(), "eset iterator reaches ESet::end() ok" );
154 --$eit;
155 is( $eit->get_termname(), 'one', "eset iterator decrement works ok" );
156 $eit->inc;
157 is( $eit, $eset->end(), "ESetIterator::inc() ok" );
158 $eit->dec;
159 isnt( $eit, $eset->end(), "ESetIterator::dec() moved off end()" );
160 is( $eit->get_termname(), 'one', "ESetIterator::dec() ok" );
161 ok( $eset = $enq->get_eset( 10, $rset, sub { $_[0] ne "one" } ), "expanded terms set with decider" );
162 is( $eset->size(), 0, "expanded terms decider filtered" );
164 # try an empty mset - this was giving begin != end
165 my ($noquery, $nomatches);
166 ok( $noquery = Xapian::Query->new( OP_AND_NOT, 'test', 'test' ), "matchless query returns ok" );
167 $enq->set_query( $noquery );
168 ok( $nomatches = $enq->get_mset( 0, 10 ), "matchless query returns match set ok" );
169 is( $nomatches->size(), 0, "matchless query's match set has zero size" );
170 is( $nomatches->begin(), $nomatches->end(), "matchless query's match set's start point and endpoint are the same" );
172 ok( $matches->convert_to_percent(100) > 0 );
173 ok( $matches->convert_to_percent( $matches->begin() ) > 0 );
175 $match = $matches->back();
176 --$match;
177 ++$match;
178 ok( $match eq $matches->back() );
180 ok( $match->get_collapse_count() == 0 );
182 # Test passing a sub as a matchspy.
183 my @spy_values = ();
184 $enq->add_matchspy(
185         sub { my $doc = shift; push @spy_values, $doc->get_value(0)}
186     );
187 $enq->set_query(Xapian::Query::MatchAll);
188 $matches = $enq->get_mset(1, 2);
189 is( join("|", @spy_values), "one|two" );
191 my $bm25;
192 ok( $bm25 = Xapian::BM25Weight->new() );
194 my $boolweight;
195 ok( $boolweight = Xapian::BoolWeight->new() );
197 my $tradweight;
198 ok( $tradweight = Xapian::TradWeight->new() );
200 my $alltermit = $db->allterms_begin();
201 ok( $alltermit != $db->allterms_end() );
202 ok( $alltermit->get_termname() eq 'one' );
203 ok( ++$alltermit != $db->allterms_end() );
204 ok( $alltermit->get_termname() eq 'test' );
205 ok( ++$alltermit != $db->allterms_end() );
206 ok( $alltermit->get_termname() eq 'two' );
207 ok( ++$alltermit == $db->allterms_end() );
209 $alltermit = $db->allterms_begin('t');
210 ok( $alltermit != $db->allterms_end('t') );
211 ok( $alltermit->get_termname() eq 'test' );
212 ok( ++$alltermit != $db->allterms_end('t') );
213 ok( $alltermit->get_termname() eq 'two' );
214 ok( ++$alltermit == $db->allterms_end('t') );
216 # Check that non-string scalars get coerced.
217 my $numberquery = Xapian::Query->new( OP_OR, (12, "34", .5) );
218 is( $numberquery->get_description(), "Query((12 OR 34 OR 0.5))" );
220 ok( defined(Xapian::ENQ_ASCENDING) );
221 ok( defined(Xapian::ENQ_DESCENDING) );
222 ok( defined(Xapian::ENQ_DONT_CARE) );