smiley 8 лет назад
Родитель
Сommit
5334bf4683

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 composer.lock
 docs
 vendor
+.idea

+ 1 - 1
src/Data/Kanji.php

@@ -55,7 +55,7 @@ class Kanji extends QRDataAbstract{
 				$c -= 0xC140;
 			}
 			else{
-				throw new QRCodeDataException('illegal char at '.($i + 1).' ('.$c.')');
+				throw new QRCodeDataException('illegal char at '.($i + 1).' ['.$c.']');
 			}
 
 			$this->bitBuffer->put((($c >> 8) & 0xff) * 0xC0 + ($c & 0xff), 13);

+ 8 - 4
src/Data/MaskPatternTester.php

@@ -37,10 +37,14 @@ class MaskPatternTester{
 	 * @see \chillerlan\QRCode\QRCode::getBestMaskPattern()
 	 *
 	 * @param \chillerlan\QRCode\Data\QRMatrix $matrix
+	 *
+	 * @return \chillerlan\QRCode\Data\MaskPatternTester
 	 */
-	public function setMatrix(QRMatrix $matrix){
+	public function setMatrix(QRMatrix $matrix):MaskPatternTester{
 		$this->matrix      = $matrix;
 		$this->moduleCount = $this->matrix->size();
+
+		return $this;
 	}
 
 	/**
@@ -50,16 +54,16 @@ class MaskPatternTester{
 	 * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern
 	 * @see \chillerlan\QRCode\QRCode::getBestMaskPattern()
 	 *
-	 * @return float
+	 * @return int
 	 */
-	public function testPattern():float{
+	public function testPattern():int{
 		$penalty  = 0;
 
 		for($level = 1; $level <= 4; $level++){
 			$penalty += call_user_func([$this, 'testLevel'.$level]);
 		}
 
-		return $penalty;
+		return (int)$penalty;
 	}
 
 	/**

+ 7 - 6
src/Data/Number.php

@@ -45,9 +45,11 @@ class Number extends QRDataAbstract{
 			if($this->strlen - $i === 1){
 				$this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 1)), 4);
 			}
+			// @codeCoverageIgnoreStart
 			elseif($this->strlen - $i === 2){
 				$this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 2)), 7);
 			}
+			// @codeCoverageIgnoreEnd
 
 		}
 
@@ -61,19 +63,18 @@ class Number extends QRDataAbstract{
 	 */
 	protected function parseInt(string $string):int {
 		$num = 0;
+		$map = str_split('0123456789');
 
 		$len = strlen($string);
 		for($i = 0; $i < $len; $i++){
 			$c = ord($string[$i]);
-			$ord0 = ord('0');
 
-			if($ord0 <= $c && $c <= ord('9')){
-				$c = $c - $ord0;
-			}
-			else{
-				throw new QRCodeDataException('illegal char: '.$c);
+			if(!in_array($string[$i], $map, true)){
+				throw new QRCodeDataException('illegal char: "'.$string[$i].'" ['.$c.']');
 			}
 
+			$c = $c - ord('0');
+
 			$num = $num * 10 + $c;
 		}
 

+ 2 - 1
src/Data/QRDataAbstract.php

@@ -229,8 +229,9 @@ abstract class QRDataAbstract implements QRDataInterface{
 
 		$this->write($data);
 
+		// there was an error writing the BitBuffer data, which is... unlikely.
 		if($this->bitBuffer->length > $MAX_BITS){
-			throw new QRCodeException('code length overflow. ('.$this->bitBuffer->length.' > '.$MAX_BITS.'bit)');
+			throw new QRCodeException('code length overflow. ('.$this->bitBuffer->length.' > '.$MAX_BITS.'bit)'); // @codeCoverageIgnore
 		}
 
 		// end code.

+ 1 - 0
src/Data/QRMatrix.php

@@ -531,6 +531,7 @@ class QRMatrix{
 	/**
 	 * @see \chillerlan\QRCode\QRMatrix::mapData()
 	 *
+	 * @codeCoverageIgnore
 	 * @internal
 	 *
 	 * @param int $x

+ 31 - 5
src/Output/QRImage.php

@@ -12,6 +12,7 @@
 
 namespace chillerlan\QRCode\Output;
 
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QRCode;
 
 /**
@@ -19,14 +20,39 @@ use chillerlan\QRCode\QRCode;
  */
 class QRImage extends QROutputAbstract{
 
+	protected $moduleValues = [
+		// light
+		QRMatrix::M_DATA            => [255, 255, 255],
+		QRMatrix::M_FINDER          => [255, 255, 255],
+		QRMatrix::M_SEPARATOR       => [255, 255, 255],
+		QRMatrix::M_ALIGNMENT       => [255, 255, 255],
+		QRMatrix::M_TIMING          => [255, 255, 255],
+		QRMatrix::M_FORMAT          => [255, 255, 255],
+		QRMatrix::M_VERSION         => [255, 255, 255],
+		QRMatrix::M_QUIETZONE       => [255, 255, 255],
+		QRMatrix::M_TEST            => [255, 255, 255],
+		// dark
+		QRMatrix::M_DARKMODULE << 8 => [0, 0, 0],
+		QRMatrix::M_DATA << 8       => [0, 0, 0],
+		QRMatrix::M_FINDER << 8     => [0, 0, 0],
+		QRMatrix::M_ALIGNMENT << 8  => [0, 0, 0],
+		QRMatrix::M_TIMING << 8     => [0, 0, 0],
+		QRMatrix::M_FORMAT << 8     => [0, 0, 0],
+		QRMatrix::M_VERSION << 8    => [0, 0, 0],
+		QRMatrix::M_TEST << 8       => [0, 0, 0],
+	];
+
 	/**
 	 * @return string
 	 */
 	public function dump():string{
-		$scale      = $this->options->scale;
-		$length     = $this->moduleCount * $scale;
-		$image      = imagecreatetruecolor($length, $length);
-		$background = imagecolorallocate($image, ...$this->options->imageTransparencyBG);
+		$scale        = $this->options->scale;
+		$length       = $this->moduleCount * $scale;
+		$image        = imagecreatetruecolor($length, $length);
+		$background   = imagecolorallocate($image, ...$this->options->imageTransparencyBG);
+		$moduleValues = is_array($this->options->moduleValues[QRMatrix::M_DATA])
+			? $this->options->moduleValues // @codeCoverageIgnore
+			: $this->moduleValues;
 
 		if((bool)$this->options->imageTransparent && in_array($this->options->outputType, [QRCode::OUTPUT_IMAGE_PNG, QRCode::OUTPUT_IMAGE_GIF,], true)){
 			imagecolortransparent($image, $background);
@@ -36,7 +62,7 @@ class QRImage extends QROutputAbstract{
 
 		foreach($this->matrix->matrix() as $y => $row){
 			foreach($row as $x => $pixel){
-				$color = imagecolorallocate($image, ...$this->options->moduleValues[$pixel]);
+				$color = imagecolorallocate($image, ...$moduleValues[$pixel]);
 
 				imagefilledrectangle($image, $x * $scale, $y * $scale, ($x + 1) * $scale - 1, ($y + 1) * $scale - 1, $color);
 			}

+ 9 - 7
src/QRCode.php

@@ -58,10 +58,10 @@ class QRCode{
 	const DATA_KANJI    = 0b1000;
 
 	const ECC_MODES = [
-		QRCode::ECC_L => 0,
-		QRCode::ECC_M => 1,
-		QRCode::ECC_Q => 2,
-		QRCode::ECC_H => 3,
+		self::ECC_L => 0,
+		self::ECC_M => 1,
+		self::ECC_Q => 2,
+		self::ECC_H => 3,
 	];
 
 	const DATA_MODES = [
@@ -118,7 +118,7 @@ class QRCode{
 	 */
 	public function setOptions(QROptions $options):QRCode{
 
-		if(!array_key_exists(QRCode::ECC_MODES[$options->eccLevel], QRCode::ECC_MODES)){
+		if(!array_key_exists($options->eccLevel, self::ECC_MODES)){
 			throw new QRCodeException('Invalid error correct level: '.$options->eccLevel);
 		}
 
@@ -231,7 +231,7 @@ class QRCode{
 
 		}
 
-		throw new QRCodeDataException('invalid data type');
+		throw new QRCodeDataException('invalid data type'); // @codeCoverageIgnore
 	}
 
 	/**
@@ -295,7 +295,7 @@ class QRCode{
 	}
 
 	/**
-	 * checks of a string qualifies as Kanji
+	 * checks of a string qualifies as alphanumeric
 	 *
 	 * @param string $string
 	 *
@@ -321,6 +321,8 @@ class QRCode{
 	/**
 	 * a dummy
 	 *
+	 * @codeCoverageIgnore
+	 *
 	 * @param $data
 	 *
 	 * @return bool

+ 2 - 2
src/QROptions.php

@@ -105,7 +105,7 @@ class QROptions{
 	 *
 	 * @var int
 	 */
-	protected $quietzoneSize;
+	protected $quietzoneSize = 4;
 
 	/**
 	 * QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG
@@ -114,7 +114,7 @@ class QROptions{
 	 *
 	 * @var string
 	 */
-	protected $outputType;
+	protected $outputType = QRCode::OUTPUT_IMAGE_PNG;
 
 	/**
 	 * /path/to/cache.file

+ 45 - 0
tests/Data/AlphaNumTest.php

@@ -0,0 +1,45 @@
+<?php
+/**
+ * Class AlphaNumTest
+ *
+ * @filesource   AlphaNumTest.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\AlphaNum;
+
+class AlphaNumTest extends DatainterfaceTestAbstract{
+
+	protected $FQCN = AlphaNum::class;
+	protected $testdata  = '0 $%*+-./:';
+	protected $expected  = [
+		32, 80, 36, 212, 252, 15, 175, 251,
+		176, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		112, 43, 9, 248, 200, 194, 75, 25,
+		205, 173, 154, 68, 191, 16, 128,
+		92, 112, 20, 198, 27
+	];
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage illegal char: "#" [35]
+	 */
+	public function testGetCharCodeException(){
+		$this->dataInterface->setData('#');
+	}
+
+}

+ 38 - 0
tests/Data/ByteTest.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Class ByteTest
+ *
+ * @filesource   ByteTest.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\Byte;
+
+class ByteTest extends DatainterfaceTestAbstract{
+
+	protected $FQCN = Byte::class;
+	protected $testdata = '[¯\_(ツ)_/¯]';
+	protected $expected = [
+		64, 245, 188, 42, 245, 197, 242, 142,
+		56, 56, 66, 149, 242, 252, 42, 245,
+		208, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		79, 89, 226, 48, 209, 89, 151, 1,
+		12, 73, 42, 163, 11, 34, 255, 205,
+		21, 47, 250, 101
+	];
+
+
+}

+ 67 - 0
tests/Data/DatainterfaceTestAbstract.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * Class DatainterfaceTestAbstract
+ *
+ * @filesource   DatainterfaceTestAbstract.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\QRDataInterface;
+use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+abstract class DatainterfaceTestAbstract extends QRTestAbstract{
+
+	/**
+	 * @var \chillerlan\QRCode\Data\QRDataAbstract
+	 */
+	protected $dataInterface;
+
+	protected $testdata;
+	protected $expected;
+
+	protected function setUp(){
+		parent::setUp();
+
+		$this->dataInterface = $this->reflection->newInstanceArgs([new QROptions(['version' => 4])]);
+	}
+
+	public function testInstance(){
+		$this->dataInterface = $this->reflection->newInstanceArgs([new QROptions, $this->testdata]);
+
+		$this->assertInstanceOf(QRDataInterface::class, $this->dataInterface);
+	}
+
+	public function testSetData(){
+		$this->dataInterface->setData($this->testdata);
+
+		$this->assertSame($this->expected, $this->getProperty('matrixdata')->getValue($this->dataInterface));
+	}
+
+	public function testInitMatrix(){
+		$m = $this->dataInterface->setData($this->testdata)->initMatrix(0);
+
+		$this->assertInstanceOf(QRMatrix::class, $m);
+	}
+
+	public function testGetMinimumVersion(){
+		$this->assertSame(1, $this->getMethod('getMinimumVersion')->invoke($this->dataInterface));
+	}
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage data exceeds
+	 */
+	public function testGetMinimumVersionException(){
+		$this->getProperty('strlen')->setValue($this->dataInterface, 13370);
+		$this->getMethod('getMinimumVersion')->invoke($this->dataInterface);
+	}
+
+}

+ 52 - 0
tests/Data/KanjiTest.php

@@ -0,0 +1,52 @@
+<?php
+/**
+ * Class KanjiTest
+ *
+ * @filesource   KanjiTest.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\Kanji;
+
+class KanjiTest extends DatainterfaceTestAbstract{
+
+	protected $FQCN = Kanji::class;
+	protected $testdata = '茗荷茗荷茗荷茗荷茗荷';
+	protected $expected = [
+		128, 173, 85, 26, 95, 85, 70, 151,
+		213, 81, 165, 245, 84, 105, 125, 85,
+		26, 92, 0, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		195, 11, 221, 91, 141, 220, 163, 46,
+		165, 37, 163, 176, 79, 0, 64, 68,
+		96, 113, 54, 191
+	];
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage illegal char at 1 [16191]
+	 */
+	public function testIllegalCharException1(){
+		$this->dataInterface->setData('ÃÃ');
+	}
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage illegal char at 1
+	 */
+	public function testIllegalCharException2(){
+		$this->dataInterface->setData('Ã');
+	}
+}

+ 32 - 0
tests/Data/MaskPatternTesterTest.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Class MaskPatternTesterTest
+ *
+ * @filesource   MaskPatternTesterTest.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\Byte;
+use chillerlan\QRCode\Data\MaskPatternTester;
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+class MaskPatternTesterTest extends QRTestAbstract{
+
+	protected $FQCN = MaskPatternTester::class;
+
+	// coverage
+	public function testMaskpattern(){
+		$matrix = (new Byte(new QROptions(['version' => 10]), 'test'))->initMatrix(0, true);
+
+		$this->assertSame(6178, (new MaskPatternTester)->setMatrix($matrix)->testPattern());
+	}
+
+
+}

+ 45 - 0
tests/Data/NumberTest.php

@@ -0,0 +1,45 @@
+<?php
+/**
+ * Class NumberTest
+ *
+ * @filesource   NumberTest.php
+ * @created      24.11.2017
+ * @package      chillerlan\QRCodeTest\Data
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\Number;
+
+class NumberTest extends DatainterfaceTestAbstract{
+
+	protected $FQCN = Number::class;
+	protected $testdata  = '0123456789';
+	protected $expected = [
+		16, 40, 12, 86, 106, 105, 0, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		17, 236, 17, 236, 17, 236, 17, 236,
+		201, 141, 102, 116, 238, 162, 239, 230,
+		222, 37, 79, 192, 42, 109, 188, 72,
+		89, 63, 168, 151
+	];
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage illegal char: "#" [35]
+	 */
+	public function testGetCharCodeException(){
+		$this->dataInterface->setData('#');
+	}
+
+}

+ 156 - 9
tests/Data/QRMatrixTest.php

@@ -13,16 +13,24 @@
 namespace chillerlan\QRCodeTest\Data;
 
 use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\QRCode\QRCode;
 use chillerlan\QRCodeTest\QRTestAbstract;
 
 class QRMatrixTest extends QRTestAbstract{
 
 	protected $FQCN = QRMatrix::class;
 
-	public function testInstance(){
-		$q = $this->reflection->newInstanceArgs([1, 0]);
-		$this->assertCount($q->size(), $q->matrix());
-		$this->assertInstanceOf($this->FQCN, $q);
+	protected $version = 7;
+
+	/**
+	 * @var \chillerlan\QRCode\Data\QRMatrix
+	 */
+	protected $matrix;
+
+	protected function setUp(){
+		parent::setUp();
+
+		$this->matrix = $this->reflection->newInstanceArgs([$this->version, QRCode::ECC_L]);
 	}
 
 	/**
@@ -41,9 +49,148 @@ class QRMatrixTest extends QRTestAbstract{
 		$this->reflection->newInstanceArgs([1, 42]);
 	}
 
-/*	public function testSetFinderPattern(){
-		$q = $this->reflection->newInstanceArgs([1, 0]);
-		$q->setFinderPattern();
-		var_dump($q->matrix());
-	}*/
+	public function testInstance(){
+		$this->assertInstanceOf($this->FQCN, $this->matrix);
+	}
+
+	public function testSize(){
+		$this->assertCount($this->matrix->size(), $this->matrix->matrix());
+	}
+
+	public function testVersion(){
+		$this->assertSame($this->version, $this->matrix->version());
+	}
+
+	public function testECC(){
+		$this->assertSame(QRCode::ECC_L, $this->matrix->eccLevel());
+	}
+
+	public function testMaskPattern(){
+		$this->assertSame(-1, $this->matrix->maskPattern());
+	}
+
+	public function testGetSetCheck(){
+		$this->matrix->set(10, 10, true, QRMatrix::M_TEST);
+		$this->assertSame(65280, $this->matrix->get(10, 10));
+		$this->assertTrue($this->matrix->check(10, 10));
+
+		$this->matrix->set(20, 20, false, QRMatrix::M_TEST);
+		$this->assertSame(255, $this->matrix->get(20, 20));
+		$this->assertFalse($this->matrix->check(20, 20));
+	}
+
+	public function testSetDarkModule(){
+		$this->matrix->setDarkModule();
+
+		$this->assertSame(QRMatrix::M_DARKMODULE << 8, $this->matrix->get(8, $this->matrix->size() - 8));
+	}
+
+	public function testSetFinderPattern(){
+		$this->matrix->setFinderPattern();
+
+		$this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get(0, 0));
+		$this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get(0, $this->matrix->size() - 1));
+		$this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get($this->matrix->size() - 1, 0));
+	}
+
+	public function testSetSeparators(){
+		$this->matrix->setSeparators();
+
+		$this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(7, 0));
+		$this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(0, 7));
+		$this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(0, $this->matrix->size() - 8));
+		$this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get($this->matrix->size() - 8, 0));
+	}
+
+	public function testSetAlignmentPattern(){
+		$this->matrix
+			->setFinderPattern()
+			->setAlignmentPattern()
+		;
+
+		$alignmentPattern = QRMatrix::alignmentPattern[$this->version];
+
+		foreach($alignmentPattern as $py){
+			foreach($alignmentPattern as $px){
+
+				if($this->matrix->get($px, $py) === QRMatrix::M_FINDER << 8){
+					$this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get($px, $py), 'skipped finder pattern');
+					continue;
+				}
+
+				$this->assertSame(QRMatrix::M_ALIGNMENT << 8, $this->matrix->get($px, $py));
+			}
+		}
+
+	}
+
+	public function testSetTimingPattern(){
+		$this->matrix
+			->setAlignmentPattern()
+			->setTimingPattern()
+		;
+
+		$size = $this->matrix->size();
+
+		for($i = 7; $i < $size - 7; $i++){
+			if($i % 2 === 0){
+				$p1 = $this->matrix->get(6, $i);
+
+				if($p1 === QRMatrix::M_ALIGNMENT << 8){
+					$this->assertSame(QRMatrix::M_ALIGNMENT << 8, $p1, 'skipped alignment pattern');
+					continue;
+				}
+
+				$this->assertSame(QRMatrix::M_TIMING << 8, $p1);
+				$this->assertSame(QRMatrix::M_TIMING << 8, $this->matrix->get($i, 6));
+			}
+		}
+	}
+
+	public function testSetVersionNumber(){
+		$this->matrix->setVersionNumber(true);
+
+		$this->assertSame(QRMatrix::M_VERSION, $this->matrix->get($this->matrix->size() - 9, 0));
+		$this->assertSame(QRMatrix::M_VERSION, $this->matrix->get($this->matrix->size() - 11, 5));
+		$this->assertSame(QRMatrix::M_VERSION, $this->matrix->get(0, $this->matrix->size() - 9));
+		$this->assertSame(QRMatrix::M_VERSION, $this->matrix->get(5, $this->matrix->size() - 11));
+	}
+
+	public function testSetFormatInfo(){
+		$this->matrix->setFormatInfo(0, true);
+
+		$this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get(8, 0));
+		$this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get(0, 8));
+		$this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get($this->matrix->size() - 1, 8));
+		$this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get($this->matrix->size() - 8, 8));
+	}
+
+	public function testSetQuietZone(){
+		$size = $this->matrix->size();
+		$q    = 5;
+
+		$this->matrix->set(0, 0, true, QRMatrix::M_TEST);
+		$this->matrix->set($size - 1, $size - 1, true, QRMatrix::M_TEST);
+
+		$this->matrix->setQuietZone($q);
+
+		$this->assertCount($size + 2 * $q, $this->matrix->matrix());
+		$this->assertCount($size + 2 * $q, $this->matrix->matrix()[$size - 1]);
+
+		$size = $this->matrix->size();
+		$this->assertSame(QRMatrix::M_QUIETZONE, $this->matrix->get(0, 0));
+		$this->assertSame(QRMatrix::M_QUIETZONE, $this->matrix->get($size - 1, $size - 1));
+
+		$this->assertSame(QRMatrix::M_TEST << 8, $this->matrix->get($q, $q));
+		$this->assertSame(QRMatrix::M_TEST << 8, $this->matrix->get($size - 1 - $q, $size - 1 - $q));
+	}
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Data\QRCodeDataException
+	 * @expectedExceptionMessage use only after writing data
+	 */
+	public function testSetQuietZoneException(){
+		$this->matrix->setQuietZone();
+	}
+
 }

+ 2 - 2
tests/Data/BitBufferTest.php → tests/Helpers/BitBufferTest.php

@@ -4,13 +4,13 @@
  *
  * @filesource   BitBufferTest.php
  * @created      08.02.2016
- * @package      chillerlan\QRCodeTest\Data
+ * @package      chillerlan\QRCodeTest\Helpers
  * @author       Smiley <smiley@chillerlan.net>
  * @copyright    2015 Smiley
  * @license      MIT
  */
 
-namespace chillerlan\QRCodeTest\Data;
+namespace chillerlan\QRCodeTest\Helpers;
 
 use chillerlan\QRCode\Helpers\BitBuffer;
 use chillerlan\QRCode\QRCode;

+ 3 - 3
tests/Data/PolynomialTest.php → tests/Helpers/PolynomialTest.php

@@ -4,13 +4,13 @@
  *
  * @filesource   PolynomialTest.php
  * @created      09.02.2016
- * @package      chillerlan\QRCodeTest\Data
+ * @package      chillerlan\QRCodeTest\Helpers
  * @author       Smiley <smiley@chillerlan.net>
  * @copyright    2015 Smiley
  * @license      MIT
  */
 
-namespace chillerlan\QRCodeTest\Data;
+namespace chillerlan\QRCodeTest\Helpers;
 
 use chillerlan\QRCode\Helpers\Polynomial;
 use chillerlan\QRCodeTest\QRTestAbstract;
@@ -23,7 +23,7 @@ class PolynomialTest extends QRTestAbstract{
 	protected $polynomial;
 
 	protected function setUp(){
-		$this->polynomial = new \chillerlan\QRCode\Helpers\Polynomial;
+		$this->polynomial = new Polynomial;
 	}
 
 	public function testGexp(){

+ 75 - 6
tests/QRCodeTest.php

@@ -12,26 +12,95 @@
 
 namespace chillerlan\QRCodeTest;
 
-use chillerlan\QRCode\Output\QRMarkupOptions;
+use chillerlan\QRCode\QROptions;
 use chillerlan\QRCode\QRCode;
 
-abstract class QRCodeTest extends QRTestAbstract{
+class QRCodeTest extends QRTestAbstract{
 
 	protected $FQCN = QRCode::class;
 
+	/**
+	 * @var \chillerlan\QRCode\QRCode
+	 */
+	protected $qrcode;
+
+	protected function setUp(){
+		parent::setUp();
+
+		$this->qrcode = $this->reflection->newInstance();
+	}
+
+	/*
 	public function optionsDataProvider(){
 		return [
-			[QRMarkupOptions::class],
+			[QROptions::class],
 #			[],
 		];
 	}
 
-	/**
-	 * @dataProvider optionsDataProvider
-	 */
 	public function testInstance($options){
 		$q = $this->reflection->newInstanceArgs([new $options]);
 		$this->assertInstanceOf($this->FQCN, $q);
 #		print_r($q->render('test'));
 	}
+	*/
+
+	public function testIsNumber(){
+		$this->assertTrue($this->qrcode->isNumber('0123456789'));
+		$this->assertFalse($this->qrcode->isNumber('ABC'));
+	}
+
+	public function testIsAlphaNum(){
+		$this->assertTrue($this->qrcode->isAlphaNum('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 $%*+-./:'));
+		$this->assertFalse($this->qrcode->isAlphaNum('abc'));
+	}
+
+	public function testIsKanji(){
+		$this->assertTrue($this->qrcode->isKanji('茗荷'));
+		$this->assertFalse($this->qrcode->isKanji('Ã'));
+	}
+
+	// coverage
+
+	public function typeDataProvider(){
+		return [
+			[QRCode::OUTPUT_IMAGE_PNG, 'data:image/png;base64,'],
+			[QRCode::OUTPUT_IMAGE_GIF, 'data:image/gif;base64,'],
+			[QRCode::OUTPUT_IMAGE_JPG, 'data:image/jpg;base64,'],
+			[QRCode::OUTPUT_MARKUP_SVG, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="'],
+			[QRCode::OUTPUT_MARKUP_HTML, '<div><span style="background:'],
+			[QRCode::OUTPUT_STRING_TEXT, '⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕⭕'.PHP_EOL],
+			[QRCode::OUTPUT_STRING_JSON, '[[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18],'],
+		];
+	}
+
+	/**
+	 * @dataProvider typeDataProvider
+	 * @param $type
+	 */
+	public function testRenderImage($type, $expected){
+		$this->qrcode = $this->reflection->newInstanceArgs([new QROptions(['outputType' => $type])]);
+
+		$this->assertContains($expected, $this->qrcode->render('test'));
+	}
+
+	/**
+	 * @expectedException \chillerlan\QRCode\QRCodeException
+	 * @expectedExceptionMessage Invalid error correct level: 42
+	 */
+	public function testSetOptionsException(){
+		$this->qrcode->setOptions(new QROptions(['eccLevel' => 42]));
+	}
+
+	/**
+	 * @expectedException \chillerlan\QRCode\Output\QRCodeOutputException
+	 * @expectedExceptionMessage invalid output type
+	 */
+	public function testInitDataInterfaceException(){
+		$this->qrcode->setOptions(new QROptions(['outputType' => 'foo']))->render('test');
+	}
+
+
+
+
 }