From c99f5d402297cf55f5fa26b2d0be16360cfdbe6c Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 2 Nov 2025 00:48:56 +0100 Subject: [PATCH] :bath: test overhaul --- phpstan-baseline.neon | 18 ++-- tests/Common/BitBufferTest.php | 27 +++--- tests/Common/ECICharsetTest.php | 18 ++-- tests/Common/EccLevelTest.php | 17 ++-- tests/Common/MaskPatternTest.php | 20 +++-- tests/Common/ModeTest.php | 33 +++---- tests/Common/VersionTest.php | 25 ++++-- tests/Data/AlphaNumTest.php | 3 +- tests/Data/ByteTest.php | 10 ++- tests/Data/DataInterfaceTestAbstract.php | 38 +++++--- tests/Data/ECITest.php | 28 +++--- tests/Data/HanziTest.php | 9 +- tests/Data/KanjiTest.php | 9 +- tests/Data/NumberTest.php | 3 +- tests/Data/QRDataTest.php | 21 ++--- tests/Data/QRMatrixTest.php | 74 ++++++++++------ tests/Output/QREpsTest.php | 7 +- tests/Output/QRFpdfTest.php | 16 +--- tests/Output/QRGdImageAVIFTest.php | 13 +-- tests/Output/QRGdImageBMPTest.php | 2 + tests/Output/QRGdImageGIFTest.php | 2 + tests/Output/QRGdImageJPGTest.php | 2 + tests/Output/QRGdImagePNGTest.php | 2 + tests/Output/QRGdImageTestAbstract.php | 23 ++--- tests/Output/QRGdImageWEBPTest.php | 2 + tests/Output/QRImagickTest.php | 20 ++--- tests/Output/QRInterventionImageTest.php | 25 ++---- tests/Output/QRMarkupTestAbstract.php | 7 +- tests/Output/QROutputTestAbstract.php | 16 ++-- tests/Output/QRStringJSONTest.php | 7 +- tests/Output/QRStringTextTest.php | 7 +- tests/QRCodeReaderGDTest.php | 2 + tests/QRCodeReaderImagickTest.php | 12 +-- tests/QRCodeReaderTestAbstract.php | 21 +++-- tests/QRCodeTest.php | 45 ++++++++-- tests/QROptionsTest.php | 105 +++++++---------------- 36 files changed, 356 insertions(+), 333 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 349e4f997..55d3e4e5c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -102,6 +102,12 @@ parameters: count: 1 path: examples/intervention-image.php + - + rawMessage: 'Function parseHexValue() return type has no value type specified in iterable type array.' + identifier: missingType.iterableValue + count: 1 + path: examples/qrcode-interactive.php + - rawMessage: 'Method RandomDotsSVGOutput::collectModules() should return array but returns array>.' identifier: return.type @@ -234,24 +240,12 @@ parameters: count: 1 path: src/QRCode.php - - - rawMessage: 'Method chillerlan\QRCodeTest\Common\MaskPatternTest::assertMask() has parameter $expected with no value type specified in iterable type array.' - identifier: missingType.iterableValue - count: 1 - path: tests/Common/MaskPatternTest.php - - rawMessage: 'Method chillerlan\QRCodeTest\Common\MaskPatternTest::maskPatternProvider() return type has no value type specified in iterable type array.' identifier: missingType.iterableValue count: 1 path: tests/Common/MaskPatternTest.php - - - rawMessage: 'Method chillerlan\QRCodeTest\Common\MaskPatternTest::testMask() has parameter $expected with no value type specified in iterable type array.' - identifier: missingType.iterableValue - count: 1 - path: tests/Common/MaskPatternTest.php - - rawMessage: 'Parameter #1 $string of static method chillerlan\QRCode\Data\QRDataModeInterface::validateString() expects string, string|false given.' identifier: argument.type diff --git a/tests/Common/BitBufferTest.php b/tests/Common/BitBufferTest.php index 42931de5e..141120520 100644 --- a/tests/Common/BitBufferTest.php +++ b/tests/Common/BitBufferTest.php @@ -13,7 +13,7 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\{BitBuffer, Mode}; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{Test, TestWith}; use PHPUnit\Framework\TestCase; /** @@ -27,28 +27,21 @@ final class BitBufferTest extends TestCase{ $this->bitBuffer = new BitBuffer; } - /** - * @phpstan-return array - */ - public static function bitProvider():array{ - return [ - 'number' => [Mode::NUMBER, 16], - 'alphanum' => [Mode::ALPHANUM, 32], - 'byte' => [Mode::BYTE, 64], - 'kanji' => [Mode::KANJI, 128], - 'hanzi' => [Mode::HANZI, 208], - ]; - } - - #[DataProvider('bitProvider')] - public function testPut(int $data, int $expected):void{ + #[Test] + #[TestWith([Mode::NUMBER, 16], 'number')] + #[TestWith([Mode::ALPHANUM, 32], 'alphanum')] + #[TestWith([Mode::BYTE, 64], 'byte')] + #[TestWith([Mode::KANJI, 128], 'kanji')] + #[TestWith([Mode::HANZI, 208], 'hanzi')] + public function put(int $data, int $expected):void{ $this->bitBuffer->put($data, 4); $this::assertSame($expected, $this->bitBuffer->getBuffer()[0]); $this::assertSame(4, $this->bitBuffer->getLength()); } - public function testReadException():void{ + #[Test] + public function readException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid $numBits'); diff --git a/tests/Common/ECICharsetTest.php b/tests/Common/ECICharsetTest.php index 058538e94..168034509 100644 --- a/tests/Common/ECICharsetTest.php +++ b/tests/Common/ECICharsetTest.php @@ -13,20 +13,15 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\ECICharset; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{DataProvider, Test, TestWith}; use PHPUnit\Framework\TestCase; final class ECICharsetTest extends TestCase{ - /** - * @phpstan-return array - */ - public static function invalidIdProvider():array{ - return [[-1], [1000000]]; - } - - #[DataProvider('invalidIdProvider')] - public function testInvalidDataException(int $id):void{ + #[Test] + #[TestWith([-1])] + #[TestWith([1000000])] + public function invalidDataException(int $id):void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid charset id:'); @@ -46,8 +41,9 @@ final class ECICharsetTest extends TestCase{ return $params; } + #[Test] #[DataProvider('encodingProvider')] - public function testGetName(int $id, string|null $name = null):void{ + public function getName(int $id, string|null $name = null):void{ $eciCharset = new ECICharset($id); $this::assertSame($id, $eciCharset->getID()); diff --git a/tests/Common/EccLevelTest.php b/tests/Common/EccLevelTest.php index a62c24bb9..fa695a9d4 100644 --- a/tests/Common/EccLevelTest.php +++ b/tests/Common/EccLevelTest.php @@ -13,6 +13,7 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\{EccLevel, MaskPattern}; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -20,37 +21,43 @@ use PHPUnit\Framework\TestCase; */ final class EccLevelTest extends TestCase{ - public function testConstructInvalidEccException():void{ + #[Test] + public function constructInvalidEccException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid ECC level'); new EccLevel(69); } - public function testToString():void{ + #[Test] + public function eccToString():void{ $ecc = new EccLevel(EccLevel::L); $this::assertSame('L', (string)$ecc); } - public function testGetLevel():void{ + #[Test] + public function getLevel():void{ $ecc = new EccLevel(EccLevel::L); $this::assertSame(EccLevel::L, $ecc->getLevel()); } - public function testGetOrdinal():void{ + #[Test] + public function getOrdinal():void{ $ecc = new EccLevel(EccLevel::L); $this::assertSame(0, $ecc->getOrdinal()); } - public function testGetformatPattern():void{ + #[Test] + public function getformatPattern():void{ $ecc = new EccLevel(EccLevel::Q); $this::assertSame(0b010010010110100, $ecc->getformatPattern(new MaskPattern(4))); } + #[Test] public function getMaxBits():void{ $ecc = new EccLevel(EccLevel::Q); diff --git a/tests/Common/MaskPatternTest.php b/tests/Common/MaskPatternTest.php index 4e33b0085..fc354d341 100644 --- a/tests/Common/MaskPatternTest.php +++ b/tests/Common/MaskPatternTest.php @@ -16,7 +16,7 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\MaskPattern; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{DataProvider, Test}; use PHPUnit\Framework\TestCase; use Closure; @@ -100,8 +100,9 @@ final class MaskPatternTest extends TestCase{ * * @param int[][] $expected */ + #[Test] #[DataProvider('maskPatternProvider')] - public function testMask(int $pattern, array $expected):void{ + public function mask(int $pattern, array $expected):void{ $maskPattern = new MaskPattern($pattern); $this::assertTrue($this->assertMask($maskPattern->getMask(), $expected)); @@ -126,14 +127,16 @@ final class MaskPatternTest extends TestCase{ /** * Tests if an exception is thrown on an incorrect mask pattern */ - public function testInvalidMaskPatternException():void{ + #[Test] + public function invalidMaskPatternException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid mask pattern'); new MaskPattern(42); } - public function testPenaltyRule1():void{ + #[Test] + public function penaltyRule1():void{ // horizontal $this::assertSame(0, MaskPattern::testRule1([[false, false, false, false]], 1, 4)); $this::assertSame(3, MaskPattern::testRule1([[false, false, false, false, false, true]], 1, 6)); @@ -144,14 +147,16 @@ final class MaskPatternTest extends TestCase{ $this::assertSame(4, MaskPattern::testRule1([[false], [false], [false], [false], [false], [false]], 6, 1)); } - public function testPenaltyRule2():void{ + #[Test] + public function penaltyRule2():void{ $this::assertSame(0, MaskPattern::testRule2([[false]], 1, 1)); $this::assertSame(0, MaskPattern::testRule2([[false, false], [false, true]], 2, 2)); $this::assertSame(3, MaskPattern::testRule2([[false, false], [false, false]], 2, 2)); $this::assertSame(12, MaskPattern::testRule2([[false, false, false], [false, false, false], [false, false, false]], 3, 3)); // phpcs:ignore } - public function testPenaltyRule3():void{ + #[Test] + public function penaltyRule3():void{ // horizontal $this::assertSame(40, MaskPattern::testRule3([[false, false, false, false, true, false, true, true, true, false, true]], 1, 11)); // phpcs:ignore $this::assertSame(40, MaskPattern::testRule3([[true, false, true, true, true, false, true, false, false, false, false]], 1, 11)); // phpcs:ignore @@ -162,7 +167,8 @@ final class MaskPatternTest extends TestCase{ $this::assertSame(0, MaskPattern::testRule3([[true], [false], [true], [true], [true], [false], [true]], 7, 1)); } - public function testPenaltyRule4():void{ + #[Test] + public function penaltyRule4():void{ $this::assertSame(100, MaskPattern::testRule4([[false]], 1, 1)); $this::assertSame(0, MaskPattern::testRule4([[false, true]], 1, 2)); $this::assertSame(30, MaskPattern::testRule4([[false, true, true, true, true, false]], 1, 6)); diff --git a/tests/Common/ModeTest.php b/tests/Common/ModeTest.php index 7706f0c4b..96cda003b 100644 --- a/tests/Common/ModeTest.php +++ b/tests/Common/ModeTest.php @@ -13,7 +13,7 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\Mode; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{Test, TestWith}; use PHPUnit\Framework\TestCase; /** @@ -22,34 +22,29 @@ use PHPUnit\Framework\TestCase; final class ModeTest extends TestCase{ /** - * version breakpoints for numeric mode - * - * @phpstan-return array + * Tests the version breakpoints for numeric mode */ - public static function versionProvider():array{ - return [ - [ 1, 10], - [ 9, 10], - [10, 12], - [26, 12], - [27, 14], - [40, 14], - ]; - } - - #[DataProvider('versionProvider')] - public function testGetLengthBitsForVersionBreakpoints(int $version, int $expected):void{ + #[Test] + #[TestWith([ 1, 10], '10 low')] + #[TestWith([ 9, 10], '10 high')] + #[TestWith([10, 12], '12 low')] + #[TestWith([26, 12], '12 high')] + #[TestWith([27, 14], '14 low')] + #[TestWith([40, 14], '14 high')] + public function getLengthBitsForVersionBreakpoints(int $version, int $expected):void{ $this::assertSame($expected, Mode::getLengthBitsForVersion(Mode::NUMBER, $version)); } - public function testGetLengthBitsForVersionInvalidModeException():void{ + #[Test] + public function getLengthBitsForVersionInvalidModeException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid mode given'); Mode::getLengthBitsForVersion(42, 69); } - public function testGetLengthBitsForVersionInvalidVersionException():void{ + #[Test] + public function getLengthBitsForVersionInvalidVersionException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid version number'); diff --git a/tests/Common/VersionTest.php b/tests/Common/VersionTest.php index 2c95a23b3..00a2df063 100644 --- a/tests/Common/VersionTest.php +++ b/tests/Common/VersionTest.php @@ -13,6 +13,7 @@ namespace chillerlan\QRCodeTest\Common; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\Common\{EccLevel, Version}; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -26,37 +27,45 @@ final class VersionTest extends TestCase{ $this->version = new Version(7); } - public function testToString():void{ + #[Test] + public function versionToString():void{ $this::assertSame('7', (string)$this->version); } - public function testGetVersionNumber():void{ + #[Test] + public function getVersionNumber():void{ $this::assertSame(7, $this->version->getVersionNumber()); } - public function testGetDimension():void{ + #[Test] + public function getDimension():void{ $this::assertSame(45, $this->version->getDimension()); } - public function testGetVersionPattern():void{ + #[Test] + public function getVersionPattern():void{ $this::assertSame(0b000111110010010100, $this->version->getVersionPattern()); // no pattern for version < 7 $this::assertNull((new Version(6))->getVersionPattern()); } - public function testGetAlignmentPattern():void{ + #[Test] + public function getAlignmentPattern():void{ $this::assertSame([6, 22, 38], $this->version->getAlignmentPattern()); } - public function testGetRSBlocks():void{ + #[Test] + public function getRSBlocks():void{ $this::assertSame([18, [[2, 14], [4, 15]]], $this->version->getRSBlocks(new EccLevel(EccLevel::Q))); } - public function testGetTotalCodewords():void{ + #[Test] + public function getTotalCodewords():void{ $this::assertSame(196, $this->version->getTotalCodewords()); } - public function testConstructInvalidVersion():void{ + #[Test] + public function constructInvalidVersion():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('invalid version given'); diff --git a/tests/Data/AlphaNumTest.php b/tests/Data/AlphaNumTest.php index ed7a97c16..43296510a 100644 --- a/tests/Data/AlphaNumTest.php +++ b/tests/Data/AlphaNumTest.php @@ -11,8 +11,7 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Data\AlphaNum; -use chillerlan\QRCode\Data\QRDataModeInterface; +use chillerlan\QRCode\Data\{AlphaNum, QRDataModeInterface}; /** * Tests the AlphaNum class diff --git a/tests/Data/ByteTest.php b/tests/Data/ByteTest.php index 7d9c59dbf..fc4d8a663 100644 --- a/tests/Data/ByteTest.php +++ b/tests/Data/ByteTest.php @@ -11,8 +11,8 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Data\Byte; -use chillerlan\QRCode\Data\QRDataModeInterface; +use chillerlan\QRCode\Data\{Byte, QRDataModeInterface}; +use PHPUnit\Framework\Attributes\Test; /** * Tests the Byte class @@ -39,11 +39,13 @@ final class ByteTest extends DataInterfaceTestAbstract{ ]; } - public function testInvalidDataException():void{ + #[Test] + public function binaryStringInvalid():void{ $this::markTestSkipped('N/A (binary mode)'); } - public function testBinaryStringInvalid():void{ + #[Test] + public function invalidDataException():void{ $this::markTestSkipped('N/A (binary mode)'); } diff --git a/tests/Data/DataInterfaceTestAbstract.php b/tests/Data/DataInterfaceTestAbstract.php index e1a81180c..f9c33b7eb 100644 --- a/tests/Data/DataInterfaceTestAbstract.php +++ b/tests/Data/DataInterfaceTestAbstract.php @@ -11,14 +11,14 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; +use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, Mode, Version}; use chillerlan\QRCode\Data\{QRCodeDataException, QRData, QRDataModeInterface, QRMatrix}; -use chillerlan\QRCode\QROptions; use chillerlan\QRCodeTest\Traits\QRMaxLengthTrait; -use Exception, Generator; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\{DataProvider, Test}; +use PHPUnit\Framework\ExpectationFailedException; +use Exception, Generator; use function array_map, hex2bin, mb_strlen, mb_substr, sprintf, str_repeat, strlen, substr; /** @@ -49,8 +49,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests initializing the data matrix */ + #[Test] #[DataProvider('maskPatternProvider')] - public function testInitMatrix(int $pattern):void{ + public function initMatrix(int $pattern):void{ $maskPattern = new MaskPattern($pattern); $this->QRData->setData([$this->dataMode]); @@ -69,8 +70,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests if a string is properly validated for the respective data mode */ + #[Test] #[DataProvider('stringValidateProvider')] - public function testValidateString(string $string, bool $expected):void{ + public function validateString(string $string, bool $expected):void{ $this::assertSame($expected, $this->dataMode::validateString($string)); // back out on potentially invalid strings @@ -97,7 +99,8 @@ abstract class DataInterfaceTestAbstract extends TestCase{ * * @see https://github.com/chillerlan/php-qrcode/issues/182 */ - public function testBinaryStringInvalid():void{ + #[Test] + public function binaryStringInvalid():void{ $this::assertFalse($this->dataMode::validateString(hex2bin('01015989f47dff8e852122117e04c90b9f15defc1c36477b1fe1'))); } @@ -113,8 +116,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests decoding a data segment from a given BitBuffer */ + #[Test] #[DataProvider('versionBreakpointProvider')] - public function testDecodeSegment(int $version):void{ + public function decodeSegment(int $version):void{ $options = new QROptions; $options->version = $version; @@ -170,8 +174,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ } + #[Test] #[DataProvider('maxLengthProvider')] - public function testMaxLength(Version $version, EccLevel $eccLevel, string $str):void{ + public function maxLength(Version $version, EccLevel $eccLevel, string $str):void{ $options = new QROptions; $options->version = $version->getVersionNumber(); $options->eccLevel = $eccLevel->getLevel(); @@ -188,8 +193,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests getting the minimum QR version for the given data */ + #[Test] #[DataProvider('maxLengthProvider')] - public function testGetMinimumVersion(Version $version, EccLevel $eccLevel, string $str):void{ + public function getMinimumVersion(Version $version, EccLevel $eccLevel, string $str):void{ $options = new QROptions; $options->version = Version::AUTO; $options->eccLevel = $eccLevel->getLevel(); @@ -218,8 +224,9 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests if an exception is thrown on data overflow */ + #[Test] #[DataProvider('maxLengthProvider')] - public function testMaxLengthOverflowException(Version $version, EccLevel $eccLevel, string $str, string $str1):void{ + public function maxLengthOverflowException(Version $version, EccLevel $eccLevel, string $str, string $str1):void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('code length overflow'); @@ -234,7 +241,8 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests if an exception is thrown when the data exceeds the maximum version while auto-detecting */ - public function testGetMinimumVersionException():void{ + #[Test] + public function getMinimumVersionException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('data exceeds'); @@ -244,7 +252,8 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests if an exception is thrown when an invalid character is encountered */ - public function testInvalidDataException():void{ + #[Test] + public function invalidDataException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid data'); @@ -254,7 +263,8 @@ abstract class DataInterfaceTestAbstract extends TestCase{ /** * Tests if an exception is thrown if the given string is empty */ - public function testInvalidDataOnEmptyException():void{ + #[Test] + public function invalidDataOnEmptyException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid data'); diff --git a/tests/Data/ECITest.php b/tests/Data/ECITest.php index 669e16a8a..9fbc796cf 100644 --- a/tests/Data/ECITest.php +++ b/tests/Data/ECITest.php @@ -13,9 +13,9 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Common\{BitBuffer, ECICharset, Mode}; -use chillerlan\QRCode\Data\{Byte, ECI, Hanzi, QRCodeDataException, QRData, QRDataModeInterface}; -use PHPUnit\Framework\Attributes\DataProvider; +use chillerlan\QRCode\Data\{Byte, ECI, Hanzi, QRCodeDataException, QRData}; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\{DataProvider, Test}; /** * Tests the ECI class @@ -42,12 +42,6 @@ final class ECITest extends TestCase{ ]; } - public function testDataModeInstance():void{ - $datamode = new ECI($this->testCharset); - - $this::assertInstanceOf(QRDataModeInterface::class, $datamode); - } - /** * returns versions within the version breakpoints 1-9, 10-26 and 27-40 * @@ -57,8 +51,9 @@ final class ECITest extends TestCase{ return ['1-9' => [7], '10-26' => [15], '27-40' => [30]]; } + #[Test] #[DataProvider('versionBreakpointProvider')] - public function testDecodeSegment(int $version):void{ + public function decodeSegment(int $version):void{ $options = new QROptions; $options->version = $version; @@ -75,7 +70,8 @@ final class ECITest extends TestCase{ $this::assertSame(self::testData, ECI::decodeSegment($bitBuffer, $options->version)); } - public function testInvalidDataException():void{ + #[Test] + public function invalidDataException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid encoding id:'); @@ -86,7 +82,8 @@ 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 */ - public function testInvalidDataOnEmptyException():void{ + #[Test] + public function invalidDataOnEmptyException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('invalid encoding id:'); @@ -107,8 +104,9 @@ final class ECITest extends TestCase{ ]; } + #[Test] #[DataProvider('eciCharsetIdProvider')] - public function testReadWrite(int $id, int $lengthInBits):void{ + public function readWrite(int $id, int $lengthInBits):void{ $bitBuffer = new BitBuffer; $eci = (new ECI($id))->write($bitBuffer, 1); @@ -120,7 +118,8 @@ final class ECITest extends TestCase{ /** * Tests if and exception is thrown when the ECI segment is followed by a mode that is not 8-bit byte */ - public function testDecodeECISegmentFollowedByInvalidModeException():void{ + #[Test] + public function decodeECISegmentFollowedByInvalidModeException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('ECI designator followed by invalid mode:'); @@ -151,8 +150,9 @@ final class ECITest extends TestCase{ /** * Tests detection of an unknown character set */ + #[Test] #[DataProvider('unknownEncodingDataProvider')] - public function testConvertUnknownEncoding(int $id, string $data):void{ + public function convertUnknownEncoding(int $id, string $data):void{ $options = new QROptions; $options->version = 5; diff --git a/tests/Data/HanziTest.php b/tests/Data/HanziTest.php index 36ffe0b10..b034ed83f 100644 --- a/tests/Data/HanziTest.php +++ b/tests/Data/HanziTest.php @@ -11,10 +11,8 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Data\Hanzi; -use chillerlan\QRCode\Data\QRDataModeInterface; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Group; +use chillerlan\QRCode\Data\{Hanzi, QRDataModeInterface}; +use PHPUnit\Framework\Attributes\{DataProvider, Group, Test}; use Generator, Throwable; use function bin2hex, chr, defined, sprintf; @@ -70,9 +68,10 @@ final class HanziTest extends DataInterfaceTestAbstract{ } + #[Test] #[Group('slow')] #[DataProvider('hanziProvider')] - public function testValidateGB2312(string $chr):void{ + public function validateGB2312(string $chr):void{ // we may run into several issues due to encoding detection failures try{ $this::assertTrue(Hanzi::validateString($chr)); diff --git a/tests/Data/KanjiTest.php b/tests/Data/KanjiTest.php index 8619c9e04..4771daa22 100644 --- a/tests/Data/KanjiTest.php +++ b/tests/Data/KanjiTest.php @@ -11,11 +11,9 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Data\Kanji; -use chillerlan\QRCode\Data\QRDataModeInterface; +use chillerlan\QRCode\Data\{Kanji, QRDataModeInterface}; +use PHPUnit\Framework\Attributes\{DataProvider, Group, Test}; use Generator, Throwable; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Group; use function bin2hex, chr, defined, sprintf; /** @@ -97,9 +95,10 @@ final class KanjiTest extends DataInterfaceTestAbstract{ } + #[Test] #[Group('slow')] #[DataProvider('kanjiProvider')] - public function testValidateSJIS(string $chr):void{ + public function validateSJIS(string $chr):void{ // we may run into several issues due to encoding detection failures try{ $this::assertTrue(Kanji::validateString($chr)); diff --git a/tests/Data/NumberTest.php b/tests/Data/NumberTest.php index e80e57b61..abfa66116 100644 --- a/tests/Data/NumberTest.php +++ b/tests/Data/NumberTest.php @@ -11,8 +11,7 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Data\Number; -use chillerlan\QRCode\Data\QRDataModeInterface; +use chillerlan\QRCode\Data\{Number, QRDataModeInterface}; /** * Tests the Number class diff --git a/tests/Data/QRDataTest.php b/tests/Data/QRDataTest.php index c4b1e3d71..986002d14 100644 --- a/tests/Data/QRDataTest.php +++ b/tests/Data/QRDataTest.php @@ -11,14 +11,11 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Data; -use chillerlan\QRCode\Common\BitBuffer; -use chillerlan\QRCode\Common\EccLevel; -use chillerlan\QRCode\Common\MaskPattern; -use chillerlan\QRCode\Data\Byte; -use chillerlan\QRCode\Data\QRData; +use PHPUnit\Framework\Attributes\Test; +use chillerlan\QRCode\{QRCode, QROptions}; +use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern}; +use chillerlan\QRCode\Data\{Byte, QRData}; use chillerlan\QRCode\Output\QRGdImagePNG; -use chillerlan\QRCode\QRCode; -use chillerlan\QRCode\QROptions; use chillerlan\QRCodeTest\Traits\QRMatrixDebugTrait; use PHPUnit\Framework\TestCase; @@ -28,7 +25,8 @@ final class QRDataTest extends TestCase{ /** * tests setting the BitBuffer object directly */ - public function testSetBitBuffer():void{ + #[Test] + public function setBitBuffer():void{ $rawBytes = [ 67, 22, 135, 71, 71, 7, 51, 162, 242, 247, 119, 119, 114, 231, 150, 247, 87, 71, 86, 38, 82, 230, 54, 246, 210, 247, 118, 23, 70, 54, 131, 247, @@ -60,17 +58,16 @@ final class QRDataTest extends TestCase{ $this->debugMatrix($matrix); - $this::assertSame($decodeResult->data, 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s'); + $this::assertSame('https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s', $decodeResult->data); } - public function testEstimateTotalBitLength():void{ + #[Test] + public function estimateTotalBitLength():void{ $options = new QROptions([ 'versionMin' => 10, 'quietzoneSize' => 2, 'eccLevel' => EccLevel::H, -# 'outputType' => QROutputInterface::CUSTOM, -# 'outputInterface' => PmaQrCodeSVG::class, 'outputBase64' => false, 'cssClass' => 'pma-2fa-qrcode', 'drawCircularModules' => true, diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index e4b7d855c..2f5d997dc 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -16,7 +16,7 @@ use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version}; use chillerlan\QRCode\Data\{QRCodeDataException, QRMatrix}; use chillerlan\QRCodeTest\Traits\QRMatrixDebugTrait; use PHPUnit\Framework\TestCase; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{DataProvider, Test}; use Generator; /** @@ -41,28 +41,32 @@ final class QRMatrixTest extends TestCase{ /** * Tests if size() returns the actual matrix size/count */ - public function testGetSize():void{ + #[Test] + public function getSize():void{ $this::assertCount($this->matrix->getSize(), $this->matrix->getBooleanMatrix()); } /** * Tests if version() returns the current (given) version */ - public function testGetVersion():void{ + #[Test] + public function getVersion():void{ $this::assertSame($this::version, $this->matrix->getVersion()->getVersionNumber()); } /** * Tests if eccLevel() returns the current (given) ECC level */ - public function testGetECC():void{ + #[Test] + public function getECC():void{ $this::assertSame(EccLevel::L, $this->matrix->getEccLevel()->getLevel()); } /** * Tests if maskPattern() returns the current (or default) mask pattern */ - public function testGetMaskPattern():void{ + #[Test] + public function getMaskPattern():void{ // set via matrix evaluation $matrix = (new QRCode)->addByteSegment('testdata')->getQRMatrix(); @@ -73,7 +77,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests the set(), get() and check() methods */ - public function testGetSetCheck():void{ + #[Test] + public function getSetCheck():void{ $this->matrix->set(10, 10, true, QRMatrix::M_LOGO); $this::assertSame(QRMatrix::M_LOGO_DARK, $this->matrix->get(10, 10)); $this::assertTrue($this->matrix->check(10, 10)); @@ -108,8 +113,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests setting the dark module and verifies its position */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetDarkModule(QRMatrix $matrix):void{ + public function setDarkModule(QRMatrix $matrix):void{ $matrix->setDarkModule(); $this->dm($matrix); @@ -120,8 +126,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests setting the finder patterns and verifies their positions */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetFinderPattern(QRMatrix $matrix):void{ + public function setFinderPattern(QRMatrix $matrix):void{ $matrix->setFinderPattern(); $this->dm($matrix); @@ -134,8 +141,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the separator patterns and verifies their positions */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetSeparators(QRMatrix $matrix):void{ + public function setSeparators(QRMatrix $matrix):void{ $matrix->setSeparators(); $this->dm($matrix); @@ -149,8 +157,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the alignment patterns and verifies their positions - version 1 (no pattern) skipped */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetAlignmentPattern(QRMatrix $matrix):void{ + public function setAlignmentPattern(QRMatrix $matrix):void{ $version = $matrix->getVersion(); if($version->getVersionNumber() === 1){ @@ -180,8 +189,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the timing patterns and verifies their positions */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetTimingPattern(QRMatrix $matrix):void{ + public function setTimingPattern(QRMatrix $matrix):void{ $matrix ->setFinderPattern() @@ -208,8 +218,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the version patterns and verifies their positions - version < 7 skipped */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetVersionNumber(QRMatrix $matrix):void{ + public function setVersionNumber(QRMatrix $matrix):void{ if($matrix->getVersion()->getVersionNumber() < 7){ $this::markTestSkipped('N/A (Version < 7)'); @@ -228,8 +239,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the format patterns and verifies their positions */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetFormatInfo(QRMatrix $matrix):void{ + public function setFormatInfo(QRMatrix $matrix):void{ $matrix->setFormatInfo(new MaskPattern(MaskPattern::PATTERN_000)); $this->dm($matrix); @@ -243,8 +255,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests the quiet zone pattern and verifies its position */ + #[Test] #[DataProvider('matrixProvider')] - public function testSetQuietZone(QRMatrix $matrix):void{ + public function setQuietZone(QRMatrix $matrix):void{ $size = $matrix->getSize(); $quietZoneSize = 5; @@ -274,7 +287,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests if an exception is thrown in an attempt to create the quiet zone before data was written */ - public function testSetQuietZoneException():void{ + #[Test] + public function setQuietZoneException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('use only after writing data'); @@ -284,8 +298,9 @@ final class QRMatrixTest extends TestCase{ /** * Tests rotating the matrix by 90 degrees CW */ + #[Test] #[DataProvider('matrixProvider')] - public function testRotate90(QRMatrix $matrix):void{ + public function rotate90(QRMatrix $matrix):void{ $matrix->initFunctionalPatterns(); // matrix size @@ -320,7 +335,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests if the logo space is drawn square if one of the dimensions is omitted */ - public function testSetLogoSpaceOmitDimension():void{ + #[Test] + public function setLogoSpaceOmitDimension():void{ $o = new QROptions; $o->version = 2; $o->eccLevel = EccLevel::H; @@ -342,7 +358,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests the auto orientation of the logo space */ - public function testSetLogoSpaceOrientation():void{ + #[Test] + public function setLogoSpaceOrientation():void{ $o = new QROptions; $o->version = 10; $o->eccLevel = EccLevel::H; @@ -366,7 +383,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests the manual positioning of the logo space */ - public function testSetLogoSpacePosition():void{ + #[Test] + public function setLogoSpacePosition():void{ $o = new QROptions; $o->version = 10; $o->eccLevel = EccLevel::H; @@ -394,7 +412,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests whether an exception is thrown when an ECC level other than "H" is set when attempting to add logo space */ - public function testSetLogoSpaceInvalidEccException():void{ + #[Test] + public function setLogoSpaceInvalidEccException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('ECC level "H" required to add logo space'); @@ -404,7 +423,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests whether an exception is thrown when width or height exceed the matrix size */ - public function testSetLogoSpaceExceedsException():void{ + #[Test] + public function setLogoSpaceExceedsException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('logo dimensions exceed matrix size'); @@ -418,7 +438,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests whether an exception is thrown when the logo space size exceeds the maximum ECC capacity */ - public function testSetLogoSpaceMaxSizeException():void{ + #[Test] + public function setLogoSpaceMaxSizeException():void{ $this->expectException(QRCodeDataException::class); $this->expectExceptionMessage('logo space exceeds the maximum error correction capacity'); @@ -432,7 +453,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests flipping the value of a module */ - public function testFlip():void{ + #[Test] + public function flip():void{ $this->matrix->set(20, 20, true, QRMatrix::M_LOGO); // cover checkType() @@ -452,7 +474,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests checking whether the M_TYPE of a module is not one of an array of M_TYPES */ - public function testCheckTypeIn():void{ + #[Test] + public function checkTypeIn():void{ $this->matrix->set(10, 10, true, QRMatrix::M_QUIETZONE); $this::assertFalse($this->matrix->checkTypeIn(10, 10, [QRMatrix::M_DATA, QRMatrix::M_FINDER])); @@ -462,7 +485,8 @@ final class QRMatrixTest extends TestCase{ /** * Tests checking the adjacent modules */ - public function testCheckNeighbours():void{ + #[Test] + public function checkNeighbours():void{ $this->matrix ->setFinderPattern() diff --git a/tests/Output/QREpsTest.php b/tests/Output/QREpsTest.php index 03dca73de..aca22ec63 100644 --- a/tests/Output/QREpsTest.php +++ b/tests/Output/QREpsTest.php @@ -15,7 +15,11 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QREps, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\Test; +/** + * Tests the QREps output class + */ class QREpsTest extends QROutputTestAbstract{ public static function moduleValueProvider():array{ @@ -37,7 +41,8 @@ class QREpsTest extends QROutputTestAbstract{ return new QREps($options, $matrix); } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data diff --git a/tests/Output/QRFpdfTest.php b/tests/Output/QRFpdfTest.php index 4b0d71e3d..d406e0783 100644 --- a/tests/Output/QRFpdfTest.php +++ b/tests/Output/QRFpdfTest.php @@ -16,24 +16,15 @@ use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRFpdf, QROutputInterface}; use chillerlan\QRCodeTest\Traits\RGBArrayModuleValueProviderTrait; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\Test; use FPDF; -use function class_exists; /** - * Tests the QRFpdf output module + * Tests the QRFpdf output class */ final class QRFpdfTest extends QROutputTestAbstract{ use RGBArrayModuleValueProviderTrait; - protected function setUp():void{ - - if(!class_exists(FPDF::class)){ - $this::markTestSkipped('FPDF not available'); - } - - parent::setUp(); - } - protected function getOutputInterface( SettingsContainerInterface|QROptions $options, QRMatrix $matrix, @@ -41,7 +32,8 @@ final class QRFpdfTest extends QROutputTestAbstract{ return new QRFpdf($options, $matrix); } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data diff --git a/tests/Output/QRGdImageAVIFTest.php b/tests/Output/QRGdImageAVIFTest.php index 9e2d0eb0c..4ff5f8059 100644 --- a/tests/Output/QRGdImageAVIFTest.php +++ b/tests/Output/QRGdImageAVIFTest.php @@ -15,19 +15,12 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImageAVIF, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; -use function function_exists; +use PHPUnit\Framework\Attributes\{RequiresFunction, RequiresPhpExtension}; +#[RequiresPhpExtension('gd')] +#[RequiresFunction('imageavif')] final class QRGdImageAVIFTest extends QRGdImageTestAbstract{ - protected function setUp():void{ - parent::setUp(); - - if(!function_exists('imageavif')){ - $this::markTestSkipped('no AVIF support'); - } - - } - protected function getOutputInterface( SettingsContainerInterface|QROptions $options, QRMatrix $matrix, diff --git a/tests/Output/QRGdImageBMPTest.php b/tests/Output/QRGdImageBMPTest.php index eba634d5b..a2fc1e9a5 100644 --- a/tests/Output/QRGdImageBMPTest.php +++ b/tests/Output/QRGdImageBMPTest.php @@ -15,7 +15,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImageBMP, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; +#[RequiresPhpExtension('gd')] final class QRGdImageBMPTest extends QRGdImageTestAbstract{ protected function getOutputInterface( diff --git a/tests/Output/QRGdImageGIFTest.php b/tests/Output/QRGdImageGIFTest.php index 0f6bfc66d..53f89373f 100644 --- a/tests/Output/QRGdImageGIFTest.php +++ b/tests/Output/QRGdImageGIFTest.php @@ -15,7 +15,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImageGIF, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; +#[RequiresPhpExtension('gd')] final class QRGdImageGIFTest extends QRGdImageTestAbstract{ protected function getOutputInterface( diff --git a/tests/Output/QRGdImageJPGTest.php b/tests/Output/QRGdImageJPGTest.php index d7e19c8d3..a65e90bb1 100644 --- a/tests/Output/QRGdImageJPGTest.php +++ b/tests/Output/QRGdImageJPGTest.php @@ -15,7 +15,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImageJPEG, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; +#[RequiresPhpExtension('gd')] final class QRGdImageJPGTest extends QRGdImageTestAbstract{ protected function getOutputInterface( diff --git a/tests/Output/QRGdImagePNGTest.php b/tests/Output/QRGdImagePNGTest.php index a36622bd5..7b0b3ec87 100644 --- a/tests/Output/QRGdImagePNGTest.php +++ b/tests/Output/QRGdImagePNGTest.php @@ -15,7 +15,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImagePNG, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; +#[RequiresPhpExtension('gd')] final class QRGdImagePNGTest extends QRGdImageTestAbstract{ protected function getOutputInterface( diff --git a/tests/Output/QRGdImageTestAbstract.php b/tests/Output/QRGdImageTestAbstract.php index b7faa1130..f1ad24568 100644 --- a/tests/Output/QRGdImageTestAbstract.php +++ b/tests/Output/QRGdImageTestAbstract.php @@ -15,25 +15,18 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCodeTest\Traits\RGBArrayModuleValueProviderTrait; +use PHPUnit\Framework\Attributes\{RequiresPhpExtension, Test}; use GdImage; -use function extension_loaded; /** - * Tests the QRGdImage output module + * Tests the QRGdImage output classes */ +#[RequiresPhpExtension('gd')] abstract class QRGdImageTestAbstract extends QROutputTestAbstract{ use RGBArrayModuleValueProviderTrait; - protected function setUp():void{ - - if(!extension_loaded('gd')){ - $this::markTestSkipped('ext-gd not loaded'); - } - - parent::setUp(); - } - - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data @@ -48,14 +41,16 @@ abstract class QRGdImageTestAbstract extends QROutputTestAbstract{ $this::assertTrue(true); // tricking the code coverage } - public function testOutputGetResource():void{ + #[Test] + public function outputGetResource():void{ $this->options->returnResource = true; $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); $this::assertInstanceOf(GdImage::class, $this->outputInterface->dump()); } - public function testBase64MimeType():void{ + #[Test] + public function base64MimeType():void{ $this->options->outputBase64 = true; $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); diff --git a/tests/Output/QRGdImageWEBPTest.php b/tests/Output/QRGdImageWEBPTest.php index 29433eca4..2bb9706e2 100644 --- a/tests/Output/QRGdImageWEBPTest.php +++ b/tests/Output/QRGdImageWEBPTest.php @@ -15,7 +15,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRGdImageWEBP, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; +#[RequiresPhpExtension('gd')] final class QRGdImageWEBPTest extends QRGdImageTestAbstract{ protected function getOutputInterface( diff --git a/tests/Output/QRImagickTest.php b/tests/Output/QRImagickTest.php index fa83b333a..6c509b22f 100644 --- a/tests/Output/QRImagickTest.php +++ b/tests/Output/QRImagickTest.php @@ -17,23 +17,15 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRImagick, QROutputInterface}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\{RequiresPhpExtension, Test}; use Imagick; -use function extension_loaded; /** - * Tests the QRImagick output module + * Tests the QRImagick output class */ +#[RequiresPhpExtension('imagick')] final class QRImagickTest extends QROutputTestAbstract{ - protected function setUp():void{ - - if(!extension_loaded('imagick')){ - $this::markTestSkipped('ext-imagick not loaded'); - } - - parent::setUp(); - } - protected function getOutputInterface( SettingsContainerInterface|QROptions $options, QRMatrix $matrix, @@ -67,7 +59,8 @@ final class QRImagickTest extends QROutputTestAbstract{ ]; } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data @@ -82,7 +75,8 @@ final class QRImagickTest extends QROutputTestAbstract{ $this::assertTrue(true); // tricking the code coverage } - public function testOutputGetResource():void{ + #[Test] + public function outputGetResource():void{ $this->options->returnResource = true; $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); diff --git a/tests/Output/QRInterventionImageTest.php b/tests/Output/QRInterventionImageTest.php index 49ee74759..d0ef7886e 100644 --- a/tests/Output/QRInterventionImageTest.php +++ b/tests/Output/QRInterventionImageTest.php @@ -11,30 +11,21 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QRInterventionImage; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\QROptions; +use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\Output\{QRInterventionImage, QROutputInterface}; use chillerlan\QRCodeTest\Traits\CssColorModuleValueProviderTrait; use chillerlan\Settings\SettingsContainerInterface; use Intervention\Image\Interfaces\ImageInterface; -use function extension_loaded; +use PHPUnit\Framework\Attributes\{RequiresPhpExtension, Test}; /** - * Tests the QRInterventionImage output module + * Tests the QRInterventionImage output class */ +#[RequiresPhpExtension('gd')] class QRInterventionImageTest extends QROutputTestAbstract{ use CssColorModuleValueProviderTrait; - protected function setUp():void{ - - if(!extension_loaded('gd')){ - $this::markTestSkipped('ext-gd not loaded'); - } - - parent::setUp(); - } - protected function getOutputInterface( SettingsContainerInterface|QROptions $options, QRMatrix $matrix, @@ -42,7 +33,8 @@ class QRInterventionImageTest extends QROutputTestAbstract{ return new QRInterventionImage($options, $matrix); } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data @@ -57,7 +49,8 @@ class QRInterventionImageTest extends QROutputTestAbstract{ $this::assertTrue(true); // tricking the code coverage } - public function testOutputGetResource():void{ + #[Test] + public function outputGetResource():void{ $this->options->returnResource = true; $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); diff --git a/tests/Output/QRMarkupTestAbstract.php b/tests/Output/QRMarkupTestAbstract.php index ed54b4acf..2d9136dea 100644 --- a/tests/Output/QRMarkupTestAbstract.php +++ b/tests/Output/QRMarkupTestAbstract.php @@ -13,14 +13,16 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCodeTest\Traits\CssColorModuleValueProviderTrait; +use PHPUnit\Framework\Attributes\Test; /** - * Tests the QRMarkup output module + * Tests the QRMarkup output classes */ abstract class QRMarkupTestAbstract extends QROutputTestAbstract{ use CssColorModuleValueProviderTrait; - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->outputBase64 = false; $this->options->drawLightModules = true; $this->options->moduleValues = [ @@ -31,6 +33,7 @@ abstract class QRMarkupTestAbstract extends QROutputTestAbstract{ $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 f05f1ef09..8b85a4d49 100644 --- a/tests/Output/QROutputTestAbstract.php +++ b/tests/Output/QROutputTestAbstract.php @@ -11,13 +11,13 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCodeTest\Traits\BuildDirTrait; use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface}; +use chillerlan\QRCodeTest\Traits\BuildDirTrait; use chillerlan\Settings\SettingsContainerInterface; -use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\{DataProvider, Test}; use ReflectionObject; /** @@ -52,7 +52,8 @@ abstract class QROutputTestAbstract extends TestCase{ /** * Tests if an exception is thrown when trying to write a cache file to an invalid destination */ - public function testSaveException():void{ + #[Test] + public function saveException():void{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('Cannot write data to cache file: /foo/bar.test'); @@ -64,8 +65,9 @@ abstract class QROutputTestAbstract extends TestCase{ */ abstract public static function moduleValueProvider():array; + #[Test] #[DataProvider('moduleValueProvider')] - public function testValidateModuleValues(mixed $value, bool $expected):void{ + public function validateModuleValues(mixed $value, bool $expected):void{ $this::assertSame($expected, $this->outputInterface::moduleValueIsValid($value)); } @@ -76,12 +78,14 @@ abstract class QROutputTestAbstract extends TestCase{ /** * covers the module values settings */ - abstract public function testSetModuleValues():void; + #[Test] + abstract public function setModuleValues():void; /** * coverage of the built-in output modules */ - public function testRenderToCacheFile():void{ + #[Test] + public function renderToCacheFile():void{ $this->options->outputBase64 = false; $this->outputInterface = $this->getOutputInterface($this->options, $this->matrix); // create the cache file diff --git a/tests/Output/QRStringJSONTest.php b/tests/Output/QRStringJSONTest.php index f86d3104c..058ed20b3 100644 --- a/tests/Output/QRStringJSONTest.php +++ b/tests/Output/QRStringJSONTest.php @@ -16,7 +16,11 @@ use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QROutputInterface, QRStringJSON}; use chillerlan\QRCodeTest\Traits\CssColorModuleValueProviderTrait; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\Test; +/** + * Tests the QRStringJSON output class + */ final class QRStringJSONTest extends QROutputTestAbstract{ use CssColorModuleValueProviderTrait; @@ -27,7 +31,8 @@ final class QRStringJSONTest extends QROutputTestAbstract{ return new QRStringJSON($options, $matrix); } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data diff --git a/tests/Output/QRStringTextTest.php b/tests/Output/QRStringTextTest.php index b145ab541..f9b58e0e8 100644 --- a/tests/Output/QRStringTextTest.php +++ b/tests/Output/QRStringTextTest.php @@ -15,7 +15,11 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\{QROutputInterface, QRStringText}; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\Test; +/** + * Tests the QRStringText output class + */ final class QRStringTextTest extends QROutputTestAbstract{ protected function getOutputInterface( @@ -37,7 +41,8 @@ final class QRStringTextTest extends QROutputTestAbstract{ ]; } - public function testSetModuleValues():void{ + #[Test] + public function setModuleValues():void{ $this->options->moduleValues = [ // data diff --git a/tests/QRCodeReaderGDTest.php b/tests/QRCodeReaderGDTest.php index c2056634f..2c2583f94 100644 --- a/tests/QRCodeReaderGDTest.php +++ b/tests/QRCodeReaderGDTest.php @@ -14,10 +14,12 @@ namespace chillerlan\QRCodeTest; use chillerlan\QRCode\Common\{GDLuminanceSource, LuminanceSourceInterface}; use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; /** * Tests the GD based reader */ +#[RequiresPhpExtension('gd')] final class QRCodeReaderGDTest extends QRCodeReaderTestAbstract{ protected function getLuminanceSourceFromFile( diff --git a/tests/QRCodeReaderImagickTest.php b/tests/QRCodeReaderImagickTest.php index 31508a2e3..33c75ecb2 100644 --- a/tests/QRCodeReaderImagickTest.php +++ b/tests/QRCodeReaderImagickTest.php @@ -15,21 +15,16 @@ 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 PHPUnit\Framework\Attributes\{DataProvider, RequiresPhpExtension, Test}; use const PHP_OS_FAMILY; /** * Tests the Imagick based reader */ +#[RequiresPhpExtension('imagick')] final class QRCodeReaderImagickTest extends QRCodeReaderTestAbstract{ protected function setUp():void{ - - if(!extension_loaded('imagick')){ - $this::markTestSkipped('imagick not installed'); - } - parent::setUp(); $this->options->readerUseImagickIfAvailable = true; @@ -55,8 +50,9 @@ final class QRCodeReaderImagickTest extends QRCodeReaderTestAbstract{ ]; } + #[Test] #[DataProvider('vectorQRCodeProvider')] - public function testReadVectorFormats(string $img, string $expected):void{ + public function readVectorFormats(string $img, string $expected):void{ if(PHP_OS_FAMILY === 'Linux'){ $this::markTestSkipped('avoid imagick conversion errors (ha ha)'); diff --git a/tests/QRCodeReaderTestAbstract.php b/tests/QRCodeReaderTestAbstract.php index 4c8374ca1..16995e0a6 100644 --- a/tests/QRCodeReaderTestAbstract.php +++ b/tests/QRCodeReaderTestAbstract.php @@ -20,7 +20,7 @@ use chillerlan\QRCode\Decoder\Decoder; use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\QRCodeTest\Traits\{QRMatrixDebugTrait, QRMaxLengthTrait}; use chillerlan\Settings\SettingsContainerInterface; -use PHPUnit\Framework\Attributes\{DataProvider, Group}; +use PHPUnit\Framework\Attributes\{DataProvider, Group, Test}; use PHPUnit\Framework\TestCase; use Exception, Generator, RuntimeException; use function array_map, defined, realpath, sprintf, str_repeat, substr; @@ -49,6 +49,11 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ $this->options->readerUseImagickIfAvailable = false; } + abstract protected function getLuminanceSourceFromFile( + string $file, + SettingsContainerInterface|QROptions $options, + ):LuminanceSourceInterface; + /** * @phpstan-return array */ @@ -79,14 +84,10 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ ]; } - abstract protected function getLuminanceSourceFromFile( - string $file, - SettingsContainerInterface|QROptions $options, - ):LuminanceSourceInterface; - + #[Test] #[Group('slow')] #[DataProvider('qrCodeProvider')] - public function testReader(string $img, string $expected, bool $grayscale):void{ + public function reader(string $img, string $expected, bool $grayscale):void{ if($grayscale){ $this->options->readerGrayscale = true; @@ -107,7 +108,8 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ $this::assertSame($expected, (string)$result); } - public function testReaderMultiMode():void{ + #[Test] + public function readerMultiMode():void{ $this->options->outputInterface = QRGdImagePNG::class; $this->options->outputBase64 = false; @@ -154,9 +156,10 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ } + #[Test] #[Group('slow')] #[DataProvider('dataTestProvider')] - public function testReadData(Version $version, EccLevel $ecc, string $expected):void{ + public function readData(Version $version, EccLevel $ecc, string $expected):void{ $this->options->outputInterface = QRGdImagePNG::class; $this->options->imageTransparent = false; $this->options->eccLevel = $ecc->getLevel(); diff --git a/tests/QRCodeTest.php b/tests/QRCodeTest.php index 0b001c922..5b3e3cb74 100755 --- a/tests/QRCodeTest.php +++ b/tests/QRCodeTest.php @@ -11,9 +11,11 @@ declare(strict_types=1); namespace chillerlan\QRCodeTest; -use chillerlan\QRCode\{QROptions, QRCode}; -use chillerlan\QRCode\Output\QRCodeOutputException; +use chillerlan\QRCode\{QRCode, QRCodeException, QROptions}; +use chillerlan\QRCode\Common\ECICharset; +use chillerlan\QRCode\Output\{QRCodeOutputException, QRGdImagePNG}; use chillerlan\QRCodeTest\Traits\BuildDirTrait; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use stdClass; @@ -41,7 +43,8 @@ final class QRCodeTest extends TestCase{ /** * tests if an exception is thrown if the given output class does not exist */ - public function testInitCustomOutputInterfaceNotExistsException():void{ + #[Test] + public function initCustomOutputInterfaceNotExistsException():void{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('invalid output class'); @@ -53,7 +56,8 @@ final class QRCodeTest extends TestCase{ /** * tests if an exception is thrown if the given output class does not implement QROutputInterface */ - public function testInitCustomOutputInterfaceNotImplementsException():void{ + #[Test] + public function initCustomOutputInterfaceNotImplementsException():void{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('output class does not implement QROutputInterface'); @@ -65,7 +69,8 @@ final class QRCodeTest extends TestCase{ /** * Tests if an exception is thrown when trying to write a cache file to an invalid destination */ - public function testSaveException():void{ + #[Test] + public function saveException():void{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('Cannot write data to cache file: /foo/bar.test'); @@ -77,7 +82,8 @@ final class QRCodeTest extends TestCase{ /** * Tests if a cache file is properly saved in the given path */ - public function testRenderToCacheFile():void{ + #[Test] + public function renderToCacheFile():void{ $fileSubPath = $this::buildDir.'/test.cache.svg'; $this->options->cachefile = $this->getBuildPath($fileSubPath); @@ -88,4 +94,31 @@ final class QRCodeTest extends TestCase{ $this::assertSame($data, $this->getBuildFileContent($fileSubPath)); } + /** + * Tests adding and decoding an ECI sequence + */ + #[Test] + public function addEciSegment():void{ + $expected = '无可奈何燃花作香'; + + $qrCode = (new QRCode([ + 'outputBase64' => false, + 'outputInterface' => QRGdImagePNG::class, + ])); + + $qrCode->addEciSegment(ECICharset::GB18030, $expected); + + $result = $qrCode->readFromBlob($qrCode->render()); + + $this::assertSame($expected, $result->data); + } + + #[Test] + public function addEciSegmentInvalidCharsetException():void{ + $this->expectException(QRCodeException::class); + $this->expectExceptionMessage('unable to add ECI segment'); + + (new QRCode)->addEciSegment(666, 'nope'); + } + } diff --git a/tests/QROptionsTest.php b/tests/QROptionsTest.php index ee488fce6..049b60563 100644 --- a/tests/QROptionsTest.php +++ b/tests/QROptionsTest.php @@ -15,7 +15,7 @@ namespace chillerlan\QRCodeTest; use chillerlan\QRCode\{QRCodeException, QROptions}; use chillerlan\QRCode\Common\{EccLevel, Version}; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{Test, TestWith}; use PHPUnit\Framework\TestCase; /** @@ -23,45 +23,29 @@ use PHPUnit\Framework\TestCase; */ final class QROptionsTest extends TestCase{ - /** - * @return int[][] - */ - public static function VersionProvider():array{ - return [ - 'values > 40 should be clamped to 40' => [42, 40], - 'values < 1 should be clamped to 1' => [-42, 1], - 'values in between shold not be touched' => [21, 21], - 'value -1 should be treated as is (default)' => [Version::AUTO, -1], - ]; - } - /** * Tests the $version clamping */ - #[DataProvider('VersionProvider')] - public function testVersionClamp(int $version, int $expected):void{ + #[Test] + #[TestWith([42, 40], 'values > 40 should be clamped to 40')] + #[TestWith([-42, 1], 'values < 1 should be clamped to 1')] + #[TestWith([21, 21], 'values in between should not be touched')] + #[TestWith([Version::AUTO, -1], 'value -1 should be treated as is (default)')] + public function versionClamp(int $version, int $expected):void{ $o = new QROptions(['version' => $version]); $this::assertSame($expected, $o->version); } - /** - * @return int[][] - */ - public static function VersionMinMaxProvider():array{ - return [ - 'normal clamp' => [5, 10, 5, 10], - 'exceeding values' => [-42, 42, 1, 40], - 'min > max' => [10, 5, 5, 10], - 'min > max, exceeding' => [42, -42, 1, 40], - ]; - } - /** * Tests the $versionMin/$versionMax clamping */ - #[DataProvider('VersionMinMaxProvider')] - public function testVersionMinMaxClamp(int $versionMin, int $versionMax, int $expectedMin, int $expectedMax):void{ + #[Test] + #[TestWith([5, 10, 5, 10], 'normal clamp')] + #[TestWith([-42, 42, 1, 40], 'exceeding values')] + #[TestWith([10, 5, 5, 10], 'min > max' )] + #[TestWith([42, -42, 1, 40], 'min > max, exceeding')] + public function versionMinMaxClamp(int $versionMin, int $versionMax, int $expectedMin, int $expectedMax):void{ $o = new QROptions(['versionMin' => $versionMin, 'versionMax' => $versionMax]); $this::assertSame($expectedMin, $o->versionMin); @@ -73,7 +57,8 @@ final class QROptionsTest extends TestCase{ * * @phan-suppress PhanTypeMismatchPropertyProbablyReal */ - public function testSetEccLevel():void{ + #[Test] + public function setEccLevel():void{ $o = new QROptions(['eccLevel' => EccLevel::H]); $this::assertSame(EccLevel::H, $o->eccLevel); @@ -86,7 +71,8 @@ final class QROptionsTest extends TestCase{ /** * Tests if an exception is thrown when attempting to set an invalid ECC level integer */ - public function testSetEccLevelFromIntException():void{ + #[Test] + public function setEccLevelFromIntException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('Invalid ECC level: "42"'); @@ -96,42 +82,24 @@ final class QROptionsTest extends TestCase{ /** * Tests if an exception is thrown when attempting to set an invalid ECC level string */ - public function testSetEccLevelFromStringException():void{ + #[Test] + public function setEccLevelFromStringException():void{ $this->expectException(QRCodeException::class); $this->expectExceptionMessage('Invalid ECC level: "FOO"'); new QROptions(['eccLevel' => 'foo']); } - /** - * @return int[][][] - */ - public static function RGBProvider():array{ - return [ - 'exceeding values' => [[-1, 0, 999], [0, 0 ,255]], - 'too few values' => [[1, 2], [255, 255, 255]], - 'too many values' => [[1, 2, 3, 4, 5], [1, 2, 3]], - ]; - } - - /** - * @return int[][] - */ - public static function logoSpaceValueProvider():array{ - return [ - 'negative' => [ -1, 0], - 'zero' => [ 0, 0], - 'normal' => [ 69, 69], - 'max' => [177, 177], - 'exceed' => [178, 177], - ]; - } - /** * Tests the clamping (between 0 and 177) of the logo space values */ - #[DataProvider('logoSpaceValueProvider')] - public function testClampLogoSpaceValue(int $value, int $expected):void{ + #[Test] + #[TestWith([ -1, 0], 'negative')] + #[TestWith([ 0, 0], 'zero')] + #[TestWith([ 69, 69], 'normal')] + #[TestWith([177, 177], 'max')] + #[TestWith([178, 177], 'exceed')] + public function clampLogoSpaceValue(int $value, int $expected):void{ $o = new QROptions; foreach(['logoSpaceWidth', 'logoSpaceHeight', 'logoSpaceStartX', 'logoSpaceStartY'] as $prop){ @@ -144,7 +112,8 @@ final class QROptionsTest extends TestCase{ /** * Tests if the optional logo space start values are nullable */ - public function testLogoSpaceStartNullable():void{ + #[Test] + public function logoSpaceStartNullable():void{ $o = new QROptions([ 'logoSpaceStartX' => 42, 'logoSpaceStartY' => 69, @@ -160,22 +129,14 @@ final class QROptionsTest extends TestCase{ $this::assertNull($o->logoSpaceStartY); } - /** - * @return float[][] - */ - public static function circleRadiusProvider():array{ - return [ - [0.0, 0.1], - [0.5, 0.5], - [1.5, 0.75], - ]; - } - /** * Tests clamping of the circle radius */ - #[DataProvider('circleRadiusProvider')] - public function testClampCircleRadius(float $value, float $expected):void{ + #[Test] + #[TestWith([0.0, 0.1], 'min')] + #[TestWith([0.5, 0.5], 'no clamp')] + #[TestWith([1.5, 0.75], 'max')] + public function clampCircleRadius(float $value, float $expected):void{ $o = new QROptions(['circleRadius' => $value]); $this::assertSame($expected, $o->circleRadius);