From fc9e83e54a7b9651bcf76b18f158c0d6838e8e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Thu, 11 Sep 2014 12:17:42 +0200 Subject: [PATCH] Complete refactor, added tests --- .gitattributes | 2 + .gitignore | 2 + .travis.yml | 24 ++ composer.json | 15 +- examples/DefaultImageProvider.php | 6 +- examples/FakeImageProvider.php | 2 +- examples/config.neon | 1 + examples/route-with-filters.php | 14 +- readme.md | 12 +- src/Application/Response.php | 47 ++++ src/Application/Route.php | 84 +++++++ src/DI/Extension.php | 139 ++++++++++ src/Extension.php | 86 ------- src/Generator.php | 90 ++++--- src/Helpers.php | 64 +++++ src/IProvider.php | 14 +- src/Latte/Macros.php | 36 +++ src/Macros.php | 70 ------ src/Route.php | 78 ------ src/Rule.php | 48 ++++ src/Validator.php | 58 ++--- tests/.gitignore | 3 + tests/WebImages/Extension.invalid.phpt | 237 ++++++++++++++++++ tests/WebImages/Extension.macros.phpt | 20 ++ tests/WebImages/Extension.services.phpt | 40 +++ tests/WebImages/Generator.addProvider.phpt | 27 ++ tests/WebImages/Generator.generateImage.phpt | 46 ++++ tests/WebImages/Helpers.prepareArguments.phpt | 48 ++++ tests/WebImages/Helpers.prependRoute.phpt | 36 +++ tests/WebImages/Macros.src.phpt | 17 ++ tests/WebImages/Response.send.phpt | 24 ++ tests/WebImages/Route.in.phpt | 25 ++ tests/WebImages/Route.inc | 41 +++ tests/WebImages/Route.out.phpt | 25 ++ tests/WebImages/Rule.validate.phpt | 37 +++ tests/WebImages/Validator.addRule.phpt | 19 ++ tests/WebImages/Validator.validate.phpt | 51 ++++ .../files/Extension.macros.expected.phtml | 12 + tests/WebImages/files/Extension.macros.latte | 1 + tests/WebImages/files/Extension.macros.neon | 7 + tests/WebImages/files/Extension.services.neon | 18 ++ .../WebImages/files/Macros.src.expected.phtml | 12 + tests/WebImages/files/Macros.src.latte | 1 + .../files/Response.send.expected.png | Bin 0 -> 70 bytes tests/bootstrap.php | 61 +++++ tests/php-unix.ini | 6 + tests/php-win.ini | 6 + 47 files changed, 1359 insertions(+), 353 deletions(-) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 src/Application/Response.php create mode 100644 src/Application/Route.php create mode 100644 src/DI/Extension.php delete mode 100644 src/Extension.php create mode 100644 src/Helpers.php create mode 100644 src/Latte/Macros.php delete mode 100644 src/Macros.php delete mode 100644 src/Route.php create mode 100644 src/Rule.php create mode 100644 tests/.gitignore create mode 100644 tests/WebImages/Extension.invalid.phpt create mode 100644 tests/WebImages/Extension.macros.phpt create mode 100644 tests/WebImages/Extension.services.phpt create mode 100644 tests/WebImages/Generator.addProvider.phpt create mode 100644 tests/WebImages/Generator.generateImage.phpt create mode 100644 tests/WebImages/Helpers.prepareArguments.phpt create mode 100644 tests/WebImages/Helpers.prependRoute.phpt create mode 100644 tests/WebImages/Macros.src.phpt create mode 100644 tests/WebImages/Response.send.phpt create mode 100644 tests/WebImages/Route.in.phpt create mode 100644 tests/WebImages/Route.inc create mode 100644 tests/WebImages/Route.out.phpt create mode 100644 tests/WebImages/Rule.validate.phpt create mode 100644 tests/WebImages/Validator.addRule.phpt create mode 100644 tests/WebImages/Validator.validate.phpt create mode 100644 tests/WebImages/files/Extension.macros.expected.phtml create mode 100644 tests/WebImages/files/Extension.macros.latte create mode 100644 tests/WebImages/files/Extension.macros.neon create mode 100644 tests/WebImages/files/Extension.services.neon create mode 100644 tests/WebImages/files/Macros.src.expected.phtml create mode 100644 tests/WebImages/files/Macros.src.latte create mode 100644 tests/WebImages/files/Response.send.expected.png create mode 100644 tests/bootstrap.php create mode 100644 tests/php-unix.ini create mode 100644 tests/php-win.ini diff --git a/.gitattributes b/.gitattributes index 5656a8e..2fdaefa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ .gitattributes export-ignore .gitignore export-ignore +.travis.yml export-ignore examples export-ignore +tests export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de4a392 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor +/composer.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8d35f32 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: php +php: + - 5.3.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +matrix: + allow_failures: + - php: hhvm + +script: + - vendor/bin/tester tests -s -c tests/php-unix.ini + - php code-checker/src/code-checker.php -d src + +after_failure: + # Print *.actual content + - for i in $(find tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done + +before_script: + # Install Nette Tester & Code Checker + - composer install --no-interaction --dev --prefer-source + - composer create-project nette/code-checker code-checker ~2.2 --no-interaction --prefer-source diff --git a/composer.json b/composer.json index 29917aa..2fef2fd 100644 --- a/composer.json +++ b/composer.json @@ -23,12 +23,15 @@ "source": "https://github.com/dotblue/nette-webimages" }, "require": { - "php": ">=5.4", - "nette/application": ">=2.2.0,<2.3.0", - "nette/di": ">=2.2.0,<2.3.0", - "nette/http": ">=2.2.0,<2.3.0", - "latte/latte": ">=2.2.0,<2.3.0", - "nette/utils": ">=2.2.0,<2.3.0" + "php": ">=5.3.3", + "nette/application": "~2.2.0", + "nette/di": "~2.2.0", + "nette/http": "~2.2.0", + "latte/latte": "~2.2.0", + "nette/utils": "~2.2.0" + }, + "require-dev": { + "nette/tester": "@dev" }, "autoload": { "classmap": ["src/"] diff --git a/examples/DefaultImageProvider.php b/examples/DefaultImageProvider.php index 8aa4d27..a2fda15 100644 --- a/examples/DefaultImageProvider.php +++ b/examples/DefaultImageProvider.php @@ -11,21 +11,19 @@ class DefaultImageProvider implements IProvider private $wwwDir; - public function __construct($wwwDir) { $this->wwwDir = $wwwDir; } - - public function getImage($id, $width, $height, $algorithm = NULL) + public function getImage($id, $width, $height, $flags = NULL) { $path = $this->wwwDir . '/originals/' . $id . '.jpg'; if (is_file($path)) { $image = Image::fromFile($path); - $image->resize($width, $height, $algorithm); + $image->resize($width, $height, $flags); return $image; } } diff --git a/examples/FakeImageProvider.php b/examples/FakeImageProvider.php index c69c8f2..222d62a 100644 --- a/examples/FakeImageProvider.php +++ b/examples/FakeImageProvider.php @@ -7,7 +7,7 @@ class FakeImageProvider implements IProvider { - public function getImage($id, $width, $height, $algorithm = NULL) + public function getImage($id, $width, $height, $flags = NULL) { $source = "http://fakeimg.pl/{$width}x{$height}"; return Image::fromString(file_get_contents($source)); diff --git a/examples/config.neon b/examples/config.neon index a9d424d..3dff15f 100644 --- a/examples/config.neon +++ b/examples/config.neon @@ -1,6 +1,7 @@ extensions: webimages: DotBlue\WebImages\Extension + webimages: providers: - DefaultImageProvider(%wwwDir%) diff --git a/examples/route-with-filters.php b/examples/route-with-filters.php index b9d567e..4ebfe96 100644 --- a/examples/route-with-filters.php +++ b/examples/route-with-filters.php @@ -2,13 +2,15 @@ $router = $container->getService('router'); -$router[] = new DotBlue\WebImages\Route('images/-x.jpg', [ - 'id' => [ - DotBlue\WebImages\Route::FILTER_IN => function ($slug) { +$route = new DotBlue\WebImages\Application\Route('images/-x.jpg', array( + 'id' => array( + DotBlue\WebImages\Application\Route::FILTER_IN => function($slug) { // ... }, - DotBlue\WebImages\Route::FILTER_OUT => function ($id) { + DotBlue\WebImages\Application\Route::FILTER_OUT => function($id) { // ... }, - ], -], $container->getByType('DotBlue\WebImages\Generator')); + ), +), $container->getByType('DotBlue\WebImages\Generator')); + +DotBlue\WebImages\Helpers::prependRoute($router, $route); diff --git a/readme.md b/readme.md index 90680c7..bb7e8b6 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ #### Requirements -- PHP 5.4+ +- PHP 5.3.3+ - [nette/application](https://github.com/nette/application) >= 2.2 - [nette/di](https://github.com/nette/di) >= 2.2 - [nette/http](https://github.com/nette/http) >= 2.2 @@ -15,9 +15,9 @@ $ composer require dotblue/nette-webimages@~1.0 ``` 2) Register as Configurator's extension: -``` +```yml extensions: - webimages: DotBlue\WebImages\Extension + webimages: DotBlue\WebImages\DI\Extension ``` ## Concept @@ -39,7 +39,7 @@ First, you have to define your `DotBlue\WebImages\IProvider` implementation. Its When you have it, register it in configuration: -``` +```yml webimages: providers: - @@ -47,7 +47,7 @@ webimages: Secondly you have to specify route where your images will be available. Central point of the route is `id` parameter, which should uniquely identify your image. Lets setup simple route: -``` +```yml webimages: routes: - images/-x.jpg @@ -65,4 +65,4 @@ This will result in following HTML: ``` -Creation of this file will handle your implementation of `DotBlue\WebImages\IProvider`. +Creation of this file will be handled by your implementation of `DotBlue\WebImages\IProvider`. diff --git a/src/Application/Response.php b/src/Application/Response.php new file mode 100644 index 0000000..07bc0c5 --- /dev/null +++ b/src/Application/Response.php @@ -0,0 +1,47 @@ +image = $image; + $this->format = $format; + } + + + public function send(IRequest $httpRequest, HttpResponse $httpResponse) + { + if (!$this->image) { + $httpResponse->setHeader('Content-Type', image_type_to_mime_type($this->format)); + $httpResponse->setCode(HttpResponse::S404_NOT_FOUND); + return; + } + $this->image->send($this->format); + } + +} diff --git a/src/Application/Route.php b/src/Application/Route.php new file mode 100644 index 0000000..d217acf --- /dev/null +++ b/src/Application/Route.php @@ -0,0 +1,84 @@ + Image::JPEG + ); + + + /** + * @param \DotBlue\WebImages\Generator + * @param string + * @param array + * @param int + */ + public function __construct(Generator $generator, $mask, array $metadata = array(), $flags = 0) + { + $this->defaults = array_replace($this->defaults, $metadata); + $metadata['presenter'] = 'Nette:Micro'; + $me = $this; + + $metadata[NULL][self::FILTER_OUT] = function($params) use ($me, $generator) { + $width = $me->acquireArgument('width', $params); + $height = $me->acquireArgument('height', $params); + $flags = $me->acquireArgument('flags', $params); + + if (!$generator->getValidator()->validate($width, $height, $flags)) { + throw new \Nette\Application\ForbiddenRequestException("Image with params ({$width}x{$height}, {$flags}) is not allowed - check your 'webimages.rules' please."); + } + + return $params; + }; + + $metadata['callback'] = function($presenter) use ($me, $generator) { + $params = $presenter->getRequest()->getParameters(); + + $image = NULL; + try { + $id = $me->acquireArgument('id', $params); + $width = $me->acquireArgument('width', $params); + $height = $me->acquireArgument('height', $params); + $flags = $me->acquireArgument('flags', $params); + + $image = $generator->generateImage($id, $width, $height, $flags); + } catch (\Exception $e) {} + + return new Response($image); + }; + + parent::__construct($mask, $metadata, $flags); + } + + + /** + * @param string + * @param array + * @return mixed + * @throws \Nette\InvalidStateException + */ + public function acquireArgument($name, array $data) + { + if (isset($data[$name])) { + return $data[$name]; + } elseif (isset($this->defaults[$name])) { + return $this->defaults[$name]; + } else { + throw new \Nette\InvalidArgumentException("Missing parameter $name."); + } + } + +} diff --git a/src/DI/Extension.php b/src/DI/Extension.php new file mode 100644 index 0000000..95319a4 --- /dev/null +++ b/src/DI/Extension.php @@ -0,0 +1,139 @@ + array(), + 'rules' => array(), + 'providers' => array(), + 'wwwDir' => '%wwwDir%', + ); + + + /** @var array */ + protected $ruleDefaults = array( + 'width' => 0, + 'height' => 0, + 'flags' => NULL, + ); + + + public function loadConfiguration() + { + $builder = $this->getContainerBuilder(); + $config = $this->getConfig($this->defaults); + + $this->validateConfig($this->defaults, $config); + + $validator = $builder->addDefinition($this->prefix('validator')) + ->setClass('DotBlue\WebImages\Validator'); + + Validators::assertField($config, 'rules', 'array', 'option ' . $this->name . '.rules'); + + foreach ($config['rules'] as $name => $rule) { + Validators::assert($rule, 'array', 'option ' . $this->name . '.rules.' . $name); + $this->validateConfig($this->ruleDefaults, $rule, $this->prefix('rules.' . $name)); + Validators::assertField($rule, 'width', 'int', 'option ' . $this->name . '.rules.' . $name . '.width'); + Validators::assertField($rule, 'height', 'int', 'option ' . $this->name . '.rules.' . $name . '.height'); + !isset($rule['flags']) || Validators::assertField($rule, 'flags', 'int', 'option ' . $this->name . '.rules.' . $name . '.flags'); + + $builder->addDefinition($this->prefix('rule.' . $name)) + ->setClass('DotBlue\WebImages\Rule', array( + $rule['width'], + $rule['height'], + isset($rule['flags']) ? $rule['flags'] : NULL + )) + ->setAutowired(FALSE); + + $validator->addSetup('addRule', array($this->prefix('@rule.' . $name))); + } + + $builder->addDefinition($this->prefix('generator')) + ->setClass('DotBlue\WebImages\Generator', array($config['wwwDir'])); + } + + + public function beforeCompile() + { + $builder = $this->getContainerBuilder(); + $config = $this->getConfig($this->defaults); + + $generator = $builder->getDefinition($this->prefix('generator')); + + Validators::assertField($config, 'providers', 'array', 'option ' . $this->name . '.providers'); + + foreach ($config['providers'] as $name => $provider) { + Validators::assert($provider, 'string', 'option ' . $this->name . '.providers.0'); + + $this->compiler->parseServices($builder, array( + 'services' => array($this->prefix('provider.' . $name) => $provider), + )); + $generator->addSetup('addProvider', array($this->prefix('@provider.' . $name))); + } + + $router = $builder->getDefinition('router'); + + Validators::assertField($config, 'routes', 'array', 'option ' . $this->name . '.routes'); + + $i = 0; + foreach (array_reverse($config['routes']) as $mask => $defaults) { + if (!is_array($defaults)) { + $mask = $defaults; + $defaults = array(); + } + + Validators::assert($mask, 'string', 'option ' . $this->name . '.routes.' . $i); + $this->validateConfig($this->ruleDefaults, $defaults, $this->prefix('routes.' . $i)); + !isset($defaults['width']) || Validators::assertField($defaults, 'width', 'int', 'option ' . $this->name . '.routes.' . $i . '.width'); + !isset($defaults['height']) || Validators::assertField($defaults, 'height', 'int', 'option ' . $this->name . '.routes.' . $i . '.height'); + !isset($defaults['flags']) || Validators::assertField($defaults, 'flags', 'int', 'option ' . $this->name . '.routes.' . $i . '.flags'); + + $builder->addDefinition($this->prefix('route.' . $i)) + ->setClass('DotBlue\WebImages\Application\Route', array( + $this->prefix('@generator'), + $mask, + $defaults, + )) + ->setAutowired(FALSE); + + $router->addSetup('DotBlue\WebImages\Helpers::prependRoute', array( + '@self', + $this->prefix('@route.' . $i), + )); + + $i++; + } + + $latte = $builder->hasDefinition('nette.latteFactory') + ? $builder->getDefinition('nette.latteFactory') + : $builder->getDefinition('nette.latte'); + $latte->addSetup('DotBlue\WebImages\Latte\Macros::install(?->getCompiler())', array('@self')); + } + + + /** + * Checks whether $config contains only $expected items. + * @throws \Nette\InvalidStateException + */ + protected function validateConfig(array $expected, array $config = NULL, $name = NULL) + { + if ($extra = array_diff_key($config !== NULL ? $config : $this->config, $expected)) { + $name = $name ?: $this->name; + $extra = implode(", $name.", array_keys($extra)); + throw new \Nette\InvalidStateException("Unknown configuration option $name.$extra."); + } + } + +} diff --git a/src/Extension.php b/src/Extension.php deleted file mode 100644 index 26ad568..0000000 --- a/src/Extension.php +++ /dev/null @@ -1,86 +0,0 @@ - [], - 'rules' => [], - 'providers' => [], - 'wwwDir' => '%wwwDir%', - ]; - - - - public function loadConfiguration() - { - $container = $this->getContainerBuilder(); - $config = $this->getConfig($this->defaults); - - $validator = $container->addDefinition($this->prefix('validator')) - ->setClass('DotBlue\WebImages\Validator'); - - $generator = $container->addDefinition($this->prefix('generator')) - ->setClass('DotBlue\WebImages\Generator', [ - $config['wwwDir'], - ]); - - foreach ($config['rules'] as $rule) { - $validator->addSetup('$service->addRule(?, ?, ?)', [ - $rule['width'], - $rule['height'], - isset($rule['algorithm']) ? $rule['algorithm'] : NULL, - ]); - } - - $i = 0; - foreach ($config['routes'] as $route => $defaults) { - if (!is_array($defaults)) { - $route = $defaults; - $defaults = []; - } - - $route = $container->addDefinition($this->prefix('route' . $i)) - ->setClass('DotBlue\WebImages\Route', [ - $route, - $defaults, - $this->prefix('@generator'), - ]) - ->setAutowired(FALSE); - - $container->getDefinition('router') - ->addSetup('$service[] = ?', [ - $this->prefix('@route' . $i), - ]); - - $i++; - } - - if (count($config['providers']) === 0) { - throw new InvalidConfigException("You have to register at least one IProvider in '" . $this->prefix('providers') . "' directive."); - } - - foreach ($config['providers'] as $name => $provider) { - $this->compiler->parseServices($container, [ - 'services' => [$this->prefix('provider' . $name) => $provider], - ]); - $generator->addSetup('addProvider', [$this->prefix('@provider' . $name)]); - } - - $latte = $container->getDefinition('nette.latteFactory'); - $latte->addSetup('DotBlue\WebImages\Macros::install(?->getCompiler())', ['@self']); - } - -} - -class InvalidConfigException extends \Exception {} diff --git a/src/Generator.php b/src/Generator.php index 219cef8..1fe623c 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -7,101 +7,97 @@ namespace DotBlue\WebImages; use Nette; -use Nette\Application; -use Nette\Http; +use Nette\Http\IRequest; +use DotBlue\WebImages\Validator; use Nette\Utils\Image; +/** + * @method \DotBlue\WebImages\Validator getValidator() + * @method \DotBlue\WebImages\IProvider[] getProviders() + */ class Generator extends Nette\Object { /** @var string */ - private $wwwDir; + protected $wwwDir; - /** @var Http\IRequest */ - private $httpRequest; - /** @var Http\IResponse */ - private $httpResponse; + /** @var \Nette\Http\IRequest */ + protected $httpRequest; - /** @var Validator */ - private $validator; - /** @var IProvider[] */ - private $providers = []; + /** @var \DotBlue\WebImages\Validator */ + protected $validator; + /** @var \DotBlue\WebImages\IProvider[] */ + protected $providers = array(); - public function __construct($wwwDir, Http\IRequest $httpRequest, Http\IResponse $httpResponse, Validator $validator) + + /** + * @param string + * @param \Nette\Http\IRequest + * @param \DotBlue\WebImages\Validator + */ + public function __construct($wwwDir, IRequest $httpRequest, Validator $validator) { $this->wwwDir = $wwwDir; $this->httpRequest = $httpRequest; - $this->httpResponse = $httpResponse; $this->validator = $validator; } - - public function addProvider(IProvider $provider) - { - $this->providers[] = $provider; - } - - - /** - * @return Validator + * @return \DotBlue\WebImages\Generator */ - public function getValidator() + public function addProvider(IProvider $provider) { - return $this->validator; + $this->providers[] = $provider; + return $this; } - /** - * @param string - * @param int - * @param int - * @param int + * @param string + * @param int + * @param int + * @param int|NULL + * @return \Nette\Utils\Image|NULL + * @throws \Exception */ - public function generateImage($id, $width, $height, $algorithm) + public function generateImage($id, $width, $height, $flags = NULL) { - if (!$this->validator->validate($width, $height, $algorithm)) { - throw new Application\BadRequestException; + if (!$this->validator->validate($width, $height, $flags)) { + throw new \Exception("Image with params ({$width}x{$height}, {$flags}) is not allowed - check your 'webimages.rules' please."); } $image = NULL; foreach ($this->providers as $provider) { - $image = $provider->getImage($id, $width, $height, $algorithm); - if ($image) { + $image = $provider->getImage($id, $width, $height, $flags); + if ($image instanceof Image) { break; } } - if (!$image) { - $this->httpResponse->setHeader('Content-Type', 'image/jpeg'); - $this->httpResponse->setCode(Http\IResponse::S404_NOT_FOUND); - exit; + if (!$image instanceof Image) { + throw new \Exception("Image not found."); } - $destination = $this->wwwDir . '/' . $this->httpRequest->getUrl()->getPath(); + $destination = rtrim($this->wwwDir, '/') . '/' . ltrim($this->httpRequest->getUrl()->getPath(), '/'); $dirname = dirname($destination); if (!is_dir($dirname)) { - $success = @mkdir($dirname, 0777, TRUE); - if (!$success) { - throw new Application\BadRequestException; + if (!@mkdir($dirname, 0777, TRUE)) { + throw new \Exception("Cannot create image directory."); } } - $success = $image->save($destination, 90, Image::JPEG); - if (!$success) { - throw new Application\BadRequestException; + if (!$image->save($destination)) { + throw new \Exception("Cannot save image."); } - $image->send(); - exit; + return $image; } } diff --git a/src/Helpers.php b/src/Helpers.php new file mode 100644 index 0000000..dff058a --- /dev/null +++ b/src/Helpers.php @@ -0,0 +1,64 @@ + $r) { + if ($i === $lastKey) { + break; + } + $router[$i + 1] = $r; + } + + $router[0] = $route; + } + + + public static function prepareArguments(array $arguments) + { + foreach ($arguments as $key => $value) { + if ($key === 0 && !isset($arguments['id'])) { + $arguments['id'] = $value; + unset($arguments[$key]); + } elseif ($key === 1 && !isset($arguments['width'])) { + $arguments['width'] = $value; + unset($arguments[$key]); + } elseif ($key === 2 && !isset($arguments['height'])) { + $arguments['height'] = $value; + unset($arguments[$key]); + } elseif ($key === 3 && !isset($arguments['flags'])) { + $arguments['flags'] = $value; + unset($arguments[$key]); + } + } + + if (!isset($arguments['width'])) { + $arguments['width'] = 0; + } + if (!isset($arguments['height'])) { + $arguments['height'] = 0; + } + + return $arguments; + } + +} diff --git a/src/IProvider.php b/src/IProvider.php index 8b8c29f..ee83957 100644 --- a/src/IProvider.php +++ b/src/IProvider.php @@ -10,12 +10,12 @@ interface IProvider { - const FIT = 0; - const EXACT = 1; - const EXACT_HEIGHT_FIT_WIDTH = 2; - - - - function getImage($id, $width, $height, $algorithm = NULL); + /** + * @param string + * @param int + * @param int + * @param int|NULL + */ + public function getImage($id, $width, $height, $flags = NULL); } diff --git a/src/Latte/Macros.php b/src/Latte/Macros.php new file mode 100644 index 0000000..ef63ff4 --- /dev/null +++ b/src/Latte/Macros.php @@ -0,0 +1,36 @@ +addMacro('src', function (MacroNode $node, PhpWriter $writer) use ($me) { + return $me->macroSrc($node, $writer); + }, NULL, function(MacroNode $node, PhpWriter $writer) use ($me) { + return ' ?> src="macroSrc($node, $writer) . ' ?>"write('echo %escape(%modify($_presenter->link("//:Nette:Micro:", DotBlue\WebImages\Helpers::prepareArguments(%node.array))))'); + } + +} diff --git a/src/Macros.php b/src/Macros.php deleted file mode 100644 index 3a3cbcf..0000000 --- a/src/Macros.php +++ /dev/null @@ -1,70 +0,0 @@ -addMacro('src', function (MacroNode $node, PhpWriter $writer) use ($me) { - return $me->macroSrc($node, $writer); - }, NULL, function(MacroNode $node, PhpWriter $writer) use ($me) { - return ' ?> src="macroSrc($node, $writer) . ' ?>"args, 0, 2) === '//' ? '//' : ''; - $args = $absolute ? substr($node->args, 2) : $node->args; - return $writer->write('echo %escape(%modify($_presenter->link("' . $absolute . ':Nette:Micro:", DotBlue\WebImages\Macros::prepareArguments([' . $args . ']))))'); - } - - - - public static function prepareArguments(array $arguments) - { - foreach ($arguments as $key => $value) { - if ($key === 0 && !isset($arguments['id'])) { - $arguments['id'] = $value; - unset($arguments[$key]); - } elseif ($key === 1 && !isset($arguments['width'])) { - $arguments['width'] = $value; - unset($arguments[$key]); - } elseif ($key === 2 && !isset($arguments['height'])) { - $arguments['height'] = $value; - unset($arguments[$key]); - } elseif ($key === 3 && !isset($arguments['algorithm'])) { - $arguments['algorithm'] = $value; - unset($arguments[$key]); - } - } - - if (!isset($arguments['width'])) { - $arguments['width'] = 0; - } - if (!isset($arguments['height'])) { - $arguments['height'] = 0; - } - - return $arguments; - } - -} diff --git a/src/Route.php b/src/Route.php deleted file mode 100644 index e3124e8..0000000 --- a/src/Route.php +++ /dev/null @@ -1,78 +0,0 @@ - IProvider::FIT, - ]; - - - - /** - * @param string - * @param array - * @param Validator - */ - public function __construct($mask, array $defaults, Generator $generator) - { - $this->defaults = array_replace($this->defaults, $defaults); - - $defaults[NULL][self::FILTER_OUT] = function ($params) use ($defaults, $generator) { - $width = $this->acquireArgument('width', $params); - $height = $this->acquireArgument('height', $params); - $algorithm = $this->acquireArgument('algorithm', $params); - - if (!$generator->getValidator()->validate($width, $height, $algorithm)) { - throw new NotAllowedImageException("Image with params ({$width}x{$height}, {$algorithm}) is not allowed - check your 'webimages.rules' please."); - } - - if (isset($defaults[NULL][self::FILTER_OUT])) { - $params = call_user_func($defaults[NULL][self::FILTER_OUT], $params); - } - - return $params; - }; - - $defaults['presenter'] = 'Nette:Micro'; - $defaults['callback'] = function ($presenter) use ($generator) { - $params = $presenter->getRequest()->getParameters(); - - $id = $params['id']; - - $width = $this->acquireArgument('width', $params); - $height = $this->acquireArgument('height', $params); - $algorithm = $this->acquireArgument('algorithm', $params); - - $generator->generateImage($id, $width, $height, $algorithm); - }; - - parent::__construct($mask, $defaults); - } - - - - private function acquireArgument($name, array $data) - { - if (isset($data[$name])) { - return $data[$name]; - } elseif (isset($this->defaults[$name])) { - return $this->defaults[$name]; - } else { - throw new \Exception; - } - } - -} - -class NotAllowedImageException extends \Exception {} diff --git a/src/Rule.php b/src/Rule.php new file mode 100644 index 0000000..9d3f8c9 --- /dev/null +++ b/src/Rule.php @@ -0,0 +1,48 @@ +width = (int)$width; + $this->height = (int)$height; + $this->flags = $flags !== NULL ? (int)$flags : NULL; + } + + + /** + * @param int + * @param int + * @param int|NULL + */ + public function validate($width, $height, $flags = NULL) + { + return (int)$width === $this->width + && (int)$height === $this->height + && (!isset($flags) || (int)$flags === $this->flags); + } + +} diff --git a/src/Validator.php b/src/Validator.php index 0392482..f847eb6 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -9,51 +9,37 @@ use Nette; +/** + * @method \DotBlue\WebImages\Rule[] getRules() + */ class Validator extends Nette\Object { - /** @var array[] */ - private $rules = []; - + /** @var \DotBlue\WebImages\Rule[] */ + protected $rules = array(); /** - * Adds rule. - * - * @param int - * @param int - * @param int + * @param \DotBlue\WebImages\Rule $rule + * @return \DotBlue\WebImages\Validator */ - public function addRule($width, $height, $algorithm) + public function addRule(Rule $rule) { - $this->rules[] = [ - 'width' => (int) $width, - 'height' => (int) $height, - 'algorithm' => (int) $algorithm, - ]; + $this->rules[] = $rule; + return $this; } - /** - * Validates whether provided arguments match at least one rule. - * - * @param int - * @param int - * @param int - * @return bool + * @param int + * @param int + * @param int|NULL + * @return boolean */ - public function validate($width, $height, $algorithm) + public function validate($width, $height, $flags = NULL) { foreach ($this->rules as $rule) { - if ( - (int) $width === $rule['width'] - && (int) $height === $rule['height'] - && ( - !isset($algorithm) - || (int) $algorithm === $rule['algorithm'] - ) - ) { + if ($rule->validate($width, $height, $flags)) { return TRUE; } } @@ -61,16 +47,4 @@ public function validate($width, $height, $algorithm) return count($this->rules) > 0 ? FALSE : TRUE; } - - - /** - * Returns all added rules. - * - * @return array[] - */ - public function getRules() - { - return $this->rules; - } - } diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..a7ffcfd --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,3 @@ +/*/output +/test.log +/tmp diff --git a/tests/WebImages/Extension.invalid.phpt b/tests/WebImages/Extension.invalid.phpt new file mode 100644 index 0000000..86e2c2d --- /dev/null +++ b/tests/WebImages/Extension.invalid.phpt @@ -0,0 +1,237 @@ +addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + extra: TRUE +parameters: + wwwDir: '' +"); +}, 'Nette\InvalidStateException', "Unknown configuration option webimages.extra."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: TRUE +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.rules expects to be array, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - TRUE +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.rules.0 expects to be array, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ extra: TRUE ] +parameters: + wwwDir: '' +"); +}, 'Nette\InvalidStateException', "Unknown configuration option webimages.rules.0.extra."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ ] +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "Missing option webimages.rules.0.width."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ width: TRUE ] +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.rules.0.width expects to be int, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ width: 1 ] +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "Missing option webimages.rules.0.height."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ width: 1, height: TRUE ] +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.rules.0.height expects to be int, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + rules: + - [ width: 1, height: 2, flags: TRUE ] +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.rules.0.flags expects to be int, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + providers: TRUE +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.providers expects to be array, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + providers: + - TRUE +parameters: + wwwDir: '' +"); +}, 'Nette\Utils\AssertionException', "The option webimages.providers.0 expects to be string, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: TRUE +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes expects to be array, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + - TRUE +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes.0 expects to be string, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + - [ ] +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes.0 expects to be string, integer given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + '': [ extra: TRUE ] +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\InvalidStateException', "Unknown configuration option webimages.routes.0.extra."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + '': [ width: TRUE ] +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes.0.width expects to be int, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + '': [ height: TRUE ] +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes.0.height expects to be int, boolean given."); + +Assert::exception(function() { + $compiler = new Nette\DI\Compiler; + $compiler->addExtension('webimages', new DotBlue\WebImages\DI\Extension); + createContainer($compiler, " +webimages: + routes: + '': [ flags: TRUE ] +parameters: + wwwDir: '' +services: + router: Nette\Application\Routers\RouteList +"); +}, 'Nette\Utils\AssertionException', "The option webimages.routes.0.flags expects to be int, boolean given."); diff --git a/tests/WebImages/Extension.macros.phpt b/tests/WebImages/Extension.macros.phpt new file mode 100644 index 0000000..e508b5b --- /dev/null +++ b/tests/WebImages/Extension.macros.phpt @@ -0,0 +1,20 @@ +addExtension('webimages', new DotBlue\WebImages\DI\Extension); +$container = createContainer($compiler, __DIR__ . '/files/Extension.macros.neon'); + +$latte = $container->getService('nette.latteFactory'); + +Assert::matchFile(__DIR__ . '/files/Extension.macros.expected.phtml', + $latte->compile(__DIR__ . '/files/Extension.macros.latte')); diff --git a/tests/WebImages/Extension.services.phpt b/tests/WebImages/Extension.services.phpt new file mode 100644 index 0000000..d040c73 --- /dev/null +++ b/tests/WebImages/Extension.services.phpt @@ -0,0 +1,40 @@ +addExtension('webimages', new DotBlue\WebImages\DI\Extension); +$container = createContainer($compiler, __DIR__ . '/files/Extension.services.neon'); + +Assert::type('DotBlue\WebImages\Validator', $container->getService('webimages.validator')); +Assert::type('DotBlue\WebImages\Generator', $container->getService('webimages.generator')); +Assert::type('NullProvider', $container->getService('webimages.provider.one')); +Assert::type('BlankProvider', $container->getService('webimages.provider.0')); +Assert::type('DotBlue\WebImages\Application\Route', $container->getService('webimages.route.0')); +Assert::type('DotBlue\WebImages\Application\Route', $container->getService('webimages.route.1')); +Assert::type('DotBlue\WebImages\Rule', $container->getService('webimages.rule.one')); +Assert::type('DotBlue\WebImages\Rule', $container->getService('webimages.rule.0')); diff --git a/tests/WebImages/Generator.addProvider.phpt b/tests/WebImages/Generator.addProvider.phpt new file mode 100644 index 0000000..ed605c7 --- /dev/null +++ b/tests/WebImages/Generator.addProvider.phpt @@ -0,0 +1,27 @@ +addProvider() + */ + +use Tester\Assert; + + +require __DIR__ . '/../bootstrap.php'; + + +class MockProvider implements DotBlue\WebImages\IProvider +{ + public function getImage($id, $width, $height, $flags = NULL) {} +} + + +$httpRequest = new Nette\Http\Request(new Nette\Http\UrlScript); +$validator = new DotBlue\WebImages\Validator; +$generator = new DotBlue\WebImages\Generator(TEMP_DIR, $httpRequest, $validator); + +Assert::type('DotBlue\WebImages\Generator', $generator->addProvider($p1 = new MockProvider)); + +$generator->addProvider($p2 = new MockProvider); + +Assert::same(array($p1, $p2), $generator->getProviders()); diff --git a/tests/WebImages/Generator.generateImage.phpt b/tests/WebImages/Generator.generateImage.phpt new file mode 100644 index 0000000..a28a3d3 --- /dev/null +++ b/tests/WebImages/Generator.generateImage.phpt @@ -0,0 +1,46 @@ +generateImage() + */ + +use Tester\Assert; +use Nette\Utils\Image; + + +require __DIR__ . '/../bootstrap.php'; + + +class MockProvider implements DotBlue\WebImages\IProvider +{ + public function getImage($id, $width, $height, $flags = NULL) + { + return Image::fromBlank($width, $height); + } +} + + +$_SERVER['REQUEST_URI'] = 'images/test.jpg'; +$requestFactory = new Nette\Http\RequestFactory; +$httpRequest = $requestFactory->createHttpRequest(); + +$validator = new DotBlue\WebImages\Validator; +$validator->addRule(new DotBlue\WebImages\Rule(1, 2)); + +$generator = new DotBlue\WebImages\Generator(TEMP_DIR, $httpRequest, $validator); + +Assert::exception(function() use ($generator) { + $generator->generateImage('test.jpg', 3, 3); +}, 'Exception', "Image with params (3x3, ) is not allowed - check your 'webimages.rules' please."); + +Assert::exception(function() use ($generator) { + $generator->generateImage('test.jpg', 1, 2); +}, 'Exception', "Image not found."); + +$generator->addProvider(new MockProvider); + +$image = $generator->generateImage('test', 1, 2); + +Assert::type('Nette\Utils\Image', $image); + +Assert::true(file_exists(TEMP_DIR . '/images/test.jpg')); diff --git a/tests/WebImages/Helpers.prepareArguments.phpt b/tests/WebImages/Helpers.prepareArguments.phpt new file mode 100644 index 0000000..4e0334b --- /dev/null +++ b/tests/WebImages/Helpers.prepareArguments.phpt @@ -0,0 +1,48 @@ + 0, + 'height' => 0, +), DotBlue\WebImages\Helpers::prepareArguments(array())); + +Assert::same(array( + 'id' => 1, + 'width' => 0, + 'height' => 0, +), DotBlue\WebImages\Helpers::prepareArguments(array(1))); + +Assert::same(array( + 'id' => 1, + 'width' => 2, + 'height' => 0, +), DotBlue\WebImages\Helpers::prepareArguments(array(1, 2))); + +Assert::same(array( + 'id' => 1, + 'width' => 2, + 'height' => 3, +), DotBlue\WebImages\Helpers::prepareArguments(array(1, 2, 3))); + +Assert::same(array( + 'id' => 1, + 'width' => 2, + 'height' => 3, + 'flags' => 4, +), DotBlue\WebImages\Helpers::prepareArguments(array(1, 2, 3, 4))); + +Assert::same(array( + 2, + 'id' => 1, + 'width' => 0, + 'height' => 0, +), DotBlue\WebImages\Helpers::prepareArguments(array(2, 'id' => 1))); diff --git a/tests/WebImages/Helpers.prependRoute.phpt b/tests/WebImages/Helpers.prependRoute.phpt new file mode 100644 index 0000000..2ac0ea9 --- /dev/null +++ b/tests/WebImages/Helpers.prependRoute.phpt @@ -0,0 +1,36 @@ +mask); +Assert::same('a', $router[1]->mask); diff --git a/tests/WebImages/Macros.src.phpt b/tests/WebImages/Macros.src.phpt new file mode 100644 index 0000000..830ff39 --- /dev/null +++ b/tests/WebImages/Macros.src.phpt @@ -0,0 +1,17 @@ +getCompiler()); + +Assert::matchFile(__DIR__ . '/files/Macros.src.expected.phtml', + $latte->compile(__DIR__ . '/files/Macros.src.latte')); diff --git a/tests/WebImages/Response.send.phpt b/tests/WebImages/Response.send.phpt new file mode 100644 index 0000000..08cf2a3 --- /dev/null +++ b/tests/WebImages/Response.send.phpt @@ -0,0 +1,24 @@ +send() + */ + +use Tester\Assert; +use Nette\Utils\Image; + + +require __DIR__ . '/../bootstrap.php'; + + +$image = Image::fromBlank(1, 1); +$httpResponse = new Nette\Http\Response; + +$response = new DotBlue\WebImages\Application\Response($image, Image::PNG); + +ob_start(); +$response->send(new Nette\Http\Request(new Nette\Http\UrlScript), $httpResponse); +$result = ob_get_flush(); + +Assert::same(file_get_contents(__DIR__ . '/files/Response.send.expected.png'), $result); +Assert::same('image/png', $httpResponse->getHeader('Content-Type')); diff --git a/tests/WebImages/Route.in.phpt b/tests/WebImages/Route.in.phpt new file mode 100644 index 0000000..0ffd340 --- /dev/null +++ b/tests/WebImages/Route.in.phpt @@ -0,0 +1,25 @@ +-x.jpg', array()); + +testRouteIn($route, '/images/foo-1x2.jpg', 'Nette:Micro', array( + 'id' => 'foo', + 'width' => '1', + 'height' => '2', +), '/images/foo-1x2.jpg'); diff --git a/tests/WebImages/Route.inc b/tests/WebImages/Route.inc new file mode 100644 index 0000000..52f9a5e --- /dev/null +++ b/tests/WebImages/Route.inc @@ -0,0 +1,41 @@ +match($httpRequest); + + if ($request) { // matched + $params = $request->getParameters(); + Assert::same($expectedPresenter, $request->getPresenterName()); + unset($params['callback']); + Assert::same($expectedParams, $params); + + unset($params['extra']); + $request->setParameters($params); + $result = $route->constructUrl($request, $url); + $result = strncmp($result, 'http://example.com', 18) ? $result : substr($result, 18); + Assert::same($expectedUrl, $result); + + } else { // not matched + Assert::null( $expectedPresenter ); + } +} + + +function testRouteOut(Nette\Application\IRouter $route, $presenter, $params = array()) +{ + $url = new Nette\Http\Url('http://example.com'); + $request = new Nette\Application\Request($presenter, 'GET', $params); + return $route->constructUrl($request, $url); +} diff --git a/tests/WebImages/Route.out.phpt b/tests/WebImages/Route.out.phpt new file mode 100644 index 0000000..f9a1944 --- /dev/null +++ b/tests/WebImages/Route.out.phpt @@ -0,0 +1,25 @@ +-x.jpg', array()); + +Assert::same($url, testRouteOut($route1, 'Nette:Micro', array( + 'id' => 'foo', + 'width' => '1', + 'height' => '2', +))); diff --git a/tests/WebImages/Rule.validate.phpt b/tests/WebImages/Rule.validate.phpt new file mode 100644 index 0000000..0fcb8aa --- /dev/null +++ b/tests/WebImages/Rule.validate.phpt @@ -0,0 +1,37 @@ +validate() + */ + +use Tester\Assert; + + +require __DIR__ . '/../bootstrap.php'; + + +$rule1 = new DotBlue\WebImages\Rule(1, 2); + +Assert::true($rule1->validate(1, 2)); +Assert::false($rule1->validate(3, 2)); +Assert::false($rule1->validate(1, 3)); +Assert::false($rule1->validate(3, 4)); + +Assert::false($rule1->validate(1, 2, 0)); +Assert::false($rule1->validate(3, 2, 0)); +Assert::false($rule1->validate(1, 3, 0)); +Assert::false($rule1->validate(3, 4, 0)); + +$rule2 = new DotBlue\WebImages\Rule(1, 2, 3); + +Assert::true($rule2->validate(1, 2)); +Assert::false($rule2->validate(4, 2)); +Assert::false($rule2->validate(1, 4)); +Assert::false($rule2->validate(4, 5)); + +Assert::false($rule2->validate(1, 2, 0)); +Assert::false($rule2->validate(4, 2, 0)); +Assert::false($rule2->validate(1, 4, 0)); +Assert::false($rule2->validate(4, 5, 0)); + +Assert::true($rule2->validate(1, 2, 3)); diff --git a/tests/WebImages/Validator.addRule.phpt b/tests/WebImages/Validator.addRule.phpt new file mode 100644 index 0000000..fee49bc --- /dev/null +++ b/tests/WebImages/Validator.addRule.phpt @@ -0,0 +1,19 @@ +addRule() + */ + +use Tester\Assert; + + +require __DIR__ . '/../bootstrap.php'; + + +$validator = new DotBlue\WebImages\Validator; + +Assert::type('DotBlue\WebImages\Validator', $validator->addRule($r1 = new DotBlue\WebImages\Rule(1, 2))); + +$validator->addRule($r2 = new DotBlue\WebImages\Rule(3, 4)); + +Assert::same(array($r1, $r2), $validator->getRules()); diff --git a/tests/WebImages/Validator.validate.phpt b/tests/WebImages/Validator.validate.phpt new file mode 100644 index 0000000..52f0a4d --- /dev/null +++ b/tests/WebImages/Validator.validate.phpt @@ -0,0 +1,51 @@ +validate() + */ + +use Tester\Assert; + + +require __DIR__ . '/../bootstrap.php'; + + +class MockRule extends DotBlue\WebImages\Rule +{ + public function validate($width, $height, $flags = NULL) + { + Notes::add(array($width, $height, $flags)); + return parent::validate($width, $height, $flags); + } +} + + +$validator = new DotBlue\WebImages\Validator; + +Assert::true($validator->validate(1, 2)); +Assert::true($validator->validate(1, 2, 3)); + +$validator->addRule($r1 = new MockRule(1, 2)); +$validator->addRule($r2 = new MockRule(3, 4, 5)); + +Assert::true($validator->validate(1, 2)); +Assert::false($validator->validate(1, 2, 6)); +Assert::true($validator->validate(3, 4)); +Assert::true($validator->validate(3, 4, 5)); +Assert::false($validator->validate(3, 4, 6)); + +Assert::false($validator->validate(7, 8)); + +Assert::same(array( + array(1, 2, NULL), + array(1, 2, 6), + array(1, 2, 6), + array(3, 4, NULL), + array(3, 4, NULL), + array(3, 4, 5), + array(3, 4, 5), + array(3, 4, 6), + array(3, 4, 6), + array(7, 8, NULL), + array(7, 8, NULL), +), Notes::fetch()); diff --git a/tests/WebImages/files/Extension.macros.expected.phtml b/tests/WebImages/files/Extension.macros.expected.phtml new file mode 100644 index 0000000..1d0522f --- /dev/null +++ b/tests/WebImages/files/Extension.macros.expected.phtml @@ -0,0 +1,12 @@ +initialize('%[a-z0-9]+%', 'html') +; +// +// main template +// +?> + +"> diff --git a/tests/WebImages/files/Extension.macros.latte b/tests/WebImages/files/Extension.macros.latte new file mode 100644 index 0000000..9ad02a1 --- /dev/null +++ b/tests/WebImages/files/Extension.macros.latte @@ -0,0 +1 @@ + diff --git a/tests/WebImages/files/Extension.macros.neon b/tests/WebImages/files/Extension.macros.neon new file mode 100644 index 0000000..ba61291 --- /dev/null +++ b/tests/WebImages/files/Extension.macros.neon @@ -0,0 +1,7 @@ +services: + router: Nette\Application\Routers\RouteList + nette.latteFactory: Latte\Engine + - Nette\Http\UrlScript + - Nette\Http\Request +parameters: + wwwDir: '' diff --git a/tests/WebImages/files/Extension.services.neon b/tests/WebImages/files/Extension.services.neon new file mode 100644 index 0000000..d94a6db --- /dev/null +++ b/tests/WebImages/files/Extension.services.neon @@ -0,0 +1,18 @@ +webimages: + rules: + one: [ width: 1, height: 2 ] + - [ width: 1, height: 2, flags: 3 ] + providers: + one: NullProvider + - BlankProvider + routes: + - 'images/-x.jpg' + 'images/-x.png': + flags: 3 +services: + router: Nette\Application\Routers\RouteList + nette.latteFactory: Latte\Engine + - Nette\Http\UrlScript + - Nette\Http\Request +parameters: + wwwDir: '' diff --git a/tests/WebImages/files/Macros.src.expected.phtml b/tests/WebImages/files/Macros.src.expected.phtml new file mode 100644 index 0000000..1d0522f --- /dev/null +++ b/tests/WebImages/files/Macros.src.expected.phtml @@ -0,0 +1,12 @@ +initialize('%[a-z0-9]+%', 'html') +; +// +// main template +// +?> + +"> diff --git a/tests/WebImages/files/Macros.src.latte b/tests/WebImages/files/Macros.src.latte new file mode 100644 index 0000000..9ad02a1 --- /dev/null +++ b/tests/WebImages/files/Macros.src.latte @@ -0,0 +1 @@ + diff --git a/tests/WebImages/files/Response.send.expected.png b/tests/WebImages/files/Response.send.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..6415aef9a0c8c4049db79d0f8c41b623ad67c0a9 GIT binary patch literal 70 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k92}1TpU9doKU}RxrSn^generateClasses($class)); + + } elseif ($source instanceof Nette\DI\Compiler) { + if (is_string($config)) { + $loader = new Nette\DI\Config\Loader; + $config = $loader->load(is_file($config) ? $config : Tester\FileMock::create($config, 'neon')); + } + $code = $source->compile((array) $config, $class, 'Nette\DI\Container'); + } else { + return; + } + + file_put_contents(TEMP_DIR . '/code.php', "