Fix build with xapian-core < 1.4.10
[xapian.git] / search-xapian / t / search.t
blobbef6847c88dc0561e3e90a92ca85505a04c509f5
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 use Test::More;
10 BEGIN { plan tests => 122 };
11 use Search::Xapian qw(:ops);
13 #########################
15 # Insert your test code below, the Test module is use()ed here so read
16 # its man page ( perldoc Test ) for help writing this test script.
18 # None of the following tests can be expected to succeed without first
19 # creating a test database in the directory testdb.
21 # Adjust query description from 1.4 to match.
22 sub qd {
23     local $_ = (shift @_)->get_description();
24     if (substr($_, 0, 1) eq 'Q') {
25         s/\@([0-9]+)/:(pos=$1)/g;
26         s/^Query\(0 \* VALUE_RANGE/Query(VALUE_RANGE/;
27         $_ = "Xapian::$_";
28     }
29     return $_;
32 my $db;
33 ok( $db = Search::Xapian::Database->new( 'testdb' ), "test db opened ok" );
35 my $enq;
36 ok( $enq = $db->enquire(), "db enquirable" );
38 my @subqueries;
39 my $query;
40 ok( $subqueries[0] = Search::Xapian::Query->new( 'test' ), "one-term queries ok" );
41 is( qd($subqueries[0]), "Xapian::Query(test)", "query parsed correctly" );
43 # tests 5-14
44 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE) {
45   ok( $query = Search::Xapian::Query->new( $op, @subqueries ), "$Search::Xapian::OP_NAMES[$op] works with 1 object" );
46   ok( $query = Search::Xapian::Query->new( $op, 'help' ), "$Search::Xapian::OP_NAMES[$op] works with 1 term" );
48 is( qd($query), "Xapian::Query(help)", "query parsed correctly" );
50 # tests 15-41
51 $subqueries[1] = Search::Xapian::Query->new( 'help' );
52 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE,
53                 OP_AND_NOT, OP_XOR, OP_AND_MAYBE, OP_FILTER, OP_ELITE_SET) {
54   ok( $query = Search::Xapian::Query->new( $op, @subqueries ), "$Search::Xapian::OP_NAMES[$op] works with 2 objects" );
55   ok( $query = Search::Xapian::Query->new( $op, $subqueries[0], 'test'), "$Search::Xapian::OP_NAMES[$op] works with an object and a term" );
56   ok( $query = Search::Xapian::Query->new( $op, 'test', 'help'), "$Search::Xapian::OP_NAMES[$op] works with 2 terms" );
58 is( qd($query), "Xapian::Query((test ELITE_SET 10 help))", "query parsed correctly" );
60 # tests 42-...
61 $subqueries[2] = Search::Xapian::Query->new( 'one' );
62 foreach my $op (OP_OR, OP_AND, OP_NEAR, OP_PHRASE ) {
63   ok( $query = Search::Xapian::Query->new( $op, @subqueries ), "$Search::Xapian::OP_NAMES[$op] works with 3 objects" );
64   ok( $query = Search::Xapian::Query->new( $op, 'test', 'help', 'one' ), "$Search::Xapian::OP_NAMES[$op] works with 3 terms" );
66 is( qd($query), "Xapian::Query((test PHRASE 3 help PHRASE 3 one))", "query parsed correctly" );
68 ok( $enq = $db->enquire( $query ), "db queries return ok"  );
69 ok( $enq = $db->enquire( OP_OR, 'test', 'help' ), "in-line db queries return ok" );
70 is( $db->get_spelling_suggestion( 'tost' ), 'test', "spelling suggestion ok" );
72 ok( $query = Search::Xapian::Query->new(OP_SCALE_WEIGHT, $query, 3.14), "OP_SCALE_WEIGHT understood" );
74 my $matches;
75 ok( $matches = $enq->get_mset( 0, 10 ), "match set returned ok" );
76 is( $matches->get_matches_estimated(), 2, "match set contains correct number of results" );
77 my $matches2;
78 ok( $matches2 = $enq->get_mset( 0, 1, 3 ), "match set with check_at_least returned ok" );
79 is( $matches2->get_matches_estimated(), 2, "match set contains correct number of results" );
81 my $match;
82 ok( $match = $matches->begin(), "match set iterator returned ok" );
83 is( $match, $matches->begin(), "match set returns consistent start point");
84 ok( $match++, "match set iterator can increment" );
85 isnt( $match, $matches->begin(), "match set iterator increments correctly" );
86 ok( $match->get_docid(), "document id returned ok" );
87 ok( $match->get_percent(), "percent relevance returned ok" );
88 is( $match->get_percent(), $matches->convert_to_percent($match->get_weight()),
89         "converting a weight to a percentage works" );
90 is( $match->get_percent(), $matches->convert_to_percent($match),
91         "converting an MSetIterator to a percentage works" );
93 my $doc;
94 ok( $doc = $match->get_document(), "documents retrievable" );
95 ok( $doc->get_data(), "data retrievable" );
97 ok( $match--, "match set iterator can decrement" );
98 is( $match, $matches->begin(), "match set iterator decrements correctly" );
100 for (1 .. $matches->size()) { $match++; }
101 is( $match, $matches->end(), "match set returns correct endpoint");
103 my $rset;
104 ok( $rset = Search::Xapian::RSet->new(), "relevance set created ok" );
105 $rset->add_document( 1 );
106 ok( $rset->contains( 1 ), "document added to relevance set successfully" );
107 ok( !$rset->contains( 2 ), "relevance set correctly fails to match document it does not contain" );
108 $rset->remove_document( 1 );
109 ok( !$rset->contains( 1 ), "document removed from relevance set successfully" );
110 $rset->add_document( 1 );
112 my $matches3;
113 ok( $matches3 = $enq->get_mset(0, 10, $rset), "get_mset with rset" );
114 is( $matches3->size, $matches->size, "rset doesn't change mset size" );
115 ok( $matches3 = $enq->get_mset(0, 10, 11, $rset), "get_mset with check_at_least and rset" );
116 is( $matches3->size, $matches->size, "rset and check_at_least don't change mset size" );
118 my $d;
119 # This was generating a warning converting "0" to an RSet object:
120 ok( $matches3 = $enq->get_mset(0, 10,
121                         sub { $d = scalar @_; return $_[0]->get_value(0) ne ""; }),
122         "get_mset with matchdecider" );
123 ok( defined $d, "matchdecider was called" );
124 ok( $d == 1, "matchdecider got an argument" );
126 sub mdecider {
127     $d = scalar @_;
128     return $_[0]->get_value(0) ne "";
131 $d = undef;
132 ok( $matches3 = $enq->get_mset(0, 10, \&mdecider),
133         "get_mset with named matchdecider function" );
134 ok( defined $d, "matchdecider was called" );
135 ok( $d == 1, "matchdecider got an argument" );
137 my $eset;
138 ok( $eset = $enq->get_eset( 10, $rset ), "can get expanded terms set" );
139 is( $eset->size(), 1, "expanded terms set of correct size" );
140 my $eit;
141 ok( $eit = $eset->begin(), "expanded terms set iterator retuns ok" );
142 is( $eit->get_termname(), 'one', "expanded terms set contains correct terms");
143 is( ++$eit, $eset->end(), "eset iterator reaches ESet::end() ok" );
144 --$eit;
145 is( $eit->get_termname(), 'one', "eset iterator decrement works ok" );
146 ok( $eset = $enq->get_eset( 10, $rset, sub { $_[0] ne "one" } ), "expanded terms set with decider" );
147 is( $eset->size(), 0, "expanded terms decider filtered" );
149 # try an empty mset - this was giving begin != end
150 my ($noquery, $nomatches);
151 ok( $noquery = Search::Xapian::Query->new( OP_AND_NOT, 'test', 'test' ), "matchless query returns ok" );
152 $enq->set_query( $noquery );
153 ok( $nomatches = $enq->get_mset( 0, 10 ), "matchless query returns match set ok" );
154 is( $nomatches->size(), 0, "matchless query's match set has zero size" );
155 is( $nomatches->begin(), $nomatches->end(), "matchless query's match set's start point and endpoint are the same" );
157 ok( $matches->convert_to_percent(100) > 0 );
158 ok( $matches->convert_to_percent( $matches->begin() ) > 0 );
160 $match = $matches->back();
161 --$match;
162 ++$match;
163 ok( $match eq $matches->back() );
165 ok( $match->get_collapse_count() == 0 );
167 my $bm25;
168 ok( $bm25 = Search::Xapian::BM25Weight->new() );
170 my $boolweight;
171 ok( $boolweight = Search::Xapian::BoolWeight->new() );
173 my $tradweight;
174 ok( $tradweight = Search::Xapian::TradWeight->new() );
176 my $alltermit = $db->allterms_begin();
177 ok( $alltermit != $db->allterms_end() );
178 ok( "$alltermit" eq 'one' );
179 ok( $alltermit->get_termname() eq 'one' );
180 ok( ++$alltermit != $db->allterms_end() );
181 ok( "$alltermit" eq 'test' );
182 ok( $alltermit->get_termname() eq 'test' );
183 ok( ++$alltermit != $db->allterms_end() );
184 ok( "$alltermit" eq 'two' );
185 ok( $alltermit->get_termname() eq 'two' );
186 ok( ++$alltermit == $db->allterms_end() );
188 $alltermit = $db->allterms_begin('t');
189 ok( $alltermit != $db->allterms_end('t') );
190 ok( "$alltermit" eq 'test' );
191 ok( $alltermit->get_termname() eq 'test' );
192 ok( ++$alltermit != $db->allterms_end('t') );
193 ok( "$alltermit" eq 'two' );
194 ok( $alltermit->get_termname() eq 'two' );
195 ok( ++$alltermit == $db->allterms_end('t') );
197 # Check that non-string scalars get coerced.
198 my $numberquery = Search::Xapian::Query->new( OP_OR, (12, "34", .5) );
199 is( qd($numberquery), "Xapian::Query((12 OR 34 OR 0.5))" );