QROutputTestAbstract.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * Class QROutputTestAbstract
  4. *
  5. * @filesource QROutputTestAbstract.php
  6. * @created 24.12.2017
  7. * @package chillerlan\QRCodeTest\Output
  8. * @author Smiley <smiley@chillerlan.net>
  9. * @copyright 2017 Smiley
  10. * @license MIT
  11. */
  12. namespace chillerlan\QRCodeTest\Output;
  13. use chillerlan\QRCode\{QRCode, QROptions};
  14. use chillerlan\QRCode\Common\MaskPattern;
  15. use chillerlan\QRCode\Data\{Byte, QRData, QRMatrix};
  16. use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface};
  17. use PHPUnit\Framework\TestCase;
  18. use function file_exists, mkdir;
  19. use const PHP_OS_FAMILY;
  20. /**
  21. * Test abstract for the several (built-in) output modules,
  22. * should also be used to test custom output modules
  23. */
  24. abstract class QROutputTestAbstract extends TestCase{
  25. /** @internal */
  26. protected string $builddir = __DIR__.'/../../.build/output_test';
  27. /** @internal */
  28. protected QROutputInterface $outputInterface;
  29. /** @internal */
  30. protected QROptions $options;
  31. /** @internal */
  32. protected QRMatrix $matrix;
  33. /**
  34. * Attempts to create a directory under /.build and instances several required objects
  35. *
  36. * @internal
  37. */
  38. protected function setUp():void{
  39. if(!file_exists($this->builddir)){
  40. mkdir($this->builddir, 0777, true);
  41. }
  42. $this->options = new QROptions;
  43. $this->matrix = (new QRData($this->options, [[Byte::class, 'testdata']]))
  44. ->writeMatrix(new MaskPattern(MaskPattern::PATTERN_010));
  45. $this->outputInterface = $this->getOutputInterface($this->options);
  46. }
  47. /**
  48. * Returns a QROutputInterface instance with the given options and using $this->matrix
  49. *
  50. * @internal
  51. */
  52. abstract protected function getOutputInterface(QROptions $options):QROutputInterface;
  53. /**
  54. * Validate the instance of the interface
  55. */
  56. public function testInstance():void{
  57. $this::assertInstanceOf(QROutputInterface::class, $this->outputInterface);
  58. }
  59. /**
  60. * Tests if an exception is thrown when trying to write a cache file to an invalid destination
  61. */
  62. public function testSaveException():void{
  63. if(PHP_OS_FAMILY === 'Windows'){
  64. $this::markTestSkipped('why does this fail on CI??');
  65. /** @noinspection PhpUnreachableStatementInspection */
  66. return;
  67. }
  68. $this->expectException(QRCodeOutputException::class);
  69. $this->expectExceptionMessage('Could not write data to cache file: /foo');
  70. $this->options->cachefile = '/foo';
  71. $this->outputInterface = $this->getOutputInterface($this->options);
  72. $this->outputInterface->dump();
  73. }
  74. /**
  75. * covers the module values settings
  76. */
  77. abstract public function testSetModuleValues():void;
  78. /*
  79. * additional, non-essential, potentially inaccurate coverage tests
  80. */
  81. /**
  82. * @see testStringOutput()
  83. * @return string[][]
  84. * @internal
  85. */
  86. abstract public function types():array;
  87. /**
  88. * coverage of the built-in output modules
  89. *
  90. * @dataProvider types
  91. */
  92. public function testStringOutput(string $type):void{
  93. $this->options->outputType = $type;
  94. $this->options->cachefile = $this->builddir.'/test.'.$type;
  95. $this->options->imageBase64 = false;
  96. $this->outputInterface = $this->getOutputInterface($this->options);
  97. $data = $this->outputInterface->dump(); // creates the cache file
  98. $this::assertSame($data, file_get_contents($this->options->cachefile));
  99. }
  100. /**
  101. * covers the built-in output modules, tests against pre-rendered data
  102. *
  103. * @dataProvider types
  104. */
  105. public function testRenderImage(string $type):void{
  106. // may fail on CI, different PHP (platform) versions produce different output
  107. // the samples were generated on php-7.4.3-Win32-vc15-x64
  108. if(
  109. PHP_OS_FAMILY !== 'Windows' && (
  110. $type === QRCode::OUTPUT_IMAGE_JPG
  111. || $type === QRCode::OUTPUT_IMAGICK
  112. || $type === QRCode::OUTPUT_MARKUP_SVG
  113. )){
  114. $this::markTestSkipped('may fail on CI');
  115. /** @noinspection PhpUnreachableStatementInspection */
  116. return;
  117. }
  118. $this->options->outputType = $type;
  119. $this::assertSame(
  120. trim(file_get_contents(__DIR__.'/samples/'.$type)),
  121. trim((new QRCode($this->options))->render('test'))
  122. );
  123. }
  124. }