1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-29 08:40:33 +02:00

Refactor InputHandler logic

This commit is contained in:
Oliver Vogel
2024-05-06 16:38:11 +02:00
parent 2e0cbf2408
commit cf0291f9c1
22 changed files with 152 additions and 654 deletions

View File

@@ -10,7 +10,7 @@ use Intervention\Image\Colors\Cmyk\Channels\Magenta;
use Intervention\Image\Colors\Cmyk\Channels\Yellow;
use Intervention\Image\Colors\Cmyk\Channels\Key;
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\InputHandler;
use Intervention\Image\Interfaces\ColorChannelInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
@@ -44,11 +44,9 @@ class Color extends AbstractColor
*/
public static function create(mixed $input): ColorInterface
{
return (new class ([
return (new InputHandler([
Decoders\StringColorDecoder::class,
]) extends AbstractInputHandler
{
})->handle($input);
]))->handle($input);
}
/**

View File

@@ -9,7 +9,7 @@ use Intervention\Image\Colors\Hsl\Channels\Hue;
use Intervention\Image\Colors\Hsl\Channels\Luminance;
use Intervention\Image\Colors\Hsl\Channels\Saturation;
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\InputHandler;
use Intervention\Image\Interfaces\ColorChannelInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
@@ -43,11 +43,9 @@ class Color extends AbstractColor
*/
public static function create(mixed $input): ColorInterface
{
return (new class ([
return (new InputHandler([
Decoders\StringColorDecoder::class,
]) extends AbstractInputHandler
{
})->handle($input);
]))->handle($input);
}
/**

View File

@@ -9,7 +9,7 @@ use Intervention\Image\Colors\Hsv\Channels\Hue;
use Intervention\Image\Colors\Hsv\Channels\Saturation;
use Intervention\Image\Colors\Hsv\Channels\Value;
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\InputHandler;
use Intervention\Image\Interfaces\ColorChannelInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
@@ -43,11 +43,9 @@ class Color extends AbstractColor
*/
public static function create(mixed $input): ColorInterface
{
return (new class ([
return (new InputHandler([
Decoders\StringColorDecoder::class,
]) extends AbstractInputHandler
{
})->handle($input);
]))->handle($input);
}
/**

View File

@@ -9,7 +9,7 @@ use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Colors\Rgb\Channels\Alpha;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\InputHandler;
use Intervention\Image\Interfaces\ColorChannelInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
@@ -53,14 +53,12 @@ class Color extends AbstractColor
*/
public static function create(mixed $input): ColorInterface
{
return (new class ([
return (new InputHandler([
Decoders\HexColorDecoder::class,
Decoders\StringColorDecoder::class,
Decoders\TransparentColorDecoder::class,
Decoders\HtmlColornameDecoder::class,
]) extends AbstractInputHandler
{
})->handle($input);
]))->handle($input);
}
/**

View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Decoders;
use Intervention\Image\Drivers\SpecializableDecoder;
class ColorObjectDecoder extends SpecializableDecoder
{
}

View File

@@ -6,54 +6,14 @@ namespace Intervention\Image\Drivers;
use Exception;
use Intervention\Image\Collection;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Interfaces\CollectionInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Traits\CanBuildFilePointer;
abstract class AbstractDecoder implements DecoderInterface
{
use CanBuildFilePointer;
public function __construct(protected ?self $successor = null)
{
}
/**
* Try to decode given input to image or color object
*
* @param mixed $input
* @throws RuntimeException
* @return ImageInterface|ColorInterface
*/
final public function handle(mixed $input): ImageInterface|ColorInterface
{
try {
$decoded = $this->decode($input);
} catch (DecoderException $e) {
if (!$this->hasSuccessor()) {
throw new DecoderException($e->getMessage());
}
return $this->successor->handle($input);
}
return $decoded;
}
/**
* Determine if current decoder has a successor
*
* @return bool
*/
protected function hasSuccessor(): bool
{
return $this->successor !== null;
}
/**
* Determine if the given input is GIF data format
*

View File

@@ -6,10 +6,13 @@ namespace Intervention\Image\Drivers;
use Intervention\Image\Exceptions\DriverException;
use Intervention\Image\Exceptions\NotSupportedException;
use Intervention\Image\InputHandler;
use Intervention\Image\Interfaces\AnalyzerInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\EncoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface;
use Intervention\Image\Interfaces\SpecializableInterface;
use Intervention\Image\Interfaces\SpecializedInterface;
@@ -25,6 +28,16 @@ abstract class AbstractDriver implements DriverInterface
$this->checkHealth();
}
/**
* {@inheritdoc}
*
* @see DriverInterface::handleInput()
*/
public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface
{
return (new InputHandler($decoders, $this))->handle($input);
}
/**
* {@inheritdoc}
*

View File

@@ -1,71 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Drivers;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\InputHandlerInterface;
abstract class AbstractInputHandler implements InputHandlerInterface
{
/**
* Decoder classnames in hierarchical order
*
* @var array<string|DecoderInterface>
*/
protected array $decoders = [];
/**
* Create new input handler instance with given decoder classnames
*
* @param array<string|DecoderInterface> $decoders
* @return void
*/
public function __construct(array $decoders = [])
{
$this->decoders = count($decoders) ? $decoders : $this->decoders;
}
/**
* {@inheritdoc}
*
* @see InputHandlerInterface::handle()
*/
public function handle($input): ImageInterface|ColorInterface
{
return $this->chain()->handle($input);
}
/**
* Stack the decoder array into a nested decoder object
*
* @throws DecoderException
* @return AbstractDecoder
*/
protected function chain(): AbstractDecoder
{
if (count($this->decoders) == 0) {
throw new DecoderException('No decoders found in ' . $this::class);
}
// get last decoder in stack
list($decoder) = array_slice(array_reverse($this->decoders), 0, 1);
$chain = ($decoder instanceof DecoderInterface) ? $decoder : new $decoder();
// only accept DecoderInterface
if (!($chain instanceof DecoderInterface)) {
throw new DecoderException('Decoder must implement in ' . DecoderInterface::class);
}
// build decoder chain
foreach (array_slice(array_reverse($this->decoders), 1) as $decoder) {
$chain = ($decoder instanceof DecoderInterface) ? new ($decoder::class)($chain) : new $decoder($chain);
}
return $chain;
}
}

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders;
use Intervention\Image\Drivers\AbstractDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders;
use Intervention\Image\Drivers\AbstractDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;

View File

@@ -11,7 +11,6 @@ use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Format;
use Intervention\Image\FileExtension;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorProcessorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
use Intervention\Image\Interfaces\DriverInterface;
@@ -113,16 +112,6 @@ class Driver extends AbstractDriver
return call_user_func($animation);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::handleInput()
*/
public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface
{
return (new InputHandler($this->specializeMultiple($decoders)))->handle($input);
}
/**
* {@inheritdoc}
*

View File

@@ -1,50 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd;
use Intervention\Image\Colors\Rgb\Decoders\HexColorDecoder as RgbHexColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
use Intervention\Image\Colors\Hsv\Decoders\StringColorDecoder as HsvStringColorDecoder;
use Intervention\Image\Colors\Hsl\Decoders\StringColorDecoder as HslStringColorDecoder;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\Drivers\Gd\Decoders\ImageObjectDecoder;
use Intervention\Image\Drivers\Gd\Decoders\ColorObjectDecoder;
use Intervention\Image\Drivers\Gd\Decoders\FilePointerImageDecoder;
use Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Gd\Decoders\BinaryImageDecoder;
use Intervention\Image\Drivers\Gd\Decoders\DataUriImageDecoder;
use Intervention\Image\Drivers\Gd\Decoders\Base64ImageDecoder;
use Intervention\Image\Drivers\Gd\Decoders\NativeObjectDecoder;
use Intervention\Image\Drivers\Gd\Decoders\SplFileInfoImageDecoder;
class InputHandler extends AbstractInputHandler
{
/**
* Decoders in hierarchical order
*
* @var array<string>
*/
protected array $decoders = [
NativeObjectDecoder::class,
ImageObjectDecoder::class,
ColorObjectDecoder::class,
RgbHexColorDecoder::class,
RgbStringColorDecoder::class,
CmykStringColorDecoder::class,
HsvStringColorDecoder::class,
HslStringColorDecoder::class,
TransparentColorDecoder::class,
HtmlColornameDecoder::class,
FilePointerImageDecoder::class,
FilePathImageDecoder::class,
SplFileInfoImageDecoder::class,
BinaryImageDecoder::class,
DataUriImageDecoder::class,
Base64ImageDecoder::class,
];
}

View File

@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Imagick\Decoders;
use Intervention\Image\Drivers\AbstractDecoder;
use Intervention\Image\Drivers\SpecializableDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface;
class ColorObjectDecoder extends AbstractDecoder
class ColorObjectDecoder extends SpecializableDecoder
{
public function decode(mixed $input): ImageInterface|ColorInterface
{

View File

@@ -13,7 +13,6 @@ use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Format;
use Intervention\Image\FileExtension;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorProcessorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface;
use Intervention\Image\Interfaces\DriverInterface;
@@ -116,16 +115,6 @@ class Driver extends AbstractDriver
return call_user_func($animation);
}
/**
* {@inheritdoc}
*
* @see DriverInterface::handleInput()
*/
public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface
{
return (new InputHandler($this->specializeMultiple($decoders)))->handle($input);
}
/**
* {@inheritdoc}
*

View File

@@ -1,50 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Drivers\Imagick;
use Intervention\Image\Colors\Rgb\Decoders\HexColorDecoder as RgbHexColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
use Intervention\Image\Colors\Hsv\Decoders\StringColorDecoder as HsvStringColorDecoder;
use Intervention\Image\Colors\Hsl\Decoders\StringColorDecoder as HslStringColorDecoder;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\Drivers\Imagick\Decoders\ImageObjectDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\ColorObjectDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\FilePointerImageDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\FilePathImageDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\BinaryImageDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\DataUriImageDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\Base64ImageDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\NativeObjectDecoder;
use Intervention\Image\Drivers\Imagick\Decoders\SplFileInfoImageDecoder;
class InputHandler extends AbstractInputHandler
{
/**
* Decoders in hierarchical order
*
* @var array<string>
*/
protected array $decoders = [
NativeObjectDecoder::class,
ImageObjectDecoder::class,
ColorObjectDecoder::class,
RgbHexColorDecoder::class,
RgbStringColorDecoder::class,
CmykStringColorDecoder::class,
HsvStringColorDecoder::class,
HslStringColorDecoder::class,
TransparentColorDecoder::class,
HtmlColornameDecoder::class,
FilePointerImageDecoder::class,
FilePathImageDecoder::class,
SplFileInfoImageDecoder::class,
BinaryImageDecoder::class,
DataUriImageDecoder::class,
Base64ImageDecoder::class,
];
}

112
src/InputHandler.php Normal file
View File

@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
namespace Intervention\Image;
use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder;
use Intervention\Image\Colors\Hsl\Decoders\StringColorDecoder as HslStringColorDecoder;
use Intervention\Image\Colors\Hsv\Decoders\StringColorDecoder as HsvStringColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\HexColorDecoder as RgbHexColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder;
use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorDecoder;
use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder;
use Intervention\Image\Decoders\Base64ImageDecoder;
use Intervention\Image\Decoders\BinaryImageDecoder;
use Intervention\Image\Decoders\ColorObjectDecoder;
use Intervention\Image\Decoders\DataUriImageDecoder;
use Intervention\Image\Decoders\FilePathImageDecoder;
use Intervention\Image\Decoders\FilePointerImageDecoder;
use Intervention\Image\Decoders\ImageObjectDecoder;
use Intervention\Image\Decoders\SplFileInfoImageDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Exceptions\NotSupportedException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\DriverInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\InputHandlerInterface;
class InputHandler implements InputHandlerInterface
{
/**
* Decoder classnames in hierarchical order
*
* @var array<string|DecoderInterface>
*/
protected array $decoders = [
// NativeObjectDecoder::class,
ImageObjectDecoder::class,
ColorObjectDecoder::class,
RgbHexColorDecoder::class,
RgbStringColorDecoder::class,
CmykStringColorDecoder::class,
HsvStringColorDecoder::class,
HslStringColorDecoder::class,
TransparentColorDecoder::class,
HtmlColornameDecoder::class,
FilePointerImageDecoder::class,
FilePathImageDecoder::class,
SplFileInfoImageDecoder::class,
BinaryImageDecoder::class,
DataUriImageDecoder::class,
Base64ImageDecoder::class,
];
/**
* Driver with which the decoder classes are specialized
*
* @var null|DriverInterface
*/
protected ?DriverInterface $driver = null;
/**
* Create new input handler instance with given decoder classnames
*
* @param DriverInterface $driver
* @param array<string|DecoderInterface> $decoders
* @return void
*/
public function __construct(array $decoders = [], ?DriverInterface $driver = null)
{
$this->decoders = count($decoders) ? $decoders : $this->decoders;
$this->driver = $driver;
}
/**
* {@inheritdoc}
*
* @see InputHandlerInterface::handle()
*/
public function handle($input): ImageInterface|ColorInterface
{
foreach ($this->decoders as $decoderClassname) {
// resolve river specialized decoder
$decoder = $this->resolve($decoderClassname);
try {
return $decoder->decode($input);
} catch (DecoderException $e) {
// let next decoder try
}
}
throw new DecoderException(isset($e) ? $e->getMessage() : '');
}
/**
* Resolve the given classname to an decoder object
*
* @param string|DecoderInterface $decoder
* @return DecoderInterface
* @throws NotSupportedException
*/
private function resolve(string|DecoderInterface $decoder): DecoderInterface
{
if (empty($this->driver)) {
return new $decoder();
}
return $this->driver->specialize(new $decoder());
}
}

View File

@@ -14,7 +14,7 @@ abstract class GdTestCase extends BaseTestCase
{
public function readTestImage($filename = 'test.jpg'): Image
{
return (new FilePathImageDecoder())->handle(
return (new FilePathImageDecoder())->decode(
$this->getTestResourcePath($filename)
);
}

View File

@@ -15,7 +15,7 @@ abstract class ImagickTestCase extends BaseTestCase
{
public function readTestImage($filename = 'test.jpg'): Image
{
return (new FilePathImageDecoder())->handle(
return (new FilePathImageDecoder())->decode(
$this->getTestResourcePath($filename)
);
}

View File

@@ -7,7 +7,6 @@ namespace Intervention\Image\Tests\Unit\Drivers;
use PHPUnit\Framework\Attributes\CoversClass;
use Exception;
use Intervention\Image\Drivers\AbstractDecoder;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\CollectionInterface;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface;
@@ -18,35 +17,6 @@ use stdClass;
#[CoversClass(\Intervention\Image\Drivers\AbstractDecoder::class)]
final class AbstractDecoderTest extends BaseTestCase
{
public function testHandle(): void
{
$result = Mockery::mock(ColorInterface::class);
$decoder = Mockery::mock(AbstractDecoder::class);
$decoder->shouldReceive('decode')->with('test input')->andReturn($result);
$decoder->handle('test input');
}
public function testHandleFail(): void
{
$decoder = Mockery::mock(AbstractDecoder::class, []);
$decoder->shouldReceive('decode')->with('test input')->andThrow(DecoderException::class);
$this->expectException(DecoderException::class);
$decoder->handle('test input');
}
public function testHandleFailWithSuccessor(): void
{
$result = Mockery::mock(ColorInterface::class);
$successor = Mockery::mock(AbstractDecoder::class);
$successor->shouldReceive('decode')->with('test input')->andReturn($result);
$decoder = Mockery::mock(
AbstractDecoder::class,
[$successor]
);
$decoder->shouldReceive('decode')->with('test input')->andThrow(DecoderException::class);
$decoder->handle('test input');
}
public function testIsGifFormat(): void
{
$decoder = Mockery::mock(AbstractDecoder::class);

View File

@@ -1,55 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Tests\Unit\Drivers;
use PHPUnit\Framework\Attributes\CoversClass;
use Intervention\Image\Drivers\AbstractDecoder;
use Intervention\Image\Drivers\AbstractInputHandler;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Tests\BaseTestCase;
use Mockery;
#[CoversClass(\Intervention\Image\Drivers\AbstractInputHandler::class)]
final class AbstractInputHandlerTest extends BaseTestCase
{
public function testHandle(): void
{
$image = Mockery::mock(ImageInterface::class);
$chain = Mockery::mock(AbstractDecoder::class);
$chain->shouldReceive('handle')->with('test image')->andReturn($image);
$chain->shouldReceive('decode')->with('test image')->andReturn(Mockery::mock(ImageInterface::class));
$modifier = $this->getModifier($chain);
$modifier->handle('test image');
}
public function testChainNoItems(): void
{
$handler = new class () extends AbstractInputHandler
{
};
$this->expectException(DecoderException::class);
$handler->handle('test');
}
private function getModifier(AbstractDecoder $chain): AbstractInputHandler
{
return new class ([$chain]) extends AbstractInputHandler
{
public function __construct(protected array $decoders = [])
{
//
}
protected function chain(): AbstractDecoder
{
return $this->decoders[0];
}
};
}
}

View File

@@ -1,153 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Tests\Unit\Drivers\Gd;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
use Intervention\Image\Colors\Hsv\Color as HsvColor;
use Intervention\Image\Colors\Rgb\Color as RgbColor;
use Intervention\Image\Image;
use Intervention\Image\Drivers\Gd\InputHandler;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Tests\BaseTestCase;
use SplFileInfo;
#[RequiresPhpExtension('gd')]
#[CoversClass(\Intervention\Image\Drivers\Gd\InputHandler::class)]
final class InputHandlerTest extends BaseTestCase
{
public function testHandleEmptyString(): void
{
$handler = new InputHandler();
$this->expectException(DecoderException::class);
$handler->handle('');
}
public function testHandleBinaryImage(): void
{
$handler = new InputHandler();
$input = file_get_contents($this->getTestResourcePath('test.jpg'));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleGdImage(): void
{
$handler = new InputHandler();
$result = $handler->handle(imagecreatetruecolor(3, 2));
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleSplFileInfo(): void
{
$handler = new InputHandler();
$input = new SplFileInfo($this->getTestResourcePath('test.jpg'));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleFilePathImage(): void
{
$handler = new InputHandler();
$input = $this->getTestResourcePath('animation.gif');
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleBase64Image(): void
{
$handler = new InputHandler();
$input = base64_encode(file_get_contents($this->getTestResourcePath('animation.gif')));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleDataUriImage(): void
{
$handler = new InputHandler();
$input = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNb' .
'yblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleHexColor(): void
{
$handler = new InputHandler();
$input = 'ccff33';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([204, 255, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = 'cf3';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([204, 255, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = '#123456';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([18, 52, 86, 255], $result->toArray());
$handler = new InputHandler();
$input = '#333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = '#3333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 51], $result->toArray());
$handler = new InputHandler();
$input = '#33333333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 51], $result->toArray());
}
public function testHandleRgbString(): void
{
$handler = new InputHandler();
$result = $handler->handle('rgb(10, 20, 30)');
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([10, 20, 30, 255], $result->toArray());
$handler = new InputHandler();
$result = $handler->handle('rgba(10, 20, 30, 1.0)');
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([10, 20, 30, 255], $result->toArray());
}
public function testHandleHsvString(): void
{
$handler = new InputHandler();
$result = $handler->handle('hsv(10, 20, 30)');
$this->assertInstanceOf(HsvColor::class, $result);
$this->assertEquals([10, 20, 30], $result->toArray());
}
public function testHandleCmykString(): void
{
$handler = new InputHandler();
$result = $handler->handle('cmyk(10, 20, 30, 40)');
$this->assertInstanceOf(CmykColor::class, $result);
$this->assertEquals([10, 20, 30, 40], $result->toArray());
}
public function testHandleTransparent(): void
{
$handler = new InputHandler();
$input = 'transparent';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([255, 255, 255, 0], $result->toArray());
}
}

View File

@@ -1,157 +0,0 @@
<?php
declare(strict_types=1);
namespace Intervention\Image\Tests\Unit\Drivers\Imagick;
use Imagick;
use ImagickPixel;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
use Intervention\Image\Colors\Hsv\Color as HsvColor;
use Intervention\Image\Colors\Rgb\Color as RgbColor;
use Intervention\Image\Drivers\Imagick\InputHandler;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Image;
use Intervention\Image\Tests\BaseTestCase;
use SplFileInfo;
#[RequiresPhpExtension('imagick')]
#[CoversClass(\Intervention\Image\Drivers\Imagick\InputHandler::class)]
final class InputHandlerTest extends BaseTestCase
{
public function testHandleEmptyString(): void
{
$handler = new InputHandler();
$this->expectException(DecoderException::class);
$handler->handle('');
}
public function testHandleBinaryImage(): void
{
$handler = new InputHandler();
$input = file_get_contents($this->getTestResourcePath('animation.gif'));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleImagick(): void
{
$imagick = new Imagick();
$imagick->newImage(3, 2, new ImagickPixel('rgba(255, 255, 255, 255)'), 'png');
$handler = new InputHandler();
$result = $handler->handle($imagick);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleSplFileInfo(): void
{
$handler = new InputHandler();
$input = new SplFileInfo($this->getTestResourcePath('test.jpg'));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleFilePathImage(): void
{
$handler = new InputHandler();
$input = $this->getTestResourcePath('animation.gif');
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleBase64Image(): void
{
$handler = new InputHandler();
$input = base64_encode(file_get_contents($this->getTestResourcePath('animation.gif')));
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleDataUriImage(): void
{
$handler = new InputHandler();
$input = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACN' .
'byblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
$result = $handler->handle($input);
$this->assertInstanceOf(Image::class, $result);
}
public function testHandleHexColor(): void
{
$handler = new InputHandler();
$input = 'ccff33';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([204, 255, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = 'cf3';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([204, 255, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = '#123456';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([18, 52, 86, 255], $result->toArray());
$handler = new InputHandler();
$input = '#333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 255], $result->toArray());
$handler = new InputHandler();
$input = '#3333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 51], $result->toArray());
$handler = new InputHandler();
$input = '#33333333';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([51, 51, 51, 51], $result->toArray());
}
public function testHandleRgbString(): void
{
$handler = new InputHandler();
$result = $handler->handle('rgb(10, 20, 30)');
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([10, 20, 30, 255], $result->toArray());
$handler = new InputHandler();
$result = $handler->handle('rgba(10, 20, 30, 1.0)');
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([10, 20, 30, 255], $result->toArray());
}
public function testHandleCmykString(): void
{
$handler = new InputHandler();
$result = $handler->handle('cmyk(10, 20, 30, 40)');
$this->assertInstanceOf(CmykColor::class, $result);
$this->assertEquals([10, 20, 30, 40], $result->toArray());
}
public function testHandleHsvString(): void
{
$handler = new InputHandler();
$result = $handler->handle('hsv(10, 20, 30)');
$this->assertInstanceOf(HsvColor::class, $result);
$this->assertEquals([10, 20, 30], $result->toArray());
}
public function testHandleTransparent(): void
{
$handler = new InputHandler();
$input = 'transparent';
$result = $handler->handle($input);
$this->assertInstanceOf(RgbColor::class, $result);
$this->assertEquals([255, 255, 255, 0], $result->toArray());
}
}