ResourceLoaderImage: Add basic tests

Also remove some wrappers from ResourceLoaderImageModule tests that
are no longer necessary, since the files they were mocking now exist.

Bug: T86334
Change-Id: If02e58716ce8e6c8327c8939c6c6425bd48bb560
This commit is contained in:
Bartosz Dziewoński 2015-03-29 19:53:47 +02:00
parent fca3887393
commit d469b37955
14 changed files with 245 additions and 94 deletions

View file

@ -82,9 +82,13 @@ $wgAutoloadClasses += array(
# tests/phpunit/includes/diff
'FakeDiffOp' => "$testDir/phpunit/includes/diff/FakeDiffOp.php",
# tests/phpunit/includes/passwords
# tests/phpunit/includes/password
'PasswordTestCase' => "$testDir/phpunit/includes/password/PasswordTestCase.php",
# tests/phpunit/includes/resourceloader
'ResourceLoaderImageModuleTest' => "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
'ResourceLoaderImageModuleTestable' => "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
# tests/phpunit/languages
'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="bold-a">
<path d="M16 18h3l-5-12h-3l-5 12h3l1.25-3h4.5l1.25 3zm-4.917-5l1.417-3.4 1.417 3.4h-2.834z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 261 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="bold-b">
<path id="b" d="M7 18h6c2 0 4-1 4-3 0-1.064.011-1.975-1.989-3 2-.975 1.989-1.935 1.989-3 0-2-2-3-4-3h-6v12zm7-8c0 1.001 0 1-2 1h-2v-3h2c2 0 2 0 2 1v1zm-2 6h-2v-3h2c2 0 2 0 2 1v1s0 1-2 1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 357 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="bold-f">
<path id="f" d="M16 8v-2h-8v12h3v-5h4v-2h-4v-3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 218 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="help">
<path id="circle" d="M12.001 2.085c-5.478 0-9.916 4.438-9.916 9.916 0 5.476 4.438 9.914 9.916 9.914 5.476 0 9.914-4.438 9.914-9.914 0-5.478-4.438-9.916-9.914-9.916zm.001 18c-4.465 0-8.084-3.619-8.084-8.083 0-4.465 3.619-8.084 8.084-8.084 4.464 0 8.083 3.619 8.083 8.084 0 4.464-3.619 8.083-8.083 8.083z"/>
<g id="question-mark">
<path id="top" d="M11.766 6.688c-2.5 0-3.219 2.188-3.219 2.188l1.411.854s.298-.791.901-1.229c.516-.375 1.625-.625 2.219.125.701.885-.17 1.587-1.078 2.719-.953 1.186-1 3.655-1 3.655h1.969s.135-2.318 1.041-3.381c.603-.707 1.443-1.338 1.443-2.494s-1.187-2.437-3.687-2.437z"/>
<path id="bottom" d="M11 16h2v2h-2z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 851 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="help">
<path id="circle" d="M12.001 2.085c-5.478 0-9.916 4.438-9.916 9.916 0 5.476 4.438 9.914 9.916 9.914 5.476 0 9.914-4.438 9.914-9.914 0-5.478-4.438-9.916-9.914-9.916zm.001 18c-4.465 0-8.084-3.619-8.084-8.083 0-4.465 3.619-8.084 8.084-8.084 4.464 0 8.083 3.619 8.083 8.084 0 4.464-3.619 8.083-8.083 8.083z"/>
<g id="question-mark" transform="translate(24, 0) scale(-1, 1)">
<path id="top" d="M11.766 6.688c-2.5 0-3.219 2.188-3.219 2.188l1.411.854s.298-.791.901-1.229c.516-.375 1.625-.625 2.219.125.701.885-.17 1.587-1.078 2.719-.953 1.186-1 3.655-1 3.655h1.969s.135-2.318 1.041-3.381c.603-.707 1.443-1.338 1.443-2.494s-1.187-2.437-3.687-2.437z"/>
<path id="bottom" d="M11 16h2v2h-2z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 893 B

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M16.5 13.1l-8.9 8.9c-.8-.8-.8-2 0-2.8l6.1-6.1-6-6.1c-.8-.8-.8-2 0-2.8l8.8 8.9z" id="path108"/>
</svg>

After

Width:  |  Height:  |  Size: 238 B

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M 16.5 13.1 l -8.9 8.9 c -0.8 -0.8 -0.8 -2 0 -2.8 l 6.1 -6.1 -6 -6.1 c -0.8 -0.8 -0.8 -2 0 -2.8 l 8.8 8.9 z" id="path108"/>
</svg>

After

Width:  |  Height:  |  Size: 288 B

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M7 13.1l8.9 8.9c.8-.8.8-2 0-2.8l-6.1-6.1 6-6.1c.8-.8.8-2 0-2.8l-8.8 8.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="remove">
<path id="trash-can" d="M12 10h-1v6h1v-6zm-2 0h-1v6h1v-6zm4 0h-1v6h1v-6zm0-4v-1h-5v1h-3v3h1v7.966l1 1.031v-.074.077h6.984l.016-.018v.015l1-1.031v-7.966h1v-3h-3zm1 11h-7v-8h7v8zm1-9h-9v-1h9v1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 362 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="red">
<g xmlns:default="http://www.w3.org/2000/svg" id="remove">
<path id="trash-can" d="M12 10h-1v6h1v-6zm-2 0h-1v6h1v-6zm4 0h-1v6h1v-6zm0-4v-1h-5v1h-3v3h1v7.966l1 1.031v-.074.077h6.984l.016-.018v.015l1-1.031v-7.966h1v-3h-3zm1 11h-7v-8h7v8zm1-9h-9v-1h9v1z"/>
</g>
</g></svg>

After

Width:  |  Height:  |  Size: 423 B

View file

@ -5,67 +5,67 @@
*/
class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
public static $commonImageData = array(
'add' => 'add.gif',
'remove' => array(
'file' => 'remove.svg',
'variants' => array( 'destructive' ),
),
'next' => array(
'file' => array(
'ltr' => 'next.svg',
'rtl' => 'prev.svg'
),
),
'help' => array(
'file' => array(
'ltr' => 'help-ltr.svg',
'rtl' => 'help-rtl.svg',
'lang' => array(
'he' => 'help-ltr.svg',
)
),
),
'bold' => array(
'file' => array(
'default' => 'bold-a.svg',
'lang' => array(
'en' => 'bold-b.svg',
'de' => 'bold-f.svg',
)
),
)
);
public static $commonImageVariants = array(
'invert' => array(
'color' => '#FFFFFF',
'global' => true,
),
'primary' => array(
'color' => '#598AD1',
),
'constructive' => array(
'color' => '#00C697',
),
'destructive' => array(
'color' => '#E81915',
),
);
public static function providerGetModules() {
$commonVariants = array(
'invert' => array(
'color' => '#FFFFFF',
'global' => true,
),
'primary' => array(
'color' => '#598AD1',
),
'constructive' => array(
'color' => '#00C697',
),
'destructive' => array(
'color' => '#E81915',
),
);
$commonImageData = array(
'advanced' => 'advanced.svg',
'remove' => array(
'file' => 'remove.svg',
'variants' => array( 'destructive' ),
),
'next' => array(
'file' => array(
'ltr' => 'next.svg',
'rtl' => 'prev.svg'
),
),
'help' => array(
'file' => array(
'ltr' => 'help-ltr.svg',
'rtl' => 'help-rtl.svg',
'lang' => array(
'he' => 'help-ltr.svg',
)
),
),
'bold' => array(
'file' => array(
'default' => 'bold-a.svg',
'lang' => array(
'en' => 'bold-b.svg',
'de' => 'bold-f.svg',
)
),
)
);
return array(
array(
array(
'class' => 'ResourceLoaderImageModule',
'prefix' => 'oo-ui-icon',
'variants' => $commonVariants,
'images' => $commonImageData,
'variants' => self::$commonImageVariants,
'images' => self::$commonImageData,
),
'.oo-ui-icon-advanced {
'.oo-ui-icon-add {
...
}
.oo-ui-icon-advanced-invert {
.oo-ui-icon-add-invert {
...
}
.oo-ui-icon-remove {
@ -101,13 +101,13 @@ class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
'class' => 'ResourceLoaderImageModule',
'selectorWithoutVariant' => '.mw-ui-icon-{name}:after, .mw-ui-icon-{name}:before',
'selectorWithVariant' => '.mw-ui-icon-{name}-{variant}:after, .mw-ui-icon-{name}-{variant}:before',
'variants' => $commonVariants,
'images' => $commonImageData,
'variants' => self::$commonImageVariants,
'images' => self::$commonImageData,
),
'.mw-ui-icon-advanced:after, .mw-ui-icon-advanced:before {
'.mw-ui-icon-add:after, .mw-ui-icon-add:before {
...
}
.mw-ui-icon-advanced-invert:after, .mw-ui-icon-advanced-invert:before {
.mw-ui-icon-add-invert:after, .mw-ui-icon-add-invert:before {
...
}
.mw-ui-icon-remove:after, .mw-ui-icon-remove:before {
@ -146,7 +146,7 @@ class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
* @covers ResourceLoaderImageModule::getStyles
*/
public function testGetStyles( $module, $expected ) {
$module = new ResourceLoaderImageModuleTestable( $module );
$module = new ResourceLoaderImageModuleTestable( $module, __DIR__ . '/../../data/resourceloader' );
$styles = $module->getStyles( $this->getResourceLoaderContext() );
$this->assertEquals( $expected, $styles['all'] );
}
@ -159,40 +159,4 @@ class ResourceLoaderImageModuleTestable extends ResourceLoaderImageModule {
protected function getCssDeclarations( $primary, $fallback ) {
return array( '...' );
}
/**
* Return mock ResourceLoaderImages that don't call file_get_contents and such.
*/
public function getImages() {
$images = parent::getImages();
foreach ( $images as $name => &$image ) {
$image = new ResourceLoaderImageWrapper( $image );
}
return $images;
}
}
/**
* Wraps a ResourceLoaderImage not to call file_get_contents and such.
*/
class ResourceLoaderImageWrapper extends ResourceLoaderImage {
public function __construct( ResourceLoaderImage $image ) {
$this->image = $image;
}
public function getUrl( ResourceLoaderContext $context, $script, $variant, $format ) {
return null;
}
public function getDataUri( ResourceLoaderContext $context, $variant, $format ) {
return null;
}
public function __call( $method, $arguments ) {
return call_user_func_array( array( $this->image, $method ), $arguments );
}
public function __get( $name ) {
return $this->image->$name;
}
}

View file

@ -0,0 +1,121 @@
<?php
/**
* @group ResourceLoader
*/
class ResourceLoaderImageTest extends ResourceLoaderTestCase {
protected $imagesPath;
protected function setUp() {
parent::setUp();
$this->imagesPath = __DIR__ . '/../../data/resourceloader';
}
protected function getTestImage( $name ) {
$options = ResourceLoaderImageModuleTest::$commonImageData[$name];
$fileDescriptor = is_string( $options ) ? $options : $options['file'];
$allowedVariants = is_array( $options ) && isset( $options['variants'] ) ? $options['variants'] : array();
$variants = array_fill_keys( $allowedVariants, array( 'color' => 'red' ) );
return new ResourceLoaderImageTestable( $name, 'test', $fileDescriptor, $this->imagesPath, $variants );
}
public static function provideGetPath() {
return array(
array( 'add', 'en', 'add.gif' ),
array( 'add', 'he', 'add.gif' ),
array( 'remove', 'en', 'remove.svg' ),
array( 'remove', 'he', 'remove.svg' ),
array( 'next', 'en', 'next.svg' ),
array( 'next', 'he', 'prev.svg' ),
array( 'help', 'en', 'help-ltr.svg' ),
array( 'help', 'ar', 'help-rtl.svg' ),
array( 'help', 'he', 'help-ltr.svg' ),
array( 'bold', 'en', 'bold-b.svg' ),
array( 'bold', 'de', 'bold-f.svg' ),
array( 'bold', 'fr', 'bold-a.svg' ),
array( 'bold', 'he', 'bold-a.svg' ),
);
}
/**
* @covers ResourceLoaderImage::getPath
* @dataProvider provideGetPath
*/
public function testGetPath( $imageName, $languageCode, $path ) {
static $dirMap = array(
'en' => 'ltr',
'de' => 'ltr',
'fr' => 'ltr',
'he' => 'rtl',
'ar' => 'rtl',
);
static $contexts = array();
$image = $this->getTestImage( $imageName );
$context = $this->getResourceLoaderContext( $languageCode, $dirMap[$languageCode] );
$this->assertEquals( $image->getPath( $context ), $this->imagesPath . '/' . $path );
}
/**
* @covers ResourceLoaderImage::getExtension
* @covers ResourceLoaderImage::getMimeType
*/
public function testGetExtension() {
$image = $this->getTestImage( 'remove' );
$this->assertEquals( $image->getExtension(), 'svg' );
$this->assertEquals( $image->getExtension( 'original' ), 'svg' );
$this->assertEquals( $image->getExtension( 'rasterized' ), 'png' );
$image = $this->getTestImage( 'add' );
$this->assertEquals( $image->getExtension(), 'gif' );
$this->assertEquals( $image->getExtension( 'original' ), 'gif' );
$this->assertEquals( $image->getExtension( 'rasterized' ), 'gif' );
}
/**
* @covers ResourceLoaderImage::getImageData
* @covers ResourceLoaderImage::variantize
* @covers ResourceLoaderImage::massageSvgPathdata
*/
public function testGetImageData() {
$context = $this->getResourceLoaderContext( 'en', 'ltr' );
$image = $this->getTestImage( 'remove' );
$data = file_get_contents( $this->imagesPath . '/remove.svg' );
$dataConstructive = file_get_contents( $this->imagesPath . '/remove_variantize.svg' );
$this->assertEquals( $image->getImageData( $context, null, 'original' ), $data );
$this->assertEquals( $image->getImageData( $context, 'destructive', 'original' ), $dataConstructive );
// Stub, since we don't know if we even have a SVG handler, much less what exactly it'll output
$this->assertEquals( $image->getImageData( $context, null, 'rasterized' ), 'RASTERIZESTUB' );
$image = $this->getTestImage( 'add' );
$data = file_get_contents( $this->imagesPath . '/add.gif' );
$this->assertEquals( $image->getImageData( $context, null, 'original' ), $data );
$this->assertEquals( $image->getImageData( $context, null, 'rasterized' ), $data );
}
/**
* @covers ResourceLoaderImage::massageSvgPathdata
*/
public function testMassageSvgPathdata() {
$image = $this->getTestImage( 'next' );
$data = file_get_contents( $this->imagesPath . '/next.svg' );
$dataMassaged = file_get_contents( $this->imagesPath . '/next_massage.svg' );
$this->assertEquals( $image->massageSvgPathdata( $data ), $dataMassaged );
}
}
class ResourceLoaderImageTestable extends ResourceLoaderImage {
// Make some protected methods public
public function getPath( ResourceLoaderContext $context ) {
return parent::getPath( $context );
}
public function massageSvgPathdata( $svg ) {
return parent::massageSvgPathdata( $svg );
}
// Stub, since we don't know if we even have a SVG handler, much less what exactly it'll output
public function rasterize( $svg ) {
return 'RASTERIZESTUB';
}
}