wiki.techinc.nl/tests/phpunit/includes/HooksTest.php

351 lines
9.9 KiB
PHP
Raw Normal View History

2011-01-17 16:43:12 +00:00
<?php
use MediaWiki\HookContainer\HookContainer;
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
use Wikimedia\ScopedCallback;
class HooksTest extends MediaWikiIntegrationTestCase {
2011-03-27 01:27:02 +00:00
private const MOCK_HOOK_NAME = 'MediaWikiHooksTest001';
protected function setUp(): void {
parent::setUp();
2011-01-17 16:43:12 +00:00
}
2011-03-27 01:27:02 +00:00
public static function provideHooks() {
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$obj = new HookTestDummyHookHandlerClass();
return [
[
'Object and method',
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
[ $obj, 'someNonStatic' ],
'changed-nonstatic',
'changed-nonstatic'
],
[ 'Object and no method', $obj, 'changed-onevent', 'original' ],
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
[ 'Object and static method', [ $obj, 'someStatic' ], 'changed-static', 'original' ],
[
'Class::method static call',
'HookTestDummyHookHandlerClass::someStatic',
'changed-static',
'original'
],
[ 'Global function', 'wfNothingFunction', 'changed-func', 'original' ],
[ 'Closure', static function ( &$foo, $bar ) {
$foo = 'changed-closure';
return true;
}, 'changed-closure', 'original' ],
];
}
2011-03-27 01:27:02 +00:00
/**
* @dataProvider provideHooks
* @covers Hooks::register
* @covers Hooks::run
*/
public function testRunningNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) {
$this->hideDeprecated( 'Hooks::run' );
$foo = $bar = 'original';
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, $hook );
Hooks::run( self::MOCK_HOOK_NAME, [ &$foo, &$bar ] );
2011-03-27 01:27:02 +00:00
$this->assertSame( $expectedFoo, $foo, $msg );
$this->assertSame( $expectedBar, $bar, $msg );
}
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
/**
* @covers Hooks::getHandlers
*/
public function testGetHandlers() {
global $wgHooks;
$hookContainer = $this->getServiceContainer()->getHookContainer();
$this->filterDeprecated( '/\$wgHooks/' );
$this->filterDeprecated( '/Hooks::getHandlers was deprecated/' );
$this->filterDeprecated( '/HookContainer::getHandlerCallbacks was deprecated/' );
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$this->assertSame(
[],
Hooks::getHandlers( 'MediaWikiHooksTest001' ),
'No hooks registered'
);
$a = [ new HookTestDummyHookHandlerClass(), 'someStatic' ];
$b = [ new HookTestDummyHookHandlerClass(), 'onMediaWikiHooksTest001' ];
$wgHooks['MediaWikiHooksTest001'][] = $a;
$this->assertSame(
[ $a ],
array_values( Hooks::getHandlers( 'MediaWikiHooksTest001' ) ),
'Hook registered by $wgHooks'
);
$reset = $hookContainer->scopedRegister( 'MediaWikiHooksTest001', $b );
$this->assertSame(
[ $a, $b ],
array_values( Hooks::getHandlers( 'MediaWikiHooksTest001' ) ),
'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register'
);
ScopedCallback::consume( $reset );
unset( $wgHooks['MediaWikiHooksTest001'] );
$hookContainer->register( 'MediaWikiHooksTest001', $b );
$this->assertSame(
[ $b ],
array_values( Hooks::getHandlers( 'MediaWikiHooksTest001' ) ),
'Hook registered by Hook::register'
);
}
/**
* @covers Hooks::isRegistered
* @covers Hooks::getHandlers
* @covers Hooks::register
* @covers Hooks::run
*/
public function testRegistration() {
$this->hideDeprecated( 'Hooks::isRegistered' );
$this->hideDeprecated( 'Hooks::run' );
global $wgHooks;
$hookContainer = $this->getServiceContainer()->getHookContainer();
$this->expectDeprecationAndContinue( '/\$wgHooks .* deprecated/' );
$this->expectDeprecationAndContinue( '/Use of Hooks::register was deprecated/' );
$this->expectDeprecationAndContinue( '/Hooks::getHandlers was deprecated/' );
$this->expectDeprecationAndContinue( '/HookContainer::getHandlerCallbacks was deprecated/' );
$a = new HookTestDummyHookHandlerClass();
$b = new HookTestDummyHookHandlerClass();
$c = new HookTestDummyHookHandlerClass();
$wgHooks[ self::MOCK_HOOK_NAME ][] = $a;
Hooks::register( self::MOCK_HOOK_NAME, $b );
$hookContainer->register( self::MOCK_HOOK_NAME, $c );
$this->assertTrue( Hooks::isRegistered( self::MOCK_HOOK_NAME ) );
$this->assertCount( 3, Hooks::getHandlers( self::MOCK_HOOK_NAME ) );
$foo = 'quux';
$bar = 'qaax';
Hooks::run( self::MOCK_HOOK_NAME, [ &$foo, &$bar ] );
$this->assertSame(
1,
$a->calls,
'Hooks::run() should run hooks registered via $wgHooks'
);
$this->assertSame(
1,
$b->calls,
'Hooks::run() should run hooks registered via Hooks::register'
);
$this->assertSame(
1,
$c->calls,
'Hooks::run() should run hooks registered via HookContainer::register'
);
}
/**
* @covers Hooks::run
*/
public function testUncallableFunction() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
// NOTE: Currently, register() doesn't immediately normalize and check the hook.
// Failure to normalize later, on run, is ignored silently. Should it trigger a warning?
$hookContainer->register( self::MOCK_HOOK_NAME, 'ThisFunctionDoesntExist' );
Hooks::run( self::MOCK_HOOK_NAME, [] );
// We assert that run() doesn't throw.
$this->addToAssertionCount( 1 );
}
/**
* @covers Hooks::run
*/
public function testFalseReturn() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
return false;
} );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
$foo = 'test';
return true;
} );
$foo = 'original';
Hooks::run( self::MOCK_HOOK_NAME, [ &$foo ] );
$this->assertSame( 'original', $foo, 'Hooks abort after a false return.' );
}
/**
* @covers Hooks::run
*/
public function testNullReturn() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
return;
} );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
$foo = 'test';
return true;
} );
$foo = 'original';
Hooks::run( self::MOCK_HOOK_NAME, [ &$foo ] );
$this->assertSame( 'test', $foo, 'Hooks continue after a null return.' );
}
/**
Hook Container New classes and modificatons to existing classes to support the new Hooks system. All changes are documented in RFC https://phabricator.wikimedia.org/T240307. - HookContainer.php: Class for doing much of what Hooks.php has historically done, but enabling new-style hooks to be processed and registered. Changes include new ways of defining hook handler functions as an object with defined dependencies in extension.json, removing runWithoutAbort() and addit it to an $options parameter to be passed to HookContainer::run(), being able to decipher whether a hook handler is legacy or non-legacy style and run them in the appropriate way, etc. - DeprecatedHooks.php: For marking hooks deprecated and verifying if one is deprecated - DeprecatedHooksTest.php: Unit tests for DeprecatedHooks.php - Hooks.php: register() will now additionally register hooks with handlers in new HooksContainer.php. getHandlers() will be a legacy wrapper for calling the newer HookContainer::getHandlers() - MediaWikiServices.php: Added getHookContainer() for retrieving HookContainer singleton - ExtensionProcessor.php: modified extractHooks() to be able to extract new style handler objects being registered in extension.json - ServiceWiring.php: Added HookContainer to list of services to return - HookContainerTest.php: Unit tests for HookContainer.php - ExtensionProcessorTest.php: Moved file out of /unit folder and now extends MediaWikiTestCase instead of MediaWikiUnitTestCase (as the tests are not truly unit tests). Modified existing tests for ExtensionProcessor::extractHooks() to include a test case for new style handler Bug: T240307 Change-Id: I432861d8995cfd7180e77e115251d8055b7eceec
2020-02-10 14:47:46 +00:00
* @covers Hooks::run
*/
public function testCallHook_NoopHook() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, HookContainer::NOOP );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
$foo = 'test';
return true;
} );
$foo = 'original';
Hooks::run( self::MOCK_HOOK_NAME, [ &$foo ] );
$this->assertSame( 'test', $foo, 'Hooks that are falsey are skipped.' );
}
/**
Hook Container New classes and modificatons to existing classes to support the new Hooks system. All changes are documented in RFC https://phabricator.wikimedia.org/T240307. - HookContainer.php: Class for doing much of what Hooks.php has historically done, but enabling new-style hooks to be processed and registered. Changes include new ways of defining hook handler functions as an object with defined dependencies in extension.json, removing runWithoutAbort() and addit it to an $options parameter to be passed to HookContainer::run(), being able to decipher whether a hook handler is legacy or non-legacy style and run them in the appropriate way, etc. - DeprecatedHooks.php: For marking hooks deprecated and verifying if one is deprecated - DeprecatedHooksTest.php: Unit tests for DeprecatedHooks.php - Hooks.php: register() will now additionally register hooks with handlers in new HooksContainer.php. getHandlers() will be a legacy wrapper for calling the newer HookContainer::getHandlers() - MediaWikiServices.php: Added getHookContainer() for retrieving HookContainer singleton - ExtensionProcessor.php: modified extractHooks() to be able to extract new style handler objects being registered in extension.json - ServiceWiring.php: Added HookContainer to list of services to return - HookContainerTest.php: Unit tests for HookContainer.php - ExtensionProcessorTest.php: Moved file out of /unit folder and now extends MediaWikiTestCase instead of MediaWikiUnitTestCase (as the tests are not truly unit tests). Modified existing tests for ExtensionProcessor::extractHooks() to include a test case for new style handler Bug: T240307 Change-Id: I432861d8995cfd7180e77e115251d8055b7eceec
2020-02-10 14:47:46 +00:00
* @covers Hooks::run
*/
public function testCallHook_UnknownDatatype() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
// NOTE: Currently, register() doesn't immediately normalize and check the hook.
// Failure to normalize later, on run, is ignored silently. Should it trigger a warning?
$hookContainer->register( self::MOCK_HOOK_NAME, 12345 );
Hooks::run( self::MOCK_HOOK_NAME );
// We assert that run() doesn't throw.
$this->addToAssertionCount( 1 );
}
/**
Hook Container New classes and modificatons to existing classes to support the new Hooks system. All changes are documented in RFC https://phabricator.wikimedia.org/T240307. - HookContainer.php: Class for doing much of what Hooks.php has historically done, but enabling new-style hooks to be processed and registered. Changes include new ways of defining hook handler functions as an object with defined dependencies in extension.json, removing runWithoutAbort() and addit it to an $options parameter to be passed to HookContainer::run(), being able to decipher whether a hook handler is legacy or non-legacy style and run them in the appropriate way, etc. - DeprecatedHooks.php: For marking hooks deprecated and verifying if one is deprecated - DeprecatedHooksTest.php: Unit tests for DeprecatedHooks.php - Hooks.php: register() will now additionally register hooks with handlers in new HooksContainer.php. getHandlers() will be a legacy wrapper for calling the newer HookContainer::getHandlers() - MediaWikiServices.php: Added getHookContainer() for retrieving HookContainer singleton - ExtensionProcessor.php: modified extractHooks() to be able to extract new style handler objects being registered in extension.json - ServiceWiring.php: Added HookContainer to list of services to return - HookContainerTest.php: Unit tests for HookContainer.php - ExtensionProcessorTest.php: Moved file out of /unit folder and now extends MediaWikiTestCase instead of MediaWikiUnitTestCase (as the tests are not truly unit tests). Modified existing tests for ExtensionProcessor::extractHooks() to include a test case for new style handler Bug: T240307 Change-Id: I432861d8995cfd7180e77e115251d8055b7eceec
2020-02-10 14:47:46 +00:00
* @covers Hooks::run
*/
public function testCallHook_Deprecated() {
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, 'HookTestDummyHookHandlerClass::someStatic' );
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$this->expectDeprecationAndContinue( '/Use of MediaWikiHooksTest001 hook/' );
$a = $b = 0;
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$this->hideDeprecated( 'Hooks::run' );
Hooks::run( self::MOCK_HOOK_NAME, [ $a, $b ], '1.31' );
}
/**
* @covers Hooks::runWithoutAbort
*/
public function testRunWithoutAbort() {
$this->hideDeprecated( 'Hooks::runWithoutAbort' );
$list = [];
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$list ) {
$list[] = 1;
return true; // Explicit true
} );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$list ) {
$list[] = 2;
return; // Implicit null
} );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$list ) {
$list[] = 3;
// No return
} );
Hooks::runWithoutAbort( self::MOCK_HOOK_NAME, [ &$list ] );
$this->assertSame( [ 1, 2, 3 ], $list, 'All hooks ran.' );
}
/**
* @covers Hooks::runWithoutAbort
*/
public function testRunWithoutAbortWarning() {
$this->hideDeprecated( 'Hooks::runWithoutAbort' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
return false;
} );
$hookContainer->register( self::MOCK_HOOK_NAME, static function ( &$foo ) {
$foo = 'test';
return true;
} );
$foo = 'original';
$this->expectException( UnexpectedValueException::class );
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$this->expectExceptionMessage( 'unabortable MediaWikiHooksTest001' );
Hooks::runWithoutAbort( self::MOCK_HOOK_NAME, [ &$foo ] );
2011-01-17 16:43:12 +00:00
}
/**
* @covers Hooks::run
*/
public function testBadHookFunction() {
$this->hideDeprecated( 'Hooks::run' );
$hookContainer = $this->getServiceContainer()->getHookContainer();
$hookContainer->register( self::MOCK_HOOK_NAME, static function () {
return 'test';
} );
Simplify HookContainer (v2) This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating change I7d690a1172 (commit d139eb07fe). The only change from the original is in getHookMethodName(), additionally replacing '-' with '_' (not just ':' and '\'). The original commit message follows: This converts all hook handlers to the same internal representation. This is done lazily, when the hook is run for the first time. The logic for temporarily disabling handlers by calling scopedRegister() with the $replace parameter set has been greatly simplified. There are some minor changes to the class's interface and behavior, none of which should be breaking changes: * run() will emit deprecation warnings if and only if it was called with the deprecationVersion option set, for all kinds of handlers. The idea is that deprecated hooks should emit a warning either from run(), or from emitDeprecationWarnings(). The latter happens if the hook is listed in DeprecatedHooks. * register() now also accepts hook handlers declared in the way that extensions register hooks. * Attempts to call register() with an invalid hook definition now result in an invalidArgumentException. * Attempts to call register() for a deprecated hook will consistently result in a deprecation warning. * The internal getRegisteredHooks() method has been removed in favor of the identical getHookNames() method. * The internal getLegacyHandlers method has been removed in favor of getHandlerDescriptions() and getHandlerCallbacks(). * The call order changed so that dynamically registered handlers are called last, instead of getting called before handler objects from extensions. Bug: T338213 Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 09:25:48 +00:00
$this->expectException( UnexpectedValueException::class );
Hooks::run( self::MOCK_HOOK_NAME, [] );
}
}
function wfNothingFunction( &$foo, &$bar ) {
$foo = 'changed-func';
return true;
}
function wfNothingFunctionData( $data, &$foo, &$bar ) {
$foo = $data;
return true;
2011-01-17 16:43:12 +00:00
}
class HookTestDummyHookHandlerClass {
public $calls = 0;
public static function someStatic( &$foo, &$bar ) {
$foo = 'changed-static';
2011-01-17 16:43:12 +00:00
return true;
}
2011-03-27 01:27:02 +00:00
2011-01-17 16:43:12 +00:00
public function someNonStatic( &$foo, &$bar ) {
$this->calls++;
$foo = 'changed-nonstatic';
$bar = 'changed-nonstatic';
2011-01-17 16:43:12 +00:00
return true;
}
2011-03-27 01:27:02 +00:00
2011-01-17 16:43:12 +00:00
public function onMediaWikiHooksTest001( &$foo, &$bar ) {
$this->calls++;
$foo = 'changed-onevent';
2011-01-17 16:43:12 +00:00
return true;
}
2011-03-27 01:27:02 +00:00
public function someNonStaticWithData( $data, &$foo, &$bar ) {
$this->calls++;
$foo = $data;
2011-01-17 16:43:12 +00:00
return true;
}
}