%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/UserTestingTest.php

<?php

namespace CirrusSearch;

/**
 * Make sure cirrus doens't break any hooks.
 *
 * 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 UserTestingTest extends \MediaWikiTestCase {
	public function setUp() {
		parent::setUp();
		ElasticsearchIntermediary::resetExecutionId();
		UserTesting::resetInstance();
	}

	public function testPartitipcationInTest() {
		$config = $this->config( 'test' );
		$ut = $this->ut( $config, true );
		$this->assertEquals( true, $ut->isParticipatingIn( 'test' ) );
		$ut = $this->ut( $config, false );
		$this->assertEquals( false, $ut->isParticipatingIn( 'test' ) );
	}

	// There is no way to run this test correctly...random values mean
	// best we can do is measure distribution over a decent sample size
	public function testSamplesFairlyWithDefaultCallback() {
		$mockReq = $this->getMockBuilder( 'WebRequest' )
			->disableOriginalConstructor()
			->getMock();
		$mockReq->expects( $this->any() )
			->method( 'getIP' )
			->will( $this->returnCallback( function () { return mt_rand(); } ) );
		$mockReq->expects( $this->any() )
			->method( 'getHeader' )
			->will( $this->returnCallback( function () { return mt_rand(); } ) );

		\RequestContext::getMain()->setRequest( $mockReq );

		$config = $this->config( 'test', 3 );
		$samples = 3000;
		$expected = $samples / $config['test']['sampleRate'];
		$expectedPerBucket = $expected / count( $config['test']['buckets'] );
		$allowedError = .25;
		$buckets = [];
		for ( $i = 0; $i < $samples; ++$i ) {
			$ut = new UserTesting( $config );
			if ( $ut->isParticipatingIn( 'test' ) ) {
				$bucket = $ut->getBucket( 'test' );
				if ( isset( $buckets[$bucket] ) ) {
					$buckets[$bucket]++;
				} else {
					$buckets[$bucket] = 1;
				}
			}
		}
		unset( $buckets[''] );
		$participants = array_sum( $buckets );
		$this->assertGreaterThan( $expected * ( 1 - $allowedError ), $participants );
		$this->assertLessThan( $expected * ( 1 + $allowedError ), $participants );
		foreach ( $buckets as $bucket => $participants ) {
			$this->assertGreaterThan( $expectedPerBucket * ( 1 - $allowedError ), $participants );
			$this->assertLessThan( $expectedPerBucket * ( 1 + $allowedError ), $participants );
		}
	}

	public function testListsTestsCurrentlyParticipatingIn() {
		$config = $this->config( [ 'test', 'foo', 'bar' ] );
		$ut = $this->ut( $config, true);
		$this->assertEquals( [ 'test', 'foo', 'bar' ], $ut->getActiveTestNames() );
		$ut = $this->ut( $config, [ false, true, true ] );
		$this->assertEquals( [ 'foo', 'bar' ], $ut->getActiveTestNames() );
	}

	public function testActiveTestOverridesGlobalVariables() {
		$config = $this->config( 'test', 10, [
			'wgCirrusSearchBoostLinks' => true,
			'dontsetthisvariable' => true,
		] );

		$this->setMwGlobals( 'wgCirrusSearchBoostLinks', false );
		$ut = $this->ut( $config, true );
		$this->assertEquals( true, $GLOBALS['wgCirrusSearchBoostLinks'] );
		$this->assertArrayNotHasKey( 'dontsetthisvariable', $GLOBALS );
		$this->setMwGlobals( 'wgCirrusSearchBoostLinks', false );
		$ut = $this->ut( $config, false );
		$this->assertEquals( false, $GLOBALS['wgCirrusSearchBoostLinks'] );
	}

	public function testDoesNotReinitializeFromGetInstance() {
		$this->setMwGlobals( [
			'wgCirrusSearchUserTesting' => $this->config( 'test', 10, [
				'wgCirrusSearchBoostLinks' => true,
			] ),
			'wgCirrusSearchBoostLinks' => false,
		] );
		$ut = UserTesting::getInstance( function () { return true; } );
		$this->assertEquals( true, $GLOBALS['wgCirrusSearchBoostLinks'] );
		$GLOBALS['wgCirrusSearchBoostLinks'] = false;
		$ut = UserTesting::getInstance( function () { return true; } );
		$this->assertEquals( false, $GLOBALS['wgCirrusSearchBoostLinks'] );
	}

	public function testPerBucketGlobalsOverridePerTestGlobals() {
		$this->setMwGlobals( 'wgCirrusSearchBoostLinks', false );
		$config = $this->config( 'test', 10, [
			'wgCirrusSearchBoostLinks' => 'test',
		] );
		$config['test']['buckets']['a']['globals']['wgCirrusSearchBoostLinks'] = 'bucket';
		$config['test']['buckets']['b']['globals']['wgCirrusSearchBoostLinks'] = 'bucket';

		$ut = $this->ut( $config, true );
		$this->assertEquals( 'bucket', $GLOBALS['wgCirrusSearchBoostLinks'] );
	}

	public function providerChooseBucket() {
		return [
			[ 'a', 0, [ 'a', 'b', 'c' ] ],
			[ 'a', 0, [ 'a', 'b', 'c', 'd' ] ],
			[ 'a', 0.24, [ 'a', 'b', 'c', 'd' ] ],
			[ 'a', 0.25, [ 'a', 'b', 'c', 'd' ] ],
			[ 'b', 0.26, [ 'a', 'b', 'c', 'd' ] ],
			[ 'b', 0.49, [ 'a', 'b', 'c', 'd' ] ],
			[ 'b', 0.50, [ 'a', 'b', 'c', 'd' ] ],
			[ 'c', 0.51, [ 'a', 'b', 'c', 'd' ] ],
			[ 'd', 1, [ 'a', 'b', 'c', 'd' ] ],
		];
	}

	/**
	 * @dataProvider providerChooseBucket
	 */
	public function testChooseBucket( $expect, $probability, array $buckets ) {
		$this->assertEquals( $expect, UserTesting::chooseBucket( $probability, $buckets ) );
	}

	public function testTrigger() {
		$config = [
			'someTest' => [
				'buckets' => [
					'a' => [
						'trigger' => 'hi there',
					],
					'b' => [
						'trigger' =>  'or this one',
					],
				],
			],
		];

		$req = new \FauxRequest( [ 'cirrusUserTesting' => 'hi there' ] );
		$this->setMwGlobals( 'wgCirrusSearchUserTesting', $config );
		\RequestContext::getMain()->setRequest( $req );
		$this->assertEquals( [ 'someTest:a' ], UserTesting::getInstance()->getActiveTestNamesWithBucket() );

		$ut = new UserTesting( $config, null, 'hi there' );
		$this->assertEquals( [ 'someTest:a' ], $ut->getActiveTestNamesWithBucket() );

		$ut = new UserTesting( $config, null, 'or this one' );
		$this->assertEquals( [ 'someTest:b' ], $ut->getActiveTestNamesWithBucket() );
	}

	protected function config( $testNames, $sampleRate = 10, $globals = [] ) {
		if ( $globals ) {
			$globals = [ 'globals' => $globals ];
		}
		$config = [];
		foreach ( (array)$testNames as $name ) {
			$config[$name] = $globals + [
				'sampleRate' => $sampleRate,
				'buckets' => [
					'a' => [],
					'b' => [],
				],
			];
		}
		return $config;
	}

	protected function ut( $config, $callback ) {
		if ( is_array( $callback ) ) {
			// reverse so pop in reverse order
			$retvals = array_reverse( $callback );
			$callback = function () use ( &$retvals ) {
				$retval = array_pop( $retvals );
				return $retval ? mt_rand( 0, mt_getrandmax() ) / mt_getrandmax() : 0;
			};
		} elseif ( is_bool( $callback ) ) {
			$retval = $callback;
			$callback = function () use ( $retval ) {
				return $retval ? mt_rand( 0, mt_getrandmax() ) / mt_getrandmax() : 0;
			};
		}
		return new UserTesting( $config, $callback );
	}
}

Zerion Mini Shell 1.0