Depends-On: I99c5e5664d2401c36a9890f148eba7c25e6e8324 Depends-On: I48ab818b2965da14af15ef370aa83ad9455badd9 Depends-On: I018371e4b77911e56152ca7b2df734afc73f58a5 Change-Id: I04ebdb52102f6191d49a9cc70b1f98308299e72f
160 lines
4.9 KiB
PHP
160 lines
4.9 KiB
PHP
<?php
|
|
|
|
use Psr\Container\ContainerInterface;
|
|
use Wikimedia\ObjectFactory\ObjectFactory;
|
|
|
|
/**
|
|
* @covers SkinFactory
|
|
*/
|
|
class SkinFactoryTest extends \MediaWikiUnitTestCase {
|
|
|
|
private function createSkinFactory( $service = null, $options = [] ): SkinFactory {
|
|
$objectFactory = $service
|
|
? new ObjectFactory( $service )
|
|
: new ObjectFactory( $this->createMock( ContainerInterface::class ) );
|
|
|
|
return new SkinFactory( $objectFactory, $options );
|
|
}
|
|
|
|
public function testRegisterWithInvalidCallable() {
|
|
$factory = $this->createSkinFactory();
|
|
|
|
$this->expectException( InvalidArgumentException::class );
|
|
$factory->register( 'invalid', 'Invalid', 'Invalid callback' );
|
|
}
|
|
|
|
public function testRegisterWithCallable() {
|
|
$factory = $this->createSkinFactory();
|
|
$instance = new SkinFallback();
|
|
|
|
$factory->register( 'fallback', 'Fallback', static function () use ( $instance ) {
|
|
return $instance;
|
|
}, true );
|
|
|
|
$this->assertSame( $instance, $factory->makeSkin( 'fallback' ) );
|
|
}
|
|
|
|
public function testRegisterWithSpec() {
|
|
$factory = $this->createSkinFactory();
|
|
$factory->register( 'fallback', 'Fallback', [
|
|
'class' => SkinFallback::class
|
|
], true );
|
|
|
|
$this->assertInstanceOf( SkinFallback::class, $factory->makeSkin( 'fallback' ) );
|
|
}
|
|
|
|
public function testMakeSkinWithNoBuilders() {
|
|
$factory = $this->createSkinFactory();
|
|
$this->expectException( SkinException::class );
|
|
$factory->makeSkin( 'nobuilderregistered' );
|
|
}
|
|
|
|
public function testMakeSkinWithInvalidCallback() {
|
|
$factory = $this->createSkinFactory();
|
|
$factory->register( 'unittest', 'Unittest', static function () {
|
|
// Not a Skin object
|
|
return true;
|
|
} );
|
|
$this->expectException( UnexpectedValueException::class );
|
|
$factory->makeSkin( 'unittest' );
|
|
}
|
|
|
|
public function testMakeSkinWithValidCallback() {
|
|
$factory = $this->createSkinFactory();
|
|
$factory->register( 'testfallback', 'TestFallback', static function () {
|
|
return new SkinFallback();
|
|
} );
|
|
|
|
$skin = $factory->makeSkin( 'testfallback' );
|
|
$this->assertInstanceOf( SkinFallback::class, $skin );
|
|
$this->assertEquals( 'fallback', $skin->getSkinName() );
|
|
}
|
|
|
|
public function testMakeSkinWithValidSpec() {
|
|
$serviceInstance = (object)[];
|
|
|
|
$serviceContainer = $this->createMock( ContainerInterface::class );
|
|
$serviceContainer->method( 'has' )->willReturn( true );
|
|
$serviceContainer->method( 'get' )->willReturn( $serviceInstance );
|
|
|
|
$args = [];
|
|
$factory = $this->createSkinFactory( $serviceContainer );
|
|
$factory->register( 'testfallback', 'TestFallback', [
|
|
'factory' => static function ( $service, $options ) use ( &$args ) {
|
|
$args = [ $service, $options ];
|
|
return new SkinFallback();
|
|
},
|
|
'services' => [
|
|
'testservice'
|
|
]
|
|
] );
|
|
|
|
$skin = $factory->makeSkin( 'testfallback' );
|
|
$this->assertInstanceOf( SkinFallback::class, $skin );
|
|
$this->assertEquals( 'fallback', $skin->getSkinName() );
|
|
$this->assertSame( 'testfallback', $args[1]['name'] );
|
|
$this->assertSame( $serviceInstance, $args[0] );
|
|
}
|
|
|
|
public function testRegisterReplaces() {
|
|
$factory = $this->createSkinFactory();
|
|
|
|
$s1 = $this->createMock( Skin::class );
|
|
$factory->register( 'foo', 'Skin 1',
|
|
static function () use ( $s1 ) {
|
|
return $s1;
|
|
},
|
|
true
|
|
);
|
|
$this->assertEquals( [ 'foo' => 'Skin 1' ], $factory->getSkinNames() );
|
|
$this->assertSame( $s1, $factory->makeSkin( 'foo' ) );
|
|
$this->assertSame( [], $factory->getAllowedSkins(), 'skipped' );
|
|
|
|
// Skippable state from previous register() call must not leak to replacement
|
|
$s2 = $this->createMock( Skin::class );
|
|
$factory->register( 'foo', 'Skin 2',
|
|
static function () use ( $s2 ) {
|
|
return $s2;
|
|
}
|
|
);
|
|
$this->assertEquals( [ 'foo' => 'Skin 2' ], $factory->getSkinNames() );
|
|
$this->assertSame( $s2, $factory->makeSkin( 'foo' ) );
|
|
$this->assertSame( [ 'foo' => 'Skin 2' ], $factory->getAllowedSkins(), 'not skipped' );
|
|
}
|
|
|
|
public function testGetSkinNames() {
|
|
$factory = $this->createSkinFactory();
|
|
$factory->register( 'skin1', 'Skin1', [] );
|
|
$factory->register( 'skin2', 'Skin2', [] );
|
|
|
|
$names = $factory->getSkinNames();
|
|
$this->assertEquals( 'Skin1', $names['skin1'] );
|
|
$this->assertEquals( 'Skin2', $names['skin2'] );
|
|
}
|
|
|
|
public function testGetAllowedSkins() {
|
|
$sf = $this->createSkinFactory( null, [ 'quux' ] );
|
|
$sf->register( 'foo', 'Foo', [] );
|
|
$sf->register( 'apioutput', 'ApiOutput', [], true );
|
|
|
|
// Skippable state is unspecified here and must inherit from site config,
|
|
// which we seeded with 'quux', and thus skipped from allowed skins.
|
|
$sf->register( 'quux', 'Quux', [] );
|
|
|
|
$sf->register( 'fallback', 'Fallback', [], true );
|
|
$sf->register( 'bar', 'Barbar', [] );
|
|
|
|
$this->assertEquals(
|
|
[ 'foo' => 'Foo', 'bar' => 'Barbar' ],
|
|
$sf->getAllowedSkins()
|
|
);
|
|
}
|
|
|
|
public function testGetAllowedSkinsEmpty() {
|
|
$sf = $this->createSkinFactory();
|
|
$sf->register( 'apioutput', 'ApiOutput', [], true );
|
|
$sf->register( 'fallback', 'Fallback', [], true );
|
|
|
|
$this->assertEquals( [], $sf->getAllowedSkins() );
|
|
}
|
|
}
|