%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/
Upload File :
Create Path :
Current File : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/CompletionSuggesterTest.php

<?php

namespace CirrusSearch;

use CirrusSearch\Test\HashSearchConfig;
use CirrusSearch\Test\DummyConnection;
use CirrusSearch\BuildDocument\SuggestBuilder;

/**
 * Completion Suggester Tests
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */
class CompletionSuggesterTest extends \PHPUnit_Framework_TestCase {

	/**
	 * @dataProvider provideQueries
	 */
	public function testQueries( $config, $limit, $search, $variants, $expectedProfiles, $expectedQueries ) {
		$completion = new MyCompletionSuggester( new HashSearchConfig( $config ), $limit );
		list( $profiles, $suggest ) = $completion->testBuildQuery( $search, $variants );
		$this->assertEquals( $expectedProfiles, $profiles );
		$this->assertEquals( $expectedQueries, $suggest );
	}


	public function provideQueries() {
		$simpleProfile = [
			'plain' => [
				'field' => 'suggest',
				'min_query_len' => 0,
				'discount' => 1.0,
				'fetch_limit_factor' => 2,
			],
		];

		$simpleFuzzy = $simpleProfile + [
			'plain-fuzzy' => [
				'field' => 'suggest',
				'min_query_len' => 0,
				'fuzzy' => [
					'fuzzyness' => 'AUTO',
					'prefix_length' => 1,
					'unicode_aware' => true,
				],
				'discount' => 0.5,
				'fetch_limit_factor' => 1.5
			]
		];

		$profile = [
			'simple' => $simpleProfile,
			'fuzzy' => $simpleFuzzy,
		];

		return [
			"simple" => [
				[
					'CirrusSearchCompletionSettings' => 'simple',
					'CirrusSearchCompletionProfiles' => $profile,
				],
				10,
				' complete me ',
				null,
				$simpleProfile, // The profile remains unmodified here
				[
					'plain' => [
						'text' => 'complete me ', // keep trailing white spaces
						'completion' => [
							'field' => 'suggest',
							'size' => 20, // effect of fetch_limit_factor
						],
					],
				],
			],
			"simple with fuzzy" => [
				[
					'CirrusSearchCompletionSettings' => 'fuzzy',
					'CirrusSearchCompletionProfiles' => $profile,
				],
				10,
				' complete me ',
				null,
				$simpleFuzzy, // The profiles remains unmodified here
				[
					'plain' => [
						'text' => 'complete me ', // keep trailing white spaces
						'completion' => [
							'field' => 'suggest',
							'size' => 20, // effect of fetch_limit_factor
						],
					],
					'plain-fuzzy' => [
						'text' => 'complete me ', // keep trailing white spaces
						'completion' => [
							'field' => 'suggest',
							'size' => 15.0, // effect of fetch_limit_factor
							// fuzzy config is simply copied from the profile
							'fuzzy' => [
								'fuzzyness' => 'AUTO',
								'prefix_length' => 1,
								'unicode_aware' => true,
							],
						],
					],
				],
			],
			"simple with variants" => [
				[
					'CirrusSearchCompletionSettings' => 'simple',
					'CirrusSearchCompletionProfiles' => $profile,
				],
				10,
				' complete me ',
				[ ' variant1 ', ' complete me ', ' variant2 ' ],
				// Profile is updated with extra variant setup
				// to include an extra discount
				// ' complete me ' variant duplicate will be ignored
				$simpleProfile + [
					'plain-variant-1' => [
						'field' => 'suggest',
						'min_query_len' => 0,
						'discount' => 1.0 * CompletionSuggester::VARIANT_EXTRA_DISCOUNT,
						'fetch_limit_factor' => 2,
						'fallback' => true, // extra key added, not used for now
					],
					'plain-variant-2' => [
						'field' => 'suggest',
						'min_query_len' => 0,
						'discount' => 1.0 * (CompletionSuggester::VARIANT_EXTRA_DISCOUNT/2),
						'fetch_limit_factor' => 2,
						'fallback' => true, // extra key added, not used for now
					]
				],
				[
					'plain' => [
						'text' => 'complete me ', // keep trailing white spaces
						'completion' => [
							'field' => 'suggest',
							'size' => 20, // effect of fetch_limit_factor
						],
					],
					'plain-variant-1' => [
						'text' => 'variant1 ',
						'completion' => [
							'field' => 'suggest',
							'size' => 20, // effect of fetch_limit_factor
						],
					],
					'plain-variant-2' => [
						'text' => 'variant2 ',
						'completion' => [
							'field' => 'suggest',
							'size' => 20, // effect of fetch_limit_factor
						],
					],
				],
			],
		];
	}

	/**
	 * @dataProvider provideMinMaxQueries
	 */
	public function testMinMaxDefaultProfile( $len, $query ) {
		global $wgCirrusSearchCompletionProfiles;
		$config = [
			'CirrusSearchCompletionSettings' => 'fuzzy',
			'CirrusSearchCompletionProfiles' => $wgCirrusSearchCompletionProfiles,
		];
		// Test that we generate at most 4 profiles
		$completion = new MyCompletionSuggester( new HashSearchConfig( $config ), 1 );
		list( $profiles, $suggest ) = $completion->testBuildQuery( $query, [] );
		// Unused profiles are kept
		$this->assertEquals( count( $wgCirrusSearchCompletionProfiles['fuzzy'] ), count( $profiles ) );
		// Never run more than 4 suggest query (without variants)
		$this->assertTrue( count( $suggest ) <= 4 );
		// small queries
		$this->assertTrue( count( $suggest ) >= 2 );

		if ( $len < 3 ) {
			// We do not run fuzzy for small queries
			$this->assertEquals( 2, count( $suggest ) );
			foreach( $suggest as $key => $value ) {
				$this->assertArrayNotHasKey( 'fuzzy', $value );
			}
		}
		foreach( $suggest as $key => $value ) {
			// Make sure the query is truncated otherwise elastic won't send results
			$this->assertTrue( mb_strlen( $value['text'] ) < SuggestBuilder::MAX_INPUT_LENGTH );
		}
		foreach( array_keys( $suggest ) as $sug ) {
			// Makes sure we have the corresponding profile
			$this->assertArrayHasKey( $sug, $profiles );
		}
	}

	public function provideMinMaxQueries() {
		$queries = [];
		// The completion should not count extra spaces
		// This is to avoid enbling costly fuzzy profiles
		// by cheating with spaces
		$query = '  ';
		for( $i = 0; $i < 100; $i++ ) {
			$test = "Query length {$i}";
			$queries[$test] = [ $i, $query . '   ' ];
			$query .= '';
		}
		return $queries;
	}

	/**
	 * @dataProvider provideResponse
	 */
	public function testOffsets( \Elastica\Response $resp, $limit, $offset, $first, $last, $size, $hardLimit ) {
		global $wgCirrusSearchCompletionProfiles;
		$config = [
			'CirrusSearchCompletionSettings' => 'fuzzy',
			'CirrusSearchCompletionProfiles' => $wgCirrusSearchCompletionProfiles,
			'CirrusSearchCompletionSuggesterHardLimit' => $hardLimit,
		];
		// Test that we generate at most 4 profiles
		$completion = new MyCompletionSuggester( new HashSearchConfig( $config ), $limit, $offset );

		$suggestions = $completion->testPostProcess( 'Tit', $resp );
		$this->assertEquals( $size, $suggestions->getSize() );
		if ( $size > 0 ) {
			$suggestions = $suggestions->getSuggestions();
			$firstS = reset( $suggestions );
			$lastS = end( $suggestions );
			$this->assertEquals( $first, $firstS->getText() );
			$this->assertEquals( $last, $lastS->getText() );
		}
	}

	public function provideResponse() {
		$suggestions = [];
		$max = 200;
		for( $i = 1; $i <= $max; $i++ ) {
			$score = $max - $i;
			$suggestions[] = [
				'text'=> "$i:t:Title$i",
				'score' => $score,
			];
		}

		$suggestData = [ [
					'text' => 'Tit',
					'options' => $suggestions
				] ];

		$data = [
			'_shards' => [],
			'plain' => $suggestData,
			'plain_fuzzy_2' => $suggestData,
			'plain_stop' => $suggestData,
			'plain_stop_fuzzy_2' => $suggestData,
		];
		$resp = new \Elastica\Response( $data );
		return [
			'Simple offset 0' => [
				$resp,
				5, 0, 'Title1', 'Title5', 5, 50
			 ],
			'Simple offset 5' => [
				$resp,
				5, 5, 'Title6', 'Title10', 5, 50
			 ],
			'Reach ES limit' => [
				$resp,
				5, $max-3, 'Title198', 'Title200', 3, 300
			 ],
			'Reach Cirrus limit' => [
				$resp,
				5, 47, 'Title48', 'Title50', 3, 50
			 ],
			'Out of Cirrus bounds' => [
				$resp,
				5, 67, null, null, 0, 50
			 ],
			'Out of elastic results' => [
				$resp,
				5, 200, null, null, 0, 300
			 ],
		];

	}
}

/**
 * No package visibility in with PHP so we have to subclass...
 */
class MyCompletionSuggester extends CompletionSuggester {
	public function __construct( SearchConfig $config, $limit, $offset=0 ) {
		parent::__construct( new DummyConnection(), $limit, $offset, $config, [ NS_MAIN ], null, "dummy" );
	}

	public function testBuildQuery( $search, $variants ) {
		$this->setTermAndVariants( $search, $variants );
		return $this->buildQuery();
	}

	public function testPostProcess( $search, \Elastica\Response $resp ) {
		$this->setTermAndVariants( $search );
		list( $profiles ) = $this->buildQuery();
		return $this->postProcessSuggest( $resp, $profiles );
	}
}

Zerion Mini Shell 1.0