Support offsets in prefix searching
[mediawiki.git] / tests / phpunit / includes / PrefixSearchTest.php
blobd0f62080347b0f0c4132fe4875f93643affafe7c
1 <?php
2 /**
3 * @group Search
4 * @group Database
5 */
6 class PrefixSearchTest extends MediaWikiLangTestCase {
8 protected function setUp() {
9 parent::setUp();
11 if ( !$this->isWikitextNS( NS_MAIN ) ) {
12 $this->markTestSkipped( 'Main namespace does not support wikitext.' );
15 $this->insertPages();
17 // Avoid special pages from extensions interferring with the tests
18 $this->setMwGlobals( 'wgSpecialPages', array() );
21 protected function searchProvision( Array $results = null ) {
22 if ( $results === null ) {
23 $this->setMwGlobals( 'wgHooks', array() );
24 } else {
25 $this->setMwGlobals( 'wgHooks', array(
26 'PrefixSearchBackend' => array(
27 function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
28 $srchres = $results;
29 return false;
32 ) );
36 public function insertPages() {
37 $this->insertPage( 'Sandbox' );
38 $this->insertPage( 'Bar' );
39 $this->insertPage( 'Example' );
40 $this->insertPage( 'Example Bar' );
41 $this->insertPage( 'Example Foo' );
42 $this->insertPage( 'Example Foo/Bar' );
43 $this->insertPage( 'Example/Baz' );
44 $this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
45 $this->insertPage( 'Redirect Test');
46 $this->insertPage( 'Redirect Test Worse Result');
47 $this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
48 $this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
49 $this->insertPage( 'Redirect Test2');
50 $this->insertPage( 'Redirect Test2 Worse Result');
52 $this->insertPage( 'Talk:Sandbox' );
53 $this->insertPage( 'Talk:Example' );
55 $this->insertPage( 'User:Example' );
58 public static function provideSearch() {
59 return array(
60 array( array(
61 'Empty string',
62 'query' => '',
63 'results' => array(),
64 ) ),
65 array( array(
66 'Main namespace with title prefix',
67 'query' => 'Ex',
68 'results' => array(
69 'Example',
70 'Example/Baz',
71 'Example Bar',
73 // Third result when testing offset
74 'offsetresult' => array(
75 'Example Foo',
77 ) ),
78 array( array(
79 'Talk namespace prefix',
80 'query' => 'Talk:',
81 'results' => array(
82 'Talk:Example',
83 'Talk:Sandbox',
85 ) ),
86 array( array(
87 'User namespace prefix',
88 'query' => 'User:',
89 'results' => array(
90 'User:Example',
92 ) ),
93 array( array(
94 'Special namespace prefix',
95 'query' => 'Special:',
96 'results' => array(
97 'Special:ActiveUsers',
98 'Special:AllMessages',
99 'Special:AllMyFiles',
101 // Third result when testing offset
102 'offsetresult' => array(
103 'Special:AllMyUploads',
105 ) ),
106 array( array(
107 'Special namespace with prefix',
108 'query' => 'Special:Un',
109 'results' => array(
110 'Special:Unblock',
111 'Special:UncategorizedCategories',
112 'Special:UncategorizedFiles',
114 // Third result when testing offset
115 'offsetresult' => array(
116 'Special:UncategorizedImages',
118 ) ),
119 array( array(
120 'Special page name',
121 'query' => 'Special:EditWatchlist',
122 'results' => array(
123 'Special:EditWatchlist',
125 ) ),
126 array( array(
127 'Special page subpages',
128 'query' => 'Special:EditWatchlist/',
129 'results' => array(
130 'Special:EditWatchlist/clear',
131 'Special:EditWatchlist/raw',
133 ) ),
134 array( array(
135 'Special page subpages with prefix',
136 'query' => 'Special:EditWatchlist/cl',
137 'results' => array(
138 'Special:EditWatchlist/clear',
140 ) ),
145 * @dataProvider provideSearch
146 * @covers PrefixSearch::search
147 * @covers PrefixSearch::searchBackend
149 public function testSearch( Array $case ) {
150 $this->searchProvision( null );
151 $searcher = new StringPrefixSearch;
152 $results = $searcher->search( $case['query'], 3 );
153 $this->assertEquals(
154 $case['results'],
155 $results,
156 $case[0]
161 * @dataProvider provideSearch
162 * @covers PrefixSearch::search
163 * @covers PrefixSearch::searchBackend
165 public function testSearchWithOffset( Array $case ) {
166 $this->searchProvision( null );
167 $searcher = new StringPrefixSearch;
168 $results = $searcher->search( $case['query'], 3, array(), 1 );
170 // We don't expect the first result when offsetting
171 array_shift( $case['results'] );
172 // And sometimes we expect a different last result
173 $expected = isset( $case['offsetresult'] ) ?
174 array_merge( $case['results'], $case['offsetresult'] ):
175 $case['results'];
177 $this->assertEquals(
178 $expected,
179 $results,
180 $case[0]
184 public static function provideSearchBackend() {
185 return array(
186 array( array(
187 'Simple case',
188 'provision' => array(
189 'Bar',
190 'Barcelona',
191 'Barbara',
193 'query' => 'Bar',
194 'results' => array(
195 'Bar',
196 'Barcelona',
197 'Barbara',
199 ) ),
200 array( array(
201 'Exact match not on top (bug 70958)',
202 'provision' => array(
203 'Barcelona',
204 'Bar',
205 'Barbara',
207 'query' => 'Bar',
208 'results' => array(
209 'Bar',
210 'Barcelona',
211 'Barbara',
213 ) ),
214 array( array(
215 'Exact match missing (bug 70958)',
216 'provision' => array(
217 'Barcelona',
218 'Barbara',
219 'Bart',
221 'query' => 'Bar',
222 'results' => array(
223 'Bar',
224 'Barcelona',
225 'Barbara',
227 ) ),
228 array( array(
229 'Exact match missing and not existing',
230 'provision' => array(
231 'Exile',
232 'Exist',
233 'External',
235 'query' => 'Ex',
236 'results' => array(
237 'Exile',
238 'Exist',
239 'External',
241 ) ),
242 array( array(
243 "Exact match shouldn't override already found match if " .
244 "exact is redirect and found isn't",
245 'provision' => array(
246 // Target of the exact match is low in the list
247 'Redirect Test Worse Result',
248 'Redirect Test',
250 'query' => 'redirect test',
251 'results' => array(
252 // Redirect target is pulled up and exact match isn't added
253 'Redirect Test',
254 'Redirect Test Worse Result',
256 ) ),
257 array( array(
258 "Exact match shouldn't override already found match if " .
259 "both exact match and found match are redirect",
260 'provision' => array(
261 // Another redirect to the same target as the exact match
262 // is low in the list
263 'Redirect Test2 Worse Result',
264 'Redirect test2',
266 'query' => 'redirect TEST2',
267 'results' => array(
268 // Found redirect is pulled to the top and exact match isn't
269 // added
270 'Redirect test2',
271 'Redirect Test2 Worse Result',
273 ) ),
274 array( array(
275 "Exact match should override any already found matches that " .
276 "are redirects to it",
277 'provision' => array(
278 // Another redirect to the same target as the exact match
279 // is low in the list
280 'Redirect Test Worse Result',
281 'Redirect test',
283 'query' => 'Redirect Test',
284 'results' => array(
285 // Found redirect is pulled to the top and exact match isn't
286 // added
287 'Redirect Test',
288 'Redirect Test Worse Result',
290 ) ),
295 * @dataProvider provideSearchBackend
296 * @covers PrefixSearch::searchBackend
298 public function testSearchBackend( Array $case ) {
299 $this->searchProvision( $case['provision'] );
300 $searcher = new StringPrefixSearch;
301 $results = $searcher->search( $case['query'], 3 );
302 $this->assertEquals(
303 $case['results'],
304 $results,
305 $case[0]