From 812fa4c8c42e467875e20426fa8d5281c202ac64 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Thu, 1 Dec 2016 19:25:56 +0100 Subject: [PATCH 1/9] Mapper & unit tests Signed-off-by: Tom Van Herreweghe --- src/Reader/Mapper.php | 53 +++++++++++++++ tests/unit/Reader/MapperTest.php | 112 +++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 src/Reader/Mapper.php create mode 100644 tests/unit/Reader/MapperTest.php diff --git a/src/Reader/Mapper.php b/src/Reader/Mapper.php new file mode 100644 index 0000000..0ba70df --- /dev/null +++ b/src/Reader/Mapper.php @@ -0,0 +1,53 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader; + +use PHPExif\Common\Adapter\MapperInterface; +use PHPExif\Common\Data\MetadataInterface; +use PHPExif\Common\Mapper\ArrayMapper; +use PHPExif\Common\Mapper\FieldMapperTrait; + +/** + * Mapper + * + * Maps the array of exif & iptc data onto the + * correct fields of given MetadataInterface object + * + * @category PHPExif + * @package Exiftool + */ +class Mapper implements MapperInterface, ArrayMapper +{ + use FieldMapperTrait; + + /** + * {@inheritDoc} + */ + public function map(array $input, MetadataInterface &$output) + { + $this->mapArray($input, $output); + + $output->setRawData($input); + } + + /** + * {@inheritDoc} + */ + public function mapArray(array $input, &$output) + { + $mappers = $this->getFieldMappers(); + + foreach ($mappers as $field => $mapper) { + $mapper->mapField($field, $input, $output); + } + } +} diff --git a/tests/unit/Reader/MapperTest.php b/tests/unit/Reader/MapperTest.php new file mode 100644 index 0000000..a76b689 --- /dev/null +++ b/tests/unit/Reader/MapperTest.php @@ -0,0 +1,112 @@ + + */ +class MapperTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::map + * @group mapper + * + * @return void + */ + public function testMapForwardsCall() + { + $input = []; + $output = new Metadata(new Exif, new Iptc); + + $mock = m::mock(Mapper::class . '[mapArray]')->makePartial(); + $mock->shouldReceive('mapArray') + ->once() + ->with( + $input, + m::type(Metadata::class) + ) + ->andReturnNull(); + + $mock->map($input, $output); + } + + /** + * @covers ::map + * @group mapper + * + * @return void + */ + public function testMapSetsRawData() + { + $input = [ 'raw' => 'data' ]; + $output = new Metadata(new Exif, new Iptc); + + $mock = m::mock(Mapper::class . '[mapArray]')->makePartial(); + $mock->shouldReceive('mapArray') + ->once() + ->with( + $input, + m::type(Metadata::class) + ) + ->andReturnNull(); + + $this->assertCount( + 0, + $output->getRawData() + ); + + $mock->map($input, $output); + + $this->assertEquals( + $input, + $output->getRawData() + ); + } + + /** + * @covers ::mapArray + * @group mapper + * + * @return void + */ + public function testMapArrayForwardsCall() + { + $input = []; + $output = new Metadata( + new Exif, + new Iptc + ); + + $mapper = new Mapper; + + foreach (array(Exif::class, Iptc::class) as $field) { + $fieldMapper = m::mock(FieldMapper::class . '[getSupportedFields,mapField]'); + $fieldMapper->shouldReceive('getSupportedFields') + ->once() + ->andReturn(array($field)); + $fieldMapper->shouldReceive('mapField') + ->once() + ->with( + $field, + $input, + m::type(Metadata::class) + ) + ->andReturnNull(); + + $mapper->registerFieldMapper($fieldMapper); + } + + $mapper->mapArray($input, $output); + } +} From e617767636420c1740e1fb4592673c1a8c3baa1a Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Mon, 2 Jan 2017 20:15:14 +0100 Subject: [PATCH 2/9] Exiftool Reader class & unit tests Signed-off-by: Tom Van Herreweghe --- src/Reader.php | 50 ++++++-- tests/unit/ReaderTest.php | 245 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+), 11 deletions(-) create mode 100644 tests/unit/ReaderTest.php diff --git a/src/Reader.php b/src/Reader.php index 567eb3b..752e69a 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -9,7 +9,7 @@ * @package Exiftool */ -namespace PHPExif\Adapter\Native; +namespace PHPExif\Adapter\Exiftool; use PHPExif\Common\Adapter\MapperInterface; use PHPExif\Common\Adapter\ReaderInterface; @@ -31,6 +31,7 @@ final class Reader implements ReaderInterface { const PATH = 'path'; const BIN = 'binary'; + const NUMERIC = 'numeric'; /** * @var MapperInterface @@ -45,7 +46,7 @@ final class Reader implements ReaderInterface /** * @var bool */ - private $numeric = true; + private $numeric; /** * @var string @@ -62,11 +63,13 @@ public function __construct( $defaults = [ self::BIN => 'exiftool', self::PATH => '/usr/bin/env', + self::NUMERIC => true, ]; $config = array_replace($defaults, $config); $this->binary = $config[self::BIN]; $this->path = $config[self::PATH]; + $this->numeric = $config[self::NUMERIC]; $this->mapper = $mapper; } @@ -94,12 +97,13 @@ public function getMetadataFromFile($filePath) ) ); - $data = json_decode($result, true); - - if (false === $data) { + if (false === $result) { throw NoExifDataException::fromFile($filePath); } + $data = json_decode($result, true)[0]; + $data = $this->normalizeArrayKeys($data); + // map the data: $mapper = $this->getMapper(); $metadata = new Metadata( @@ -111,14 +115,38 @@ public function getMetadataFromFile($filePath) return $metadata; } + /** + * Lowercases the keys for given array + * + * @param array $data + * + * @return array + */ + private function normalizeArrayKeys(array $data) + { + $keys = array_keys($data); + $keys = array_map('strtolower', $keys); + $values = array_values($data); + $values = array_map(function ($value) { + if (!is_array($value)) { + return $value; + } + + return $this->normalizeArrayKeys($value); + }, $values); + + return array_combine( + $keys, + $values + ); + } + /** * Returns the output from given cli command * * @param string $command * - * @throws RuntimeException If the command can't be executed - * - * @return string + * @return string|boolean */ protected function getCliOutput($command) { @@ -128,11 +156,11 @@ protected function getCliOutput($command) 2 => array('pipe', 'a') ); $process = proc_open($command, $descriptorspec, $pipes); + if (!is_resource($process)) { - throw new RuntimeException( - 'Could not open a resource to the exiftool binary' - ); + return false; } + $result = stream_get_contents($pipes[1]); fclose($pipes[0]); fclose($pipes[1]); diff --git a/tests/unit/ReaderTest.php b/tests/unit/ReaderTest.php new file mode 100644 index 0000000..676959c --- /dev/null +++ b/tests/unit/ReaderTest.php @@ -0,0 +1,245 @@ + + */ + class ReaderTest extends \PHPUnit_Framework_TestCase + { + public function setUp() + { + global $mockProcOpen; + global $mockStreamGetContents; + + $mockProcOpen = false; + $mockStreamGetContents = false; + } + + /** + * @covers ::__construct + * @dataProvider defaultPropertyValues + * @group reader + * + * @return void + */ + public function testConstructorSetsDefaultConfiguration($propertyName, $expectedValue) + { + $mapper = m::mock(MapperInterface::class); + $reader = new Reader($mapper); + + $reflProp = new ReflectionProperty(Reader::class, $propertyName); + $reflProp->setAccessible(true); + + $this->assertEquals( + $expectedValue, + $reflProp->getValue($reader) + ); + } + + /** + * @return array + */ + public function defaultPropertyValues() + { + return [ + [ + 'binary', + 'exiftool' + ], + [ + 'numeric', + true + ], + [ + 'path', + '/usr/bin/env' + ], + ]; + } + + /** + * @covers ::__construct + * @dataProvider overrideDefaultPropertyValues + * @group reader + * + * @return void + */ + public function testConstructorCanOverrideDefaultConfiguration($propertyName, $defaultValue, $key, $newValue) + { + $mapper = m::mock(MapperInterface::class); + $reader = new Reader($mapper); + + $reflProp = new ReflectionProperty(Reader::class, $propertyName); + $reflProp->setAccessible(true); + + $this->assertEquals( + $defaultValue, + $reflProp->getValue($reader) + ); + + $reader = new Reader($mapper, [$key => $newValue]); + + $this->assertEquals( + $newValue, + $reflProp->getValue($reader) + ); + } + + /** + * @return array + */ + public function overrideDefaultPropertyValues() + { + return [ + [ + 'binary', + 'exiftool', + Reader::BIN, + 'exiftool2', + ], + [ + 'numeric', + true, + Reader::NUMERIC, + false, + ], + [ + 'path', + '/usr/bin/env', + Reader::PATH, + '/dev/null', + ], + ]; + } + + /** + * @covers ::getMapper + * @group reader + * + * @return void + */ + public function testGetMapperReturnsMapper() + { + $mapper = m::mock(MapperInterface::class); + $reader = new Reader($mapper); + + $this->assertSame( + $mapper, + $reader->getMapper() + ); + } + + /** + * @covers ::getMetadataFromFile + * @group reader + * + * @return void + */ + public function testGetMetadataFromFileThrowsExceptionWhenNoProcOpen() + { + global $mockProcOpen; + $mockProcOpen = -10; + + $this->setExpectedException(NoExifDataException::class); + $mapper = m::mock(MapperInterface::class); + $reader = new Reader($mapper); + + $reader->getMetadataFromFile('/dev/null'); + } + + /** + * @covers ::getMetadataFromFile + * @group reader + * + * @return void + */ + public function testGetMetadataFromFileThrowsExceptionWhenNoData() + { + global $mockStreamGetContents; + $mockStreamGetContents = -10; + + $this->setExpectedException(NoExifDataException::class); + + $mapper = m::mock(MapperInterface::class); + $mapper->shouldReceive('map') + ->andReturnNull(); + $reader = new Reader($mapper); + $result = $reader->getMetadataFromFile('/tmp'); + + $this->assertInstanceOf( + Metadata::class, + $result + ); + } + + /** + * @covers ::getMetadataFromFile + * @group reader + * + * @return void + */ + public function testGetMetadataFromFileReturnsMetadataInstance() + { + global $mockStreamGetContents; + $mockStreamGetContents = -20; + + $mapper = m::mock(MapperInterface::class); + $mapper->shouldReceive('map') + ->andReturnNull(); + $reader = new Reader($mapper); + $result = $reader->getMetadataFromFile('/tmp'); + + $this->assertInstanceOf( + Metadata::class, + $result + ); + } + } +} From 0a85b5d4dd73620b31cbfaaeae5f344cb4089ed3 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Mon, 2 Jan 2017 20:38:28 +0100 Subject: [PATCH 3/9] Update composer dependencies Signed-off-by: Tom Van Herreweghe --- composer.json | 1 - composer.lock | 229 ++++++++++++++++++++++++++------------------------ 2 files changed, 121 insertions(+), 109 deletions(-) diff --git a/composer.json b/composer.json index 1535f17..69a9afa 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,6 @@ "keywords": ["EXIF", "IPTC", "jpeg", "tiff", "exiftool"], "require": { "php": "^5.6 || ^7.0", - "ext-exif": "*", "miljar/php-exif-common": "dev-develop" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 931a858..115f6df 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "81559ee1fec23aa83f611d77ad2433de", - "content-hash": "64d33cd0233764a85a193542e605c5ba", + "hash": "47de1c57b3827779457d31fedc2d0786", + "content-hash": "ca09a0cc839eeb84cbe8ab84551699ff", "packages": [ { "name": "doctrine/collections", @@ -79,12 +79,12 @@ "source": { "type": "git", "url": "https://github.com/PHPExif/php-exif-common.git", - "reference": "a8c5e83b70e13ec5a61763928ebe31208861881f" + "reference": "9b3cdc1aad7426b94af1d761d693cc91b94160cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPExif/php-exif-common/zipball/a8c5e83b70e13ec5a61763928ebe31208861881f", - "reference": "a8c5e83b70e13ec5a61763928ebe31208861881f", + "url": "https://api.github.com/repos/PHPExif/php-exif-common/zipball/9b3cdc1aad7426b94af1d761d693cc91b94160cc", + "reference": "9b3cdc1aad7426b94af1d761d693cc91b94160cc", "shasum": "" }, "require": { @@ -124,7 +124,7 @@ "jpeg", "tiff" ], - "time": "2016-11-23 17:04:04" + "time": "2016-12-07 19:26:31" } ], "packages-dev": [ @@ -325,16 +325,16 @@ }, { "name": "mockery/mockery", - "version": "0.9.6", + "version": "0.9.7", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "65d4ca18e15cb02eeb1e5336f884e46b9b905be0" + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/65d4ca18e15cb02eeb1e5336f884e46b9b905be0", - "reference": "65d4ca18e15cb02eeb1e5336f884e46b9b905be0", + "url": "https://api.github.com/repos/padraic/mockery/zipball/4de7969f4664da3cef1ccd83866c9f59378c3371", + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371", "shasum": "" }, "require": { @@ -386,7 +386,7 @@ "test double", "testing" ], - "time": "2016-09-30 12:09:40" + "time": "2016-12-19 14:50:55" }, { "name": "myclabs/deep-copy", @@ -571,16 +571,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "0.2", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", "shasum": "" }, "require": { @@ -614,7 +614,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2016-11-25 06:54:22" }, { "name": "phpmd/phpmd", @@ -746,16 +746,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "4.0.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d" + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6cba06ff75a1a63a71033e1a01b89056f3af1e8d", - "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a", + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a", "shasum": "" }, "require": { @@ -805,20 +805,20 @@ "testing", "xunit" ], - "time": "2016-11-01 05:06:24" + "time": "2016-12-20 15:22:42" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { @@ -852,7 +852,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2016-10-03 07:40:28" }, { "name": "phpunit/php-text-template", @@ -990,16 +990,16 @@ }, { "name": "phpunit/phpunit", - "version": "5.6.5", + "version": "5.6.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "875145fabfa261fa9c1aea663dd29ddce92dca8f" + "reference": "18a7e88581109a6a701b4ed4180921f0ea486978" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/875145fabfa261fa9c1aea663dd29ddce92dca8f", - "reference": "875145fabfa261fa9c1aea663dd29ddce92dca8f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/18a7e88581109a6a701b4ed4180921f0ea486978", + "reference": "18a7e88581109a6a701b4ed4180921f0ea486978", "shasum": "" }, "require": { @@ -1011,14 +1011,14 @@ "myclabs/deep-copy": "~1.3", "php": "^5.6 || ^7.0", "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "^4.0.1", + "phpunit/php-code-coverage": "^4.0.3", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "^3.2", "sebastian/comparator": "~1.2.2", "sebastian/diff": "~1.2", - "sebastian/environment": "^1.3 || ^2.0", + "sebastian/environment": "^1.3.4 || ^2.0", "sebastian/exporter": "~2.0", "sebastian/global-state": "~1.0", "sebastian/object-enumerator": "~2.0", @@ -1068,20 +1068,20 @@ "testing", "xunit" ], - "time": "2016-11-21 15:23:34" + "time": "2016-12-01 17:07:38" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.4.1", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc" + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/45026c8383187ad1dcb14fbfec77dced265b9cfc", - "reference": "45026c8383187ad1dcb14fbfec77dced265b9cfc", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", "shasum": "" }, "require": { @@ -1127,7 +1127,7 @@ "mock", "xunit" ], - "time": "2016-11-19 09:07:46" + "time": "2016-12-08 20:27:08" }, { "name": "psr/log", @@ -1397,28 +1397,28 @@ }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1443,7 +1443,7 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-11-26 07:53:53" }, { "name": "sebastian/exporter", @@ -1796,16 +1796,16 @@ }, { "name": "sebastian/version", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { @@ -1835,20 +1835,20 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-02-04 12:56:52" + "time": "2016-10-03 07:35:21" }, { "name": "squizlabs/php_codesniffer", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed" + "reference": "9b324f3a1132459a7274a0ace2e1b766ba80930f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", - "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9b324f3a1132459a7274a0ace2e1b766ba80930f", + "reference": "9b324f3a1132459a7274a0ace2e1b766ba80930f", "shasum": "" }, "require": { @@ -1913,33 +1913,36 @@ "phpcs", "standards" ], - "time": "2016-09-01 23:53:02" + "time": "2016-11-30 04:02:31" }, { "name": "symfony/config", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "ab4fa32ffe6e625f9b7444e5e8d4702a0bc3ad7a" + "reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ab4fa32ffe6e625f9b7444e5e8d4702a0bc3ad7a", - "reference": "ab4fa32ffe6e625f9b7444e5e8d4702a0bc3ad7a", + "url": "https://api.github.com/repos/symfony/config/zipball/b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4", + "reference": "b4ec9f099599cfc5b7f4d07bb2e910781a2be5e4", "shasum": "" }, "require": { "php": ">=5.5.9", "symfony/filesystem": "~2.8|~3.0" }, + "require-dev": { + "symfony/yaml": "~3.0" + }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1966,20 +1969,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-11-03 08:04:31" + "time": "2016-12-09 07:45:17" }, { "name": "symfony/console", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5be36e1f3ac7ecbe7e34fb641480ad8497b83aa6" + "reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5be36e1f3ac7ecbe7e34fb641480ad8497b83aa6", - "reference": "5be36e1f3ac7ecbe7e34fb641480ad8497b83aa6", + "url": "https://api.github.com/repos/symfony/console/zipball/d12aa9ca20f4db83ec58410978dab6afcb9d6aaa", + "reference": "d12aa9ca20f4db83ec58410978dab6afcb9d6aaa", "shasum": "" }, "require": { @@ -1990,17 +1993,19 @@ "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2027,20 +2032,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-11-16 22:17:09" + "time": "2016-12-11 14:34:22" }, { "name": "symfony/debug", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "c058661c32f5b462722e36d120905940089cbd9a" + "reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/c058661c32f5b462722e36d120905940089cbd9a", - "reference": "c058661c32f5b462722e36d120905940089cbd9a", + "url": "https://api.github.com/repos/symfony/debug/zipball/9f923e68d524a3095c5a2ae5fc7220c7cbc12231", + "reference": "9f923e68d524a3095c5a2ae5fc7220c7cbc12231", "shasum": "" }, "require": { @@ -2057,7 +2062,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2084,29 +2089,32 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-11-15 12:55:20" + "time": "2016-11-16 22:18:16" }, { "name": "symfony/dependency-injection", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "87598e21bb9020bd9ccd6df6936b9c369c72775d" + "reference": "037054501c41007c93b6de1b5c7a7acb83523593" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/87598e21bb9020bd9ccd6df6936b9c369c72775d", - "reference": "87598e21bb9020bd9ccd6df6936b9c369c72775d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/037054501c41007c93b6de1b5c7a7acb83523593", + "reference": "037054501c41007c93b6de1b5c7a7acb83523593", "shasum": "" }, "require": { "php": ">=5.5.9" }, + "conflict": { + "symfony/yaml": "<3.2" + }, "require-dev": { "symfony/config": "~2.8|~3.0", "symfony/expression-language": "~2.8|~3.0", - "symfony/yaml": "~2.8.7|~3.0.7|~3.1.1|~3.2" + "symfony/yaml": "~3.2" }, "suggest": { "symfony/config": "", @@ -2117,7 +2125,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2144,11 +2152,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-11-18 21:15:08" + "time": "2016-12-08 15:27:33" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.14", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -2208,16 +2216,16 @@ }, { "name": "symfony/filesystem", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6" + "reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/0565b61bf098cb4dc09f4f103f033138ae4f42c6", - "reference": "0565b61bf098cb4dc09f4f103f033138ae4f42c6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4", + "reference": "8d4cf7561a5b17e5eb7a02b80d0b8f014a3796d4", "shasum": "" }, "require": { @@ -2226,7 +2234,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2253,20 +2261,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-10-18 04:30:12" + "time": "2016-11-24 00:46:43" }, { "name": "symfony/finder", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9925935bf7144f9e4d2b976905881b4face036fb" + "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9925935bf7144f9e4d2b976905881b4face036fb", - "reference": "9925935bf7144f9e4d2b976905881b4face036fb", + "url": "https://api.github.com/repos/symfony/finder/zipball/a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", + "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", "shasum": "" }, "require": { @@ -2275,7 +2283,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2302,7 +2310,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-11-03 08:04:31" + "time": "2016-12-13 09:39:43" }, { "name": "symfony/polyfill-mbstring", @@ -2365,16 +2373,16 @@ }, { "name": "symfony/stopwatch", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1" + "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1", - "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", + "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", "shasum": "" }, "require": { @@ -2383,7 +2391,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2410,29 +2418,35 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:41:56" + "time": "2016-06-29 05:43:10" }, { "name": "symfony/yaml", - "version": "v3.1.7", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "9da375317228e54f4ea1b013b30fa47417e84943" + "reference": "a7095af4b97a0955f85c8989106c249fa649011f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/9da375317228e54f4ea1b013b30fa47417e84943", - "reference": "9da375317228e54f4ea1b013b30fa47417e84943", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f", + "reference": "a7095af4b97a0955f85c8989106c249fa649011f", "shasum": "" }, "require": { "php": ">=5.5.9" }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2459,7 +2473,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-11-18 21:05:29" + "time": "2016-12-10 10:07:06" }, { "name": "theseer/fdomdocument", @@ -2560,8 +2574,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^5.6 || ^7.0", - "ext-exif": "*" + "php": "^5.6 || ^7.0" }, "platform-dev": [] } From dc0f460f92812b7837006b09755b02b67ea601a1 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Mon, 2 Jan 2017 20:39:06 +0100 Subject: [PATCH 4/9] Add Apperture FieldMapper & unit tests Signed-off-by: Tom Van Herreweghe --- src/Reader/Mapper.php | 53 ------- .../Mapper/Exif/ApertureFieldMapper.php | 56 +++++++ .../Mapper/Exif/ApertureFieldMapperTest.php | 72 +++++++++ .../Mapper/Exif/BaseFieldMapperTest.php | 137 ++++++++++++++++++ tests/unit/Reader/MapperTest.php | 112 -------------- 5 files changed, 265 insertions(+), 165 deletions(-) delete mode 100644 src/Reader/Mapper.php create mode 100644 src/Reader/Mapper/Exif/ApertureFieldMapper.php create mode 100644 tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php create mode 100644 tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php delete mode 100644 tests/unit/Reader/MapperTest.php diff --git a/src/Reader/Mapper.php b/src/Reader/Mapper.php deleted file mode 100644 index 0ba70df..0000000 --- a/src/Reader/Mapper.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License - * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository - * @package Exiftool - */ - -namespace PHPExif\Adapter\Exiftool\Reader; - -use PHPExif\Common\Adapter\MapperInterface; -use PHPExif\Common\Data\MetadataInterface; -use PHPExif\Common\Mapper\ArrayMapper; -use PHPExif\Common\Mapper\FieldMapperTrait; - -/** - * Mapper - * - * Maps the array of exif & iptc data onto the - * correct fields of given MetadataInterface object - * - * @category PHPExif - * @package Exiftool - */ -class Mapper implements MapperInterface, ArrayMapper -{ - use FieldMapperTrait; - - /** - * {@inheritDoc} - */ - public function map(array $input, MetadataInterface &$output) - { - $this->mapArray($input, $output); - - $output->setRawData($input); - } - - /** - * {@inheritDoc} - */ - public function mapArray(array $input, &$output) - { - $mappers = $this->getFieldMappers(); - - foreach ($mappers as $field => $mapper) { - $mapper->mapField($field, $input, $output); - } - } -} diff --git a/src/Reader/Mapper/Exif/ApertureFieldMapper.php b/src/Reader/Mapper/Exif/ApertureFieldMapper.php new file mode 100644 index 0000000..4b08334 --- /dev/null +++ b/src/Reader/Mapper/Exif/ApertureFieldMapper.php @@ -0,0 +1,56 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader\Mapper\Exif; + +use PHPExif\Common\Data\ExifInterface; +use PHPExif\Common\Data\ValueObject\Aperture; +use PHPExif\Common\Mapper\FieldMapper; +use PHPExif\Common\Mapper\GuardInvalidArgumentsForExifTrait; + +/** + * Mapper + * + * @category PHPExif + * @package Common + */ +class ApertureFieldMapper implements FieldMapper +{ + use GuardInvalidArgumentsForExifTrait; + + /** + * {@inheritDoc} + */ + public function getSupportedFields() + { + return array( + Aperture::class, + ); + } + + /** + * {@inheritDoc} + */ + public function mapField($field, array $input, &$output) + { + $this->guardInvalidArguments($field, $input, $output); + + if (!array_key_exists('composite:aperture', $input)) { + return; + } + + $aperture = new Aperture( + $input['composite:aperture'] + ); + + $output = $output->withAperture($aperture); + } +} diff --git a/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php new file mode 100644 index 0000000..7b64669 --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php @@ -0,0 +1,72 @@ + + */ +class ApertureFieldMapperTest extends BaseFieldMapperTest +{ + /** + * FQCN of the fieldmapper being tested + * + * @var mixed + */ + protected $fieldMapperClass = ApertureFieldMapper::class; + + /** + * List of supported fields + * + * @var array + */ + protected $supportedFields = [ + Aperture::class, + ]; + + /** + * Valid input data + * + * @var array + */ + protected $validInput = [ + 'composite:aperture' => 5.0, + ]; + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldHasDataInOutput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalData = $output->getAperture(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->getAperture(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + Aperture::class, + $newData + ); + + $this->assertEquals( + 'f/' . $this->validInput['composite:aperture'], + (string) $newData + ); + } +} diff --git a/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php new file mode 100644 index 0000000..65b067d --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php @@ -0,0 +1,137 @@ +fieldMapperClass(); + $actual = $mapper->getSupportedFields(); + + $this->assertInternalType('array', $actual); + + $this->assertEquals($this->supportedFields, $actual); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldThrowsExceptionForUnsupportedField() + { + $this->setExpectedException(UnsupportedFieldException::class); + + $field = 'foo'; + $input = []; + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $mapper->mapField($field, $input, $output); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldThrowsExceptionForUnsupportedOutput() + { + $this->setExpectedException(UnsupportedOutputException::class); + + $field = reset($this->supportedFields); + $input = []; + $output = new \stdClass; + $mapper = new $this->fieldMapperClass(); + + $mapper->mapField($field, $input, $output); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldYieldsNewOutputForValidInput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalHash = spl_object_hash($output); + + $mapper->mapField($field, $this->validInput, $output); + + $newHash = spl_object_hash($output); + + $this->assertNotEquals( + $originalHash, + $newHash + ); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldYieldsSameOutputForInvalidInput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalHash = spl_object_hash($output); + + $mapper->mapField($field, [], $output); + + $newHash = spl_object_hash($output); + + $this->assertEquals( + $originalHash, + $newHash + ); + } +} diff --git a/tests/unit/Reader/MapperTest.php b/tests/unit/Reader/MapperTest.php deleted file mode 100644 index a76b689..0000000 --- a/tests/unit/Reader/MapperTest.php +++ /dev/null @@ -1,112 +0,0 @@ - - */ -class MapperTest extends \PHPUnit_Framework_TestCase -{ - /** - * @covers ::map - * @group mapper - * - * @return void - */ - public function testMapForwardsCall() - { - $input = []; - $output = new Metadata(new Exif, new Iptc); - - $mock = m::mock(Mapper::class . '[mapArray]')->makePartial(); - $mock->shouldReceive('mapArray') - ->once() - ->with( - $input, - m::type(Metadata::class) - ) - ->andReturnNull(); - - $mock->map($input, $output); - } - - /** - * @covers ::map - * @group mapper - * - * @return void - */ - public function testMapSetsRawData() - { - $input = [ 'raw' => 'data' ]; - $output = new Metadata(new Exif, new Iptc); - - $mock = m::mock(Mapper::class . '[mapArray]')->makePartial(); - $mock->shouldReceive('mapArray') - ->once() - ->with( - $input, - m::type(Metadata::class) - ) - ->andReturnNull(); - - $this->assertCount( - 0, - $output->getRawData() - ); - - $mock->map($input, $output); - - $this->assertEquals( - $input, - $output->getRawData() - ); - } - - /** - * @covers ::mapArray - * @group mapper - * - * @return void - */ - public function testMapArrayForwardsCall() - { - $input = []; - $output = new Metadata( - new Exif, - new Iptc - ); - - $mapper = new Mapper; - - foreach (array(Exif::class, Iptc::class) as $field) { - $fieldMapper = m::mock(FieldMapper::class . '[getSupportedFields,mapField]'); - $fieldMapper->shouldReceive('getSupportedFields') - ->once() - ->andReturn(array($field)); - $fieldMapper->shouldReceive('mapField') - ->once() - ->with( - $field, - $input, - m::type(Metadata::class) - ) - ->andReturnNull(); - - $mapper->registerFieldMapper($fieldMapper); - } - - $mapper->mapArray($input, $output); - } -} From d5ae08ad8fb801309142f309a49d3830d886a3cc Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Tue, 3 Jan 2017 17:07:22 +0100 Subject: [PATCH 5/9] Creation date Field Mapper & unit tests Signed-off-by: Tom Van Herreweghe --- .../Mapper/Exif/DateTimeFieldMapper.php | 65 ++++++++++ .../Mapper/Exif/DateTimeFieldMapperTest.php | 118 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 src/Reader/Mapper/Exif/DateTimeFieldMapper.php create mode 100644 tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php diff --git a/src/Reader/Mapper/Exif/DateTimeFieldMapper.php b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php new file mode 100644 index 0000000..64db444 --- /dev/null +++ b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php @@ -0,0 +1,65 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader\Mapper\Exif; + +use PHPExif\Common\Data\ExifInterface; +use PHPExif\Common\Mapper\FieldMapper; +use PHPExif\Common\Mapper\GuardInvalidArgumentsForExifTrait; +use \DateTimeImmutable; + +/** + * Mapper + * + * @category PHPExif + * @package Common + */ +class DateTimeFieldMapper implements FieldMapper +{ + use GuardInvalidArgumentsForExifTrait; + + /** + * {@inheritDoc} + */ + public function getSupportedFields() + { + return array( + DateTimeImmutable::class, + ); + } + + /** + * {@inheritDoc} + */ + public function mapField($field, array $input, &$output) + { + $this->guardInvalidArguments($field, $input, $output); + + $validKeys = [ + 'system:filemodifydate', + 'composite:subsecdatetimeoriginal', + 'composite:subsecmodifydate', + 'exififd:datetimeoriginal', + 'exififd:createdate', + 'ifd0:modifydate', + ]; + + while ($key = array_shift($validKeys)) { + if (!array_key_exists($key, $input)) { + continue; + } + + $datetimeOriginal = new DateTimeImmutable($input[$key]); + $output = $output->withCreationDate($datetimeOriginal); + break; + } + } +} diff --git a/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php new file mode 100644 index 0000000..b8beed2 --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php @@ -0,0 +1,118 @@ + + */ +class DateTimeFieldMapperTest extends BaseFieldMapperTest +{ + /** + * FQCN of the fieldmapper being tested + * + * @var mixed + */ + protected $fieldMapperClass = DateTimeFieldMapper::class; + + /** + * List of supported fields + * + * @var array + */ + protected $supportedFields = [ + DateTimeImmutable::class, + ]; + + /** + * Valid input data + * + * @var array + */ + protected $validInput = [ + 'system:filemodifydate' => '2016-11-17 20:00:00', + 'composite:subsecdatetimeoriginal' => '2016-11-17 20:01:00', + 'composite:subsecmodifydate' => '2016-11-17 20:02:00', + 'exififd:datetimeoriginal' => '2016-11-17 20:03:00', + 'exififd:createdate' => '2016-11-17 20:04:00', + 'ifd0:modifydate' => '2016-11-17 20:05:00', + ]; + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldHasDataInOutput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalData = $output->getCreationDate(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->getCreationDate(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + DateTimeImmutable::class, + $newData + ); + + $this->assertEquals( + $this->validInput['system:filemodifydate'], + $newData->format('Y-m-d H:i:s') + ); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldTraversesSetOfKeys() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $keys = array_keys($this->validInput); + foreach ($this->validInput as $key => $value) { + unset($this->validInput[$key]); + array_shift($keys); + + if (count($keys) === 0) { + break; + } + + $newKey = $keys[0]; + + $originalData = $output->getCreationDate(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->getCreationDate(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + DateTimeImmutable::class, + $newData + ); + + $this->assertEquals( + $this->validInput[$newKey], + $newData->format('Y-m-d H:i:s') + ); + } + } +} From 23335fb55f9eb19ebc2fc44fc2ac14942f931baf Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Tue, 3 Jan 2017 18:49:38 +0100 Subject: [PATCH 6/9] Manipulated list of valid keys on DatetimeFieldMapper Signed-off-by: Tom Van Herreweghe --- .../Mapper/Exif/DateTimeFieldMapper.php | 43 ++++++++++++++----- .../Mapper/Exif/DateTimeFieldMapperTest.php | 33 ++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/Reader/Mapper/Exif/DateTimeFieldMapper.php b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php index 64db444..218ba9f 100644 --- a/src/Reader/Mapper/Exif/DateTimeFieldMapper.php +++ b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php @@ -26,6 +26,38 @@ class DateTimeFieldMapper implements FieldMapper { use GuardInvalidArgumentsForExifTrait; + /** + * @var array + */ + private $validKeys = [ + 'system:filemodifydate', + 'composite:subsecdatetimeoriginal', + 'composite:subsecmodifydate', + 'exififd:datetimeoriginal', + 'exififd:createdate', + 'ifd0:modifydate', + ]; + + /** + * Getter for validKeys + * + * @return array + */ + public function getValidKeys() + { + return $this->validKeys; + } + + /** + * Setter for validKeys + * + * @param array $validKeys + */ + public function setValidKeys(array $validKeys) + { + $this->validKeys = $validKeys; + } + /** * {@inheritDoc} */ @@ -43,16 +75,7 @@ public function mapField($field, array $input, &$output) { $this->guardInvalidArguments($field, $input, $output); - $validKeys = [ - 'system:filemodifydate', - 'composite:subsecdatetimeoriginal', - 'composite:subsecmodifydate', - 'exififd:datetimeoriginal', - 'exififd:createdate', - 'ifd0:modifydate', - ]; - - while ($key = array_shift($validKeys)) { + foreach ($this->validKeys as $key) { if (!array_key_exists($key, $input)) { continue; } diff --git a/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php index b8beed2..60bdd86 100644 --- a/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php +++ b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php @@ -115,4 +115,37 @@ public function testMapFieldTraversesSetOfKeys() ); } } + + /** + * @covers ::getValidKeys + * @group mapper + * + * @return void + */ + public function testGetValidKeysReturnsArray() + { + $mapper = new $this->fieldMapperClass(); + $this->assertInternalType( + 'array', + $mapper->getValidKeys() + ); + } + + /** + * @covers ::setValidKeys + * @group mapper + * + * @return void + */ + public function testSetValidKeysSetsCorrectData() + { + $mapper = new $this->fieldMapperClass(); + $data = [ + 'foo', 'bar', 'baz', + ]; + + $this->assertNotEquals($data, $mapper->getValidKeys()); + $mapper->setValidKeys($data); + $this->assertEquals($data, $mapper->getValidKeys()); + } } From 77085925e3ac9f1919603959fce29c61d3a13e22 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Tue, 3 Jan 2017 19:30:22 +0100 Subject: [PATCH 7/9] ExposureTime FieldMapper & unit tests Signed-off-by: Tom Van Herreweghe --- .../Mapper/Exif/ExposureTimeFieldMapper.php | 84 ++++++++++ .../Exif/ExposureTimeFieldMapperTest.php | 147 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php create mode 100644 tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php diff --git a/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php b/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php new file mode 100644 index 0000000..c539f5f --- /dev/null +++ b/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php @@ -0,0 +1,84 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader\Mapper\Exif; + +use PHPExif\Common\Data\ExifInterface; +use PHPExif\Common\Data\ValueObject\ExposureTime; +use PHPExif\Common\Mapper\FieldMapper; +use PHPExif\Common\Mapper\GuardInvalidArgumentsForExifTrait; + +/** + * Mapper + * + * @category PHPExif + * @package Common + */ +class ExposureTimeFieldMapper implements FieldMapper +{ + use GuardInvalidArgumentsForExifTrait; + + /** + * @var array + */ + private $validKeys = [ + 'exififd:exposuretime', + 'composite:shutterspeed', + ]; + + /** + * Getter for validKeys + * + * @return array + */ + public function getValidKeys() + { + return $this->validKeys; + } + + /** + * Setter for validKeys + * + * @param array $validKeys + */ + public function setValidKeys(array $validKeys) + { + $this->validKeys = $validKeys; + } + + /** + * {@inheritDoc} + */ + public function getSupportedFields() + { + return array( + ExposureTime::class, + ); + } + + /** + * {@inheritDoc} + */ + public function mapField($field, array $input, &$output) + { + $this->guardInvalidArguments($field, $input, $output); + + foreach ($this->validKeys as $key) { + if (!array_key_exists($key, $input)) { + continue; + } + + $shutterSpeed = new ExposureTime($input[$key]); + $output = $output->withExposureTime($shutterSpeed); + break; + } + } +} diff --git a/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php new file mode 100644 index 0000000..3295831 --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php @@ -0,0 +1,147 @@ + + */ +class ExposureTimeFieldMapperTest extends BaseFieldMapperTest +{ + /** + * FQCN of the fieldmapper being tested + * + * @var mixed + */ + protected $fieldMapperClass = ExposureTimeFieldMapper::class; + + /** + * List of supported fields + * + * @var array + */ + protected $supportedFields = [ + ExposureTime::class, + ]; + + /** + * Valid input data + * + * @var array + */ + protected $validInput = [ + 'exififd:exposuretime' => '1/60', + 'composite:shutterspeed' => '1/80', + ]; + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldHasDataInOutput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalData = $output->getExposureTime(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->getExposureTime(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + ExposureTime::class, + $newData + ); + + $this->assertEquals( + $this->validInput['exififd:exposuretime'], + $newData + ); + } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldTraversesSetOfKeys() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $keys = array_keys($this->validInput); + foreach ($this->validInput as $key => $value) { + unset($this->validInput[$key]); + array_shift($keys); + + if (count($keys) === 0) { + break; + } + + $newKey = $keys[0]; + + $originalData = $output->getExposureTime(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->getExposureTime(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + ExposureTime::class, + $newData + ); + + $this->assertEquals( + $this->validInput[$newKey], + $newData + ); + } + } + + /** + * @covers ::getValidKeys + * @group mapper + * + * @return void + */ + public function testGetValidKeysReturnsArray() + { + $mapper = new $this->fieldMapperClass(); + $this->assertInternalType( + 'array', + $mapper->getValidKeys() + ); + } + + /** + * @covers ::setValidKeys + * @group mapper + * + * @return void + */ + public function testSetValidKeysSetsCorrectData() + { + $mapper = new $this->fieldMapperClass(); + $data = [ + 'foo', 'bar', 'baz', + ]; + + $this->assertNotEquals($data, $mapper->getValidKeys()); + $mapper->setValidKeys($data); + $this->assertEquals($data, $mapper->getValidKeys()); + } +} From 9824634d575323589ea47e9043a65ef3435203a6 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Wed, 4 Jan 2017 12:03:30 +0100 Subject: [PATCH 8/9] Refactored {get,set}ValidKeys to Trait; Refactored unit tests Signed-off-by: Tom Van Herreweghe --- .../Mapper/Exif/ApertureFieldMapper.php | 27 ++++-- .../Mapper/Exif/DateTimeFieldMapper.php | 23 +---- .../Mapper/Exif/ExposureTimeFieldMapper.php | 23 +---- src/Reader/Mapper/Exif/ValidKeysTrait.php | 41 ++++++++ .../Mapper/Exif/ApertureFieldMapperTest.php | 21 ++-- .../Mapper/Exif/BaseFieldMapperTest.php | 51 ++++++++++ .../Mapper/Exif/DateTimeFieldMapperTest.php | 58 +++-------- .../Exif/ExposureTimeFieldMapperTest.php | 95 ++----------------- .../Reader/Mapper/Exif/ValidKeysTraitTest.php | 70 ++++++++++++++ 9 files changed, 216 insertions(+), 193 deletions(-) create mode 100644 src/Reader/Mapper/Exif/ValidKeysTrait.php create mode 100644 tests/unit/Reader/Mapper/Exif/ValidKeysTraitTest.php diff --git a/src/Reader/Mapper/Exif/ApertureFieldMapper.php b/src/Reader/Mapper/Exif/ApertureFieldMapper.php index 4b08334..736d4c5 100644 --- a/src/Reader/Mapper/Exif/ApertureFieldMapper.php +++ b/src/Reader/Mapper/Exif/ApertureFieldMapper.php @@ -20,11 +20,21 @@ * Mapper * * @category PHPExif - * @package Common + * @package Exiftool */ class ApertureFieldMapper implements FieldMapper { use GuardInvalidArgumentsForExifTrait; + use ValidKeysTrait; + + /** + * @var array + */ + private $validKeys = [ + 'composite:aperture', + 'exififd:fnumber', + 'exififd:aperturevalue', + ]; /** * {@inheritDoc} @@ -43,14 +53,13 @@ public function mapField($field, array $input, &$output) { $this->guardInvalidArguments($field, $input, $output); - if (!array_key_exists('composite:aperture', $input)) { - return; - } - - $aperture = new Aperture( - $input['composite:aperture'] - ); + foreach ($this->validKeys as $key) { + if (!array_key_exists($key, $input)) { + continue; + } - $output = $output->withAperture($aperture); + $aperture = new Aperture($input[$key]); + $output = $output->withAperture($aperture); + } } } diff --git a/src/Reader/Mapper/Exif/DateTimeFieldMapper.php b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php index 218ba9f..28e3cf8 100644 --- a/src/Reader/Mapper/Exif/DateTimeFieldMapper.php +++ b/src/Reader/Mapper/Exif/DateTimeFieldMapper.php @@ -20,11 +20,12 @@ * Mapper * * @category PHPExif - * @package Common + * @package Exiftool */ class DateTimeFieldMapper implements FieldMapper { use GuardInvalidArgumentsForExifTrait; + use ValidKeysTrait; /** * @var array @@ -38,26 +39,6 @@ class DateTimeFieldMapper implements FieldMapper 'ifd0:modifydate', ]; - /** - * Getter for validKeys - * - * @return array - */ - public function getValidKeys() - { - return $this->validKeys; - } - - /** - * Setter for validKeys - * - * @param array $validKeys - */ - public function setValidKeys(array $validKeys) - { - $this->validKeys = $validKeys; - } - /** * {@inheritDoc} */ diff --git a/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php b/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php index c539f5f..56e14fb 100644 --- a/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php +++ b/src/Reader/Mapper/Exif/ExposureTimeFieldMapper.php @@ -20,11 +20,12 @@ * Mapper * * @category PHPExif - * @package Common + * @package Exiftool */ class ExposureTimeFieldMapper implements FieldMapper { use GuardInvalidArgumentsForExifTrait; + use ValidKeysTrait; /** * @var array @@ -34,26 +35,6 @@ class ExposureTimeFieldMapper implements FieldMapper 'composite:shutterspeed', ]; - /** - * Getter for validKeys - * - * @return array - */ - public function getValidKeys() - { - return $this->validKeys; - } - - /** - * Setter for validKeys - * - * @param array $validKeys - */ - public function setValidKeys(array $validKeys) - { - $this->validKeys = $validKeys; - } - /** * {@inheritDoc} */ diff --git a/src/Reader/Mapper/Exif/ValidKeysTrait.php b/src/Reader/Mapper/Exif/ValidKeysTrait.php new file mode 100644 index 0000000..c63b638 --- /dev/null +++ b/src/Reader/Mapper/Exif/ValidKeysTrait.php @@ -0,0 +1,41 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader\Mapper\Exif; + +/** + * Common methods to manipulate the validKeys property + * + * @category PHPExif + * @package Exiftool + */ +trait ValidKeysTrait +{ + /** + * Getter for validKeys + * + * @return array + */ + public function getValidKeys() + { + return (!property_exists($this, 'validKeys')) ? [] : $this->validKeys; + } + + /** + * Setter for validKeys + * + * @param array $validKeys + */ + public function setValidKeys(array $validKeys) + { + $this->validKeys = $validKeys; + } +} diff --git a/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php index 7b64669..eb9ce9a 100644 --- a/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php +++ b/tests/unit/Reader/Mapper/Exif/ApertureFieldMapperTest.php @@ -17,30 +17,29 @@ class ApertureFieldMapperTest extends BaseFieldMapperTest { /** - * FQCN of the fieldmapper being tested - * - * @var mixed + * {@inheritdoc} */ protected $fieldMapperClass = ApertureFieldMapper::class; /** - * List of supported fields - * - * @var array + * {@inheritdoc} */ protected $supportedFields = [ Aperture::class, ]; /** - * Valid input data - * - * @var array + * {@inheritdoc} */ protected $validInput = [ 'composite:aperture' => 5.0, ]; + /** + * {@inheritdoc} + */ + protected $outputAccessor = 'getAperture'; + /** * @covers ::mapField * @group mapper @@ -53,9 +52,9 @@ public function testMapFieldHasDataInOutput() $output = new Exif; $mapper = new $this->fieldMapperClass(); - $originalData = $output->getAperture(); + $originalData = $output->{$this->outputAccessor}(); $mapper->mapField($field, $this->validInput, $output); - $newData = $output->getAperture(); + $newData = $output->{$this->outputAccessor}(); $this->assertNotSame($originalData, $newData); diff --git a/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php index 65b067d..d72dc26 100644 --- a/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php +++ b/tests/unit/Reader/Mapper/Exif/BaseFieldMapperTest.php @@ -35,6 +35,14 @@ abstract class BaseFieldMapperTest extends \PHPUnit_Framework_TestCase */ protected $validInput = []; + /** + * Which method should be used on the output to access the + * mapped data? + * + * @var string + */ + protected $outputAccessor; + /** * @covers ::getSupportedFields * @group mapper @@ -134,4 +142,47 @@ public function testMapFieldYieldsSameOutputForInvalidInput() $newHash ); } + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldTraversesSetOfKeys() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $keys = array_keys($this->validInput); + foreach ($this->validInput as $key => $value) { + unset($this->validInput[$key]); + array_shift($keys); + + if (count($keys) === 0) { + break; + } + + $newKey = $keys[0]; + + $originalData = $output->{$this->outputAccessor}(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->{$this->outputAccessor}(); + + $this->assertNotSame($originalData, $newData); + + if (null !== $originalData) { + $this->assertInstanceOf( + get_class($originalData), + $newData + ); + } + + $this->assertEquals( + $this->validInput[$newKey], + $newData + ); + } + } } diff --git a/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php index 60bdd86..591feb3 100644 --- a/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php +++ b/tests/unit/Reader/Mapper/Exif/DateTimeFieldMapperTest.php @@ -17,25 +17,19 @@ class DateTimeFieldMapperTest extends BaseFieldMapperTest { /** - * FQCN of the fieldmapper being tested - * - * @var mixed + * {@inheritdoc} */ protected $fieldMapperClass = DateTimeFieldMapper::class; /** - * List of supported fields - * - * @var array + * {@inheritdoc} */ protected $supportedFields = [ DateTimeImmutable::class, ]; /** - * Valid input data - * - * @var array + * {@inheritdoc} */ protected $validInput = [ 'system:filemodifydate' => '2016-11-17 20:00:00', @@ -46,6 +40,11 @@ class DateTimeFieldMapperTest extends BaseFieldMapperTest 'ifd0:modifydate' => '2016-11-17 20:05:00', ]; + /** + * {@inheritdoc} + */ + protected $outputAccessor = 'getCreationDate'; + /** * @covers ::mapField * @group mapper @@ -58,9 +57,9 @@ public function testMapFieldHasDataInOutput() $output = new Exif; $mapper = new $this->fieldMapperClass(); - $originalData = $output->getCreationDate(); + $originalData = $output->{$this->outputAccessor}(); $mapper->mapField($field, $this->validInput, $output); - $newData = $output->getCreationDate(); + $newData = $output->{$this->outputAccessor}(); $this->assertNotSame($originalData, $newData); @@ -98,9 +97,9 @@ public function testMapFieldTraversesSetOfKeys() $newKey = $keys[0]; - $originalData = $output->getCreationDate(); + $originalData = $output->{$this->outputAccessor}(); $mapper->mapField($field, $this->validInput, $output); - $newData = $output->getCreationDate(); + $newData = $output->{$this->outputAccessor}(); $this->assertNotSame($originalData, $newData); @@ -115,37 +114,4 @@ public function testMapFieldTraversesSetOfKeys() ); } } - - /** - * @covers ::getValidKeys - * @group mapper - * - * @return void - */ - public function testGetValidKeysReturnsArray() - { - $mapper = new $this->fieldMapperClass(); - $this->assertInternalType( - 'array', - $mapper->getValidKeys() - ); - } - - /** - * @covers ::setValidKeys - * @group mapper - * - * @return void - */ - public function testSetValidKeysSetsCorrectData() - { - $mapper = new $this->fieldMapperClass(); - $data = [ - 'foo', 'bar', 'baz', - ]; - - $this->assertNotEquals($data, $mapper->getValidKeys()); - $mapper->setValidKeys($data); - $this->assertEquals($data, $mapper->getValidKeys()); - } } diff --git a/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php index 3295831..2b982fe 100644 --- a/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php +++ b/tests/unit/Reader/Mapper/Exif/ExposureTimeFieldMapperTest.php @@ -17,31 +17,30 @@ class ExposureTimeFieldMapperTest extends BaseFieldMapperTest { /** - * FQCN of the fieldmapper being tested - * - * @var mixed + * {@inheritdoc} */ protected $fieldMapperClass = ExposureTimeFieldMapper::class; /** - * List of supported fields - * - * @var array + * {@inheritdoc} */ protected $supportedFields = [ ExposureTime::class, ]; /** - * Valid input data - * - * @var array + * {@inheritdoc} */ protected $validInput = [ 'exififd:exposuretime' => '1/60', 'composite:shutterspeed' => '1/80', ]; + /** + * {@inheritdoc} + */ + protected $outputAccessor = 'getExposureTime'; + /** * @covers ::mapField * @group mapper @@ -54,9 +53,9 @@ public function testMapFieldHasDataInOutput() $output = new Exif; $mapper = new $this->fieldMapperClass(); - $originalData = $output->getExposureTime(); + $originalData = $output->{$this->outputAccessor}(); $mapper->mapField($field, $this->validInput, $output); - $newData = $output->getExposureTime(); + $newData = $output->{$this->outputAccessor}(); $this->assertNotSame($originalData, $newData); @@ -70,78 +69,4 @@ public function testMapFieldHasDataInOutput() $newData ); } - - /** - * @covers ::mapField - * @group mapper - * - * @return void - */ - public function testMapFieldTraversesSetOfKeys() - { - $field = reset($this->supportedFields); - $output = new Exif; - $mapper = new $this->fieldMapperClass(); - - $keys = array_keys($this->validInput); - foreach ($this->validInput as $key => $value) { - unset($this->validInput[$key]); - array_shift($keys); - - if (count($keys) === 0) { - break; - } - - $newKey = $keys[0]; - - $originalData = $output->getExposureTime(); - $mapper->mapField($field, $this->validInput, $output); - $newData = $output->getExposureTime(); - - $this->assertNotSame($originalData, $newData); - - $this->assertInstanceOf( - ExposureTime::class, - $newData - ); - - $this->assertEquals( - $this->validInput[$newKey], - $newData - ); - } - } - - /** - * @covers ::getValidKeys - * @group mapper - * - * @return void - */ - public function testGetValidKeysReturnsArray() - { - $mapper = new $this->fieldMapperClass(); - $this->assertInternalType( - 'array', - $mapper->getValidKeys() - ); - } - - /** - * @covers ::setValidKeys - * @group mapper - * - * @return void - */ - public function testSetValidKeysSetsCorrectData() - { - $mapper = new $this->fieldMapperClass(); - $data = [ - 'foo', 'bar', 'baz', - ]; - - $this->assertNotEquals($data, $mapper->getValidKeys()); - $mapper->setValidKeys($data); - $this->assertEquals($data, $mapper->getValidKeys()); - } } diff --git a/tests/unit/Reader/Mapper/Exif/ValidKeysTraitTest.php b/tests/unit/Reader/Mapper/Exif/ValidKeysTraitTest.php new file mode 100644 index 0000000..64095a6 --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/ValidKeysTraitTest.php @@ -0,0 +1,70 @@ + + */ +class ValidKeysTraitTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers ::getValidKeys + * @group mapper + * + * @return void + */ + public function testGetValidKeysReturnsArray() + { + $mock = $this->getMockBuilder(ValidKeysTrait::class) + ->getMockForTrait(); + + $this->assertInternalType( + 'array', + $mock->getValidKeys() + ); + } + + /** + * @covers ::getValidKeys + * @group mapper + * + * @return void + */ + public function testGetValidKeysReturnsEmptyArray() + { + $mock = $this->getMockBuilder(ValidKeysTrait::class) + ->getMockForTrait(); + + $this->assertCount( + 0, + $mock->getValidKeys() + ); + } + + /** + * @covers ::setValidKeys + * @group mapper + * + * @return void + */ + public function testSetValidKeysSetsCorrectData() + { + $mock = $this->getMockBuilder(ValidKeysTrait::class) + ->getMockForTrait(); + $data = [ + 'foo', 'bar', 'baz', + ]; + + $this->assertNotEquals($data, $mock->getValidKeys()); + $mock->setValidKeys($data); + $this->assertEquals($data, $mock->getValidKeys()); + } +} From 48a74845b709ddf44d75c10eff8f955a47e33699 Mon Sep 17 00:00:00 2001 From: Tom Van Herreweghe Date: Wed, 4 Jan 2017 12:03:47 +0100 Subject: [PATCH 9/9] Filename Fieldmapper & unit tests Signed-off-by: Tom Van Herreweghe --- .../Mapper/Exif/FilenameFieldMapper.php | 65 +++++++++++++++++ .../Mapper/Exif/FilenameFieldMapperTest.php | 72 +++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/Reader/Mapper/Exif/FilenameFieldMapper.php create mode 100644 tests/unit/Reader/Mapper/Exif/FilenameFieldMapperTest.php diff --git a/src/Reader/Mapper/Exif/FilenameFieldMapper.php b/src/Reader/Mapper/Exif/FilenameFieldMapper.php new file mode 100644 index 0000000..854b27b --- /dev/null +++ b/src/Reader/Mapper/Exif/FilenameFieldMapper.php @@ -0,0 +1,65 @@ + + * @license http://github.com/PHPExif/php-exif-exiftool/blob/master/LICENSE MIT License + * @link http://github.com/PHPExif/php-exif-exiftool for the canonical source repository + * @package Exiftool + */ + +namespace PHPExif\Adapter\Exiftool\Reader\Mapper\Exif; + +use PHPExif\Common\Data\ExifInterface; +use PHPExif\Common\Data\ValueObject\Filename; +use PHPExif\Common\Mapper\FieldMapper; +use PHPExif\Common\Mapper\GuardInvalidArgumentsForExifTrait; + +/** + * Mapper + * + * @category PHPExif + * @package Exiftool + */ +class FilenameFieldMapper implements FieldMapper +{ + use GuardInvalidArgumentsForExifTrait; + use ValidKeysTrait; + + /** + * @var array + */ + private $validKeys = [ + 'sourcefile', + 'system:filename', + ]; + + /** + * {@inheritDoc} + */ + public function getSupportedFields() + { + return array( + Filename::class, + ); + } + + /** + * {@inheritDoc} + */ + public function mapField($field, array $input, &$output) + { + $this->guardInvalidArguments($field, $input, $output); + + foreach ($this->validKeys as $key) { + if (!array_key_exists($key, $input)) { + continue; + } + + $filename = new Filename($input[$key]); + $output = $output->withFilename($filename); + break; + } + } +} diff --git a/tests/unit/Reader/Mapper/Exif/FilenameFieldMapperTest.php b/tests/unit/Reader/Mapper/Exif/FilenameFieldMapperTest.php new file mode 100644 index 0000000..6ca5d4f --- /dev/null +++ b/tests/unit/Reader/Mapper/Exif/FilenameFieldMapperTest.php @@ -0,0 +1,72 @@ + + */ +class FilenameFieldMapperTest extends BaseFieldMapperTest +{ + /** + * {@inheritdoc} + */ + protected $fieldMapperClass = FilenameFieldMapper::class; + + /** + * {@inheritdoc} + */ + protected $supportedFields = [ + Filename::class, + ]; + + /** + * {@inheritdoc} + */ + protected $validInput = [ + 'sourcefile' => 'IMG_0001.JPG', + 'system:filename' => 'IMG_0002.JPG', + ]; + + /** + * {@inheritdoc} + */ + protected $outputAccessor = 'getFilename'; + + /** + * @covers ::mapField + * @group mapper + * + * @return void + */ + public function testMapFieldHasDataInOutput() + { + $field = reset($this->supportedFields); + $output = new Exif; + $mapper = new $this->fieldMapperClass(); + + $originalData = $output->{$this->outputAccessor}(); + $mapper->mapField($field, $this->validInput, $output); + $newData = $output->{$this->outputAccessor}(); + + $this->assertNotSame($originalData, $newData); + + $this->assertInstanceOf( + Filename::class, + $newData + ); + + $this->assertEquals( + $this->validInput['sourcefile'], + $newData + ); + } +}