diff --git a/tests/phpunit/includes/class-wp-test-stream.php b/tests/phpunit/includes/class-wp-test-stream.php index c10866f003..f489b2bdcc 100644 --- a/tests/phpunit/includes/class-wp-test-stream.php +++ b/tests/phpunit/includes/class-wp-test-stream.php @@ -11,8 +11,7 @@ * 'DIRECTORY' to the static variable WP_Test_Stream::$data['bucket']['/foo/'] * (note the trailing slash). * - * This class can be used to test that code works with basic read/write streams, - * as such, operations such as seeking are not supported. + * This class can be used to test that code works with basic read/write streams. * * This class does not register itself as a stream handler: test fixtures * should make the appropriate call to stream_wrapper_register(). @@ -24,12 +23,12 @@ class WP_Test_Stream { /** * In-memory storage for files and directories simulated by this wrapper. */ - static $data = array(); + public static $data = array(); - var $position; - var $file; - var $bucket; - var $data_ref; + public $position; + public $file; + public $bucket; + public $data_ref; /** * Initializes internal state for reading the given URL. @@ -66,7 +65,7 @@ class WP_Test_Stream { * * @see streamWrapper::stream_open */ - function stream_open( $path, $mode, $options, &$opened_path ) { + public function stream_open( $path, $mode, $options, &$opened_path ) { $this->open( $path ); return true; } @@ -76,7 +75,7 @@ class WP_Test_Stream { * * @see streamWrapper::stream_read */ - function stream_read( $count ) { + public function stream_read( $count ) { if ( ! isset( $this->data_ref ) ) { return ''; } @@ -92,7 +91,7 @@ class WP_Test_Stream { * * @see streamWrapper::stream_write */ - function stream_write( $data ) { + public function stream_write( $data ) { if ( ! isset( $this->data_ref ) ) { $this->data_ref = ''; } @@ -106,12 +105,54 @@ class WP_Test_Stream { return strlen( $data ); } + /** + * Seeks to specific location in a stream. + * + * @see streamWrapper::stream_seek + * + * @param int $offset The stream offset to seek to. + * @param int $whence Optional. Seek position. + * @return bool Returns true when position is updated, else false. + */ + public function stream_seek( $offset, $whence = SEEK_SET ) { + if ( empty( $this->data_ref ) ) { + return false; + } + + $new_offset = $this->position; + switch ( $whence ) { + case SEEK_CUR: + $new_offset += $offset; + break; + + case SEEK_END: + $new_offset = strlen( $this->data_ref ) + $offset; + break; + + case SEEK_SET: + $new_offset = $offset; + break; + + default: + return false; + } + + if ( $new_offset < 0 ) { + return false; + } + + // Save the new position. + $this->position = $new_offset; + + return true; + } + /** * Retrieves the current position of a stream. * * @see streamWrapper::stream_tell */ - function stream_tell() { + public function stream_tell() { return $this->position; } @@ -120,7 +161,7 @@ class WP_Test_Stream { * * @see streamWrapper::stream_eof */ - function stream_eof() { + public function stream_eof() { if ( ! isset( $this->data_ref ) ) { return true; } @@ -133,7 +174,7 @@ class WP_Test_Stream { * * @see streamWrapper::stream_metadata */ - function stream_metadata( $path, $option, $var ) { + public function stream_metadata( $path, $option, $var ) { $this->open( $path ); if ( STREAM_META_TOUCH === $option ) { if ( ! isset( $this->data_ref ) ) { @@ -149,7 +190,7 @@ class WP_Test_Stream { * * @see streamWrapper::mkdir */ - function mkdir( $path, $mode, $options ) { + public function mkdir( $path, $mode, $options ) { $this->open( $path ); $plainfile = rtrim( $this->file, '/' ); diff --git a/tests/phpunit/tests/image/meta.php b/tests/phpunit/tests/image/meta.php index 2e0f2fabd0..a54120967b 100644 --- a/tests/phpunit/tests/image/meta.php +++ b/tests/phpunit/tests/image/meta.php @@ -6,9 +6,28 @@ * @group upload * @requires extension gd * @requires extension exif + * + * @covers ::wp_read_image_metadata */ class Tests_Image_Meta extends WP_UnitTestCase { + public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { + require_once DIR_TESTROOT . '/includes/class-wp-test-stream.php'; + stream_wrapper_register( 'testimagemeta', 'WP_Test_Stream' ); + + WP_Test_Stream::$data = array( + 'wp_read_image_metadata' => array( + '/image1.jpg' => file_get_contents( DIR_TESTDATA . '/images/test-image-upside-down.jpg' ), + '/image2.jpg' => file_get_contents( DIR_TESTDATA . '/images/2004-07-22-DSC_0007.jpg' ), + '/image3.jpg' => file_get_contents( DIR_TESTDATA . '/images/33772.jpg' ), + ), + ); + } + + public static function wpTearDownAfterClass() { + stream_wrapper_unregister( 'testimagemeta' ); + } + function test_exif_d70() { // Exif from a Nikon D70. $out = wp_read_image_metadata( DIR_TESTDATA . '/images/2004-07-22-DSC_0008.jpg' ); @@ -150,4 +169,74 @@ class Tests_Image_Meta extends WP_UnitTestCase { $this->assertSame( array( 'beach', 'baywatch', 'LA', 'sunset' ), $out['keywords'] ); } + /** + * @dataProvider data_stream + * + * @ticket 52826 + * @ticket 52922 + * + * @param string Stream's URI. + * @param array Expected metadata. + */ + public function test_stream( $file, $expected ) { + $actual = wp_read_image_metadata( $file ); + + $this->assertSame( $expected, $actual ); + } + + public function data_stream() { + return array( + 'Orientation only metadata' => array( + 'file' => 'testimagemeta://wp_read_image_metadata/image1.jpg', + 'metadata' => array( + 'aperture' => '0', + 'credit' => '', + 'camera' => '', + 'caption' => '', + 'created_timestamp' => '0', + 'copyright' => '', + 'focal_length' => '0', + 'iso' => '0', + 'shutter_speed' => '0', + 'title' => '', + 'orientation' => '3', + 'keywords' => array(), + ), + ), + 'Exif from a Nikon D70 with IPTC data added later' => array( + 'file' => 'testimagemeta://wp_read_image_metadata/image2.jpg', + 'metadata' => array( + 'aperture' => '6.3', + 'credit' => 'IPTC Creator', + 'camera' => 'NIKON D70', + 'caption' => 'IPTC Caption', + 'created_timestamp' => '1090516475', + 'copyright' => 'IPTC Copyright', + 'focal_length' => '18', + 'iso' => '200', + 'shutter_speed' => '0.04', + 'title' => 'IPTC Headline', + 'orientation' => '0', + 'keywords' => array(), + ), + ), + 'Exif from a DMC-LX2 camera with keywords' => array( + 'file' => 'testimagemeta://wp_read_image_metadata/image3.jpg', + 'metadata' => array( + 'aperture' => '8', + 'credit' => 'Photoshop Author', + 'camera' => 'DMC-LX2', + 'caption' => 'Photoshop Description', + 'created_timestamp' => '1306315327', + 'copyright' => 'Photoshop Copyrright Notice', + 'focal_length' => '6.3', + 'iso' => '100', + 'shutter_speed' => '0.0025', + 'title' => 'Photoshop Document Ttitle', + 'orientation' => '1', + 'keywords' => array( 'beach', 'baywatch', 'LA', 'sunset' ), + ), + ), + ); + } }