diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..e45abd6 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,22 @@ +version: 2 + +jobs: + build: + docker: + - image: circleci/php:5.6-node-browsers + + steps: + - checkout + - run: sudo composer self-update + - restore_cache: + keys: + - composer-v1-{{ checksum "composer.json" }} + - composer-v1- + - run: composer install -n --prefer-dist + - save_cache: + key: composer-v1-{{ checksum "composer.json" }} + paths: + - vendor + - ~/.composer/cache + - run: php -d memory_limit=2G ./vendor/bin/phpunit + - run: php -n -d memory_limit=2G ./vendor/bin/php-cs-fixer fix --verbose --diff --diff-format=udiff --dry-run diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..846eb70 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +.github export-ignore +.circleci export-ignore +.gitignore export-ignore +.php_cs export-ignore +.gitattributes export-ignore +/tests export-ignore diff --git a/.gitignore b/.gitignore index 9d50a57..8ca0152 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ /composer.phar /vendor +# Cache +/.php_cs.cache + # IDEs /.idea *.iml @@ -10,3 +13,4 @@ # System files .DS_Store +*.swp diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..1348296 --- /dev/null +++ b/.php_cs @@ -0,0 +1,21 @@ +setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + 'ordered_imports' => true, + 'concat_space' => ['spacing' => 'one'], + 'array_syntax' => ['syntax' => 'short'], + 'php_unit_construct' => true, + 'phpdoc_align' => false, + 'class_definition' => [ + 'multiLineExtendsEachSingleLine' => true, + ] + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('Resources') + ->exclude('vendor') + ->in(__DIR__) + ); diff --git a/composer.json b/composer.json index 75322eb..c30d7b9 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,9 @@ "twig/twig": "^1.11 || ^2.0" }, "require-dev": { - "symfony/property-access": "^2.8 || ^3.0 || ^4.0" + "phpunit/phpunit": "^5.0 || ^6.0 || ^7.0", + "symfony/property-access": "^2.8 || ^3.0 || ^4.0", + "friendsofphp/php-cs-fixer": "^2.11" }, "suggest": { "symfony/property-access": "The ImageTwigExtension requires the symfony/property-access service." diff --git a/docs/image.md b/docs/image.md index dd1fe2d..c331c60 100644 --- a/docs/image.md +++ b/docs/image.md @@ -57,7 +57,7 @@ This could be: ```twig Logo - cody_redwoodsa-X2 diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..a78ea42 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + + + ./tests + + + diff --git a/src/ComponentTwigExtension.php b/src/ComponentTwigExtension.php index 05c3c4f..d8120be 100644 --- a/src/ComponentTwigExtension.php +++ b/src/ComponentTwigExtension.php @@ -100,7 +100,7 @@ public function getComponents($jsonEncode = true, $clear = true) * * @param bool $jsonEncode * - * @return string. + * @return string */ public function getComponentList($jsonEncode = false) { @@ -156,7 +156,7 @@ public function getServices($jsonEncode = true, $clear = true) * * @param bool $jsonEncode * - * @return string. + * @return string */ public function getServiceList($jsonEncode = false) { diff --git a/src/ImageTwigExtension.php b/src/ImageTwigExtension.php index 455d8ea..0ce7075 100644 --- a/src/ImageTwigExtension.php +++ b/src/ImageTwigExtension.php @@ -35,6 +35,10 @@ public function getImage($media, $attributes = [], $sources = []) return ''; } + if (is_array($media)) { + $media = (object) $media; + } + $propertyAccessor = PropertyAccess::createPropertyAccessor(); // Thumbnails exists all times - it only can be empty. @@ -63,7 +67,7 @@ public function getImage($media, $attributes = [], $sources = []) $sourceTags = ''; foreach ($sources as $media => $sourceAttributes) { // Get the source tag with all given attributes. - $sourceTags .= $this->createTag('source', array_merge(['media' => $media], $sourceAttributes), $thumbnails); + $sourceTags .= $this->createTag('source', array_merge(['media' => $media], $sourceAttributes), $thumbnails); } // Returns the picture tag with all sources and the fallback image tag. @@ -71,9 +75,11 @@ public function getImage($media, $attributes = [], $sources = []) } /** - * @param $tag - * @param $attributes - * @param $thumbnails + * Create html tag. + * + * @param string $tag + * @param array $attributes + * @param array $thumbnails * * @return string */ diff --git a/tests/ComponentTwigExtensionTest.php b/tests/ComponentTwigExtensionTest.php new file mode 100644 index 0000000..05f1ce7 --- /dev/null +++ b/tests/ComponentTwigExtensionTest.php @@ -0,0 +1,182 @@ +componentTwigExtension = new ComponentTwigExtension(); + } + + public function testRegisterComponent() + { + $this->assertEquals('test-1', $this->componentTwigExtension->registerComponent('test')); + + $this->assertEquals( + json_encode([ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => new stdClass(), + ], + ]), + $this->componentTwigExtension->getComponents() + ); + } + + public function testRegisterMultipleComponent() + { + $this->assertEquals('test-1', $this->componentTwigExtension->registerComponent('test')); + $this->assertEquals('test-2', $this->componentTwigExtension->registerComponent('test')); + + $this->assertEquals( + json_encode([ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => new stdClass(), + ], + [ + 'name' => 'test', + 'id' => 'test-2', + 'options' => new stdClass(), + ], + ]), + $this->componentTwigExtension->getComponents() + ); + } + + public function testRegisterCustomIdComponent() + { + $this->assertEquals('custom', $this->componentTwigExtension->registerComponent('test', ['id' => 'custom'])); + + $this->assertEquals( + json_encode([ + [ + 'name' => 'test', + 'id' => 'custom', + 'options' => (object) ['id' => 'custom'], + ], + ]), + $this->componentTwigExtension->getComponents() + ); + } + + public function testRegisterOptionComponent() + { + $this->assertEquals('test-1', $this->componentTwigExtension->registerComponent('test', ['option1' => 'value1', 'option2' => 'value2'])); + + $this->assertEquals( + json_encode([ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => (object) [ + 'option1' => 'value1', + 'option2' => 'value2', + ], + ], + ]), + $this->componentTwigExtension->getComponents() + ); + } + + public function testRegisterComponentArray() + { + $this->assertEquals('test-1', $this->componentTwigExtension->registerComponent('test')); + + $this->assertEquals( + [ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => new stdClass(), + ], + ], + $this->componentTwigExtension->getComponents(false) + ); + } + + public function testRegisterComponentClear() + { + $this->assertEquals('test-1', $this->componentTwigExtension->registerComponent('test')); + + // Get components without clearing them. + $this->assertEquals( + [ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => new stdClass(), + ], + ], + $this->componentTwigExtension->getComponents(false, false) + ); + + // Get components with clearing. + $this->assertEquals( + [ + [ + 'name' => 'test', + 'id' => 'test-1', + 'options' => new stdClass(), + ], + ], + $this->componentTwigExtension->getComponents(false) + ); + + // Check if cleared correctly. + $this->assertEquals([], $this->componentTwigExtension->getComponents(false)); + } + + public function testComponentList() + { + $this->componentTwigExtension->registerComponent('test'); + $this->componentTwigExtension->registerComponent('test'); + $this->componentTwigExtension->registerComponent('test2'); + $this->componentTwigExtension->registerComponent('test3'); + + $componentList = $this->componentTwigExtension->getComponentList(); + + $this->assertCount(3, $componentList); + $this->assertEquals(['test', 'test2', 'test3'], $componentList); + } + + public function testCallService() + { + $this->componentTwigExtension->callService('service', 'function', ['key' => 'value']); + + $this->assertEquals( + json_encode([ + [ + 'name' => 'service', + 'func' => 'function', + 'args' => [ + 'key' => 'value', + ], + ], + ]), + $this->componentTwigExtension->getServices() + ); + } + + public function testGetServices() + { + $this->componentTwigExtension->callService('service', 'function', ['key' => 'value']); + $this->componentTwigExtension->callService('service2', 'function', ['key' => 'value']); + $this->componentTwigExtension->callService('service2', 'function', ['key' => 'value']); + $this->componentTwigExtension->callService('service3', 'function', ['key' => 'value']); + + $servicesList = $this->componentTwigExtension->getServiceList(); + + $this->assertCount(3, $servicesList); + $this->assertEquals(['service', 'service2', 'service3'], $servicesList); + } +} diff --git a/tests/ImageTwigExtensionTest.php b/tests/ImageTwigExtensionTest.php new file mode 100644 index 0000000..f8eb43c --- /dev/null +++ b/tests/ImageTwigExtensionTest.php @@ -0,0 +1,106 @@ +imageTwigExtension = new ImageTwigExtension(); + $this->image = [ + 'title' => 'Title', + 'description' => 'Description', + 'thumbnails' => [ + 'sulu-100x100' => '/uploads/media/sulu-100x100/01/image.jpg?v=1-0', + 'sulu-170x170' => '/uploads/media/sulu-170x170/01/image.jpg?v=1-0', + 'sulu-400x400' => '/uploads/media/sulu-400x400/01/image.jpg?v=1-0', + ], + ]; + } + + public function testImageTag() + { + $this->assertEquals( + 'Title', + $this->imageTwigExtension->getImage($this->image, 'sulu-100x100') + ); + } + + public function testImageTagObject() + { + $this->assertEquals( + 'Title', + $this->imageTwigExtension->getImage((object) $this->image, 'sulu-100x100') + ); + } + + public function testComplexImageTag() + { + $this->assertEquals( + 'Logo', + $this->imageTwigExtension->getImage( + $this->image, + [ + 'src' => 'sulu-400x400', + 'srcset' => 'sulu-400x400 1024w, sulu-170x170 800w, sulu-100x100 460w', + 'sizes' => '(max-width: 1024px) 100vw, (max-width: 800px) 100vw, 100vw', + 'id' => 'image-id', + 'class' => 'image-class', + 'alt' => 'Logo', + ] + ) + ); + } + + public function testPictureTag() + { + $this->assertEquals( + '' . + '' . + '' . + 'Title' . + '', + $this->imageTwigExtension->getImage( + $this->image, + [ + 'src' => 'sulu-400x400', + 'class' => 'image-class', + ], + [ + '(max-width: 1024px)' => [ + 'srcset' => 'sulu-400x400 1024w, sulu-170x170 800w, sulu-100x100 460w', + 'sizes' => '(max-width: 1024px) 100vw, (max-width: 800px) 100vw, 100vw', + ], + '(max-width: 650px)' => [ + 'srcset' => 'sulu-400x400 1024w, sulu-170x170 800w, sulu-100x100 460w', + 'sizes' => '(max-width: 1024px) 100vw, (max-width: 800px) 100vw, 100vw', + ], + ] + ) + ); + } +}