Rename tests/phpunit/includes/media files to match class names
authorKunal Mehta <legoktm@member.fsf.org>
Wed, 30 Jan 2019 05:35:11 +0000 (21:35 -0800)
committerKunal Mehta <legoktm@member.fsf.org>
Wed, 30 Jan 2019 07:21:13 +0000 (23:21 -0800)
The classes were renamed in 9bf39163, this updates the test cases to
match. Also take care of XCF while we're at it too.

Change-Id: Iaaeee93e496af6cdd610df5bc75302ecfe273f64

12 files changed:
.phpcs.xml
autoload.php
includes/media/XCF.php [deleted file]
includes/media/XCFHandler.php [new file with mode: 0644]
tests/phpunit/includes/media/GIFHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/media/GIFTest.php [deleted file]
tests/phpunit/includes/media/PNGHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/media/PNGTest.php [deleted file]
tests/phpunit/includes/media/WebPHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/media/WebPTest.php [deleted file]
tests/phpunit/includes/media/XCFHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/media/XCFTest.php [deleted file]

index c0154c7..88a6f8c 100644 (file)
@@ -78,7 +78,6 @@
                        Whitelist existing violations, but enable the sniff to prevent
                        any new occurrences.
                -->
-               <exclude-pattern>*/includes/media/XCF\.php</exclude-pattern>
                <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
                <exclude-pattern>*/includes/libs/xmp/XMP\.php</exclude-pattern>
                <exclude-pattern>*/includes/jobqueue/JobSpecification\.php</exclude-pattern>
index df1c0b2..0d17916 100644 (file)
@@ -1699,7 +1699,7 @@ $wgAutoloadLocalClasses = [
        'WithoutInterwikiPage' => __DIR__ . '/includes/specials/SpecialWithoutinterwiki.php',
        'WordLevelDiff' => __DIR__ . '/includes/diff/WordLevelDiff.php',
        'WrapOldPasswords' => __DIR__ . '/maintenance/wrapOldPasswords.php',
-       'XCFHandler' => __DIR__ . '/includes/media/XCF.php',
+       'XCFHandler' => __DIR__ . '/includes/media/XCFHandler.php',
        'XMLRCFeedFormatter' => __DIR__ . '/includes/rcfeed/XMLRCFeedFormatter.php',
        'XMPInfo' => __DIR__ . '/includes/compat/XMPReader.php',
        'XMPReader' => __DIR__ . '/includes/compat/XMPReader.php',
diff --git a/includes/media/XCF.php b/includes/media/XCF.php
deleted file mode 100644 (file)
index 0cb618f..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-<?php
-/**
- * Handler for the Gimp's native file format (XCF)
- *
- * Overview:
- *   https://en.wikipedia.org/wiki/XCF_(file_format)
- * Specification in Gnome repository:
- *   http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
- *
- * 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
- *
- * @file
- * @ingroup Media
- */
-
-/**
- * Handler for the Gimp's native file format; getimagesize() doesn't
- * support these files
- *
- * @ingroup Media
- */
-class XCFHandler extends BitmapHandler {
-       /**
-        * @param File $file
-        * @return bool
-        */
-       public function mustRender( $file ) {
-               return true;
-       }
-
-       /**
-        * Render files as PNG
-        *
-        * @param string $ext
-        * @param string $mime
-        * @param array|null $params
-        * @return array
-        */
-       function getThumbType( $ext, $mime, $params = null ) {
-               return [ 'png', 'image/png' ];
-       }
-
-       /**
-        * Get width and height from the XCF header.
-        *
-        * @param File|FSFile $image
-        * @param string $filename
-        * @return array
-        */
-       function getImageSize( $image, $filename ) {
-               $header = self::getXCFMetaData( $filename );
-               if ( !$header ) {
-                       return false;
-               }
-
-               # Forge a return array containing metadata information just like getimagesize()
-               # See PHP documentation at: https://secure.php.net/getimagesize
-               return [
-                       0 => $header['width'],
-                       1 => $header['height'],
-                       2 => null, # IMAGETYPE constant, none exist for XCF.
-                       3 => "height=\"{$header['height']}\" width=\"{$header['width']}\"",
-                       'mime' => 'image/x-xcf',
-                       'channels' => null,
-                       'bits' => 8, # Always 8-bits per color
-               ];
-       }
-
-       /**
-        * Metadata for a given XCF file
-        *
-        * Will return false if file magic signature is not recognized
-        * @author Hexmode
-        * @author Hashar
-        *
-        * @param string $filename Full path to a XCF file
-        * @return bool|array Metadata Array just like PHP getimagesize()
-        */
-       static function getXCFMetaData( $filename ) {
-               # Decode master structure
-               $f = fopen( $filename, 'rb' );
-               if ( !$f ) {
-                       return false;
-               }
-               # The image structure always starts at offset 0 in the XCF file.
-               # So we just read it :-)
-               $binaryHeader = fread( $f, 26 );
-               fclose( $f );
-
-               /**
-                * Master image structure:
-                *
-                * byte[9] "gimp xcf "  File type magic
-                * byte[4] version      XCF version
-                *                        "file" - version 0
-                *                        "v001" - version 1
-                *                        "v002" - version 2
-                * byte    0            Zero-terminator for version tag
-                * uint32  width        With of canvas
-                * uint32  height       Height of canvas
-                * uint32  base_type    Color mode of the image; one of
-                *                         0: RGB color
-                *                         1: Grayscale
-                *                         2: Indexed color
-                *        (enum GimpImageBaseType in libgimpbase/gimpbaseenums.h)
-                */
-               try {
-                       $header = wfUnpack(
-                               "A9magic" . # A: space padded
-                                       "/a5version" . # a: zero padded
-                                       "/Nwidth" . # \
-                                       "/Nheight" . # N: unsigned long 32bit big endian
-                                       "/Nbase_type", # /
-                               $binaryHeader
-                       );
-               } catch ( Exception $mwe ) {
-                       return false;
-               }
-
-               # Check values
-               if ( $header['magic'] !== 'gimp xcf' ) {
-                       wfDebug( __METHOD__ . " '$filename' has invalid magic signature.\n" );
-
-                       return false;
-               }
-               # TODO: we might want to check for sane values of width and height
-
-               wfDebug( __METHOD__ .
-                       ": canvas size of '$filename' is {$header['width']} x {$header['height']} px\n" );
-
-               return $header;
-       }
-
-       /**
-        * Store the channel type
-        *
-        * Greyscale files need different command line options.
-        *
-        * @param File|FSFile $file The image object, or false if there isn't one.
-        *   Warning, FSFile::getPropsFromPath might pass an (object)array() instead (!)
-        * @param string $filename
-        * @return string
-        */
-       public function getMetadata( $file, $filename ) {
-               $header = self::getXCFMetaData( $filename );
-               $metadata = [];
-               if ( $header ) {
-                       // Try to be consistent with the names used by PNG files.
-                       // Unclear from base media type if it has an alpha layer,
-                       // so just assume that it does since it "potentially" could.
-                       switch ( $header['base_type'] ) {
-                               case 0:
-                                       $metadata['colorType'] = 'truecolour-alpha';
-                                       break;
-                               case 1:
-                                       $metadata['colorType'] = 'greyscale-alpha';
-                                       break;
-                               case 2:
-                                       $metadata['colorType'] = 'index-coloured';
-                                       break;
-                               default:
-                                       $metadata['colorType'] = 'unknown';
-                       }
-               } else {
-                       // Marker to prevent repeated attempted extraction
-                       $metadata['error'] = true;
-               }
-               return serialize( $metadata );
-       }
-
-       /**
-        * Should we refresh the metadata
-        *
-        * @param File $file The file object for the file in question
-        * @param string $metadata Serialized metadata
-        * @return bool One of the self::METADATA_(BAD|GOOD|COMPATIBLE) constants
-        */
-       public function isMetadataValid( $file, $metadata ) {
-               if ( !$metadata ) {
-                       // Old metadata when we just put an empty string in there
-                       return self::METADATA_BAD;
-               } else {
-                       return self::METADATA_GOOD;
-               }
-       }
-
-       /**
-        * Must use "im" for XCF
-        *
-        * @param string $dstPath
-        * @param bool $checkDstPath
-        * @return string
-        */
-       protected function getScalerType( $dstPath, $checkDstPath = true ) {
-               return "im";
-       }
-
-       /**
-        * Can we render this file?
-        *
-        * Image magick doesn't support indexed xcf files as of current
-        * writing (as of 6.8.9-3)
-        * @param File $file
-        * @return bool
-        */
-       public function canRender( $file ) {
-               Wikimedia\suppressWarnings();
-               $xcfMeta = unserialize( $file->getMetadata() );
-               Wikimedia\restoreWarnings();
-               if ( isset( $xcfMeta['colorType'] ) && $xcfMeta['colorType'] === 'index-coloured' ) {
-                       return false;
-               }
-               return parent::canRender( $file );
-       }
-}
diff --git a/includes/media/XCFHandler.php b/includes/media/XCFHandler.php
new file mode 100644 (file)
index 0000000..0cb618f
--- /dev/null
@@ -0,0 +1,228 @@
+<?php
+/**
+ * Handler for the Gimp's native file format (XCF)
+ *
+ * Overview:
+ *   https://en.wikipedia.org/wiki/XCF_(file_format)
+ * Specification in Gnome repository:
+ *   http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
+ *
+ * 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
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
+ * Handler for the Gimp's native file format; getimagesize() doesn't
+ * support these files
+ *
+ * @ingroup Media
+ */
+class XCFHandler extends BitmapHandler {
+       /**
+        * @param File $file
+        * @return bool
+        */
+       public function mustRender( $file ) {
+               return true;
+       }
+
+       /**
+        * Render files as PNG
+        *
+        * @param string $ext
+        * @param string $mime
+        * @param array|null $params
+        * @return array
+        */
+       function getThumbType( $ext, $mime, $params = null ) {
+               return [ 'png', 'image/png' ];
+       }
+
+       /**
+        * Get width and height from the XCF header.
+        *
+        * @param File|FSFile $image
+        * @param string $filename
+        * @return array
+        */
+       function getImageSize( $image, $filename ) {
+               $header = self::getXCFMetaData( $filename );
+               if ( !$header ) {
+                       return false;
+               }
+
+               # Forge a return array containing metadata information just like getimagesize()
+               # See PHP documentation at: https://secure.php.net/getimagesize
+               return [
+                       0 => $header['width'],
+                       1 => $header['height'],
+                       2 => null, # IMAGETYPE constant, none exist for XCF.
+                       3 => "height=\"{$header['height']}\" width=\"{$header['width']}\"",
+                       'mime' => 'image/x-xcf',
+                       'channels' => null,
+                       'bits' => 8, # Always 8-bits per color
+               ];
+       }
+
+       /**
+        * Metadata for a given XCF file
+        *
+        * Will return false if file magic signature is not recognized
+        * @author Hexmode
+        * @author Hashar
+        *
+        * @param string $filename Full path to a XCF file
+        * @return bool|array Metadata Array just like PHP getimagesize()
+        */
+       static function getXCFMetaData( $filename ) {
+               # Decode master structure
+               $f = fopen( $filename, 'rb' );
+               if ( !$f ) {
+                       return false;
+               }
+               # The image structure always starts at offset 0 in the XCF file.
+               # So we just read it :-)
+               $binaryHeader = fread( $f, 26 );
+               fclose( $f );
+
+               /**
+                * Master image structure:
+                *
+                * byte[9] "gimp xcf "  File type magic
+                * byte[4] version      XCF version
+                *                        "file" - version 0
+                *                        "v001" - version 1
+                *                        "v002" - version 2
+                * byte    0            Zero-terminator for version tag
+                * uint32  width        With of canvas
+                * uint32  height       Height of canvas
+                * uint32  base_type    Color mode of the image; one of
+                *                         0: RGB color
+                *                         1: Grayscale
+                *                         2: Indexed color
+                *        (enum GimpImageBaseType in libgimpbase/gimpbaseenums.h)
+                */
+               try {
+                       $header = wfUnpack(
+                               "A9magic" . # A: space padded
+                                       "/a5version" . # a: zero padded
+                                       "/Nwidth" . # \
+                                       "/Nheight" . # N: unsigned long 32bit big endian
+                                       "/Nbase_type", # /
+                               $binaryHeader
+                       );
+               } catch ( Exception $mwe ) {
+                       return false;
+               }
+
+               # Check values
+               if ( $header['magic'] !== 'gimp xcf' ) {
+                       wfDebug( __METHOD__ . " '$filename' has invalid magic signature.\n" );
+
+                       return false;
+               }
+               # TODO: we might want to check for sane values of width and height
+
+               wfDebug( __METHOD__ .
+                       ": canvas size of '$filename' is {$header['width']} x {$header['height']} px\n" );
+
+               return $header;
+       }
+
+       /**
+        * Store the channel type
+        *
+        * Greyscale files need different command line options.
+        *
+        * @param File|FSFile $file The image object, or false if there isn't one.
+        *   Warning, FSFile::getPropsFromPath might pass an (object)array() instead (!)
+        * @param string $filename
+        * @return string
+        */
+       public function getMetadata( $file, $filename ) {
+               $header = self::getXCFMetaData( $filename );
+               $metadata = [];
+               if ( $header ) {
+                       // Try to be consistent with the names used by PNG files.
+                       // Unclear from base media type if it has an alpha layer,
+                       // so just assume that it does since it "potentially" could.
+                       switch ( $header['base_type'] ) {
+                               case 0:
+                                       $metadata['colorType'] = 'truecolour-alpha';
+                                       break;
+                               case 1:
+                                       $metadata['colorType'] = 'greyscale-alpha';
+                                       break;
+                               case 2:
+                                       $metadata['colorType'] = 'index-coloured';
+                                       break;
+                               default:
+                                       $metadata['colorType'] = 'unknown';
+                       }
+               } else {
+                       // Marker to prevent repeated attempted extraction
+                       $metadata['error'] = true;
+               }
+               return serialize( $metadata );
+       }
+
+       /**
+        * Should we refresh the metadata
+        *
+        * @param File $file The file object for the file in question
+        * @param string $metadata Serialized metadata
+        * @return bool One of the self::METADATA_(BAD|GOOD|COMPATIBLE) constants
+        */
+       public function isMetadataValid( $file, $metadata ) {
+               if ( !$metadata ) {
+                       // Old metadata when we just put an empty string in there
+                       return self::METADATA_BAD;
+               } else {
+                       return self::METADATA_GOOD;
+               }
+       }
+
+       /**
+        * Must use "im" for XCF
+        *
+        * @param string $dstPath
+        * @param bool $checkDstPath
+        * @return string
+        */
+       protected function getScalerType( $dstPath, $checkDstPath = true ) {
+               return "im";
+       }
+
+       /**
+        * Can we render this file?
+        *
+        * Image magick doesn't support indexed xcf files as of current
+        * writing (as of 6.8.9-3)
+        * @param File $file
+        * @return bool
+        */
+       public function canRender( $file ) {
+               Wikimedia\suppressWarnings();
+               $xcfMeta = unserialize( $file->getMetadata() );
+               Wikimedia\restoreWarnings();
+               if ( isset( $xcfMeta['colorType'] ) && $xcfMeta['colorType'] === 'index-coloured' ) {
+                       return false;
+               }
+               return parent::canRender( $file );
+       }
+}
diff --git a/tests/phpunit/includes/media/GIFHandlerTest.php b/tests/phpunit/includes/media/GIFHandlerTest.php
new file mode 100644 (file)
index 0000000..4dd7443
--- /dev/null
@@ -0,0 +1,172 @@
+<?php
+
+/**
+ * @group Media
+ */
+class GIFHandlerTest extends MediaWikiMediaTestCase {
+
+       /** @var GIFHandler */
+       protected $handler;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->handler = new GIFHandler();
+       }
+
+       /**
+        * @covers GIFHandler::getMetadata
+        */
+       public function testInvalidFile() {
+               $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
+               $this->assertEquals( GIFHandler::BROKEN_FILE, $res );
+       }
+
+       /**
+        * @param string $filename Basename of the file to check
+        * @param bool $expected Expected result.
+        * @dataProvider provideIsAnimated
+        * @covers GIFHandler::isAnimatedImage
+        */
+       public function testIsAnimanted( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/gif' );
+               $actual = $this->handler->isAnimatedImage( $file );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideIsAnimated() {
+               return [
+                       [ 'animated.gif', true ],
+                       [ 'nonanimated.gif', false ],
+               ];
+       }
+
+       /**
+        * @param string $filename
+        * @param int $expected Total image area
+        * @dataProvider provideGetImageArea
+        * @covers GIFHandler::getImageArea
+        */
+       public function testGetImageArea( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/gif' );
+               $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideGetImageArea() {
+               return [
+                       [ 'animated.gif', 5400 ],
+                       [ 'nonanimated.gif', 1350 ],
+               ];
+       }
+
+       /**
+        * @param string $metadata Serialized metadata
+        * @param int $expected One of the class constants of GIFHandler
+        * @dataProvider provideIsMetadataValid
+        * @covers GIFHandler::isMetadataValid
+        */
+       public function testIsMetadataValid( $metadata, $expected ) {
+               $actual = $this->handler->isMetadataValid( null, $metadata );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideIsMetadataValid() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       [ GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ],
+                       [ '', GIFHandler::METADATA_BAD ],
+                       [ null, GIFHandler::METADATA_BAD ],
+                       [ 'Something invalid!', GIFHandler::METADATA_BAD ],
+                       [
+                               'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}',
+                               GIFHandler::METADATA_GOOD
+                       ],
+               ];
+               // phpcs:enable
+       }
+
+       /**
+        * @param string $filename
+        * @param string $expected Serialized array
+        * @dataProvider provideGetMetadata
+        * @covers GIFHandler::getMetadata
+        */
+       public function testGetMetadata( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/gif' );
+               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
+               $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
+       }
+
+       public static function provideGetMetadata() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       [
+                               'nonanimated.gif',
+                               'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}'
+                       ],
+                       [
+                               'animated-xmp.gif',
+                               'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}'
+                       ],
+               ];
+               // phpcs:enable
+       }
+
+       /**
+        * @param string $filename
+        * @param string $expected Serialized array
+        * @dataProvider provideGetIndependentMetaArray
+        * @covers GIFHandler::getCommonMetaArray
+        */
+       public function testGetIndependentMetaArray( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/gif' );
+               $actual = $this->handler->getCommonMetaArray( $file );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideGetIndependentMetaArray() {
+               return [
+                       [ 'nonanimated.gif', [
+                               'GIFFileComment' => [
+                                       'GIF test file ⁕ Created with GIMP',
+                               ],
+                       ] ],
+                       [ 'animated-xmp.gif',
+                               [
+                                       'Artist' => 'Bawolff',
+                                       'ImageDescription' => [
+                                               'x-default' => 'A file to test GIF',
+                                               '_type' => 'lang',
+                                       ],
+                                       'SublocationDest' => 'The interwebs',
+                                       'GIFFileComment' =>
+                                       [
+                                               'GIƒ·test·file',
+                                       ],
+                               ]
+                       ],
+               ];
+       }
+
+       /**
+        * @param string $filename
+        * @param float $expectedLength
+        * @dataProvider provideGetLength
+        * @covers GIFHandler::getLength
+        */
+       public function testGetLength( $filename, $expectedLength ) {
+               $file = $this->dataFile( $filename, 'image/gif' );
+               $actualLength = $file->getLength();
+               $this->assertEquals( $expectedLength, $actualLength, '', 0.00001 );
+       }
+
+       public function provideGetLength() {
+               return [
+                       [ 'animated.gif', 2.4 ],
+                       [ 'animated-xmp.gif', 2.4 ],
+                       [ 'nonanimated', 0.0 ],
+                       [ 'Bishzilla_blink.gif', 1.4 ],
+               ];
+       }
+}
diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php
deleted file mode 100644 (file)
index 4dd7443..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-
-/**
- * @group Media
- */
-class GIFHandlerTest extends MediaWikiMediaTestCase {
-
-       /** @var GIFHandler */
-       protected $handler;
-
-       protected function setUp() {
-               parent::setUp();
-
-               $this->handler = new GIFHandler();
-       }
-
-       /**
-        * @covers GIFHandler::getMetadata
-        */
-       public function testInvalidFile() {
-               $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
-               $this->assertEquals( GIFHandler::BROKEN_FILE, $res );
-       }
-
-       /**
-        * @param string $filename Basename of the file to check
-        * @param bool $expected Expected result.
-        * @dataProvider provideIsAnimated
-        * @covers GIFHandler::isAnimatedImage
-        */
-       public function testIsAnimanted( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/gif' );
-               $actual = $this->handler->isAnimatedImage( $file );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideIsAnimated() {
-               return [
-                       [ 'animated.gif', true ],
-                       [ 'nonanimated.gif', false ],
-               ];
-       }
-
-       /**
-        * @param string $filename
-        * @param int $expected Total image area
-        * @dataProvider provideGetImageArea
-        * @covers GIFHandler::getImageArea
-        */
-       public function testGetImageArea( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/gif' );
-               $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideGetImageArea() {
-               return [
-                       [ 'animated.gif', 5400 ],
-                       [ 'nonanimated.gif', 1350 ],
-               ];
-       }
-
-       /**
-        * @param string $metadata Serialized metadata
-        * @param int $expected One of the class constants of GIFHandler
-        * @dataProvider provideIsMetadataValid
-        * @covers GIFHandler::isMetadataValid
-        */
-       public function testIsMetadataValid( $metadata, $expected ) {
-               $actual = $this->handler->isMetadataValid( null, $metadata );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideIsMetadataValid() {
-               // phpcs:disable Generic.Files.LineLength
-               return [
-                       [ GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ],
-                       [ '', GIFHandler::METADATA_BAD ],
-                       [ null, GIFHandler::METADATA_BAD ],
-                       [ 'Something invalid!', GIFHandler::METADATA_BAD ],
-                       [
-                               'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}',
-                               GIFHandler::METADATA_GOOD
-                       ],
-               ];
-               // phpcs:enable
-       }
-
-       /**
-        * @param string $filename
-        * @param string $expected Serialized array
-        * @dataProvider provideGetMetadata
-        * @covers GIFHandler::getMetadata
-        */
-       public function testGetMetadata( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/gif' );
-               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
-               $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
-       }
-
-       public static function provideGetMetadata() {
-               // phpcs:disable Generic.Files.LineLength
-               return [
-                       [
-                               'nonanimated.gif',
-                               'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}'
-                       ],
-                       [
-                               'animated-xmp.gif',
-                               'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}'
-                       ],
-               ];
-               // phpcs:enable
-       }
-
-       /**
-        * @param string $filename
-        * @param string $expected Serialized array
-        * @dataProvider provideGetIndependentMetaArray
-        * @covers GIFHandler::getCommonMetaArray
-        */
-       public function testGetIndependentMetaArray( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/gif' );
-               $actual = $this->handler->getCommonMetaArray( $file );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideGetIndependentMetaArray() {
-               return [
-                       [ 'nonanimated.gif', [
-                               'GIFFileComment' => [
-                                       'GIF test file ⁕ Created with GIMP',
-                               ],
-                       ] ],
-                       [ 'animated-xmp.gif',
-                               [
-                                       'Artist' => 'Bawolff',
-                                       'ImageDescription' => [
-                                               'x-default' => 'A file to test GIF',
-                                               '_type' => 'lang',
-                                       ],
-                                       'SublocationDest' => 'The interwebs',
-                                       'GIFFileComment' =>
-                                       [
-                                               'GIƒ·test·file',
-                                       ],
-                               ]
-                       ],
-               ];
-       }
-
-       /**
-        * @param string $filename
-        * @param float $expectedLength
-        * @dataProvider provideGetLength
-        * @covers GIFHandler::getLength
-        */
-       public function testGetLength( $filename, $expectedLength ) {
-               $file = $this->dataFile( $filename, 'image/gif' );
-               $actualLength = $file->getLength();
-               $this->assertEquals( $expectedLength, $actualLength, '', 0.00001 );
-       }
-
-       public function provideGetLength() {
-               return [
-                       [ 'animated.gif', 2.4 ],
-                       [ 'animated-xmp.gif', 2.4 ],
-                       [ 'nonanimated', 0.0 ],
-                       [ 'Bishzilla_blink.gif', 1.4 ],
-               ];
-       }
-}
diff --git a/tests/phpunit/includes/media/PNGHandlerTest.php b/tests/phpunit/includes/media/PNGHandlerTest.php
new file mode 100644 (file)
index 0000000..5a66586
--- /dev/null
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * @group Media
+ */
+class PNGHandlerTest extends MediaWikiMediaTestCase {
+
+       /** @var PNGHandler */
+       protected $handler;
+
+       protected function setUp() {
+               parent::setUp();
+               $this->handler = new PNGHandler();
+       }
+
+       /**
+        * @covers PNGHandler::getMetadata
+        */
+       public function testInvalidFile() {
+               $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
+               $this->assertEquals( PNGHandler::BROKEN_FILE, $res );
+       }
+
+       /**
+        * @param string $filename Basename of the file to check
+        * @param bool $expected Expected result.
+        * @dataProvider provideIsAnimated
+        * @covers PNGHandler::isAnimatedImage
+        */
+       public function testIsAnimanted( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actual = $this->handler->isAnimatedImage( $file );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideIsAnimated() {
+               return [
+                       [ 'Animated_PNG_example_bouncing_beach_ball.png', true ],
+                       [ '1bit-png.png', false ],
+               ];
+       }
+
+       /**
+        * @param string $filename
+        * @param int $expected Total image area
+        * @dataProvider provideGetImageArea
+        * @covers PNGHandler::getImageArea
+        */
+       public function testGetImageArea( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideGetImageArea() {
+               return [
+                       [ '1bit-png.png', 2500 ],
+                       [ 'greyscale-png.png', 2500 ],
+                       [ 'Png-native-test.png', 126000 ],
+                       [ 'Animated_PNG_example_bouncing_beach_ball.png', 10000 ],
+               ];
+       }
+
+       /**
+        * @param string $metadata Serialized metadata
+        * @param int $expected One of the class constants of PNGHandler
+        * @dataProvider provideIsMetadataValid
+        * @covers PNGHandler::isMetadataValid
+        */
+       public function testIsMetadataValid( $metadata, $expected ) {
+               $actual = $this->handler->isMetadataValid( null, $metadata );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideIsMetadataValid() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       [ PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ],
+                       [ '', PNGHandler::METADATA_BAD ],
+                       [ null, PNGHandler::METADATA_BAD ],
+                       [ 'Something invalid!', PNGHandler::METADATA_BAD ],
+                       [
+                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}',
+                               PNGHandler::METADATA_GOOD
+                       ],
+               ];
+               // phpcs:enable
+       }
+
+       /**
+        * @param string $filename
+        * @param string $expected Serialized array
+        * @dataProvider provideGetMetadata
+        * @covers PNGHandler::getMetadata
+        */
+       public function testGetMetadata( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
+//             $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
+               $this->assertEquals( ( $expected ), ( $actual ) );
+       }
+
+       public static function provideGetMetadata() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       [
+                               'rgb-na-png.png',
+                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}'
+                       ],
+                       [
+                               'xmp.png',
+                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}'
+                       ],
+               ];
+               // phpcs:enable
+       }
+
+       /**
+        * @param string $filename
+        * @param array $expected Expected standard metadata
+        * @dataProvider provideGetIndependentMetaArray
+        * @covers PNGHandler::getCommonMetaArray
+        */
+       public function testGetIndependentMetaArray( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actual = $this->handler->getCommonMetaArray( $file );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideGetIndependentMetaArray() {
+               return [
+                       [ 'rgb-na-png.png', [] ],
+                       [ 'xmp.png',
+                               [
+                                       'SerialNumber' => '123456789',
+                               ]
+                       ],
+               ];
+       }
+
+       /**
+        * @param string $filename
+        * @param float $expectedLength
+        * @dataProvider provideGetLength
+        * @covers PNGHandler::getLength
+        */
+       public function testGetLength( $filename, $expectedLength ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actualLength = $file->getLength();
+               $this->assertEquals( $expectedLength, $actualLength, '', 0.00001 );
+       }
+
+       public function provideGetLength() {
+               return [
+                       [ 'Animated_PNG_example_bouncing_beach_ball.png', 1.5 ],
+                       [ 'Png-native-test.png', 0.0 ],
+                       [ 'greyscale-png.png', 0.0 ],
+                       [ '1bit-png.png', 0.0 ],
+               ];
+       }
+}
diff --git a/tests/phpunit/includes/media/PNGTest.php b/tests/phpunit/includes/media/PNGTest.php
deleted file mode 100644 (file)
index 5a66586..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-
-/**
- * @group Media
- */
-class PNGHandlerTest extends MediaWikiMediaTestCase {
-
-       /** @var PNGHandler */
-       protected $handler;
-
-       protected function setUp() {
-               parent::setUp();
-               $this->handler = new PNGHandler();
-       }
-
-       /**
-        * @covers PNGHandler::getMetadata
-        */
-       public function testInvalidFile() {
-               $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
-               $this->assertEquals( PNGHandler::BROKEN_FILE, $res );
-       }
-
-       /**
-        * @param string $filename Basename of the file to check
-        * @param bool $expected Expected result.
-        * @dataProvider provideIsAnimated
-        * @covers PNGHandler::isAnimatedImage
-        */
-       public function testIsAnimanted( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actual = $this->handler->isAnimatedImage( $file );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideIsAnimated() {
-               return [
-                       [ 'Animated_PNG_example_bouncing_beach_ball.png', true ],
-                       [ '1bit-png.png', false ],
-               ];
-       }
-
-       /**
-        * @param string $filename
-        * @param int $expected Total image area
-        * @dataProvider provideGetImageArea
-        * @covers PNGHandler::getImageArea
-        */
-       public function testGetImageArea( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideGetImageArea() {
-               return [
-                       [ '1bit-png.png', 2500 ],
-                       [ 'greyscale-png.png', 2500 ],
-                       [ 'Png-native-test.png', 126000 ],
-                       [ 'Animated_PNG_example_bouncing_beach_ball.png', 10000 ],
-               ];
-       }
-
-       /**
-        * @param string $metadata Serialized metadata
-        * @param int $expected One of the class constants of PNGHandler
-        * @dataProvider provideIsMetadataValid
-        * @covers PNGHandler::isMetadataValid
-        */
-       public function testIsMetadataValid( $metadata, $expected ) {
-               $actual = $this->handler->isMetadataValid( null, $metadata );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideIsMetadataValid() {
-               // phpcs:disable Generic.Files.LineLength
-               return [
-                       [ PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ],
-                       [ '', PNGHandler::METADATA_BAD ],
-                       [ null, PNGHandler::METADATA_BAD ],
-                       [ 'Something invalid!', PNGHandler::METADATA_BAD ],
-                       [
-                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}',
-                               PNGHandler::METADATA_GOOD
-                       ],
-               ];
-               // phpcs:enable
-       }
-
-       /**
-        * @param string $filename
-        * @param string $expected Serialized array
-        * @dataProvider provideGetMetadata
-        * @covers PNGHandler::getMetadata
-        */
-       public function testGetMetadata( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
-//             $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
-               $this->assertEquals( ( $expected ), ( $actual ) );
-       }
-
-       public static function provideGetMetadata() {
-               // phpcs:disable Generic.Files.LineLength
-               return [
-                       [
-                               'rgb-na-png.png',
-                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}'
-                       ],
-                       [
-                               'xmp.png',
-                               'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}'
-                       ],
-               ];
-               // phpcs:enable
-       }
-
-       /**
-        * @param string $filename
-        * @param array $expected Expected standard metadata
-        * @dataProvider provideGetIndependentMetaArray
-        * @covers PNGHandler::getCommonMetaArray
-        */
-       public function testGetIndependentMetaArray( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actual = $this->handler->getCommonMetaArray( $file );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideGetIndependentMetaArray() {
-               return [
-                       [ 'rgb-na-png.png', [] ],
-                       [ 'xmp.png',
-                               [
-                                       'SerialNumber' => '123456789',
-                               ]
-                       ],
-               ];
-       }
-
-       /**
-        * @param string $filename
-        * @param float $expectedLength
-        * @dataProvider provideGetLength
-        * @covers PNGHandler::getLength
-        */
-       public function testGetLength( $filename, $expectedLength ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actualLength = $file->getLength();
-               $this->assertEquals( $expectedLength, $actualLength, '', 0.00001 );
-       }
-
-       public function provideGetLength() {
-               return [
-                       [ 'Animated_PNG_example_bouncing_beach_ball.png', 1.5 ],
-                       [ 'Png-native-test.png', 0.0 ],
-                       [ 'greyscale-png.png', 0.0 ],
-                       [ '1bit-png.png', 0.0 ],
-               ];
-       }
-}
diff --git a/tests/phpunit/includes/media/WebPHandlerTest.php b/tests/phpunit/includes/media/WebPHandlerTest.php
new file mode 100644 (file)
index 0000000..ac0ad98
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * @covers WebPHandler
+ */
+class WebPHandlerTest extends MediaWikiTestCase {
+       public function setUp() {
+               parent::setUp();
+               // Allocated file for testing
+               $this->tempFileName = tempnam( wfTempDir(), 'WEBP' );
+       }
+
+       public function tearDown() {
+               parent::tearDown();
+               unlink( $this->tempFileName );
+       }
+
+       /**
+        * @dataProvider provideTestExtractMetaData
+        */
+       public function testExtractMetaData( $header, $expectedResult ) {
+               // Put header into file
+               file_put_contents( $this->tempFileName, $header );
+
+               $this->assertEquals( $expectedResult, WebPHandler::extractMetadata( $this->tempFileName ) );
+       }
+
+       public function provideTestExtractMetaData() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       // Files from https://developers.google.com/speed/webp/gallery2
+                       [ "\x52\x49\x46\x46\x90\x68\x01\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x83\x68\x01\x00\x2F\x8F\x01\x4B\x10\x8D\x38\x6C\xDB\x46\x92\xE0\xE0\x82\x7B\x6C",
+                               [ 'compression' => 'lossless', 'width' => 400, 'height' => 301 ] ],
+                       [ "\x52\x49\x46\x46\x64\x5B\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x8F\x01\x00\x2C\x01\x00\x41\x4C\x50\x48\xE5\x0E",
+                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 400, 'height' => 301 ] ],
+                       [ "\x52\x49\x46\x46\xA8\x72\x00\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x9B\x72\x00\x00\x2F\x81\x81\x62\x10\x8D\x40\x8C\x24\x39\x6E\x73\x73\x38\x01\x96",
+                               [ 'compression' => 'lossless', 'width' => 386, 'height' => 395 ] ],
+                       [ "\x52\x49\x46\x46\xE0\x42\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x81\x01\x00\x8A\x01\x00\x41\x4C\x50\x48\x56\x10",
+                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 386, 'height' => 395 ] ],
+                       [ "\x52\x49\x46\x46\x70\x61\x02\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x63\x61\x02\x00\x2F\x1F\xC3\x95\x10\x8D\xC8\x72\xDB\xC8\x92\x24\xD8\x91\xD9\x91",
+                               [ 'compression' => 'lossless', 'width' => 800, 'height' => 600 ] ],
+                       [ "\x52\x49\x46\x46\x1C\x1D\x01\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x1F\x03\x00\x57\x02\x00\x41\x4C\x50\x48\x25\x8B",
+                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 800, 'height' => 600 ] ],
+                       [ "\x52\x49\x46\x46\xFA\xC5\x00\x00\x57\x45\x42\x50\x56\x50\x38\x4C\xEE\xC5\x00\x00\x2F\xA4\x81\x28\x10\x8D\x40\x68\x24\xC9\x91\xA4\xAE\xF3\x97\x75",
+                               [ 'compression' => 'lossless', 'width' => 421, 'height' => 163 ] ],
+                       [ "\x52\x49\x46\x46\xF6\x5D\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\xA4\x01\x00\xA2\x00\x00\x41\x4C\x50\x48\x38\x1A",
+                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 421, 'height' => 163 ] ],
+                       [ "\x52\x49\x46\x46\xC4\x96\x01\x00\x57\x45\x42\x50\x56\x50\x38\x4C\xB8\x96\x01\x00\x2F\x2B\xC1\x4A\x10\x11\x87\x6D\xDB\x48\x12\xFC\x60\xB0\x83\x24",
+                               [ 'compression' => 'lossless', 'width' => 300, 'height' => 300 ] ],
+                       [ "\x52\x49\x46\x46\x0A\x11\x01\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x2B\x01\x00\x2B\x01\x00\x41\x4C\x50\x48\x67\x6E",
+                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 300, 'height' => 300 ] ],
+
+                       // Lossy files from https://developers.google.com/speed/webp/gallery1
+                       [ "\x52\x49\x46\x46\x68\x76\x00\x00\x57\x45\x42\x50\x56\x50\x38\x20\x5C\x76\x00\x00\xD2\xBE\x01\x9D\x01\x2A\x26\x02\x70\x01\x3E\xD5\x4E\x97\x43\xA2",
+                               [ 'compression' => 'lossy', 'width' => 550, 'height' => 368 ] ],
+                       [ "\x52\x49\x46\x46\xB0\xEC\x00\x00\x57\x45\x42\x50\x56\x50\x38\x20\xA4\xEC\x00\x00\xB2\x4B\x02\x9D\x01\x2A\x26\x02\x94\x01\x3E\xD1\x50\x96\x46\x26",
+                               [ 'compression' => 'lossy', 'width' => 550, 'height' => 404 ] ],
+                       [ "\x52\x49\x46\x46\x7A\x19\x03\x00\x57\x45\x42\x50\x56\x50\x38\x20\x6E\x19\x03\x00\xB2\xF8\x09\x9D\x01\x2A\x00\x05\xD0\x02\x3E\xAD\x46\x99\x4A\xA5",
+                               [ 'compression' => 'lossy', 'width' => 1280, 'height' => 720 ] ],
+                       [ "\x52\x49\x46\x46\x44\xB3\x02\x00\x57\x45\x42\x50\x56\x50\x38\x20\x38\xB3\x02\x00\x52\x57\x06\x9D\x01\x2A\x00\x04\x04\x03\x3E\xA5\x44\x96\x49\x26",
+                               [ 'compression' => 'lossy', 'width' => 1024, 'height' => 772 ] ],
+                       [ "\x52\x49\x46\x46\x02\x43\x01\x00\x57\x45\x42\x50\x56\x50\x38\x20\xF6\x42\x01\x00\x12\xC0\x05\x9D\x01\x2A\x00\x04\xF0\x02\x3E\x79\x34\x93\x47\xA4",
+                               [ 'compression' => 'lossy', 'width' => 1024, 'height' => 752 ] ],
+
+                       // Animated file from https://groups.google.com/a/chromium.org/d/topic/blink-dev/Y8tRC4mdQz8/discussion
+                       [ "\x52\x49\x46\x46\xD0\x0B\x02\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x12\x00\x00\x00\x3F\x01\x00\x3F\x01\x00\x41\x4E",
+                               [ 'compression' => 'unknown', 'animated' => true, 'transparency' => true, 'width' => 320, 'height' => 320 ] ],
+
+                       // Error cases
+                       [ '', false ],
+                       [ '                                    ', false ],
+                       [ 'RIFF                                ', false ],
+                       [ 'RIFF1234WEBP                        ', false ],
+                       [ 'RIFF1234WEBPVP8                     ', false ],
+                       [ 'RIFF1234WEBPVP8L                    ', false ],
+               ];
+               // phpcs:enable
+       }
+
+       /**
+        * @dataProvider provideTestWithFileExtractMetaData
+        */
+       public function testWithFileExtractMetaData( $filename, $expectedResult ) {
+               $this->assertEquals( $expectedResult, WebPHandler::extractMetadata( $filename ) );
+       }
+
+       public function provideTestWithFileExtractMetaData() {
+               return [
+                       [ __DIR__ . '/../../data/media/2_webp_ll.webp',
+                               [
+                                       'compression' => 'lossless',
+                                       'width' => 386,
+                                       'height' => 395
+                               ]
+                       ],
+                       [ __DIR__ . '/../../data/media/2_webp_a.webp',
+                               [
+                                       'compression' => 'lossy',
+                                       'animated' => false,
+                                       'transparency' => true,
+                                       'width' => 386,
+                                       'height' => 395
+                               ]
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideTestGetImageSize
+        */
+       public function testGetImageSize( $path, $expectedResult ) {
+               $handler = new WebPHandler();
+               $this->assertEquals( $expectedResult, $handler->getImageSize( null, $path ) );
+       }
+
+       public function provideTestGetImageSize() {
+               return [
+                       // Public domain files from https://developers.google.com/speed/webp/gallery2
+                       [ __DIR__ . '/../../data/media/2_webp_a.webp', [ 386, 395 ] ],
+                       [ __DIR__ . '/../../data/media/2_webp_ll.webp', [ 386, 395 ] ],
+                       [ __DIR__ . '/../../data/media/webp_animated.webp', [ 300, 225 ] ],
+
+                       // Error cases
+                       [ __FILE__, false ],
+               ];
+       }
+
+       /**
+        * Tests the WebP MIME detection. This should really be a separate test, but sticking it
+        * here for now.
+        *
+        * @dataProvider provideTestGetMimeType
+        */
+       public function testGuessMimeType( $path ) {
+               $mime = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
+               $this->assertEquals( 'image/webp', $mime->guessMimeType( $path, false ) );
+       }
+
+       public function provideTestGetMimeType() {
+               return [
+                               // Public domain files from https://developers.google.com/speed/webp/gallery2
+                               [ __DIR__ . '/../../data/media/2_webp_a.webp' ],
+                               [ __DIR__ . '/../../data/media/2_webp_ll.webp' ],
+                               [ __DIR__ . '/../../data/media/webp_animated.webp' ],
+               ];
+       }
+}
+
+/* Python code to extract a header and convert to PHP format:
+ * print '"%s"' % ''.implode( '\\x%02X' % ord(c) for c in urllib.urlopen(url).read(36) )
+ */
diff --git a/tests/phpunit/includes/media/WebPTest.php b/tests/phpunit/includes/media/WebPTest.php
deleted file mode 100644 (file)
index ac0ad98..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-
-/**
- * @covers WebPHandler
- */
-class WebPHandlerTest extends MediaWikiTestCase {
-       public function setUp() {
-               parent::setUp();
-               // Allocated file for testing
-               $this->tempFileName = tempnam( wfTempDir(), 'WEBP' );
-       }
-
-       public function tearDown() {
-               parent::tearDown();
-               unlink( $this->tempFileName );
-       }
-
-       /**
-        * @dataProvider provideTestExtractMetaData
-        */
-       public function testExtractMetaData( $header, $expectedResult ) {
-               // Put header into file
-               file_put_contents( $this->tempFileName, $header );
-
-               $this->assertEquals( $expectedResult, WebPHandler::extractMetadata( $this->tempFileName ) );
-       }
-
-       public function provideTestExtractMetaData() {
-               // phpcs:disable Generic.Files.LineLength
-               return [
-                       // Files from https://developers.google.com/speed/webp/gallery2
-                       [ "\x52\x49\x46\x46\x90\x68\x01\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x83\x68\x01\x00\x2F\x8F\x01\x4B\x10\x8D\x38\x6C\xDB\x46\x92\xE0\xE0\x82\x7B\x6C",
-                               [ 'compression' => 'lossless', 'width' => 400, 'height' => 301 ] ],
-                       [ "\x52\x49\x46\x46\x64\x5B\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x8F\x01\x00\x2C\x01\x00\x41\x4C\x50\x48\xE5\x0E",
-                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 400, 'height' => 301 ] ],
-                       [ "\x52\x49\x46\x46\xA8\x72\x00\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x9B\x72\x00\x00\x2F\x81\x81\x62\x10\x8D\x40\x8C\x24\x39\x6E\x73\x73\x38\x01\x96",
-                               [ 'compression' => 'lossless', 'width' => 386, 'height' => 395 ] ],
-                       [ "\x52\x49\x46\x46\xE0\x42\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x81\x01\x00\x8A\x01\x00\x41\x4C\x50\x48\x56\x10",
-                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 386, 'height' => 395 ] ],
-                       [ "\x52\x49\x46\x46\x70\x61\x02\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x63\x61\x02\x00\x2F\x1F\xC3\x95\x10\x8D\xC8\x72\xDB\xC8\x92\x24\xD8\x91\xD9\x91",
-                               [ 'compression' => 'lossless', 'width' => 800, 'height' => 600 ] ],
-                       [ "\x52\x49\x46\x46\x1C\x1D\x01\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x1F\x03\x00\x57\x02\x00\x41\x4C\x50\x48\x25\x8B",
-                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 800, 'height' => 600 ] ],
-                       [ "\x52\x49\x46\x46\xFA\xC5\x00\x00\x57\x45\x42\x50\x56\x50\x38\x4C\xEE\xC5\x00\x00\x2F\xA4\x81\x28\x10\x8D\x40\x68\x24\xC9\x91\xA4\xAE\xF3\x97\x75",
-                               [ 'compression' => 'lossless', 'width' => 421, 'height' => 163 ] ],
-                       [ "\x52\x49\x46\x46\xF6\x5D\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\xA4\x01\x00\xA2\x00\x00\x41\x4C\x50\x48\x38\x1A",
-                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 421, 'height' => 163 ] ],
-                       [ "\x52\x49\x46\x46\xC4\x96\x01\x00\x57\x45\x42\x50\x56\x50\x38\x4C\xB8\x96\x01\x00\x2F\x2B\xC1\x4A\x10\x11\x87\x6D\xDB\x48\x12\xFC\x60\xB0\x83\x24",
-                               [ 'compression' => 'lossless', 'width' => 300, 'height' => 300 ] ],
-                       [ "\x52\x49\x46\x46\x0A\x11\x01\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x2B\x01\x00\x2B\x01\x00\x41\x4C\x50\x48\x67\x6E",
-                               [ 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 300, 'height' => 300 ] ],
-
-                       // Lossy files from https://developers.google.com/speed/webp/gallery1
-                       [ "\x52\x49\x46\x46\x68\x76\x00\x00\x57\x45\x42\x50\x56\x50\x38\x20\x5C\x76\x00\x00\xD2\xBE\x01\x9D\x01\x2A\x26\x02\x70\x01\x3E\xD5\x4E\x97\x43\xA2",
-                               [ 'compression' => 'lossy', 'width' => 550, 'height' => 368 ] ],
-                       [ "\x52\x49\x46\x46\xB0\xEC\x00\x00\x57\x45\x42\x50\x56\x50\x38\x20\xA4\xEC\x00\x00\xB2\x4B\x02\x9D\x01\x2A\x26\x02\x94\x01\x3E\xD1\x50\x96\x46\x26",
-                               [ 'compression' => 'lossy', 'width' => 550, 'height' => 404 ] ],
-                       [ "\x52\x49\x46\x46\x7A\x19\x03\x00\x57\x45\x42\x50\x56\x50\x38\x20\x6E\x19\x03\x00\xB2\xF8\x09\x9D\x01\x2A\x00\x05\xD0\x02\x3E\xAD\x46\x99\x4A\xA5",
-                               [ 'compression' => 'lossy', 'width' => 1280, 'height' => 720 ] ],
-                       [ "\x52\x49\x46\x46\x44\xB3\x02\x00\x57\x45\x42\x50\x56\x50\x38\x20\x38\xB3\x02\x00\x52\x57\x06\x9D\x01\x2A\x00\x04\x04\x03\x3E\xA5\x44\x96\x49\x26",
-                               [ 'compression' => 'lossy', 'width' => 1024, 'height' => 772 ] ],
-                       [ "\x52\x49\x46\x46\x02\x43\x01\x00\x57\x45\x42\x50\x56\x50\x38\x20\xF6\x42\x01\x00\x12\xC0\x05\x9D\x01\x2A\x00\x04\xF0\x02\x3E\x79\x34\x93\x47\xA4",
-                               [ 'compression' => 'lossy', 'width' => 1024, 'height' => 752 ] ],
-
-                       // Animated file from https://groups.google.com/a/chromium.org/d/topic/blink-dev/Y8tRC4mdQz8/discussion
-                       [ "\x52\x49\x46\x46\xD0\x0B\x02\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x12\x00\x00\x00\x3F\x01\x00\x3F\x01\x00\x41\x4E",
-                               [ 'compression' => 'unknown', 'animated' => true, 'transparency' => true, 'width' => 320, 'height' => 320 ] ],
-
-                       // Error cases
-                       [ '', false ],
-                       [ '                                    ', false ],
-                       [ 'RIFF                                ', false ],
-                       [ 'RIFF1234WEBP                        ', false ],
-                       [ 'RIFF1234WEBPVP8                     ', false ],
-                       [ 'RIFF1234WEBPVP8L                    ', false ],
-               ];
-               // phpcs:enable
-       }
-
-       /**
-        * @dataProvider provideTestWithFileExtractMetaData
-        */
-       public function testWithFileExtractMetaData( $filename, $expectedResult ) {
-               $this->assertEquals( $expectedResult, WebPHandler::extractMetadata( $filename ) );
-       }
-
-       public function provideTestWithFileExtractMetaData() {
-               return [
-                       [ __DIR__ . '/../../data/media/2_webp_ll.webp',
-                               [
-                                       'compression' => 'lossless',
-                                       'width' => 386,
-                                       'height' => 395
-                               ]
-                       ],
-                       [ __DIR__ . '/../../data/media/2_webp_a.webp',
-                               [
-                                       'compression' => 'lossy',
-                                       'animated' => false,
-                                       'transparency' => true,
-                                       'width' => 386,
-                                       'height' => 395
-                               ]
-                       ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideTestGetImageSize
-        */
-       public function testGetImageSize( $path, $expectedResult ) {
-               $handler = new WebPHandler();
-               $this->assertEquals( $expectedResult, $handler->getImageSize( null, $path ) );
-       }
-
-       public function provideTestGetImageSize() {
-               return [
-                       // Public domain files from https://developers.google.com/speed/webp/gallery2
-                       [ __DIR__ . '/../../data/media/2_webp_a.webp', [ 386, 395 ] ],
-                       [ __DIR__ . '/../../data/media/2_webp_ll.webp', [ 386, 395 ] ],
-                       [ __DIR__ . '/../../data/media/webp_animated.webp', [ 300, 225 ] ],
-
-                       // Error cases
-                       [ __FILE__, false ],
-               ];
-       }
-
-       /**
-        * Tests the WebP MIME detection. This should really be a separate test, but sticking it
-        * here for now.
-        *
-        * @dataProvider provideTestGetMimeType
-        */
-       public function testGuessMimeType( $path ) {
-               $mime = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
-               $this->assertEquals( 'image/webp', $mime->guessMimeType( $path, false ) );
-       }
-
-       public function provideTestGetMimeType() {
-               return [
-                               // Public domain files from https://developers.google.com/speed/webp/gallery2
-                               [ __DIR__ . '/../../data/media/2_webp_a.webp' ],
-                               [ __DIR__ . '/../../data/media/2_webp_ll.webp' ],
-                               [ __DIR__ . '/../../data/media/webp_animated.webp' ],
-               ];
-       }
-}
-
-/* Python code to extract a header and convert to PHP format:
- * print '"%s"' % ''.implode( '\\x%02X' % ord(c) for c in urllib.urlopen(url).read(36) )
- */
diff --git a/tests/phpunit/includes/media/XCFHandlerTest.php b/tests/phpunit/includes/media/XCFHandlerTest.php
new file mode 100644 (file)
index 0000000..b75335d
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @group Media
+ */
+class XCFHandlerTest extends MediaWikiMediaTestCase {
+
+       /** @var XCFHandler */
+       protected $handler;
+
+       protected function setUp() {
+               parent::setUp();
+               $this->handler = new XCFHandler();
+       }
+
+       /**
+        * @param string $filename
+        * @param int $expectedWidth Width
+        * @param int $expectedHeight Height
+        * @dataProvider provideGetImageSize
+        * @covers XCFHandler::getImageSize
+        */
+       public function testGetImageSize( $filename, $expectedWidth, $expectedHeight ) {
+               $file = $this->dataFile( $filename, 'image/x-xcf' );
+               $actual = $this->handler->getImageSize( $file, $file->getLocalRefPath() );
+               $this->assertEquals( $expectedWidth, $actual[0] );
+               $this->assertEquals( $expectedHeight, $actual[1] );
+       }
+
+       public static function provideGetImageSize() {
+               return [
+                       [ '80x60-2layers.xcf', 80, 60 ],
+                       [ '80x60-RGB.xcf', 80, 60 ],
+                       [ '80x60-Greyscale.xcf', 80, 60 ],
+               ];
+       }
+
+       /**
+        * @param string $metadata Serialized metadata
+        * @param int $expected One of the class constants of XCFHandler
+        * @dataProvider provideIsMetadataValid
+        * @covers XCFHandler::isMetadataValid
+        */
+       public function testIsMetadataValid( $metadata, $expected ) {
+               $actual = $this->handler->isMetadataValid( null, $metadata );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideIsMetadataValid() {
+               return [
+                       [ '', XCFHandler::METADATA_BAD ],
+                       [ serialize( [ 'error' => true ] ), XCFHandler::METADATA_GOOD ],
+                       [ false, XCFHandler::METADATA_BAD ],
+                       [ serialize( [ 'colorType' => 'greyscale-alpha' ] ), XCFHandler::METADATA_GOOD ],
+               ];
+       }
+
+       /**
+        * @param string $filename
+        * @param string $expected Serialized array
+        * @dataProvider provideGetMetadata
+        * @covers XCFHandler::getMetadata
+        */
+       public function testGetMetadata( $filename, $expected ) {
+               $file = $this->dataFile( $filename, 'image/png' );
+               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public static function provideGetMetadata() {
+               return [
+                       [ '80x60-2layers.xcf',
+                               'a:1:{s:9:"colorType";s:16:"truecolour-alpha";}'
+                       ],
+                       [ '80x60-RGB.xcf',
+                               'a:1:{s:9:"colorType";s:16:"truecolour-alpha";}'
+                       ],
+                       [ '80x60-Greyscale.xcf',
+                               'a:1:{s:9:"colorType";s:15:"greyscale-alpha";}'
+                       ],
+               ];
+       }
+}
diff --git a/tests/phpunit/includes/media/XCFTest.php b/tests/phpunit/includes/media/XCFTest.php
deleted file mode 100644 (file)
index b75335d..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-/**
- * @group Media
- */
-class XCFHandlerTest extends MediaWikiMediaTestCase {
-
-       /** @var XCFHandler */
-       protected $handler;
-
-       protected function setUp() {
-               parent::setUp();
-               $this->handler = new XCFHandler();
-       }
-
-       /**
-        * @param string $filename
-        * @param int $expectedWidth Width
-        * @param int $expectedHeight Height
-        * @dataProvider provideGetImageSize
-        * @covers XCFHandler::getImageSize
-        */
-       public function testGetImageSize( $filename, $expectedWidth, $expectedHeight ) {
-               $file = $this->dataFile( $filename, 'image/x-xcf' );
-               $actual = $this->handler->getImageSize( $file, $file->getLocalRefPath() );
-               $this->assertEquals( $expectedWidth, $actual[0] );
-               $this->assertEquals( $expectedHeight, $actual[1] );
-       }
-
-       public static function provideGetImageSize() {
-               return [
-                       [ '80x60-2layers.xcf', 80, 60 ],
-                       [ '80x60-RGB.xcf', 80, 60 ],
-                       [ '80x60-Greyscale.xcf', 80, 60 ],
-               ];
-       }
-
-       /**
-        * @param string $metadata Serialized metadata
-        * @param int $expected One of the class constants of XCFHandler
-        * @dataProvider provideIsMetadataValid
-        * @covers XCFHandler::isMetadataValid
-        */
-       public function testIsMetadataValid( $metadata, $expected ) {
-               $actual = $this->handler->isMetadataValid( null, $metadata );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideIsMetadataValid() {
-               return [
-                       [ '', XCFHandler::METADATA_BAD ],
-                       [ serialize( [ 'error' => true ] ), XCFHandler::METADATA_GOOD ],
-                       [ false, XCFHandler::METADATA_BAD ],
-                       [ serialize( [ 'colorType' => 'greyscale-alpha' ] ), XCFHandler::METADATA_GOOD ],
-               ];
-       }
-
-       /**
-        * @param string $filename
-        * @param string $expected Serialized array
-        * @dataProvider provideGetMetadata
-        * @covers XCFHandler::getMetadata
-        */
-       public function testGetMetadata( $filename, $expected ) {
-               $file = $this->dataFile( $filename, 'image/png' );
-               $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" );
-               $this->assertEquals( $expected, $actual );
-       }
-
-       public static function provideGetMetadata() {
-               return [
-                       [ '80x60-2layers.xcf',
-                               'a:1:{s:9:"colorType";s:16:"truecolour-alpha";}'
-                       ],
-                       [ '80x60-RGB.xcf',
-                               'a:1:{s:9:"colorType";s:16:"truecolour-alpha";}'
-                       ],
-                       [ '80x60-Greyscale.xcf',
-                               'a:1:{s:9:"colorType";s:15:"greyscale-alpha";}'
-                       ],
-               ];
-       }
-}