/ */ abstract class P4Cms_Image_Driver_TestAbstract extends TestCase { // class of the image driver to test (defined by extending class) protected static $_driverClass = null; // driver instance to use by the tests in this class protected $_driver = null; // list of transformations to test protected $_testedTransforms = array( 'scale', 'sharpen' ); /** * Create image driver and store reference in $_driver property, so tests can access it. */ public function setUp() { // try to create an image driver instance from the driver class if (static::$_driverClass) { try{ $this->_driver = P4Cms_Image_Driver_Factory::create(static::$_driverClass); } catch(P4Cms_Image_Exception $e) { // image driver failed to create } } // skip tests entirely if we have no driver if (!$this->_driver) { $this->markTestSkipped("No image driver set to test with."); } parent::setUp(); } /** * Verify functionality of getData() and setData() methods. */ public function testSetGetData() { // ensure getData() returns null if no or an empty image input image was set $this->assertSame( null, $this->_driver->getData(), "Expected getData() returns null if no image data were set." ); // ensure we can set empty input data $this->_driver->setData(null); $this->assertSame( null, $this->_driver->getData(), "Expected getData() returns null if empty image data were set." ); // following tests will use jpeg image; mark test incomplete if driver // doesn't support jpeg images if (!$this->_driver->isSupportedType('jpeg')) { $this->markTestIncomplete("Driver doesn't support jpeg."); } // set real image data and check that output of getData() represents image // with the correct mime type $data = file_get_contents(TEST_ASSETS_PATH . '/images/perforce-logo.jpg'); $this->_driver->setData($data); $mime = $this->_getMimeType($this->_driver->getData()); if (!$mime) { // cannot verify output data mime type $this->assertTrue(is_string($driver->getData())); } else { $this->assertSame( 'image/jpeg', $mime, 'Expected mime for output image.' ); } } /** * Test getImageSize() method. */ public function testGetImageSize() { // ensure that exception is thrown if called when no image data were previously set try { $this->_driver->getImageSize(); $this->fail("Unexpected continuation after calling getImageSize() with no image data."); } catch (P4Cms_Image_Exception $e) { $this->assertTrue(true); } // following tests will use jpeg image; mark test incomplete if driver // doesn't support jpeg images if (!$this->_driver->isSupportedType('jpeg')) { $this->markTestIncomplete("Driver doesn't support jpeg."); } // set data representing image 200x46 pixels $data = file_get_contents(TEST_ASSETS_PATH . '/images/perforce-logo.jpg'); $this->_driver->setData($data); // ensure size is array with defined 'width' and 'height' keys $size = $this->_driver->getImageSize(); $this->assertTrue( is_array($size), "Expected getImageSize() return an array." ); $this->assertTrue( array_key_exists('width', $size), "Expected 'width' key exists in the array returned by getImageSize()." ); $this->assertTrue( array_key_exists('height', $size), "Expected 'height' key exists in the array returned by getImageSize()." ); // ensure dimensions are correct $this->assertTrue( $size['width'] === 200 && $size['height'] === 46, "Expected dimension of returned image." ); } /** * Test transform methods - ensure that each driver class defines methods for all supported * transforms according to translation in transform() method. */ public function testTransformMethods() { // create driver reflection class $reflector = new ReflectionClass($this->_driver); // ensure that there exists '_()' method, where iterates // all transforms supported by the class $driverClass = get_class($this->_driver); $supportedTransforms = $driverClass::getSupportedTransforms(); foreach ($supportedTransforms as $transform) { // ensure that there exists '_' method defined for each TRANSFORM $method = '_' . $transform; $this->assertTrue( $reflector->hasMethod($method), "Missing '$method' for '$transform' transform." ); } } /** * Test image transformations defined in $_testedTransforms property. */ public function testTransforms() { foreach ($this->_testedTransforms as $transform) { // reset driver's data $this->_driver->setData(null); $method = '_test' . ucwords($transform) . 'Transform'; call_user_func(array('static', $method)); } } /** * Test scale() transform. */ protected function _testScaleTransform() { // ensure that exception is thrown if called when no image data were previously set try { $this->_driver->transform('scale', array(11, 17)); $this->fail("Unexpected continuation after calling transform() with no image data."); } catch (P4Cms_Image_Exception $e) { $this->assertTrue(true); } // following tests will use jpeg image; mark test incomplete if driver // doesn't support jpeg images if (!$this->_driver->isSupportedType('jpeg')) { $this->markTestIncomplete("Driver doesn't support jpeg."); } // read 200x46 pixels image data $imageData = file_get_contents(TEST_ASSETS_PATH . '/images/perforce-logo.jpg'); // test 'scale' transformation with various options: // - set both width and height // - set only target width (height should be computed such that image proportions // remain the same) // - set only target height (width should be computed such that image proportions // remain the same) // - set neither width nor height (exception should be thrown) $this->_driver->setData($imageData); $this->_driver->transform('scale', array(101, 79)); $mime = $this->_getMimeType($this->_driver->getData()); if (!$mime) { // cannot verify output data mime type $this->assertTrue(is_string($this->_driver->getData())); } else { $this->assertSame( 'image/jpeg', $mime, 'Expected mime for output image.' ); } $size = $this->_driver->getImageSize(); $this->assertSame( 101, $size['width'], "Expected image width #1." ); $this->assertSame( 79, $size['height'], "Expected image height #1." ); // test 'scale' transform with only target width set $this->_driver->setData($imageData); $this->_driver->transform('scale', array(100)); $mime = $this->_getMimeType($this->_driver->getData()); if (!$mime) { // cannot verify output data mime type $this->assertTrue(is_string($this->_driver->getData())); } else { $this->assertSame( 'image/jpeg', $mime, 'Expected mime for output image.' ); } $size = $this->_driver->getImageSize(); $this->assertSame( 100, $size['width'], "Expected image width #2." ); $this->assertSame( 23, $size['height'], "Expected image height #2." ); // test 'scale' transform with only target height set $this->_driver->setData($imageData); $this->_driver->transform('scale', array(null, 138)); $mime = $this->_getMimeType($this->_driver->getData()); if (!$mime) { // cannot verify output data mime type $this->assertTrue(is_string($this->_driver->getData())); } else { $this->assertSame( 'image/jpeg', $mime, 'Expected mime for output image.' ); } $size = $this->_driver->getImageSize(); $this->assertSame( 600, $size['width'], "Expected image width #3." ); $this->assertSame( 138, $size['height'], "Expected image height #3." ); // test 'scale' transform with no arguments set $this->_driver->setData($imageData); try { $this->_driver->transform('scale', array()); $this->fail("Unexpected continuation after invalid transformation."); } catch (P4Cms_Image_Exception $e) { $this->assertTrue(true); } } /** * Test sharpen() transform. */ protected function _testSharpenTransform() { // ensure that exception is thrown if called when no image data were previously set try { $this->_driver->transform('sharpen'); $this->fail("Unexpected continuation after calling transform() with no image data."); } catch (P4Cms_Image_Exception $e) { $this->assertTrue(true); } // following tests will use jpeg image; mark test incomplete if driver // doesn't support jpeg images if (!$this->_driver->isSupportedType('jpeg')) { $this->markTestIncomplete("Driver doesn't support jpeg."); } // read 200x46 pixels image data $imageData = file_get_contents(TEST_ASSETS_PATH . '/images/perforce-logo.jpg'); $this->_driver->setData($imageData); $this->_driver->transform('sharpen'); // we cannot really test if the resulting image is sharper, so we // verify parameters and ensure that image dimensions remain unchanged $mime = $this->_getMimeType($this->_driver->getData()); if (!$mime) { // cannot verify output data mime type $this->assertTrue(is_string($this->_driver->getData())); } else { $this->assertSame( 'image/jpeg', $mime, 'Expected mime for output image.' ); } $size = $this->_driver->getImageSize(); $this->assertSame( 200, $size['width'], "Expected image width." ); $this->assertSame( 46, $size['height'], "Expected image height." ); } /** * Helper function to detect mime type of $data by using fileinfo. This extension * is enabled by default (as of PHP 5.3.0). If its turned off from whatever reason, * return null. * * @param string $data data to detect mime type on */ protected function _getMimeType($data) { if (!class_exists('finfo')) { return null; } $finfo = new finfo(FILEINFO_MIME_TYPE); return $finfo->buffer($data); } }