isWikitextNS( NS_MAIN ) ) { // tests are skipped if NS_MAIN is not wikitext return; } $this->insertPage( 'Sandbox' ); $this->insertPage( 'Bar' ); $this->insertPage( 'Example' ); $this->insertPage( 'Example Bar' ); $this->insertPage( 'Example Foo' ); $this->insertPage( 'Example Foo/Bar' ); $this->insertPage( 'Example/Baz' ); $this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' ); $this->insertPage( 'Redirect Test' ); $this->insertPage( 'Redirect Test Worse Result' ); $this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' ); $this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' ); $this->insertPage( 'Redirect Test2' ); $this->insertPage( 'Redirect Test2 Worse Result' ); $this->insertPage( 'Talk:Sandbox' ); $this->insertPage( 'Talk:Example' ); $this->insertPage( 'User:Example' ); } protected function setUp() { parent::setUp(); if ( !$this->isWikitextNS( NS_MAIN ) ) { $this->markTestSkipped( 'Main namespace does not support wikitext.' ); } // Avoid special pages from extensions interferring with the tests $this->setMwGlobals( 'wgSpecialPages', array() ); } protected function searchProvision( Array $results = null ) { if ( $results === null ) { $this->setMwGlobals( 'wgHooks', array() ); } else { $this->setMwGlobals( 'wgHooks', array( 'PrefixSearchBackend' => array( function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) { $srchres = $results; return false; } ), ) ); } } public static function provideSearch() { return array( array( array( 'Empty string', 'query' => '', 'results' => array(), ) ), array( array( 'Main namespace with title prefix', 'query' => 'Ex', 'results' => array( 'Example', 'Example/Baz', 'Example Bar', ), // Third result when testing offset 'offsetresult' => array( 'Example Foo', ), ) ), array( array( 'Talk namespace prefix', 'query' => 'Talk:', 'results' => array( 'Talk:Example', 'Talk:Sandbox', ), ) ), array( array( 'User namespace prefix', 'query' => 'User:', 'results' => array( 'User:Example', ), ) ), array( array( 'Special namespace prefix', 'query' => 'Special:', 'results' => array( 'Special:ActiveUsers', 'Special:AllMessages', 'Special:AllMyFiles', ), // Third result when testing offset 'offsetresult' => array( 'Special:AllMyUploads', ), ) ), array( array( 'Special namespace with prefix', 'query' => 'Special:Un', 'results' => array( 'Special:Unblock', 'Special:UncategorizedCategories', 'Special:UncategorizedFiles', ), // Third result when testing offset 'offsetresult' => array( 'Special:UncategorizedImages', ), ) ), array( array( 'Special page name', 'query' => 'Special:EditWatchlist', 'results' => array( 'Special:EditWatchlist', ), ) ), array( array( 'Special page subpages', 'query' => 'Special:EditWatchlist/', 'results' => array( 'Special:EditWatchlist/clear', 'Special:EditWatchlist/raw', ), ) ), array( array( 'Special page subpages with prefix', 'query' => 'Special:EditWatchlist/cl', 'results' => array( 'Special:EditWatchlist/clear', ), ) ), ); } /** * @dataProvider provideSearch * @covers PrefixSearch::search * @covers PrefixSearch::searchBackend */ public function testSearch( Array $case ) { $this->searchProvision( null ); $searcher = new StringPrefixSearch; $results = $searcher->search( $case['query'], 3 ); $this->assertEquals( $case['results'], $results, $case[0] ); } /** * @dataProvider provideSearch * @covers PrefixSearch::search * @covers PrefixSearch::searchBackend */ public function testSearchWithOffset( Array $case ) { $this->searchProvision( null ); $searcher = new StringPrefixSearch; $results = $searcher->search( $case['query'], 3, array(), 1 ); // We don't expect the first result when offsetting array_shift( $case['results'] ); // And sometimes we expect a different last result $expected = isset( $case['offsetresult'] ) ? array_merge( $case['results'], $case['offsetresult'] ) : $case['results']; $this->assertEquals( $expected, $results, $case[0] ); } public static function provideSearchBackend() { return array( array( array( 'Simple case', 'provision' => array( 'Bar', 'Barcelona', 'Barbara', ), 'query' => 'Bar', 'results' => array( 'Bar', 'Barcelona', 'Barbara', ), ) ), array( array( 'Exact match not on top (bug 70958)', 'provision' => array( 'Barcelona', 'Bar', 'Barbara', ), 'query' => 'Bar', 'results' => array( 'Bar', 'Barcelona', 'Barbara', ), ) ), array( array( 'Exact match missing (bug 70958)', 'provision' => array( 'Barcelona', 'Barbara', 'Bart', ), 'query' => 'Bar', 'results' => array( 'Bar', 'Barcelona', 'Barbara', ), ) ), array( array( 'Exact match missing and not existing', 'provision' => array( 'Exile', 'Exist', 'External', ), 'query' => 'Ex', 'results' => array( 'Exile', 'Exist', 'External', ), ) ), array( array( "Exact match shouldn't override already found match if " . "exact is redirect and found isn't", 'provision' => array( // Target of the exact match is low in the list 'Redirect Test Worse Result', 'Redirect Test', ), 'query' => 'redirect test', 'results' => array( // Redirect target is pulled up and exact match isn't added 'Redirect Test', 'Redirect Test Worse Result', ), ) ), array( array( "Exact match shouldn't override already found match if " . "both exact match and found match are redirect", 'provision' => array( // Another redirect to the same target as the exact match // is low in the list 'Redirect Test2 Worse Result', 'Redirect test2', ), 'query' => 'redirect TEST2', 'results' => array( // Found redirect is pulled to the top and exact match isn't // added 'Redirect test2', 'Redirect Test2 Worse Result', ), ) ), array( array( "Exact match should override any already found matches that " . "are redirects to it", 'provision' => array( // Another redirect to the same target as the exact match // is low in the list 'Redirect Test Worse Result', 'Redirect test', ), 'query' => 'Redirect Test', 'results' => array( // Found redirect is pulled to the top and exact match isn't // added 'Redirect Test', 'Redirect Test Worse Result', ), ) ), ); } /** * @dataProvider provideSearchBackend * @covers PrefixSearch::searchBackend */ public function testSearchBackend( Array $case ) { $this->searchProvision( $case['provision'] ); $searcher = new StringPrefixSearch; $results = $searcher->search( $case['query'], 3 ); $this->assertEquals( $case['results'], $results, $case[0] ); } }