DataInterfaceTestAbstract.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. /**
  3. * Class DataInterfaceTestAbstract
  4. *
  5. * @created 24.11.2017
  6. * @author Smiley <smiley@chillerlan.net>
  7. * @copyright 2017 Smiley
  8. * @license MIT
  9. */
  10. namespace chillerlan\QRCodeTest\Data;
  11. use chillerlan\QRCode\Common\{MaskPattern, Version};
  12. use chillerlan\QRCode\QROptions;
  13. use PHPUnit\Framework\TestCase;
  14. use chillerlan\QRCode\Data\{QRCodeDataException, QRData, QRDataModeInterface, QRMatrix};
  15. use ReflectionClass;
  16. use function str_repeat;
  17. /**
  18. * The data interface test abstract
  19. */
  20. abstract class DataInterfaceTestAbstract extends TestCase{
  21. protected ReflectionClass $reflection;
  22. protected QRData $QRData;
  23. protected string $FQN;
  24. protected string $testdata;
  25. protected function setUp():void{
  26. $this->QRData = new QRData(new QROptions);
  27. $this->reflection = new ReflectionClass($this->QRData);
  28. }
  29. /**
  30. * Verifies the QRData instance
  31. */
  32. public function testInstance():void{
  33. $this::assertInstanceOf(QRData::class, $this->QRData);
  34. }
  35. /**
  36. * Verifies the QRDataModeInterface instance
  37. */
  38. public function testDataModeInstance():void{
  39. $datamode = new $this->FQN($this->testdata);
  40. $this::assertInstanceOf(QRDataModeInterface::class, $datamode);
  41. }
  42. /**
  43. * @see testInitMatrix()
  44. * @return int[][]
  45. */
  46. public function maskPatternProvider():array{
  47. return [[0], [1], [2], [3], [4], [5], [6], [7]];
  48. }
  49. /**
  50. * Tests initializing the data matrix
  51. *
  52. * @dataProvider maskPatternProvider
  53. */
  54. public function testInitMatrix(int $maskPattern):void{
  55. $this->QRData->setData([new $this->FQN($this->testdata)]);
  56. $matrix = $this->QRData->writeMatrix(new MaskPattern($maskPattern));
  57. $this::assertInstanceOf(QRMatrix::class, $matrix);
  58. $this::assertSame($maskPattern, $matrix->maskPattern()->getPattern());
  59. }
  60. /**
  61. * Tests getting the minimum QR version for the given data
  62. */
  63. public function testGetMinimumVersion():void{
  64. $this->QRData->setData([new $this->FQN($this->testdata)]);
  65. $getMinimumVersion = $this->reflection->getMethod('getMinimumVersion');
  66. $getMinimumVersion->setAccessible(true);
  67. /** @var \chillerlan\QRCode\Common\Version $version */
  68. $version = $getMinimumVersion->invoke($this->QRData);
  69. $this::assertInstanceOf(Version::class, $version);
  70. $this::assertSame(1, $version->getVersionNumber());
  71. }
  72. abstract public function stringValidateProvider():array;
  73. /**
  74. * Tests if a string is properly validated for the respective data mode
  75. *
  76. * @dataProvider stringValidateProvider
  77. */
  78. public function testValidateString(string $string, bool $expected):void{
  79. /** @noinspection PhpUndefinedMethodInspection */
  80. $this::assertSame($expected, $this->FQN::validateString($string));
  81. }
  82. /**
  83. * returns versions within the version breakpoints 1-9, 10-26 and 27-40
  84. */
  85. public function versionBreakpointProvider():array{
  86. return ['1-9' => [7], '10-26' => [15], '27-40' => [30]];
  87. }
  88. /**
  89. * Tests decoding a data segment from a given BitBuffer
  90. *
  91. * @dataProvider versionBreakpointProvider
  92. */
  93. public function testDecodeSegment(int $version):void{
  94. $options = new QROptions;
  95. $options->version = $version;
  96. // invoke a datamode interface
  97. /** @var \chillerlan\QRCode\Data\QRDataModeInterface $datamodeInterface */
  98. $datamodeInterface = new $this->FQN($this->testdata);
  99. // invoke a QRData instance and write data
  100. $this->QRData = new QRData($options, [$datamodeInterface]);
  101. // get the filled bitbuffer
  102. $bitBuffer = $this->QRData->getBitBuffer();
  103. // read the first 4 bits
  104. $this::assertTrue($bitBuffer->read(4) === $datamodeInterface->getDataMode());
  105. // decode the data
  106. /** @noinspection PhpUndefinedMethodInspection */
  107. $this::assertSame($this->testdata, $this->FQN::decodeSegment($bitBuffer, $options->version));
  108. }
  109. /**
  110. * Tests if an exception is thrown when the data exceeds the maximum version while auto detecting
  111. */
  112. public function testGetMinimumVersionException():void{
  113. $this->expectException(QRCodeDataException::class);
  114. $this->expectExceptionMessage('data exceeds');
  115. $this->QRData->setData([new $this->FQN(str_repeat($this->testdata, 1337))]);
  116. }
  117. /**
  118. * Tests if an exception is thrown on data overflow
  119. */
  120. public function testCodeLengthOverflowException():void{
  121. $this->expectException(QRCodeDataException::class);
  122. $this->expectExceptionMessage('code length overflow');
  123. $this->QRData = new QRData(
  124. new QROptions(['version' => 4]),
  125. [new $this->FQN(str_repeat($this->testdata, 1337))]
  126. );
  127. }
  128. /**
  129. * Tests if an exception is thrown when an invalid character is encountered
  130. */
  131. public function testInvalidDataException():void{
  132. $this->expectException(QRCodeDataException::class);
  133. $this->expectExceptionMessage('invalid data');
  134. /** @phan-suppress-next-line PhanNoopNew */
  135. new $this->FQN('##');
  136. }
  137. /**
  138. * Tests if an exception is thrown if the given string is empty
  139. */
  140. public function testInvalidDataOnEmptyException():void{
  141. $this->expectException(QRCodeDataException::class);
  142. $this->expectExceptionMessage('invalid data');
  143. /** @phan-suppress-next-line PhanNoopNew */
  144. new $this->FQN('');
  145. }
  146. }