From f031c026ef9843b2f2ff59f840beaa2fcc23a44c Mon Sep 17 00:00:00 2001 From: Gwendolen Lynch Date: Thu, 23 Dec 2021 07:04:00 +0100 Subject: [PATCH] Add & update abstract class tests --- .../Abstract}/AbstractImageTest.php | 240 +++++++++++++++++- .../Abstract/AbstractInputHandlerTest.php | 44 ++++ .../Abstract/Decoders/AbstractDecoderTest.php | 46 ++++ .../Abstract/Encoders/AbstractEncoderTest.php | 48 ++++ .../Modifiers/AbstractFitModifierTest.php | 66 +++++ .../Modifiers/AbstractPadModifierTest.php | 67 +++++ .../Modifiers/AbstractRotateModifierTest.php | 80 ++++++ 7 files changed, 590 insertions(+), 1 deletion(-) rename tests/{ => Drivers/Abstract}/AbstractImageTest.php (51%) create mode 100644 tests/Drivers/Abstract/AbstractInputHandlerTest.php create mode 100644 tests/Drivers/Abstract/Decoders/AbstractDecoderTest.php create mode 100644 tests/Drivers/Abstract/Encoders/AbstractEncoderTest.php create mode 100644 tests/Drivers/Abstract/Modifiers/AbstractFitModifierTest.php create mode 100644 tests/Drivers/Abstract/Modifiers/AbstractPadModifierTest.php create mode 100644 tests/Drivers/Abstract/Modifiers/AbstractRotateModifierTest.php diff --git a/tests/AbstractImageTest.php b/tests/Drivers/Abstract/AbstractImageTest.php similarity index 51% rename from tests/AbstractImageTest.php rename to tests/Drivers/Abstract/AbstractImageTest.php index 340d0c23..bac5df9e 100644 --- a/tests/AbstractImageTest.php +++ b/tests/Drivers/Abstract/AbstractImageTest.php @@ -1,6 +1,6 @@ assertEquals(200, $img->getSize()->getHeight()); } + public function testSizeAlias(): void + { + $img = $this->abstractImageMock(); + $this->assertInstanceOf(Size::class, $img->getSize()); + $this->assertEquals(300, $img->size()->getWidth()); + $this->assertEquals(200, $img->size()->getHeight()); + } + public function testIsAnimated(): void { $img = Mockery::mock(AbstractImage::class, [new Collection()])->makePartial(); @@ -186,6 +195,51 @@ class AbstractImageTest extends TestCase $this->assertInstanceOf(ImageInterface::class, $result); } + public function testInvert(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\InvertModifier') + ->andReturn($modifier); + + $result = $img->invert(); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testBrightness(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\BrightnessModifier', 5) + ->andReturn($modifier); + + $result = $img->brightness(5); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testContrast(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\ContrastModifier', 5) + ->andReturn($modifier); + + $result = $img->contrast(5); + $this->assertInstanceOf(ImageInterface::class, $result); + } + public function testBlur(): void { $img = $this->abstractImageMock(); @@ -231,6 +285,56 @@ class AbstractImageTest extends TestCase $this->assertInstanceOf(ImageInterface::class, $result); } + public function testFill(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $color = Mockery::mock(ColorInterface::class); + + $img->shouldReceive('handleInput') + ->with('abcdef') + ->andReturn($color); + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\FillModifier', $color, null) + ->andReturn($modifier); + + $result = $img->fill('abcdef'); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testPixelate(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\PixelateModifier', 42) + ->andReturn($modifier); + + $result = $img->pixelate(42); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testSharpen(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\SharpenModifier', 7) + ->andReturn($modifier); + + $result = $img->sharpen(7); + $this->assertInstanceOf(ImageInterface::class, $result); + } + public function testPickColors(): void { $color = Mockery::mock(ColorInterface::class); @@ -239,4 +343,138 @@ class AbstractImageTest extends TestCase $result = $img->pickColors(1, 2); $this->assertInstanceOf(Collection::class, $result); } + + public function testResize(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\ResizeModifier', 200, 100) + ->andReturn($modifier); + + $result = $img->resize(200, 100); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testResizeDown(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\ResizeDownModifier', 200, 100) + ->andReturn($modifier); + + $result = $img->resizeDown(200, 100); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testScale(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\ScaleModifier', 200, 100) + ->andReturn($modifier); + + $result = $img->scale(200, 100); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testScaleDown(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\ScaleDownModifier', 200, 100) + ->andReturn($modifier); + + $result = $img->scaleDown(200, 100); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testFit(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\FitModifier', 200, 100, 'center') + ->andReturn($modifier); + + $result = $img->fit(200, 100, 'center'); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testFitDown(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\FitDownModifier', 200, 100, 'center') + ->andReturn($modifier); + + $result = $img->fitDown(200, 100, 'center'); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testPad(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\PadModifier', 200, 100, 'ffffff', 'center') + ->andReturn($modifier); + + $result = $img->pad(200, 100, 'ffffff', 'center'); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testPadDown(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\PadDownModifier', 200, 100, 'ffffff', 'center') + ->andReturn($modifier); + + $result = $img->padDown(200, 100, 'ffffff', 'center'); + $this->assertInstanceOf(ImageInterface::class, $result); + } + + public function testDestroy(): void + { + $img = $this->abstractImageMock(); + + $modifier = Mockery::mock(ModifierInterface::class); + $modifier->shouldReceive('apply')->with($img)->andReturn($img); + + $img->shouldReceive('resolveDriverClass') + ->with('Modifiers\DestroyModifier') + ->andReturn($modifier); + + $img->destroy(); + } } diff --git a/tests/Drivers/Abstract/AbstractInputHandlerTest.php b/tests/Drivers/Abstract/AbstractInputHandlerTest.php new file mode 100644 index 00000000..ee40bb97 --- /dev/null +++ b/tests/Drivers/Abstract/AbstractInputHandlerTest.php @@ -0,0 +1,44 @@ +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'); + } + + private function getModifier(AbstractDecoder $chain): AbstractInputHandler + { + return new class ($chain) extends AbstractInputHandler { + public function __construct(private AbstractDecoder $chain) + { + // + } + + protected function chain(): AbstractDecoder + { + return $this->chain; + } + }; + } +} diff --git a/tests/Drivers/Abstract/Decoders/AbstractDecoderTest.php b/tests/Drivers/Abstract/Decoders/AbstractDecoderTest.php new file mode 100644 index 00000000..157c3474 --- /dev/null +++ b/tests/Drivers/Abstract/Decoders/AbstractDecoderTest.php @@ -0,0 +1,46 @@ +makePartial(); + $decoder->shouldReceive('decode')->with('input string')->andReturn(null); + + $decoder->handle('input string'); + } + + public function testHandleFail(): void + { + $decoder = Mockery::mock(AbstractDecoder::class, [])->makePartial()->shouldAllowMockingProtectedMethods(); + $decoder->shouldReceive('decode')->with('input string')->andThrow(DecoderException::class); + + $this->expectException(DecoderException::class); + $this->expectExceptionMessage('Unable to decode given input.'); + + $decoder->handle('input string'); + } + + public function testHandleFailWithSuccessor(): void + { + $successor = Mockery::mock(AbstractDecoder::class)->makePartial(); + $successor->shouldReceive('decode')->with('input string')->andReturn(null); + + $decoder = Mockery::mock(AbstractDecoder::class, [$successor])->makePartial()->shouldAllowMockingProtectedMethods(); + $decoder->shouldReceive('decode')->with('input string')->andThrow(DecoderException::class); + + $decoder->handle('input string'); + } +} diff --git a/tests/Drivers/Abstract/Encoders/AbstractEncoderTest.php b/tests/Drivers/Abstract/Encoders/AbstractEncoderTest.php new file mode 100644 index 00000000..09626609 --- /dev/null +++ b/tests/Drivers/Abstract/Encoders/AbstractEncoderTest.php @@ -0,0 +1,48 @@ +getAbstractEncoder()->getBuffered($callback)); + } + + public function testSetGetQuality(): void + { + $encoder = $this->getAbstractEncoder(); + $encoder->setQuality(55); + + static::assertSame(55, $encoder->getQuality()); + } + + private function getAbstractEncoder(): AbstractEncoder + { + return new class () extends AbstractEncoder implements EncoderInterface { + public function getBuffered(callable $callback): string + { + return parent::getBuffered($callback); + } + + public function encode(ImageInterface $image): EncodedImage + { + } + }; + } +} diff --git a/tests/Drivers/Abstract/Modifiers/AbstractFitModifierTest.php b/tests/Drivers/Abstract/Modifiers/AbstractFitModifierTest.php new file mode 100644 index 00000000..f8678f96 --- /dev/null +++ b/tests/Drivers/Abstract/Modifiers/AbstractFitModifierTest.php @@ -0,0 +1,66 @@ + [150, 100, 50, 100, 50, 0]; + yield '100x150' => [100, 150, 75, 150, 13, 0]; + } + + /** @dataProvider providerCropSize */ + public function testGetCropSize(int $width, int $height, int $expectedWidth, int $expectedHeight, int $expectedX, int $expectedY): void + { + $modifier = $this->getModifier(100, 200, 'center'); + + $image = (new ImageFactory())->newImage($width, $height); + $size = $modifier->getCropSize($image); + + static::assertSame($expectedWidth, $size->getWidth()); + static::assertSame($expectedHeight, $size->getHeight()); + static::assertSame($expectedX, $size->getPivot()->getX()); + static::assertSame($expectedY, $size->getPivot()->getY()); + } + + public function testGetResizeSize(): void + { + $modifier = $this->getModifier(200, 100, 'center'); + + $image = (new ImageFactory())->newImage(300, 200); + $size = $modifier->getCropSize($image); + $resize = $modifier->getResizeSize($size); + + static::assertSame(200, $resize->getWidth()); + static::assertSame(100, $resize->getHeight()); + static::assertSame(0, $resize->getPivot()->getX()); + static::assertSame(0, $resize->getPivot()->getY()); + } + + private function getModifier(int $width, int $height, string $position): AbstractFitModifier + { + return new class ($width, $height, $position) extends AbstractFitModifier { + public function getCropSize(ImageInterface $image): SizeInterface + { + return parent::getCropSize($image); + } + + public function getResizeSize(SizeInterface $size): SizeInterface + { + return parent::getResizeSize($size); + } + }; + } +} diff --git a/tests/Drivers/Abstract/Modifiers/AbstractPadModifierTest.php b/tests/Drivers/Abstract/Modifiers/AbstractPadModifierTest.php new file mode 100644 index 00000000..4308a3bf --- /dev/null +++ b/tests/Drivers/Abstract/Modifiers/AbstractPadModifierTest.php @@ -0,0 +1,67 @@ + [150, 100, 100, 67, 0, 67]; + yield '100x150' => [100, 150, 100, 150, 0, 25]; + } + + /** @dataProvider providerCropSize */ + public function testGetCropSize(int $width, int $height, int $expectedWidth, int $expectedHeight, int $expectedX, int $expectedY): void + { + $modifier = $this->getModifier(100, 200, 'ffffff', 'center'); + + $image = (new ImageFactory())->newImage($width, $height); + $size = $modifier->getCropSize($image); + + static::assertSame($expectedWidth, $size->getWidth()); + static::assertSame($expectedHeight, $size->getHeight()); + static::assertSame($expectedX, $size->getPivot()->getX()); + static::assertSame($expectedY, $size->getPivot()->getY()); + } + + public function testGetResizeSize(): void + { + $modifier = $this->getModifier(200, 100, 'ffffff', 'center'); + + $image = (new ImageFactory())->newImage(300, 200); + $resize = $modifier->getResizeSize($image); + + static::assertSame(200, $resize->getWidth()); + static::assertSame(100, $resize->getHeight()); + static::assertSame(0, $resize->getPivot()->getX()); + static::assertSame(0, $resize->getPivot()->getY()); + } + + private function getModifier(int $width, int $height, $background, string $position): AbstractPadModifier + { + return new class($width, $height, $background, $position) extends AbstractPadModifier { + public function getCropSize(ImageInterface $image): SizeInterface + { + return parent::getCropSize($image); + } + + public function getResizeSize(ImageInterface $image): SizeInterface + { + return parent::getResizeSize($image); + } + }; + } +} diff --git a/tests/Drivers/Abstract/Modifiers/AbstractRotateModifierTest.php b/tests/Drivers/Abstract/Modifiers/AbstractRotateModifierTest.php new file mode 100644 index 00000000..42de945b --- /dev/null +++ b/tests/Drivers/Abstract/Modifiers/AbstractRotateModifierTest.php @@ -0,0 +1,80 @@ + [0.0, 0]; + yield '90 degrees' => [90.0, 90]; + yield '180 degrees' => [180.0, 180]; + yield '270 degrees' => [270.0, 270]; + yield '360 degrees' => [0.0, 360]; + } + + /** @dataProvider providerRotationAngle */ + public function testRotationAngle(float $expected, int $angle): void + { + $modifier = $this->getModifier($angle, 'abcdef'); + + static::assertSame($expected, $modifier->rotationAngle()); + } + + public function testBackgroundColor(): void + { + $modifier = $this->getModifier(90, 'abcdef'); + $color = $modifier->backgroundColor(); + + static::assertSame(255, $color->red()); + } + + public function testBackgroundColorInvalidValueThrowsException(): void + { + $this->expectException(TypeException::class); + $this->expectExceptionMessage('Argument #2 must be a color value'); + + $modifier = $this->getModifier(90, 'bad value'); + $modifier->backgroundColor(); + } + + private function getModifier(float $angle, $background): AbstractRotateModifier + { + return new class ($angle, $background) extends AbstractRotateModifier { + public function rotationAngle(): float + { + return parent::rotationAngle(); + } + + public function backgroundColor(): ColorInterface + { + return parent::backgroundColor(); + } + + public function handleInput($input): ImageInterface|ColorInterface + { + if ($this->background === 'bad value') { + throw new DecoderException(); + } + + $color = Mockery::mock(ColorInterface::class); + $color->shouldReceive('red')->andReturn(255); + + return $color; + } + }; + } +}