$this->tmpFiles = array_merge( $this->tmpFiles, (array)$files );
}
- // @todo Make const when we no longer support HHVM (T192166)
- private static $namespaceAffectingSettings = [
- 'wgAllowImageMoving',
- 'wgCanonicalNamespaceNames',
- 'wgCapitalLinkOverrides',
- 'wgCapitalLinks',
- 'wgContentNamespaces',
- 'wgExtensionMessagesFiles',
- 'wgExtensionNamespaces',
- 'wgExtraNamespaces',
- 'wgExtraSignatureNamespaces',
- 'wgNamespaceContentModels',
- 'wgNamespaceProtection',
- 'wgNamespacesWithSubpages',
- 'wgNonincludableNamespaces',
- 'wgRestrictionLevels',
- ];
-
protected function tearDown() {
global $wgRequest, $wgSQLMode;
foreach ( $this->iniSettings as $name => $value ) {
ini_set( $name, $value );
}
- if (
- array_intersect( self::$namespaceAffectingSettings, array_keys( $this->mwGlobals ) ) ||
- array_intersect( self::$namespaceAffectingSettings, $this->mwGlobalsToUnset )
- ) {
- $this->resetNamespaces();
- }
$this->mwGlobals = [];
$this->mwGlobalsToUnset = [];
$this->restoreLoggers();
);
if ( $name === 'ContentLanguage' ) {
- $this->doSetMwGlobals( [ 'wgContLang' => $this->localServices->getContentLanguage() ] );
+ $this->setMwGlobals( [ 'wgContLang' => $this->localServices->getContentLanguage() ] );
}
}
* The key is added to the array of globals that will be reset afterwards
* in the tearDown().
*
- * It may be necessary to call resetServices() to allow any changed configuration variables
- * to take effect on services that get initialized based on these variables.
- *
* @par Example
* @code
* protected function setUp() {
* @param mixed|null $value Value to set the global to (ignored
* if an array is given as first argument).
*
- * @note To allow changes to global variables to take effect on global service instances,
- * call resetServices().
+ * @note This will call resetServices().
*
* @since 1.21
*/
$pairs = [ $pairs => $value ];
}
- if ( isset( $pairs['wgContLang'] ) ) {
- throw new MWException(
- 'No setting $wgContLang, use setContentLang() or setService( \'ContentLanguage\' )'
- );
- }
-
- $this->doSetMwGlobals( $pairs, $value );
- }
-
- /**
- * An internal method that allows setService() to set globals that tests are not supposed to
- * touch.
- */
- private function doSetMwGlobals( $pairs, $value = null ) {
$this->doStashMwGlobals( array_keys( $pairs ) );
foreach ( $pairs as $key => $value ) {
$GLOBALS[$key] = $value;
}
- if ( array_intersect( self::$namespaceAffectingSettings, array_keys( $pairs ) ) ) {
- $this->resetNamespaces();
- }
+ $this->resetServices();
}
/**
ini_set( $name, $value );
}
- /**
- * Must be called whenever namespaces are changed, e.g., $wgExtraNamespaces is altered.
- * Otherwise old namespace data will lurk and cause bugs.
- */
- private function resetNamespaces() {
- if ( !$this->localServices ) {
- throw new Exception( __METHOD__ . ' must be called after MediaWikiTestCase::run()' );
- }
-
- if ( $this->localServices !== MediaWikiServices::getInstance() ) {
- throw new Exception( __METHOD__ . ' will not work because the global MediaWikiServices '
- . 'instance has been replaced by test code.' );
- }
-
- Language::clearCaches();
- }
-
/**
* Check if we can back up a value by performing a shallow copy.
* Values which fail this test are copied recursively.
* Useful for setting some entries in a configuration array, instead of
* setting the entire array.
*
- * It may be necessary to call resetServices() to allow any changed configuration variables
- * to take effect on services that get initialized based on these variables.
- *
* @param string $name The name of the global, as in wgFooBar
* @param array $values The array containing the entries to set in that global
*
* @throws MWException If the designated global is not an array.
*
- * @note To allow changes to global variables to take effect on global service instances,
- * call resetServices().
+ * @note This will call resetServices().
*
* @since 1.21
*/
}
self::resetGlobalParser();
+ Language::clearCaches();
}
/**
*/
public function setContentLang( $lang ) {
if ( $lang instanceof Language ) {
- $this->setMwGlobals( 'wgLanguageCode', $lang->getCode() );
// Set to the exact object requested
$this->setService( 'ContentLanguage', $lang );
+ $this->setMwGlobals( 'wgLanguageCode', $lang->getCode() );
} else {
$this->setMwGlobals( 'wgLanguageCode', $lang );
- // Let the service handler make up the object. Avoid calling setService(), because if
- // we do, overrideMwServices() will complain if it's called later on.
- $services = MediaWikiServices::getInstance();
- $services->resetServiceForTesting( 'ContentLanguage' );
- $this->doSetMwGlobals( [ 'wgContLang' => $services->getContentLanguage() ] );
}
}
* or three values to set a single permission, like
* $this->setGroupPermissions( '*', 'read', false );
*
+ * @note This will call resetServices().
+ *
* @since 1.31
* @param array|string $newPerms Either an array of permissions to change,
* in which case the next two parameters are ignored; or a single string
}
$this->setMwGlobals( 'wgGroupPermissions', $newPermissions );
-
- // Reset services so they pick up the new permissions.
- // Resetting just PermissionManager is not sufficient, since other services may
- // have the old instance of PermissionManager injected.
- $this->resetServices();
}
/**
/**
* Create a temporary hook handler which will be reset by tearDown.
* This replaces other handlers for the same hook.
+ *
+ * @note This will call resetServices().
+ *
* @param string $hookName Hook name
* @param mixed $handler Value suitable for a hook handler
* @since 1.28
] );
$this->setLogger( 'wfDebug', new LegacyLogger( 'wfDebug' ) );
+ unlink( $debugLogFile );
wfDebug( "This is a normal string" );
$this->assertEquals( "This is a normal string\n", file_get_contents( $debugLogFile ) );
- unlink( $debugLogFile );
+ unlink( $debugLogFile );
wfDebug( "This is nöt an ASCII string" );
$this->assertEquals( "This is nöt an ASCII string\n", file_get_contents( $debugLogFile ) );
- unlink( $debugLogFile );
+ unlink( $debugLogFile );
wfDebug( "\00305This has böth UTF and control chars\003" );
$this->assertEquals(
" 05This has böth UTF and control chars \n",
file_get_contents( $debugLogFile )
);
- unlink( $debugLogFile );
+ unlink( $debugLogFile );
wfDebugMem();
$this->assertGreaterThan(
1000,
preg_replace( '/\D/', '', file_get_contents( $debugLogFile ) )
);
- unlink( $debugLogFile );
+ unlink( $debugLogFile );
wfDebugMem( true );
$this->assertGreaterThan(
1000000,
preg_replace( '/\D/', '', file_get_contents( $debugLogFile ) )
);
+
unlink( $debugLogFile );
}
$this->mUserMock->method( 'getOptions' )
->willReturn( [] );
+ // DefaultPreferencesFactory calls a ton of user methods, but we still want to list all of
+ // them in case bugs are caused by unexpected things returning null that shouldn't.
+ $this->mUserMock->expects( $this->never() )->method( $this->anythingBut(
+ 'getEffectiveGroups', 'getOptionKinds', 'getInstanceForUpdate', 'getOptions', 'getId',
+ 'isAnon', 'getRequest', 'isLoggedIn', 'getName', 'getGroupMemberships', 'getEditCount',
+ 'getRegistration', 'isAllowed', 'getRealName', 'getOption', 'getStubThreshold',
+ 'getBoolOption', 'getEmail', 'getDatePreference', 'useRCPatrol', 'useNPPatrol',
+ 'setOption', 'saveSettings', 'resetOptions', 'isRegistered'
+ ) );
+
// Create a new context
$this->mContext = new DerivativeContext( new RequestContext() );
$this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) );
private function executeQuery( $request ) {
$this->mContext->setRequest( new FauxRequest( $request, true, $this->mSession ) );
+ $this->mUserMock->method( 'getRequest' )->willReturn( $this->mContext->getRequest() );
+
$this->mTested->execute();
return $this->mTested->getResult()->getResultData( null, [ 'Strip' => 'all' ] );
$this->setExpectedApiException( 'apierror-siteinfo-includealldenied' );
}
- $mockLB = $this->getMockBuilder( LoadBalancer::class )
- ->disableOriginalConstructor()
- ->setMethods( [ 'getMaxLag', 'getLagTimes', 'getServerName', '__destruct' ] )
- ->getMock();
+ $mockLB = $this->createMock( LoadBalancer::class );
$mockLB->method( 'getMaxLag' )->willReturn( [ null, 7, 1 ] );
$mockLB->method( 'getLagTimes' )->willReturn( [ 5, 7 ] );
$mockLB->method( 'getServerName' )->will( $this->returnValueMap( [
[ 0, 'apple' ], [ 1, 'carrot' ]
] ) );
+ $mockLB->method( 'getLocalDomainID' )->willReturn( 'testdomain' );
+ $mockLB->expects( $this->never() )->method( $this->anythingBut(
+ 'getMaxLag', 'getLagTimes', 'getServerName', 'getLocalDomainID', '__destruct'
+ ) );
$this->setService( 'DBLoadBalancer', $mockLB );
$this->setMwGlobals( 'wgShowHostnames', $showHostnames );
$this->assertSame( AuthenticationResponse::FAIL, $ret->status );
$this->assertSame( 'noname', $ret->message->getKey() );
+ $this->hook( 'LocalUserCreated', $this->never() );
$readOnlyMode = \MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode();
$readOnlyMode->setReason( 'Because' );
- $this->hook( 'LocalUserCreated', $this->never() );
$userReq->username = self::usernameForCreation();
$ret = $this->manager->beginAccountCreation( $creator, [ $userReq ], 'http://localhost/' );
$this->unhook( 'LocalUserCreated' );
$session, $this->request->getSession()->getSecret( 'AuthManager::accountCreationState' )
);
+ $this->hook( 'LocalUserCreated', $this->never() );
$this->request->getSession()->setSecret( 'AuthManager::accountCreationState',
[ 'username' => $creator->getName() ] + $session );
$readOnlyMode = \MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode();
$readOnlyMode->setReason( 'Because' );
- $this->hook( 'LocalUserCreated', $this->never() );
$ret = $this->manager->continueAccountCreation( [] );
$this->unhook( 'LocalUserCreated' );
$this->assertSame( AuthenticationResponse::FAIL, $ret->status );
// Wiki is read-only
$session->clear();
+ $this->hook( 'LocalUserCreated', $this->never() );
$readOnlyMode = \MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode();
$readOnlyMode->setReason( 'Because' );
$user = \User::newFromName( $username );
- $this->hook( 'LocalUserCreated', $this->never() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( wfMessage( 'readonlytext', 'Because' ) ), $ret );
* @dataProvider provideGenerateContentDiffBody
*/
public function testGenerateContentDiffBody(
- Content $oldContent, Content $newContent, $expectedDiff
+ array $oldContentArgs, array $newContentArgs, $expectedDiff
) {
+ $this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
+ 'testing-nontext' => DummyNonTextContentHandler::class,
+ ] );
+ $oldContent = ContentHandler::makeContent( ...$oldContentArgs );
+ $newContent = ContentHandler::makeContent( ...$newContentArgs );
+
// Set $wgExternalDiffEngine to something bogus to try to force use of
// the PHP engine rather than wikidiff2.
$this->setMwGlobals( [
$this->assertSame( $expectedDiff, $this->getPlainDiff( $diff ) );
}
- public function provideGenerateContentDiffBody() {
- $this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
- 'testing-nontext' => DummyNonTextContentHandler::class,
- ] );
- $content1 = ContentHandler::makeContent( 'xxx', null, CONTENT_MODEL_TEXT );
- $content2 = ContentHandler::makeContent( 'yyy', null, CONTENT_MODEL_TEXT );
+ public static function provideGenerateContentDiffBody() {
+ $content1 = [ 'xxx', null, CONTENT_MODEL_TEXT ];
+ $content2 = [ 'yyy', null, CONTENT_MODEL_TEXT ];
return [
'self-diff' => [ $content1, $content1, '' ],
/**
* @dataProvider provideGetDiff
- * @param Content|null $oldContent
- * @param Content|null $newContent
+ * @param array|null $oldContentArgs To pass to makeContent() (if not null)
+ * @param array|null $newContentArgs
* @param string|Exception $expectedResult
* @throws Exception
*/
public function testGetDiff(
- Content $oldContent = null, Content $newContent = null, $expectedResult
+ array $oldContentArgs = null, array $newContentArgs = null, $expectedResult
) {
+ $this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
+ 'testing' => DummyContentHandlerForTesting::class,
+ 'testing-nontext' => DummyNonTextContentHandler::class,
+ ] );
+
+ $oldContent = $oldContentArgs ? self::makeContent( ...$oldContentArgs ) : null;
+ $newContent = $newContentArgs ? self::makeContent( ...$newContentArgs ) : null;
+
if ( $expectedResult instanceof Exception ) {
$this->setExpectedException( get_class( $expectedResult ), $expectedResult->getMessage() );
}
$this->assertSame( $expectedResult, $plainDiff );
}
- public function provideGetDiff() {
- $this->mergeMwGlobalArrayValue( 'wgContentHandlers', [
- 'testing' => DummyContentHandlerForTesting::class,
- 'testing-nontext' => DummyNonTextContentHandler::class,
- ] );
-
+ public static function provideGetDiff() {
return [
'same text' => [
- $this->makeContent( "aaa\nbbb\nccc" ),
- $this->makeContent( "aaa\nbbb\nccc" ),
+ [ "aaa\nbbb\nccc" ],
+ [ "aaa\nbbb\nccc" ],
"",
],
'different text' => [
- $this->makeContent( "aaa\nbbb\nccc" ),
- $this->makeContent( "aaa\nxxx\nccc" ),
+ [ "aaa\nbbb\nccc" ],
+ [ "aaa\nxxx\nccc" ],
" aaa aaa\n-bbb+xxx\n ccc ccc",
],
'no right content' => [
- $this->makeContent( "aaa\nbbb\nccc" ),
+ [ "aaa\nbbb\nccc" ],
null,
"-aaa+ \n-bbb \n-ccc ",
],
'no left content' => [
null,
- $this->makeContent( "aaa\nbbb\nccc" ),
+ [ "aaa\nbbb\nccc" ],
"- +aaa\n +bbb\n +ccc",
],
'no content' => [
new InvalidArgumentException( '$oldContent and $newContent cannot both be null' ),
],
'non-text left content' => [
- $this->makeContent( '', 'testing-nontext' ),
- $this->makeContent( "aaa\nbbb\nccc" ),
+ [ '', 'testing-nontext' ],
+ [ "aaa\nbbb\nccc" ],
new ParameterTypeException( '$oldContent', 'TextContent|null' ),
],
'non-text right content' => [
- $this->makeContent( "aaa\nbbb\nccc" ),
- $this->makeContent( '', 'testing-nontext' ),
+ [ "aaa\nbbb\nccc" ],
+ [ '', 'testing-nontext' ],
new ParameterTypeException( '$newContent', 'TextContent|null' ),
],
];
* @param string $model
* @return null|TextContent
*/
- private function makeContent( $str, $model = CONTENT_MODEL_TEXT ) {
+ private static function makeContent( $str, $model = CONTENT_MODEL_TEXT ) {
return ContentHandler::makeContent( $str, null, $model );
}
/** @covers ObjectCache::newAnything */
public function testNewAnythingNoAccelNoDb() {
- $this->overrideMwServices(); // Ensures restore on tear down
- MediaWiki\MediaWikiServices::disableStorageBackend();
-
$this->setMwGlobals( [
'wgMainCacheType' => CACHE_ACCEL
] );
CACHE_ACCEL => [ 'class' => EmptyBagOStuff::class ]
] );
+ MediaWiki\MediaWikiServices::disableStorageBackend();
+
$this->assertInstanceOf(
EmptyBagOStuff::class,
ObjectCache::newAnything( [] ),