MatrixTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <?php
  2. namespace MatrixTest;
  3. use Matrix\Exception;
  4. use Matrix\Matrix;
  5. class MatrixTest extends BaseTestAbstract
  6. {
  7. public function testInstantiate()
  8. {
  9. $cells = 21;
  10. $columns = 7;
  11. $matrixObject = new Matrix($this->buildArray($cells, $columns));
  12. // Must return an object of the correct type...
  13. $this->assertIsMatrixObject($matrixObject);
  14. // ... containing the correct data
  15. $this->assertMatrixValues($matrixObject, ceil($cells / $columns), $columns, $this->buildArray($cells, $columns));
  16. }
  17. public function testRowsDefault()
  18. {
  19. $matrixObject = new Matrix($this->getMagic());
  20. $matrixRows = $matrixObject->getRows(2);
  21. // Must return an object of the correct type...
  22. $this->assertIsMatrixObject($matrixRows);
  23. // ... containing the correct data
  24. $this->assertMatrixValues($matrixRows, 1, 4, [[5, 10, 11, 8]]);
  25. // And the original Matrix object must remain unchanged
  26. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  27. }
  28. /**
  29. * @dataProvider rowsDataProvider
  30. */
  31. public function testRows($startRow, $rows, $grid)
  32. {
  33. $matrixObject = new Matrix($this->getMagic());
  34. $matrixRows = $matrixObject->getRows($startRow, $rows);
  35. // Must return an object of the correct type...
  36. $this->assertIsMatrixObject($matrixRows);
  37. // ... containing the correct data
  38. $this->assertMatrixValues($matrixRows, count($grid), 4, $grid);
  39. // And the original Matrix object must remain unchanged
  40. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  41. }
  42. public function rowsDataProvider()
  43. {
  44. return [
  45. [2, 2, [[5, 10, 11, 8], [9, 6, 7, 12]]],
  46. [2, -1, [[5, 10, 11, 8], [9, 6, 7, 12]]],
  47. [3, 0, [[9, 6, 7, 12], [4, 15, 14, 1]]],
  48. ];
  49. }
  50. public function testColumnsDefault()
  51. {
  52. $columns = 1;
  53. $matrixObject = new Matrix($this->getMagic());
  54. $matrixColumns = $matrixObject->getColumns(2);
  55. // Must return an object of the correct type...
  56. $this->assertIsMatrixObject($matrixColumns);
  57. // ... containing the correct data
  58. $this->assertMatrixValues($matrixColumns, 4, 1, [[3], [10], [6], [15]]);
  59. // And the original Matrix object must remain unchanged
  60. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  61. }
  62. /**
  63. * @dataProvider columnsDataProvider
  64. */
  65. public function testColumns($startColumn, $columns, $grid)
  66. {
  67. $matrixObject = new Matrix($this->getMagic());
  68. $matrixColumns = $matrixObject->getColumns($startColumn, $columns);
  69. // Must return an object of the correct type...
  70. $this->assertIsMatrixObject($matrixColumns);
  71. // ... containing the correct data
  72. $this->assertMatrixValues($matrixColumns, 4, count($grid[0]), $grid);
  73. // And the original Matrix object must remain unchanged
  74. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  75. }
  76. public function columnsDataProvider()
  77. {
  78. return [
  79. [2, 2, [[3, 2], [10, 11], [6, 7], [15, 14]]],
  80. [2, -1, [[3, 2], [10, 11], [6, 7], [15, 14]]],
  81. [3, 0, [[2, 13], [11, 8], [7, 12], [14, 1]]],
  82. ];
  83. }
  84. public function testDropRowsDefault()
  85. {
  86. $matrixObject = new Matrix($this->getMagic());
  87. $matrixRows = $matrixObject->dropRows(2);
  88. // Must return an object of the correct type...
  89. $this->assertIsMatrixObject($matrixRows);
  90. // ... containing the correct data
  91. $this->assertMatrixValues($matrixRows, 3, 4, [[16, 3, 2, 13], [9, 6, 7, 12], [4, 15, 14, 1]]);
  92. // And the original Matrix object must remain unchanged
  93. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  94. }
  95. /**
  96. * @dataProvider dropRowsDataProvider
  97. */
  98. public function testDropRows($startRow, $rows, $grid)
  99. {
  100. $matrixObject = new Matrix($this->getMagic());
  101. $matrixRows = $matrixObject->dropRows($startRow, $rows);
  102. // Must return an object of the correct type...
  103. $this->assertIsMatrixObject($matrixRows);
  104. // ... containing the correct data
  105. $this->assertMatrixValues($matrixRows, count($grid), 4, $grid);
  106. // And the original Matrix object must remain unchanged
  107. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  108. }
  109. public function dropRowsDataProvider()
  110. {
  111. return [
  112. [2, 2, [[16, 3, 2, 13], [4, 15, 14, 1]]],
  113. [2, -1, [[16, 3, 2, 13], [4, 15, 14, 1]]],
  114. [3, 0, [[16, 3, 2, 13], [5, 10, 11, 8]]],
  115. ];
  116. }
  117. public function testDropColumnsDefault()
  118. {
  119. $matrixObject = new Matrix($this->getMagic());
  120. $matrixColumns = $matrixObject->dropColumns(2);
  121. // Must return an object of the correct type...
  122. $this->assertIsMatrixObject($matrixColumns);
  123. // ... containing the correct data
  124. $this->assertMatrixValues($matrixColumns, 4, 3, [[16, 2, 13], [5, 11, 8], [9, 7, 12], [4, 14, 1]]);
  125. // And the original Matrix object must remain unchanged
  126. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  127. }
  128. /**
  129. * @dataProvider dropColumnsDataProvider
  130. */
  131. public function testDropColumns($startColumn, $columns, $grid)
  132. {
  133. $matrixObject = new Matrix($this->getMagic());
  134. $matrixColumns = $matrixObject->dropColumns($startColumn, $columns);
  135. // Must return an object of the correct type...
  136. $this->assertIsMatrixObject($matrixColumns);
  137. // ... containing the correct data
  138. $this->assertMatrixValues($matrixColumns, 4, count($grid[0]), $grid);
  139. // And the original Matrix object must remain unchanged
  140. $this->assertOriginalMatrixIsUnchanged($this->getMagic(), $matrixObject);
  141. }
  142. public function dropColumnsDataProvider()
  143. {
  144. return [
  145. [2, 2, [[16, 13], [5, 8], [9, 12], [4, 1]]],
  146. [2, -1, [[16, 13], [5, 8], [9, 12], [4, 1]]],
  147. [3, 0, [[16, 3], [5, 10], [9, 6], [4, 15]]],
  148. ];
  149. }
  150. /**
  151. * @dataProvider isSquareDataProvider
  152. */
  153. public function testIsSquare($expected, $grid)
  154. {
  155. $matrixObject = new Matrix($grid);
  156. $result = $matrixObject->isSquare();
  157. $this->assertEquals($expected, $result);
  158. }
  159. public function isSquareDataProvider()
  160. {
  161. return [
  162. [false, [[1, 2, 3]]],
  163. [false, [[1], [2], [3]]],
  164. [true, [[1, 2], [3, 4]]],
  165. [true, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]],
  166. [false, [[1, 2, 3], [4, 5, 6]]],
  167. ];
  168. }
  169. /**
  170. * @dataProvider isVectorDataProvider
  171. */
  172. public function testIsVector($expected, $grid)
  173. {
  174. $matrixObject = new Matrix($grid);
  175. $result = $matrixObject->isVector();
  176. $this->assertEquals($expected, $result);
  177. }
  178. public function isVectorDataProvider()
  179. {
  180. return [
  181. [true, [[1, 2, 3]]],
  182. [true, [[1], [2], [3]]],
  183. [false, [[1, 2], [3, 4]]],
  184. [false, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]],
  185. [false, [[1, 2, 3], [4, 5, 6]]],
  186. ];
  187. }
  188. public function testRowColumnIterator()
  189. {
  190. $grid = $this->getMagic();
  191. $matrixObject = new Matrix($grid);
  192. $rowIteratorObject = $matrixObject->rows();
  193. // Must return an object...
  194. $this->assertTrue(is_object($rowIteratorObject));
  195. // ... of the correct type
  196. $this->assertTrue(is_a($rowIteratorObject, 'Generator'));
  197. $rowReference = 1;
  198. foreach ($rowIteratorObject as $row => $rowObject) {
  199. $this->assertEquals($rowReference++, $row, 'Row index mismatched');
  200. // Must return an object of the correct type...
  201. $this->assertIsMatrixObject($rowObject);
  202. $this->assertTrue($rowObject->isVector());
  203. $columnIteratorObject = $rowObject->columns();
  204. // Must return an object...
  205. $this->assertTrue(is_object($columnIteratorObject));
  206. // ... of the correct type
  207. $this->assertTrue(is_a($columnIteratorObject, 'Generator'));
  208. $columnReference = 1;
  209. foreach ($columnIteratorObject as $column => $columnValue) {
  210. $this->assertEquals($columnReference++, $column, 'Column index mismatched against row vector');
  211. $this->assertTrue(is_scalar($columnValue));
  212. $this->assertEquals($grid[$row - 1][$column - 1], $columnValue);
  213. }
  214. }
  215. }
  216. public function testColumnRowIterator()
  217. {
  218. $grid = $this->getMagic();
  219. $matrixObject = new Matrix($grid);
  220. $columnIteratorObject = $matrixObject->columns();
  221. // Must return an object...
  222. $this->assertTrue(is_object($columnIteratorObject));
  223. // ... of the correct type
  224. $this->assertTrue(is_a($columnIteratorObject, 'Generator'));
  225. $columnReference = 1;
  226. foreach ($columnIteratorObject as $column => $columnObject) {
  227. $this->assertEquals($columnReference++, $column, 'Column index mismatched');
  228. // Must return an object of the correct type...
  229. $this->assertIsMatrixObject($columnObject);
  230. $this->assertTrue($columnObject->isVector());
  231. $rowIteratorObject = $columnObject->rows();
  232. // Must return an object...
  233. $this->assertTrue(is_object($rowIteratorObject));
  234. // ... of the correct type
  235. $this->assertTrue(is_a($rowIteratorObject, 'Generator'));
  236. $rowReference = 1;
  237. foreach ($rowIteratorObject as $row => $rowValue) {
  238. $this->assertEquals($rowReference++, $row, 'Row index mismatched against column vector');
  239. $this->assertTrue(is_scalar($rowValue));
  240. $this->assertEquals($grid[$row - 1][$column - 1], $rowValue);
  241. }
  242. }
  243. }
  244. protected function getMagic()
  245. {
  246. return [
  247. [16, 3, 2, 13],
  248. [5, 10, 11, 8],
  249. [9, 6, 7, 12],
  250. [4, 15, 14, 1]
  251. ];
  252. }
  253. protected function buildArray($size, $columns = null)
  254. {
  255. if ($columns === null) {
  256. $columns = ceil(sqrt($size));
  257. }
  258. return array_chunk(
  259. range(1, $size),
  260. $columns
  261. );
  262. }
  263. public function testValidateRow()
  264. {
  265. $this->assertEquals(1, Matrix::validateRow(1));
  266. $this->expectException(Exception::class);
  267. $this->expectExceptionCode(0);
  268. $this->expectExceptionMessage('Invalid Row');
  269. Matrix::validateRow(0);
  270. $this->expectException(Exception::class);
  271. $this->expectExceptionCode(0);
  272. $this->expectExceptionMessage('Invalid Row');
  273. Matrix::validateRow('a');
  274. }
  275. public function testValidateColumn()
  276. {
  277. $this->assertEquals(1, Matrix::validateColumn(1));
  278. $this->expectException(Exception::class);
  279. $this->expectExceptionCode(0);
  280. $this->expectExceptionMessage('Invalid Column');
  281. Matrix::validateColumn(0);
  282. $this->expectException(Exception::class);
  283. $this->expectExceptionCode(0);
  284. $this->expectExceptionMessage('Invalid Column');
  285. Matrix::validateColumn('a');
  286. }
  287. public function testGetRows()
  288. {
  289. $matrix = new Matrix([[1, 2], [3, 4]]);
  290. $this->assertEquals(new Matrix([[1, 2]]), $matrix->getRows(1));
  291. $this->assertEquals(new Matrix([[3, 4]]), $matrix->getRows(2));
  292. $this->expectException(Exception::class);
  293. $this->expectExceptionCode(0);
  294. $this->expectExceptionMessage('Requested Row exceeds matrix size');
  295. $matrix->getRows(3);
  296. }
  297. public function testGetColumns()
  298. {
  299. $matrix = new Matrix([[1, 2], [3, 4]]);
  300. $this->assertEquals(new Matrix([[1], [3]]), $matrix->getColumns(1));
  301. $this->assertEquals(new Matrix([[2], [4]]), $matrix->getColumns(2));
  302. $this->expectException(Exception::class);
  303. $this->expectExceptionCode(0);
  304. $this->expectExceptionMessage('Requested Column exceeds matrix size');
  305. $matrix->getColumns(3);
  306. }
  307. public function testGetInvalidProperty()
  308. {
  309. $matrix = new Matrix([[1, 2], [3, 4]]);
  310. $this->expectException(Exception::class);
  311. $this->expectExceptionCode(0);
  312. $this->expectExceptionMessage('Property does not exist');
  313. $matrix->unknownProperty;
  314. }
  315. public function testCallInvalidMethod()
  316. {
  317. $matrix = new Matrix([[1, 2], [3, 4]]);
  318. $this->expectException(Exception::class);
  319. $this->expectExceptionCode(0);
  320. $this->expectExceptionMessage('Function or Operation does not exist');
  321. $matrix->unknownMethod();
  322. }
  323. public function testBuildFromArray()
  324. {
  325. $matrix1 = new Matrix([]);
  326. $matrix2 = new Matrix([[]]);
  327. $matrix3 = new Matrix([[], []]);
  328. $this->assertEquals([], $matrix1->toArray());
  329. $this->assertEquals([[]], $matrix2->toArray());
  330. $this->assertEquals([[], []], $matrix3->toArray());
  331. }
  332. }