summaryrefslogtreecommitdiff
path: root/vendor/chillerlan/php-qrcode/tests/Output/QROutputTestAbstract.php
blob: d48468bca5fcaeabff791657aed7c05ae3a31d46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
/**
 * Class QROutputTestAbstract
 *
 * @filesource   QROutputTestAbstract.php
 * @created      24.12.2017
 * @package      chillerlan\QRCodeTest\Output
 * @author       Smiley <[email protected]>
 * @copyright    2017 Smiley
 * @license      MIT
 */

namespace chillerlan\QRCodeTest\Output;

use chillerlan\QRCode\{QRCode, QROptions};
use chillerlan\QRCode\Data\{Byte, QRMatrix};
use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface};
use PHPUnit\Framework\TestCase;

use function file_exists, in_array, mkdir;

use const PHP_OS_FAMILY, PHP_VERSION_ID;

/**
 * Test abstract for the several (built-in) output modules,
 * should also be used to test custom output modules
 */
abstract class QROutputTestAbstract extends TestCase{

	/** @internal  */
	protected string $builddir = __DIR__.'/../../.build/output_test';
	/** @internal  */
	protected QROutputInterface $outputInterface;
	/** @internal  */
	protected QROptions $options;
	/** @internal  */
	protected QRMatrix $matrix;

	/**
	 * Attempts to create a directory under /.build and instances several required objects
	 *
	 * @internal
	 */
	protected function setUp():void{

		if(!file_exists($this->builddir)){
			mkdir($this->builddir, 0777, true);
		}

		$this->options         = new QROptions;
		$this->matrix          = (new Byte($this->options, 'testdata'))->initMatrix(0);
		$this->outputInterface = $this->getOutputInterface($this->options);
	}

	/**
	 * Returns a QROutputInterface instance with the given options and using $this->matrix
	 *
	 * @internal
	 */
	abstract protected function getOutputInterface(QROptions $options):QROutputInterface;

	/**
	 * Validate the instance of the interface
	 */
	public function testInstance():void{
		$this::assertInstanceOf(QROutputInterface::class, $this->outputInterface);
	}

	/**
	 * Tests if an exception is thrown when trying to write a cache file to an invalid destination
	 */
	public function testSaveException():void{
		$this->expectException(QRCodeOutputException::class);
		$this->expectExceptionMessage('Could not write data to cache file: /foo/bar.test');

		$this->options->cachefile = '/foo/bar.test';
		$this->outputInterface = $this->getOutputInterface($this->options);
		$this->outputInterface->dump();
	}

	/**
	 * covers the module values settings
	 */
	abstract public function testSetModuleValues():void;

	/*
	 * additional, non-essential, potentially inaccurate coverage tests
	 */

	/**
	 * @see testStringOutput()
	 * @return string[][]
	 * @internal
	 */
	abstract public function types():array;

	/**
	 * coverage of the built-in output modules
	 *
	 * @dataProvider types
	 */
	public function testStringOutput(string $type):void{
		$this->options->outputType  = $type;
		$this->options->cachefile   = $this->builddir.'/test.'.$type;
		$this->options->imageBase64 = false;

		$this->outputInterface     = $this->getOutputInterface($this->options);
		$data                      = $this->outputInterface->dump(); // creates the cache file

		$this::assertSame($data, file_get_contents($this->options->cachefile));
	}

	/**
	 * covers the built-in output modules, tests against pre-rendered data
	 *
	 * @dataProvider types
	 */
	public function testRenderImage(string $type):void{

		// may fail on CI, different PHP (platform) versions produce different output
		// the samples were generated on php-7.4.3-Win32-vc15-x64
		if(
			(PHP_OS_FAMILY !== 'Windows' || PHP_VERSION_ID >= 80100)
			&& in_array($type, [QRCode::OUTPUT_IMAGE_JPG, QRCode::OUTPUT_IMAGICK, QRCode::OUTPUT_MARKUP_SVG])
		){
			$this::markTestSkipped('may fail on CI');

			/** @noinspection PhpUnreachableStatementInspection */
			return;
		}

		$this->options->outputType = $type;

		$this::assertSame(
			trim(file_get_contents(__DIR__.'/samples/'.$type)),
			trim((new QRCode($this->options))->render('test'))
		);
	}

}