From 2d2a00fabb7979d5aef779c68f6db7c99d317814 Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 26 Nov 2023 18:42:45 +0100 Subject: [PATCH] :fire: v6.0 third pass: test clean-up (again) --- phpunit.xml.dist | 2 + tests/Common/BitBufferTest.php | 8 +- tests/Common/ECICharsetTest.php | 2 +- tests/Common/EccLevelTest.php | 3 +- tests/Common/MaskPatternTest.php | 4 +- tests/Common/ModeTest.php | 2 +- tests/Common/VersionTest.php | 3 +- tests/Data/AlphaNumTest.php | 8 +- tests/Data/ByteTest.php | 8 +- tests/Data/DataInterfaceTestAbstract.php | 75 +++++++------------ tests/Data/ECITest.php | 21 +++--- tests/Data/HanziTest.php | 20 +++-- tests/Data/KanjiTest.php | 26 +++++-- tests/Data/NumberTest.php | 8 +- tests/Data/QRDataTest.php | 4 +- tests/Data/QRMatrixTest.php | 71 +----------------- tests/Output/QREpsTest.php | 15 +++- tests/Output/QRFpdfTest.php | 20 +++-- tests/Output/QRGdImageBMPTest.php | 12 ++- tests/Output/QRGdImageGIFTest.php | 12 ++- tests/Output/QRGdImageJPGTest.php | 12 ++- tests/Output/QRGdImagePNGTest.php | 12 ++- tests/Output/QRGdImageTestAbstract.php | 7 +- tests/Output/QRGdImageWEBPTest.php | 12 ++- tests/Output/QRImagickTest.php | 18 +++-- tests/Output/QRMarkupHTMLTest.php | 12 ++- tests/Output/QRMarkupSVGTest.php | 12 ++- tests/Output/QRMarkupTestAbstract.php | 2 +- tests/Output/QROutputTestAbstract.php | 40 +++++----- tests/Output/QRStringJSONTest.php | 14 +++- tests/Output/QRStringTEXTTest.php | 13 +++- tests/QRCodeReaderGDTest.php | 11 ++- tests/QRCodeReaderImagickTest.php | 24 +++--- tests/QRCodeReaderTestAbstract.php | 29 +++++--- tests/QRCodeTest.php | 5 +- tests/QRMatrixDebugTrait.php | 94 ++++++++++++++++++++++++ tests/QROptionsTest.php | 6 +- 37 files changed, 398 insertions(+), 249 deletions(-) create mode 100644 tests/QRMatrixDebugTrait.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a6ecbeeb9..fd27313f4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -37,5 +37,7 @@ + + diff --git a/tests/Common/BitBufferTest.php b/tests/Common/BitBufferTest.php index 0b720040b..7a38d1e5b 100644 --- a/tests/Common/BitBufferTest.php +++ b/tests/Common/BitBufferTest.php @@ -10,8 +10,8 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\{BitBuffer, Mode}; use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\Common\{BitBuffer, Mode}; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; @@ -32,13 +32,15 @@ final class BitBufferTest extends TestCase{ 'alphanum' => [Mode::ALPHANUM, 32], 'byte' => [Mode::BYTE, 64], 'kanji' => [Mode::KANJI, 128], + 'hanzi' => [Mode::HANZI, 208], ]; } #[DataProvider('bitProvider')] - public function testPut(int $data, int $value):void{ + public function testPut(int $data, int $expected):void{ $this->bitBuffer->put($data, 4); - $this::assertSame($value, $this->bitBuffer->getBuffer()[0]); + + $this::assertSame($expected, $this->bitBuffer->getBuffer()[0]); $this::assertSame(4, $this->bitBuffer->getLength()); } diff --git a/tests/Common/ECICharsetTest.php b/tests/Common/ECICharsetTest.php index d936c183b..6046c093e 100644 --- a/tests/Common/ECICharsetTest.php +++ b/tests/Common/ECICharsetTest.php @@ -10,8 +10,8 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\ECICharset; use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\Common\ECICharset; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Common/EccLevelTest.php b/tests/Common/EccLevelTest.php index 428c84266..eec7422ad 100644 --- a/tests/Common/EccLevelTest.php +++ b/tests/Common/EccLevelTest.php @@ -10,9 +10,8 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\EccLevel; -use chillerlan\QRCode\Common\MaskPattern; use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\Common\{EccLevel, MaskPattern}; use PHPUnit\Framework\TestCase; /** diff --git a/tests/Common/MaskPatternTest.php b/tests/Common/MaskPatternTest.php index ba3363155..07bdf7981 100644 --- a/tests/Common/MaskPatternTest.php +++ b/tests/Common/MaskPatternTest.php @@ -13,11 +13,11 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\MaskPattern; use chillerlan\QRCode\QRCodeException; -use Closure; +use chillerlan\QRCode\Common\MaskPattern; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Closure; /** * @see https://github.com/zxing/zxing/blob/f4f3c2971dc794346d8b6e14752200008cb90716/core/src/test/java/com/google/zxing/qrcode/encoder/MaskUtilTestCase.java diff --git a/tests/Common/ModeTest.php b/tests/Common/ModeTest.php index c478d72de..3e7b2f211 100644 --- a/tests/Common/ModeTest.php +++ b/tests/Common/ModeTest.php @@ -10,8 +10,8 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\Mode; use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\Common\Mode; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Common/VersionTest.php b/tests/Common/VersionTest.php index a30c5d78a..3b6196cbc 100644 --- a/tests/Common/VersionTest.php +++ b/tests/Common/VersionTest.php @@ -10,9 +10,8 @@ namespace chillerlan\QRCodeTest\Common; -use chillerlan\QRCode\Common\EccLevel; -use chillerlan\QRCode\Common\Version; use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\Common\{EccLevel, Version}; use PHPUnit\Framework\TestCase; /** diff --git a/tests/Data/AlphaNumTest.php b/tests/Data/AlphaNumTest.php index 7a2210499..f6c83868d 100644 --- a/tests/Data/AlphaNumTest.php +++ b/tests/Data/AlphaNumTest.php @@ -11,14 +11,18 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\AlphaNum; +use chillerlan\QRCode\Data\QRDataModeInterface; /** * Tests the AlphaNum class */ final class AlphaNumTest extends DataInterfaceTestAbstract{ - protected static string $FQN = AlphaNum::class; - protected static string $testdata = '0 $%*+-./:'; + protected const testData = '0 $%*+-./:'; + + protected static function getDataModeInterface(string $data):QRDataModeInterface{ + return new AlphaNum($data); + } /** * isAlphaNum() should pass on the 45 defined characters and fail on anything else (e.g. lowercase) diff --git a/tests/Data/ByteTest.php b/tests/Data/ByteTest.php index 190288697..4aaf64d0b 100644 --- a/tests/Data/ByteTest.php +++ b/tests/Data/ByteTest.php @@ -11,14 +11,18 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\Byte; +use chillerlan\QRCode\Data\QRDataModeInterface; /** * Tests the Byte class */ final class ByteTest extends DataInterfaceTestAbstract{ - protected static string $FQN = Byte::class; - protected static string $testdata = '[¯\_(ツ)_/¯]'; + protected const testData = '[¯\_(ツ)_/¯]'; + + protected static function getDataModeInterface(string $data):QRDataModeInterface{ + return new Byte($data); + } /** * isByte() passses any binary string and only fails on empty strings diff --git a/tests/Data/DataInterfaceTestAbstract.php b/tests/Data/DataInterfaceTestAbstract.php index 7ce491bdf..58632eecb 100644 --- a/tests/Data/DataInterfaceTestAbstract.php +++ b/tests/Data/DataInterfaceTestAbstract.php @@ -11,21 +11,13 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Mode, Version}; -use PHPUnit\Framework\Attributes\DataProvider; use chillerlan\QRCode\Data\{QRCodeDataException, QRData, QRDataModeInterface, QRMatrix}; use chillerlan\QRCode\QROptions; use chillerlan\QRCodeTest\QRMaxLengthTrait; -use Exception, Generator; +use Exception, Generator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; - -use function array_map; -use function hex2bin; -use function mb_strlen; -use function mb_substr; -use function sprintf; -use function str_repeat; -use function strlen; -use function substr; +use function array_map, hex2bin, mb_strlen, mb_substr, sprintf, str_repeat, strlen, substr; /** * The data interface test abstract @@ -35,26 +27,15 @@ abstract class DataInterfaceTestAbstract extends TestCase{ protected QRData $QRData; protected QRDataModeInterface $dataMode; - protected static string $FQN; - protected static string $testdata; + + protected const testData = ''; protected function setUp():void{ - $this->QRData = new QRData(new QROptions); + $this->QRData = new QRData(new QROptions); + $this->dataMode = static::getDataModeInterface(static::testData); } - /** - * Verifies the QRData instance - */ - public function testInstance():void{ - $this::assertInstanceOf(QRData::class, $this->QRData); - } - - /** - * Verifies the QRDataModeInterface instance - */ - public function testDataModeInstance():void{ - $this::assertInstanceOf(QRDataModeInterface::class, new static::$FQN(static::$testdata)); - } + abstract protected static function getDataModeInterface(string $data):QRDataModeInterface; /** * @return int[][] @@ -70,7 +51,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ public function testInitMatrix(int $pattern):void{ $maskPattern = new MaskPattern($pattern); - $this->QRData->setData([new static::$FQN(static::$testdata)]); + $this->QRData->setData([$this->dataMode]); $matrix = $this->QRData->writeMatrix()->setFormatInfo($maskPattern)->mask($maskPattern); @@ -85,18 +66,16 @@ abstract class DataInterfaceTestAbstract extends TestCase{ */ #[DataProvider('stringValidateProvider')] public function testValidateString(string $string, bool $expected):void{ - /** @noinspection PhpUndefinedMethodInspection */ - $this::assertSame($expected, static::$FQN::validateString($string)); + $this::assertSame($expected, $this->dataMode::validateString($string)); } /** - * Tests if a binary string is properly validated as false + * Tests if a random binary string is properly validated as false * * @see https://github.com/chillerlan/php-qrcode/issues/182 */ public function testBinaryStringInvalid():void{ - /** @noinspection PhpUndefinedMethodInspection */ - $this::assertFalse(static::$FQN::validateString(hex2bin('01015989f47dff8e852122117e04c90b9f15defc1c36477b1fe1'))); + $this::assertFalse($this->dataMode::validateString(hex2bin('01015989f47dff8e852122117e04c90b9f15defc1c36477b1fe1'))); } /** @@ -114,8 +93,6 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $options = new QROptions; $options->version = $version; - // invoke a datamode interface - $this->dataMode = new static::$FQN(static::$testdata); // invoke a QRData instance and write data $this->QRData = new QRData($options, [$this->dataMode]); // get the filled bitbuffer @@ -123,7 +100,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ // read the first 4 bits $this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4)); // decode the data - $this::assertSame(static::$testdata, $this->dataMode::decodeSegment($bitBuffer, $options->version)); + $this::assertSame(static::testData, $this->dataMode::decodeSegment($bitBuffer, $options->version)); } /** @@ -139,15 +116,17 @@ abstract class DataInterfaceTestAbstract extends TestCase{ */ public static function maxLengthProvider():Generator{ $eccLevels = array_map(fn(int $ecc):EccLevel => new EccLevel($ecc), [EccLevel::L, EccLevel::M, EccLevel::Q, EccLevel::H]); - $str = str_repeat(static::$testdata, 1000); - $mb = (static::$FQN::DATAMODE === Mode::KANJI || static::$FQN::DATAMODE === Mode::HANZI); + $str = str_repeat(static::testData, 1000); + /** @phan-suppress-next-line PhanAbstractStaticMethodCallInStatic */ + $dataMode = static::getDataModeInterface(static::testData)::DATAMODE; + $mb = ($dataMode === Mode::KANJI || $dataMode === Mode::HANZI); for($v = 1; $v <= 40; $v++){ $version = new Version($v); foreach($eccLevels as $eccLevel){ // maximum characters per ecc/mode - $len = static::getMaxLengthForMode(static::$FQN::DATAMODE, $version, $eccLevel); + $len = static::getMaxLengthForMode($dataMode, $version, $eccLevel); // a string that contains the maximum amount of characters for the given mode $val = ($mb) ? mb_substr($str, 0, $len) : substr($str, 0, $len); // same as above but character count exceeds @@ -171,8 +150,10 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $options = new QROptions; $options->version = $version->getVersionNumber(); $options->eccLevel = $eccLevel->getLevel(); - $this->dataMode = new static::$FQN($str); + + $this->dataMode = static::getDataModeInterface($str); $this->QRData = new QRData($options, [$this->dataMode]); + $bitBuffer = $this->QRData->getBitBuffer(); $this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4)); @@ -187,8 +168,10 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $options = new QROptions; $options->version = Version::AUTO; $options->eccLevel = $eccLevel->getLevel(); - $this->dataMode = new static::$FQN($str); + + $this->dataMode = static::getDataModeInterface($str); $this->QRData = new QRData($options, [$this->dataMode]); + $bitBuffer = $this->QRData->getBitBuffer(); $this::assertLessThanOrEqual($eccLevel->getMaxBitsForVersion($version), $this->QRData->estimateTotalBitLength()); @@ -214,7 +197,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $options->eccLevel = $eccLevel->getLevel(); /** @phan-suppress-next-line PhanNoopNew */ - new QRData($options, [new static::$FQN($str1)]); + new QRData($options, [static::getDataModeInterface($str1)]); } /** @@ -224,7 +207,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('data exceeds'); - $this->QRData->setData([new static::$FQN(str_repeat(static::$testdata, 1337))]); + $this->QRData->setData([static::getDataModeInterface(str_repeat(static::testData, 1337))]); } /** @@ -234,8 +217,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid data'); - /** @phan-suppress-next-line PhanNoopNew */ - new static::$FQN('##'); + static::getDataModeInterface('##'); } /** @@ -245,8 +227,7 @@ abstract class DataInterfaceTestAbstract extends TestCase{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid data'); - /** @phan-suppress-next-line PhanNoopNew */ - new static::$FQN(''); + static::getDataModeInterface(''); } } diff --git a/tests/Data/ECITest.php b/tests/Data/ECITest.php index f6e8293ca..7130e4f23 100644 --- a/tests/Data/ECITest.php +++ b/tests/Data/ECITest.php @@ -21,9 +21,10 @@ use PHPUnit\Framework\TestCase; */ final class ECITest extends TestCase{ - protected QRData $QRData; - protected string $testdata = '无可奈何燃花作香'; - private int $testCharset = ECICharset::GB18030; + private QRData $QRData; + private int $testCharset = ECICharset::GB18030; + + private const testData = '无可奈何燃花作香'; protected function setUp():void{ $this->QRData = new QRData(new QROptions); @@ -32,11 +33,11 @@ final class ECITest extends TestCase{ private function getDataSegments():array{ return [ new ECI($this->testCharset), - new Byte(mb_convert_encoding($this->testdata, ECICharset::MB_ENCODINGS[$this->testCharset], mb_internal_encoding())), + /** @phan-suppress-next-line PhanParamSuspiciousOrder */ + new Byte(mb_convert_encoding(self::testData, ECICharset::MB_ENCODINGS[$this->testCharset], mb_internal_encoding())), ]; } - /** @inheritDoc */ public function testDataModeInstance():void{ $datamode = new ECI($this->testCharset); @@ -50,9 +51,6 @@ final class ECITest extends TestCase{ return ['1-9' => [7], '10-26' => [15], '27-40' => [30]]; } - /** - * @inheritDoc - */ #[DataProvider('versionBreakpointProvider')] public function testDecodeSegment(int $version):void{ $options = new QROptions; @@ -68,10 +66,9 @@ final class ECITest extends TestCase{ // read the first 4 bits $this::assertSame($segments[0]::DATAMODE, $bitBuffer->read(4)); // decode the data - $this::assertSame($this->testdata, ECI::decodeSegment($bitBuffer, $options->version)); + $this::assertSame(self::testData, ECI::decodeSegment($bitBuffer, $options->version)); } - /** @inheritDoc */ public function testInvalidDataException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid encoding id:'); @@ -82,8 +79,6 @@ final class ECITest extends TestCase{ /** * since the ECI class only accepts integer values, * we'll use this test to check for the upper end of the accepted input range - * - * @inheritDoc */ public function testInvalidDataOnEmptyException():void{ $this->expectException(QRCodeDataException::class); @@ -128,7 +123,9 @@ final class ECITest extends TestCase{ // follow the ECI segment by a non-8bit-byte segment $segments[1] = new Number('1'); $bitBuffer = (new QRData($options, $segments))->getBitBuffer(); + // verify the ECI mode indicator $this::assertSame(Mode::ECI, $bitBuffer->read(4)); + // throw ECI::decodeSegment($bitBuffer, $options->version); } diff --git a/tests/Data/HanziTest.php b/tests/Data/HanziTest.php index 2a03a1bb2..aff1ec462 100644 --- a/tests/Data/HanziTest.php +++ b/tests/Data/HanziTest.php @@ -11,9 +11,10 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\Hanzi; -use Generator, Throwable; +use chillerlan\QRCode\Data\QRDataModeInterface; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; +use Generator, Throwable; use function bin2hex, chr, defined, sprintf; /** @@ -21,8 +22,11 @@ use function bin2hex, chr, defined, sprintf; */ final class HanziTest extends DataInterfaceTestAbstract{ - protected static string $FQN = Hanzi::class; - protected static string $testdata = '无可奈何燃花作香'; + protected const testData = '无可奈何燃花作香'; + + protected static function getDataModeInterface(string $data):QRDataModeInterface{ + return new Hanzi($data); + } /** * isGB2312() should pass on Hanzi/GB2312 characters and fail on everything else @@ -50,9 +54,13 @@ final class HanziTest extends DataInterfaceTestAbstract{ } for($byte2 = 0xa1; $byte2 < 0xff; $byte2++){ - yield sprintf('0x%X', ($byte1 << 8 | $byte2)) => [ - mb_convert_encoding(chr($byte1).chr($byte2), 'UTF-8', Hanzi::ENCODING), - ]; + $chr = mb_convert_encoding(chr($byte1).chr($byte2), 'UTF-8', Hanzi::ENCODING); + + if($chr === '?'){ // skip unknown glyphs + continue; + } + + yield sprintf('0x%X', (($byte1 << 8) | $byte2)) => [$chr]; } } diff --git a/tests/Data/KanjiTest.php b/tests/Data/KanjiTest.php index 9c0cb5c7a..a972dc2a9 100644 --- a/tests/Data/KanjiTest.php +++ b/tests/Data/KanjiTest.php @@ -11,6 +11,7 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\Kanji; +use chillerlan\QRCode\Data\QRDataModeInterface; use Generator, Throwable; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; @@ -21,8 +22,11 @@ use function bin2hex, chr, defined, sprintf; */ final class KanjiTest extends DataInterfaceTestAbstract{ - protected static string $FQN = Kanji::class; - protected static string $testdata = '漂う花の香り'; + protected const testData = '漂う花の香り'; + + protected static function getDataModeInterface(string $data):QRDataModeInterface{ + return new Kanji($data); + } /** * isKanji() should pass on Kanji/SJIS characters and fail on everything else @@ -42,7 +46,7 @@ final class KanjiTest extends DataInterfaceTestAbstract{ * lists the valid SJIS kanji */ public static function kanjiProvider():Generator{ - $key = fn(int $byte1, int $byte2):string => sprintf('0x%X', ($byte1 << 8 | $byte2)); + $key = fn(int $byte1, int $byte2):string => sprintf('0x%X', (($byte1 << 8) | $byte2)); $val = fn(int $byte1, int $byte2):string => mb_convert_encoding(chr($byte1).chr($byte2), 'UTF-8', Kanji::ENCODING); for($byte1 = 0x81; $byte1 < 0xeb; $byte1++){ @@ -61,7 +65,13 @@ final class KanjiTest extends DataInterfaceTestAbstract{ continue; } - yield $key($byte1, $byte2) => [$val($byte1, $byte2)]; + $chr = $val($byte1, $byte2); + + if($chr === '?'){ // skip unknown glyphs + continue; + } + + yield $key($byte1, $byte2) => [$chr]; } } @@ -69,7 +79,13 @@ final class KanjiTest extends DataInterfaceTestAbstract{ else{ for($byte2 = 0x9f; $byte2 < 0xfd; $byte2++){ - yield $key($byte1, $byte2) => [$val($byte1, $byte2)]; + $chr = $val($byte1, $byte2); + + if($chr === '?'){ + continue; + } + + yield $key($byte1, $byte2) => [$chr]; } } diff --git a/tests/Data/NumberTest.php b/tests/Data/NumberTest.php index d482a24e6..aace881f3 100644 --- a/tests/Data/NumberTest.php +++ b/tests/Data/NumberTest.php @@ -11,14 +11,18 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\Number; +use chillerlan\QRCode\Data\QRDataModeInterface; /** * Tests the Number class */ final class NumberTest extends DataInterfaceTestAbstract{ - protected static string $FQN = Number::class; - protected static string $testdata = '0123456789'; + protected const testData = '0123456789'; + + protected static function getDataModeInterface(string $data):QRDataModeInterface{ + return new Number($data); + } /** * isNumber() should pass on any number and fail on anything else diff --git a/tests/Data/QRDataTest.php b/tests/Data/QRDataTest.php index 4bd0b50f4..74ce298d3 100644 --- a/tests/Data/QRDataTest.php +++ b/tests/Data/QRDataTest.php @@ -16,12 +16,14 @@ use chillerlan\QRCode\Data\QRData; use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; +use chillerlan\QRCodeTest\QRMatrixDebugTrait; use PHPUnit\Framework\TestCase; /** * */ final class QRDataTest extends TestCase{ + use QRMatrixDebugTrait; /** * tests setting the BitBuffer object directly @@ -56,7 +58,7 @@ final class QRDataTest extends TestCase{ $output = new QRGdImagePNG($options, $matrix); $decodeResult = (new QRCode($options))->readFromBlob($output->dump()); - QRMatrixTest::debugMatrix($matrix); + $this->debugMatrix($matrix); $this::assertSame($decodeResult->data, 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s'); } diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index 26915f7fd..23e3bc97c 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -10,19 +10,19 @@ namespace chillerlan\QRCodeTest\Data; -use PHPUnit\Framework\Attributes\DataProvider; use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version}; use chillerlan\QRCode\Data\{QRCodeDataException, QRMatrix}; -use chillerlan\QRCode\Output\QRStringText; +use chillerlan\QRCodeTest\QRMatrixDebugTrait; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; use Generator; -use function defined; /** * Tests the QRMatrix class */ final class QRMatrixTest extends TestCase{ + use QRMatrixDebugTrait; private const version = 40; private QRMatrix $matrix; @@ -37,70 +37,6 @@ final class QRMatrixTest extends TestCase{ ); } - /** - * Matrix debugging console output - */ - public static function debugMatrix(QRMatrix $matrix):void{ - - /** @noinspection PhpUndefinedConstantInspection - see phpunit.xml.dist */ - if(defined('TEST_IS_CI') && TEST_IS_CI === true){ - return; - } - - $opt = new QROptions; - $opt->eol = "\n"; - $opt->moduleValues = [ - // finder - QRMatrix::M_FINDER_DARK => QRStringText::ansi8('██', 124), // dark (true) - QRMatrix::M_FINDER => QRStringText::ansi8('░░', 124), // light (false) - QRMatrix::M_FINDER_DOT => QRStringText::ansi8('██', 124), // finder dot, dark (true) - // alignment - QRMatrix::M_ALIGNMENT_DARK => QRStringText::ansi8('██', 2), - QRMatrix::M_ALIGNMENT => QRStringText::ansi8('░░', 2), - // timing - QRMatrix::M_TIMING_DARK => QRStringText::ansi8('██', 184), - QRMatrix::M_TIMING => QRStringText::ansi8('░░', 184), - // format - QRMatrix::M_FORMAT_DARK => QRStringText::ansi8('██', 200), - QRMatrix::M_FORMAT => QRStringText::ansi8('░░', 200), - // version - QRMatrix::M_VERSION_DARK => QRStringText::ansi8('██', 21), - QRMatrix::M_VERSION => QRStringText::ansi8('░░', 21), - // data - QRMatrix::M_DATA_DARK => QRStringText::ansi8('██', 166), - QRMatrix::M_DATA => QRStringText::ansi8('░░', 166), - // dark module - QRMatrix::M_DARKMODULE => QRStringText::ansi8('██', 53), - // separator - QRMatrix::M_SEPARATOR => QRStringText::ansi8('░░', 219), - // quiet zone - QRMatrix::M_QUIETZONE => QRStringText::ansi8('░░', 195), - // logo space - QRMatrix::M_LOGO => QRStringText::ansi8('░░', 105), - // empty - QRMatrix::M_NULL => QRStringText::ansi8('░░', 231), - ]; - - $out = (new QRStringText($opt, $matrix))->dump(); - - echo "\n\n".$out."\n\n"; - } - - /** - * debugging shortcut - limit to a single version when using with matrixProvider - * - * @see QRMatrixTest::matrixProvider() - */ - protected function dm(QRMatrix $matrix):void{ - - // limit - if($matrix->getVersion()->getVersionNumber() !== 7){ - return; - } - - $this::debugMatrix($matrix); - } - /** * Validates the QRMatrix instance */ @@ -599,7 +535,6 @@ final class QRMatrixTest extends TestCase{ */ $this::assertSame(0b01111101, $this->matrix->checkNeighbours(5, 5)); - /* * M_TYPE check * diff --git a/tests/Output/QREpsTest.php b/tests/Output/QREpsTest.php index 8b67a906c..82905912f 100644 --- a/tests/Output/QREpsTest.php +++ b/tests/Output/QREpsTest.php @@ -10,13 +10,13 @@ namespace chillerlan\QRCodeTest\Output; +use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QREps; +use chillerlan\QRCode\Output\{QREps, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; class QREpsTest extends QROutputTestAbstract{ - protected string $FQN = QREps::class; - public static function moduleValueProvider():array{ return [ 'valid: 3 int' => [[123, 123, 123], true], @@ -29,6 +29,13 @@ class QREpsTest extends QROutputTestAbstract{ ]; } + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QREps($options, $matrix); + } + /** * @inheritDoc */ @@ -40,7 +47,7 @@ class QREpsTest extends QROutputTestAbstract{ QRMatrix::M_DATA => [255, 255, 255], ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this->outputInterface->dump(); $this::assertTrue(true); // tricking the code coverage diff --git a/tests/Output/QRFpdfTest.php b/tests/Output/QRFpdfTest.php index caece49e9..216732bfe 100644 --- a/tests/Output/QRFpdfTest.php +++ b/tests/Output/QRFpdfTest.php @@ -10,10 +10,11 @@ namespace chillerlan\QRCodeTest\Output; -use FPDF; +use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QRFpdf; - +use chillerlan\QRCode\Output\{QRFpdf, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; +use FPDF; use function class_exists; /** @@ -21,8 +22,6 @@ use function class_exists; */ final class QRFpdfTest extends QROutputTestAbstract{ - protected string $FQN = QRFpdf::class; - /** * @inheritDoc */ @@ -35,6 +34,13 @@ final class QRFpdfTest extends QROutputTestAbstract{ parent::setUp(); } + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRFpdf($options, $matrix); + } + public static function moduleValueProvider():array{ return [ 'valid: int' => [[123, 123, 123], true], @@ -57,7 +63,7 @@ final class QRFpdfTest extends QROutputTestAbstract{ QRMatrix::M_DATA => [255, 255, 255], ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this->outputInterface->dump(); $this::assertTrue(true); // tricking the code coverage @@ -65,7 +71,7 @@ final class QRFpdfTest extends QROutputTestAbstract{ public function testOutputGetResource():void{ $this->options->returnResource = true; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this::assertInstanceOf(FPDF::class, $this->outputInterface->dump()); } diff --git a/tests/Output/QRGdImageBMPTest.php b/tests/Output/QRGdImageBMPTest.php index 09d56a657..4606c2a5a 100644 --- a/tests/Output/QRGdImageBMPTest.php +++ b/tests/Output/QRGdImageBMPTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRGdImageBMP; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRGdImageBMP, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRGdImageBMPTest extends QRGdImageTestAbstract{ - protected string $FQN = QRGdImageBMP::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRGdImageBMP($options, $matrix); + } } diff --git a/tests/Output/QRGdImageGIFTest.php b/tests/Output/QRGdImageGIFTest.php index b6ab05a33..763f2fea2 100644 --- a/tests/Output/QRGdImageGIFTest.php +++ b/tests/Output/QRGdImageGIFTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRGdImageGIF; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRGdImageGIF, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRGdImageGIFTest extends QRGdImageTestAbstract{ - protected string $FQN = QRGdImageGIF::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRGdImageGIF($options, $matrix); + } } diff --git a/tests/Output/QRGdImageJPGTest.php b/tests/Output/QRGdImageJPGTest.php index 76ada23df..ff832e877 100644 --- a/tests/Output/QRGdImageJPGTest.php +++ b/tests/Output/QRGdImageJPGTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRGdImageJPEG; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRGdImageJPEG, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRGdImageJPGTest extends QRGdImageTestAbstract{ - protected string $FQN = QRGdImageJPEG::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRGdImageJPEG($options, $matrix); + } } diff --git a/tests/Output/QRGdImagePNGTest.php b/tests/Output/QRGdImagePNGTest.php index 0151d1bc8..2ab0bce2b 100644 --- a/tests/Output/QRGdImagePNGTest.php +++ b/tests/Output/QRGdImagePNGTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRGdImagePNG; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRGdImagePNG, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRGdImagePNGTest extends QRGdImageTestAbstract{ - protected string $FQN = QRGdImagePNG::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRGdImagePNG($options, $matrix); + } } diff --git a/tests/Output/QRGdImageTestAbstract.php b/tests/Output/QRGdImageTestAbstract.php index e5972a81d..1e8bdc090 100644 --- a/tests/Output/QRGdImageTestAbstract.php +++ b/tests/Output/QRGdImageTestAbstract.php @@ -14,6 +14,7 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; use GdImage; +use function extension_loaded; /** * Tests the QRGdImage output module @@ -54,7 +55,7 @@ abstract class QRGdImageTestAbstract extends QROutputTestAbstract{ QRMatrix::M_DATA => [255, 255, 255], ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this->outputInterface->dump(); $this::assertTrue(true); // tricking the code coverage @@ -62,14 +63,14 @@ abstract class QRGdImageTestAbstract extends QROutputTestAbstract{ public function testOutputGetResource():void{ $this->options->returnResource = true; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this::assertInstanceOf(GdImage::class, $this->outputInterface->dump()); } public function testBase64MimeType():void{ $this->options->outputBase64 = true; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this::assertStringContainsString($this->outputInterface::MIME_TYPE, $this->outputInterface->dump()); } diff --git a/tests/Output/QRGdImageWEBPTest.php b/tests/Output/QRGdImageWEBPTest.php index 7a6a0d91f..444046cf7 100644 --- a/tests/Output/QRGdImageWEBPTest.php +++ b/tests/Output/QRGdImageWEBPTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRGdImageWEBP; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRGdImageWEBP, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRGdImageWEBPTest extends QRGdImageTestAbstract{ - protected string $FQN = QRGdImageWEBP::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRGdImageWEBP($options, $matrix); + } } diff --git a/tests/Output/QRImagickTest.php b/tests/Output/QRImagickTest.php index 91779182d..5a33e25bc 100644 --- a/tests/Output/QRImagickTest.php +++ b/tests/Output/QRImagickTest.php @@ -12,17 +12,18 @@ namespace chillerlan\QRCodeTest\Output; +use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QRImagick; +use chillerlan\QRCode\Output\{QRImagick, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; use Imagick; +use function extension_loaded; /** * Tests the QRImagick output module */ final class QRImagickTest extends QROutputTestAbstract{ - protected string $FQN = QRImagick::class; - /** * @inheritDoc */ @@ -35,6 +36,13 @@ final class QRImagickTest extends QROutputTestAbstract{ parent::setUp(); } + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRImagick($options, $matrix); + } + public static function moduleValueProvider():array{ return [ 'invalid: wrong type' => [[], false], @@ -72,7 +80,7 @@ final class QRImagickTest extends QROutputTestAbstract{ QRMatrix::M_DATA => '#ECF9BE', ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this->outputInterface->dump(); $this::assertTrue(true); // tricking the code coverage @@ -80,7 +88,7 @@ final class QRImagickTest extends QROutputTestAbstract{ public function testOutputGetResource():void{ $this->options->returnResource = true; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this::assertInstanceOf(Imagick::class, $this->outputInterface->dump()); } diff --git a/tests/Output/QRMarkupHTMLTest.php b/tests/Output/QRMarkupHTMLTest.php index 78cc4c630..ca1fe9bcf 100644 --- a/tests/Output/QRMarkupHTMLTest.php +++ b/tests/Output/QRMarkupHTMLTest.php @@ -10,13 +10,21 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRMarkupHTML; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRMarkupHTML, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRMarkupHTMLTest extends QRMarkupTestAbstract{ - protected string $FQN = QRMarkupHTML::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRMarkupHTML($options, $matrix); + } } diff --git a/tests/Output/QRMarkupSVGTest.php b/tests/Output/QRMarkupSVGTest.php index 87c29be99..7d0b88ad5 100644 --- a/tests/Output/QRMarkupSVGTest.php +++ b/tests/Output/QRMarkupSVGTest.php @@ -10,14 +10,22 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRMarkupSVG; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRMarkupSVG, QROutputInterface}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRMarkupSVGTest extends QRMarkupTestAbstract{ - protected string $FQN = QRMarkupSVG::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRMarkupSVG($options, $matrix); + } public static function moduleValueProvider():array{ return [ diff --git a/tests/Output/QRMarkupTestAbstract.php b/tests/Output/QRMarkupTestAbstract.php index 81ee3fbeb..e724332f1 100644 --- a/tests/Output/QRMarkupTestAbstract.php +++ b/tests/Output/QRMarkupTestAbstract.php @@ -51,7 +51,7 @@ abstract class QRMarkupTestAbstract extends QROutputTestAbstract{ QRMatrix::M_DATA => '#ECF9BE', ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $data = $this->outputInterface->dump(); $this::assertStringContainsString('#4A6000', $data); $this::assertStringContainsString('#ECF9BE', $data); diff --git a/tests/Output/QROutputTestAbstract.php b/tests/Output/QROutputTestAbstract.php index 6f47bd4c0..bf6f0296b 100644 --- a/tests/Output/QROutputTestAbstract.php +++ b/tests/Output/QROutputTestAbstract.php @@ -10,16 +10,14 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\QRCode; -use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; use PHPUnit\Framework\Attributes\DataProvider; -use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface}; use PHPUnit\Framework\TestCase; - -use function file_exists, mkdir; -use function str_replace; +use ReflectionClass; +use function file_exists, file_get_contents, mkdir, realpath; /** * Test abstract for the several (built-in) output modules, @@ -30,30 +28,27 @@ abstract class QROutputTestAbstract extends TestCase{ protected SettingsContainerInterface|QROptions $options; protected QROutputInterface $outputInterface; protected QRMatrix $matrix; - protected string $builddir = __DIR__.'/../../.build/output-test'; - protected string $FQN; + + protected const buildDir = __DIR__.'/../../.build/output-test/'; /** * Attempts to create a directory under /.build and instances several required objects */ protected function setUp():void{ - if(!file_exists($this->builddir)){ - mkdir($this->builddir, 0777, true); + if(!file_exists($this::buildDir)){ + mkdir($this::buildDir, 0777, true); } $this->options = new QROptions; - $this->options->outputInterface = $this->FQN; $this->matrix = (new QRCode($this->options))->addByteSegment('testdata')->getQRMatrix(); - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); } - /** - * Validate the instance of the interface - */ - public function testInstance():void{ - $this::assertInstanceOf(QROutputInterface::class, $this->outputInterface); - } + abstract protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface; /** * Tests if an exception is thrown when trying to write a cache file to an invalid destination @@ -62,7 +57,6 @@ abstract class QROutputTestAbstract extends TestCase{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('Cannot write data to cache file: /foo/bar.test'); - $this->outputInterface = new $this->FQN($this->options, $this->matrix); $this->outputInterface->dump('/foo/bar.test'); } @@ -70,8 +64,7 @@ abstract class QROutputTestAbstract extends TestCase{ #[DataProvider('moduleValueProvider')] public function testValidateModuleValues(mixed $value, bool $expected):void{ - /** @noinspection PhpUndefinedMethodInspection */ - $this::assertSame($expected, $this->FQN::moduleValueIsValid($value)); + $this::assertSame($expected, $this->outputInterface::moduleValueIsValid($value)); } /* @@ -88,9 +81,10 @@ abstract class QROutputTestAbstract extends TestCase{ */ public function testRenderToCacheFile():void{ $this->options->outputBase64 = false; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); // create the cache file - $file = $this->builddir.'/test.output.'.str_replace('chillerlan\\QRCode\\Output\\', '', $this->FQN); + $name = (new ReflectionClass($this->outputInterface))->getShortName(); + $file = realpath($this::buildDir).'test.output.'.$name; $data = $this->outputInterface->dump($file); $this::assertSame($data, file_get_contents($file)); diff --git a/tests/Output/QRStringJSONTest.php b/tests/Output/QRStringJSONTest.php index c003b2a60..d339f61af 100644 --- a/tests/Output/QRStringJSONTest.php +++ b/tests/Output/QRStringJSONTest.php @@ -10,7 +10,10 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QRStringJSON; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QROutputInterface, QRStringJSON}; +use chillerlan\Settings\SettingsContainerInterface; use PHPUnit\Framework\Attributes\DataProvider; use function extension_loaded; @@ -19,8 +22,6 @@ use function extension_loaded; */ final class QRStringJSONTest extends QROutputTestAbstract{ - protected string $FQN = QRStringJSON::class; - /** * @inheritDoc */ @@ -33,6 +34,13 @@ final class QRStringJSONTest extends QROutputTestAbstract{ parent::setUp(); } + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRStringJSON($options, $matrix); + } + public static function moduleValueProvider():array{ return [[null, false]]; } diff --git a/tests/Output/QRStringTEXTTest.php b/tests/Output/QRStringTEXTTest.php index 37c6fad49..43c354cf3 100644 --- a/tests/Output/QRStringTEXTTest.php +++ b/tests/Output/QRStringTEXTTest.php @@ -10,15 +10,22 @@ namespace chillerlan\QRCodeTest\Output; +use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QRStringText; +use chillerlan\QRCode\Output\{QROutputInterface, QRStringText}; +use chillerlan\Settings\SettingsContainerInterface; /** * */ final class QRStringTEXTTest extends QROutputTestAbstract{ - protected string $FQN = QRStringText::class; + protected function getOutputInterface( + SettingsContainerInterface|QROptions $options, + QRMatrix $matrix + ):QROutputInterface{ + return new QRStringText($options, $matrix); + } public static function moduleValueProvider():array{ return [ @@ -40,7 +47,7 @@ final class QRStringTEXTTest extends QROutputTestAbstract{ QRMatrix::M_DATA => 'B', ]; - $this->outputInterface = new $this->FQN($this->options, $this->matrix); + $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $data = $this->outputInterface->dump(); $this::assertStringContainsString('A', $data); diff --git a/tests/QRCodeReaderGDTest.php b/tests/QRCodeReaderGDTest.php index 25a893723..fe160d814 100644 --- a/tests/QRCodeReaderGDTest.php +++ b/tests/QRCodeReaderGDTest.php @@ -10,13 +10,20 @@ namespace chillerlan\QRCodeTest; -use chillerlan\QRCode\Common\GDLuminanceSource; +use chillerlan\QRCode\Common\{GDLuminanceSource, LuminanceSourceInterface}; +use chillerlan\QRCode\QROptions; +use chillerlan\Settings\SettingsContainerInterface; /** * Tests the GD based reader */ final class QRCodeReaderGDTest extends QRCodeReaderTestAbstract{ - protected string $FQN = GDLuminanceSource::class; + protected function getLuminanceSourceFromFile( + string $file, + SettingsContainerInterface|QROptions $options + ):LuminanceSourceInterface{ + return GDLuminanceSource::fromFile($file, $options); + } } diff --git a/tests/QRCodeReaderImagickTest.php b/tests/QRCodeReaderImagickTest.php index 6db408219..c8d2d412d 100644 --- a/tests/QRCodeReaderImagickTest.php +++ b/tests/QRCodeReaderImagickTest.php @@ -10,19 +10,19 @@ namespace chillerlan\QRCodeTest; -use chillerlan\QRCode\Common\IMagickLuminanceSource; -use chillerlan\QRCode\QRCode; +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Common\{IMagickLuminanceSource, LuminanceSourceInterface}; +use chillerlan\QRCode\Decoder\Decoder; +use chillerlan\Settings\SettingsContainerInterface; use PHPUnit\Framework\Attributes\DataProvider; use function extension_loaded; -use const PHP_OS_FAMILY, PHP_VERSION_ID; +use const PHP_OS_FAMILY; /** * Tests the Imagick based reader */ final class QRCodeReaderImagickTest extends QRCodeReaderTestAbstract{ - protected string $FQN = IMagickLuminanceSource::class; - protected function setUp():void{ if(!extension_loaded('imagick')){ @@ -34,6 +34,13 @@ final class QRCodeReaderImagickTest extends QRCodeReaderTestAbstract{ $this->options->readerUseImagickIfAvailable = true; } + protected function getLuminanceSourceFromFile( + string $file, + SettingsContainerInterface|QROptions $options + ):LuminanceSourceInterface{ + return IMagickLuminanceSource::fromFile($file, $options); + } + public static function vectorQRCodeProvider():array{ return [ // SVG convert only works on windows (Warning: Option --export-png= is deprecated) @@ -51,12 +58,9 @@ final class QRCodeReaderImagickTest extends QRCodeReaderTestAbstract{ $this::markTestSkipped('avoid imagick conversion errors (ha ha)'); } - if(PHP_OS_FAMILY === 'Windows' && PHP_VERSION_ID < 80100){ - $this::markTestSkipped('This test fails on Windows and PHP < 8.1 for whatever reason'); - } + $luminanceSource = $this->getLuminanceSourceFromFile($this::samplesDir.$img, $this->options); - $this::assertSame($expected, (string)(new QRCode) - ->readFromSource(IMagickLuminanceSource::fromFile(__DIR__.'/samples/'.$img, $this->options))); + $this::assertSame($expected, (string)(new Decoder)->decode($luminanceSource)); } } diff --git a/tests/QRCodeReaderTestAbstract.php b/tests/QRCodeReaderTestAbstract.php index 9389c388d..0da27f53a 100644 --- a/tests/QRCodeReaderTestAbstract.php +++ b/tests/QRCodeReaderTestAbstract.php @@ -12,24 +12,23 @@ namespace chillerlan\QRCodeTest; -use chillerlan\QRCodeTest\Data\QRMatrixTest; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Group; use chillerlan\QRCode\{QRCode, QROptions}; -use chillerlan\QRCode\Common\{EccLevel, Mode, Version}; +use chillerlan\QRCode\Common\{EccLevel, LuminanceSourceInterface, Mode, Version}; +use chillerlan\QRCode\Decoder\Decoder; use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\{DataProvider, Group}; use PHPUnit\Framework\TestCase; use Exception, Generator; -use function array_map, defined, sprintf, str_repeat, substr; +use function array_map, defined, realpath, sprintf, str_repeat, substr; /** * Tests the QR Code reader */ abstract class QRCodeReaderTestAbstract extends TestCase{ - use QRMaxLengthTrait; + use QRMaxLengthTrait, QRMatrixDebugTrait; - // https://www.bobrosslipsum.com/ + /** @see https://www.bobrosslipsum.com/ */ protected const loremipsum = 'Just let this happen. We just let this flow right out of our minds. ' .'Anyone can paint. We touch the canvas, the canvas takes what it wants. From all of us here, ' .'I want to wish you happy painting and God bless, my friends. A tree cannot be straight if it has a crooked trunk. ' @@ -38,8 +37,9 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ .'They say everything looks better with odd numbers of things. But sometimes I put even numbers—just ' .'to upset the critics. We\'ll lay all these little funky little things in there. '; - protected SettingsContainerInterface $options; - protected string $FQN; + protected const samplesDir = __DIR__.'/samples/'; + + protected SettingsContainerInterface|QROptions $options; protected function setUp():void{ @@ -78,6 +78,11 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ ]; } + abstract protected function getLuminanceSourceFromFile( + string $file, + SettingsContainerInterface|QROptions $options + ):LuminanceSourceInterface; + #[Group('slow')] #[DataProvider('qrCodeProvider')] public function testReader(string $img, string $expected, bool $grayscale):void{ @@ -87,10 +92,10 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ $this->options->readerIncreaseContrast = true; } - /** @noinspection PhpUndefinedMethodInspection */ - $result = (new QRCode)->readFromSource($this->FQN::fromFile(__DIR__.'/samples/'.$img, $this->options)); + $luminanceSource = $this->getLuminanceSourceFromFile(realpath($this::samplesDir.$img), $this->options); + $result = (new Decoder)->decode($luminanceSource); - QRMatrixTest::debugMatrix($result->getQRMatrix()); + $this->debugMatrix($result->getQRMatrix()); $this::assertSame($expected, (string)$result); } diff --git a/tests/QRCodeTest.php b/tests/QRCodeTest.php index 9c89d0594..6db598cb4 100755 --- a/tests/QRCodeTest.php +++ b/tests/QRCodeTest.php @@ -23,7 +23,8 @@ final class QRCodeTest extends TestCase{ private QRCode $qrcode; private QROptions $options; - private string $builddir = __DIR__.'/../.build/output-test'; + + private const buildDir = __DIR__.'/../.build/output-test/'; /** * invoke test instances @@ -73,7 +74,7 @@ final class QRCodeTest extends TestCase{ * Tests if a cache file is properly saved in the given path */ public function testRenderToCacheFile():void{ - $this->options->cachefile = $this->builddir.'/test.cache.svg'; + $this->options->cachefile = $this::buildDir.'test.cache.svg'; $this->options->outputBase64 = false; // create the cache file $data = $this->qrcode->setOptions($this->options)->render('test'); diff --git a/tests/QRMatrixDebugTrait.php b/tests/QRMatrixDebugTrait.php new file mode 100644 index 000000000..1f4105c13 --- /dev/null +++ b/tests/QRMatrixDebugTrait.php @@ -0,0 +1,94 @@ + + * @copyright 2023 smiley + * @license MIT + */ + +namespace chillerlan\QRCodeTest; + +use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\QRStringText; +use function defined, printf; + +/** + * Trait QRMatrixDebugTrait + */ +trait QRMatrixDebugTrait{ + + /** + * Matrix debugging console output + */ + protected function debugMatrix(QRMatrix $matrix):void{ + + /** @noinspection PhpUndefinedConstantInspection - see phpunit.xml.dist */ + if(defined('TEST_IS_CI') && TEST_IS_CI === true){ + return; + } + + $options = new QROptions; + + $options->eol = "\n"; + $options->moduleValues = [ + // finder + QRMatrix::M_FINDER_DARK => QRStringText::ansi8('██', 124), + QRMatrix::M_FINDER => QRStringText::ansi8('░░', 124), + QRMatrix::M_FINDER_DOT => QRStringText::ansi8('██', 124), + QRMatrix::M_FINDER_DOT_LIGHT => QRStringText::ansi8('░░', 124), + // alignment + QRMatrix::M_ALIGNMENT_DARK => QRStringText::ansi8('██', 2), + QRMatrix::M_ALIGNMENT => QRStringText::ansi8('░░', 2), + // timing + QRMatrix::M_TIMING_DARK => QRStringText::ansi8('██', 184), + QRMatrix::M_TIMING => QRStringText::ansi8('░░', 184), + // format + QRMatrix::M_FORMAT_DARK => QRStringText::ansi8('██', 200), + QRMatrix::M_FORMAT => QRStringText::ansi8('░░', 200), + // version + QRMatrix::M_VERSION_DARK => QRStringText::ansi8('██', 21), + QRMatrix::M_VERSION => QRStringText::ansi8('░░', 21), + // data + QRMatrix::M_DATA_DARK => QRStringText::ansi8('██', 166), + QRMatrix::M_DATA => QRStringText::ansi8('░░', 166), + // dark module + QRMatrix::M_DARKMODULE => QRStringText::ansi8('██', 53), + QRMatrix::M_DARKMODULE_LIGHT => QRStringText::ansi8('░░', 53), + // separator + QRMatrix::M_SEPARATOR_DARK => QRStringText::ansi8('██', 219), + QRMatrix::M_SEPARATOR => QRStringText::ansi8('░░', 219), + // quiet zone + QRMatrix::M_QUIETZONE_DARK => QRStringText::ansi8('██', 195), + QRMatrix::M_QUIETZONE => QRStringText::ansi8('░░', 195), + // logo space + QRMatrix::M_LOGO_DARK => QRStringText::ansi8('██', 105), + QRMatrix::M_LOGO => QRStringText::ansi8('░░', 105), + // empty + QRMatrix::M_NULL => QRStringText::ansi8('░░', 231), + ]; + + $out = (new QRStringText($options, $matrix))->dump(); + + printf("\n\n%s\n\n", $out) ; + } + + /** + * debugging shortcut - limit to a single version when using with matrixProvider + * + * @see QRMatrixTest::matrixProvider() + */ + protected function dm(QRMatrix $matrix):void{ + + // limit + /** @noinspection PhpUndefinedConstantInspection - see phpunit.xml.dist */ + if(!defined('MATRIX_DEBUG_VERSION') || $matrix->getVersion()->getVersionNumber() !== MATRIX_DEBUG_VERSION){ + return; + } + + $this->debugMatrix($matrix); + } + +} diff --git a/tests/QROptionsTest.php b/tests/QROptionsTest.php index a871d9c96..21ce28aa9 100644 --- a/tests/QROptionsTest.php +++ b/tests/QROptionsTest.php @@ -12,10 +12,8 @@ namespace chillerlan\QRCodeTest; -use chillerlan\QRCode\Common\EccLevel; -use chillerlan\QRCode\QRCodeException; -use chillerlan\QRCode\QROptions; -use chillerlan\QRCode\Common\Version; +use chillerlan\QRCode\{QRCodeException, QROptions}; +use chillerlan\QRCode\Common\{EccLevel, Version}; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase;