SetTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. <?php
  2. namespace MathPHP\Tests\SetTheory;
  3. use MathPHP\SetTheory\Set;
  4. use MathPHP\LinearAlgebra\Vector;
  5. use MathPHP\LinearAlgebra\NumericMatrix;
  6. class SetTest extends \PHPUnit\Framework\TestCase
  7. {
  8. /**
  9. * @test interfaces
  10. */
  11. public function testInterfaces()
  12. {
  13. // When
  14. $interfaces = class_implements(Set::class);
  15. // Then
  16. $this->assertContains('Countable', $interfaces);
  17. $this->assertContains('Iterator', $interfaces);
  18. }
  19. /**
  20. * @test asArray
  21. * @dataProvider dataProviderForAsArray
  22. * @param array $members
  23. * @param array $expected
  24. */
  25. public function testAsArray(array $members, array $expected)
  26. {
  27. // Given
  28. $set = new Set($members);
  29. // When
  30. $array = $set->asArray();
  31. // Then
  32. $this->assertEquals($expected, $array);
  33. }
  34. public function dataProviderForAsArray(): array
  35. {
  36. return [
  37. [
  38. [],
  39. [],
  40. ],
  41. [
  42. [0],
  43. [0 => 0],
  44. ],
  45. [
  46. [1],
  47. [1 => 1],
  48. ],
  49. [
  50. [5],
  51. [5 => 5],
  52. ],
  53. [
  54. [-5],
  55. ['-5' => -5],
  56. ],
  57. [
  58. [1, 2],
  59. [1 => 1, 2 => 2],
  60. ],
  61. [
  62. [1, 2, 3],
  63. [1 => 1, 2 => 2, 3 => 3],
  64. ],
  65. [
  66. [1, -2, 3],
  67. [1 => 1, '-2' => -2, 3 => 3],
  68. ],
  69. [
  70. [1, 2, 3, 4, 5, 6],
  71. [1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6],
  72. ],
  73. [
  74. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  75. [1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10],
  76. ],
  77. [
  78. [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2, 2.01, 2.001, 2.15],
  79. [1 => 1, '1.1' => 1.1, '1.2' => 1.2, '1.3' => 1.3, '1.4' => 1.4, '1.5' => 1.5, '1.6' => 1.6, 2 => 2, '2.01' => 2.01, '2.001' => 2.001, '2.15' => 2.15],
  80. ],
  81. [
  82. ['a'],
  83. ['a' => 'a'],
  84. ],
  85. [
  86. ['a', 'b'],
  87. ['a' => 'a', 'b' => 'b'],
  88. ],
  89. [
  90. ['a', 'b', 'c', 'd', 'e'],
  91. ['a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd', 'e' => 'e'],
  92. ],
  93. [
  94. [1, 2, 'a', 'b', 3.14, 'hello', 'goodbye'],
  95. [1 => 1, 2 => 2, 'a' => 'a', 'b' => 'b', '3.14' => 3.14, 'hello' => 'hello', 'goodbye' => 'goodbye'],
  96. ],
  97. [
  98. [1, 2, 3, new Set([1, 2]), 'a', 'b'],
  99. [1 => 1, 2 => 2, 3 => 3, 'Set{1, 2}' => new Set([1, 2]), 'a' => 'a', 'b' => 'b'],
  100. ],
  101. [
  102. ['a', 1, 'b', new Set([1, 'b']), new Set([3, 4, 5,]), '4', 5],
  103. ['a' => 'a', 1 => 1, 'b' => 'b', 'Set{1, b}' => new Set([1, 'b']), 'Set{3, 4, 5}' => new Set([3, 4, 5,]), '4' => '4', 5 => 5],
  104. ],
  105. ];
  106. }
  107. /**
  108. * @test asArray
  109. * @dataProvider dataProviderForSingleSet
  110. * @param array $members
  111. */
  112. public function testAsArrayAnotherWay(array $members)
  113. {
  114. // Given
  115. $set = new Set($members);
  116. // When
  117. $array = $set->asArray();
  118. $new_set = new Set($array);
  119. // Then
  120. $this->assertEquals($new_set, $set);
  121. }
  122. /**
  123. * @test length
  124. * @dataProvider dataProviderForSingleSet
  125. * @param array $members
  126. */
  127. public function testLength(array $members)
  128. {
  129. // Given
  130. $set = new Set($members);
  131. $expectedCount = count($members);
  132. // When
  133. $length = $set->length();
  134. // Then
  135. $this->assertEquals($expectedCount, $length);
  136. }
  137. /**
  138. * @test isEmpty
  139. * @dataProvider dataProviderForSingleSet
  140. * @param array $members
  141. */
  142. public function testIsEmpty(array $members)
  143. {
  144. // Given
  145. $set = new Set($members);
  146. $expectedEmptiness = empty($members);
  147. // when
  148. $isEmpty = $set->isEmpty();
  149. // Then
  150. $this->assertEquals($expectedEmptiness, $isEmpty);
  151. }
  152. /**
  153. * @test isMember
  154. * @dataProvider dataProviderForSingleSetAtLeastOneMember
  155. * @param array $members
  156. */
  157. public function testIsMember(array $members)
  158. {
  159. // Given
  160. $set = new Set($members);
  161. foreach ($members as $member) {
  162. // When
  163. $isMember = $set->isMember($member);
  164. // Then
  165. $this->assertTrue($isMember);
  166. }
  167. }
  168. /**
  169. * @test isNotMember
  170. * @dataProvider dataProviderForSingleSet
  171. * @param array $members
  172. */
  173. public function testIsNotMember(array $members)
  174. {
  175. // Given
  176. $set = new Set($members);
  177. // Then
  178. $this->assertTrue($set->isNotMember('TotallNotAMember'));
  179. $this->assertTrue($set->isNotMember('99999123'));
  180. $this->assertTrue($set->isNotMember(99999123));
  181. }
  182. /**
  183. * @return array
  184. */
  185. public function dataProviderForSingleSet(): array
  186. {
  187. $fh = fopen(__FILE__, 'r');
  188. $vector = new Vector([1, 2, 3]);
  189. $func = function ($x) {
  190. return $x * 2;
  191. };
  192. return [
  193. [[]],
  194. [[0]],
  195. [[1]],
  196. [[5]],
  197. [[-5]],
  198. [[1, 2]],
  199. [[1, 2, 3]],
  200. [[1, -2, 3]],
  201. [[1, 2, 3, 4, 5, 6]],
  202. [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
  203. [[1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2, 2.01, 2.001, 2.15]],
  204. [['a']],
  205. [['a', 'b']],
  206. [['a', 'b', 'c', 'd', 'e']],
  207. [[1, 2, 'a', 'b', 3.14, 'hello', 'goodbye']],
  208. [[1, 2, 3, new Set([1, 2]), 'a', 'b']],
  209. [['a', 1, 'b', new Set([1, 'b'])]],
  210. [['a', 1, 'b', new Set([1, 'b']), '4', 5]],
  211. [['a', 1, 'b', new Set([1, 'b']), new Set([3, 4, 5]), '4', 5]],
  212. [[1, 2, 3, [1, 2], [2, 3, 4]]],
  213. [[1, 2, $fh, $vector, [4, 5], 6, 'a', $func, 12, new Set([4, 6, 7]), new Set(), 'sets']],
  214. ];
  215. }
  216. /**
  217. * @return array
  218. */
  219. public function dataProviderForSingleSetAtLeastOneMember(): array
  220. {
  221. $fh = fopen(__FILE__, 'r');
  222. $vector = new Vector([1, 2, 3]);
  223. $func = function ($x) {
  224. return $x * 2;
  225. };
  226. return [
  227. [[0]],
  228. [[1]],
  229. [[5]],
  230. [[-5]],
  231. [[1, 2]],
  232. [[1, 2, 3]],
  233. [[1, -2, 3]],
  234. [[1, 2, 3, 4, 5, 6]],
  235. [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
  236. [[1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2, 2.01, 2.001, 2.15]],
  237. [['a']],
  238. [['a', 'b']],
  239. [['a', 'b', 'c', 'd', 'e']],
  240. [[1, 2, 'a', 'b', 3.14, 'hello', 'goodbye']],
  241. [[1, 2, 3, new Set([1, 2]), 'a', 'b']],
  242. [['a', 1, 'b', new Set([1, 'b'])]],
  243. [['a', 1, 'b', new Set([1, 'b']), '4', 5]],
  244. [['a', 1, 'b', new Set([1, 'b']), new Set([3, 4, 5]), '4', 5]],
  245. [[1, 2, 3, [1, 2], [2, 3, 4]]],
  246. [[1, 2, $fh, $vector, [4, 5], 6, 'a', $func, 12, new Set([4, 6, 7]), new Set(), 'sets']],
  247. ];
  248. }
  249. /**
  250. * @test count
  251. * @dataProvider dataProviderForSingleSet
  252. * @param array $A
  253. */
  254. public function testCount(array $A)
  255. {
  256. // Given
  257. $set = new Set($A);
  258. $expectedCount = count($A);
  259. // When
  260. $count = count($set);
  261. // Then
  262. $this->assertEquals($expectedCount, $count);
  263. $this->assertEquals($set->length(), $count);
  264. }
  265. /**
  266. * @test String representation
  267. * @dataProvider dataProviderForToString
  268. * @param array $members
  269. * @param string $expected
  270. */
  271. public function testToString(array $members, string $expected)
  272. {
  273. // Given
  274. $set = new Set($members);
  275. // When
  276. $stringRepresentation = (string) $set;
  277. // Then
  278. $this->assertSame($expected, $stringRepresentation);
  279. }
  280. public function dataProviderForToString(): array
  281. {
  282. $vector = new Vector([1, 2, 3]);
  283. $vector_hash = spl_object_hash($vector);
  284. return [
  285. [
  286. [],
  287. 'Ø',
  288. ],
  289. [
  290. [new Set()],
  291. 'Set{Ø}',
  292. ],
  293. [
  294. [0],
  295. 'Set{0}',
  296. ],
  297. [
  298. [1],
  299. 'Set{1}',
  300. ],
  301. [
  302. [5],
  303. 'Set{5}',
  304. ],
  305. [
  306. [-5],
  307. 'Set{-5}',
  308. ],
  309. [
  310. [1, 2],
  311. 'Set{1, 2}',
  312. ],
  313. [
  314. [1, 2, 3],
  315. 'Set{1, 2, 3}',
  316. ],
  317. [
  318. [1, 2, 3, new Set()],
  319. 'Set{1, 2, 3, Ø}',
  320. ],
  321. [
  322. [1, -2, 3],
  323. 'Set{1, -2, 3}',
  324. ],
  325. [
  326. [1, 2, 3, 4, 5, 6],
  327. 'Set{1, 2, 3, 4, 5, 6}',
  328. ],
  329. [
  330. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  331. 'Set{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}',
  332. ],
  333. [
  334. [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2, 2.01, 2.001, 2.15],
  335. 'Set{1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2, 2.01, 2.001, 2.15}',
  336. ],
  337. [
  338. ['a'],
  339. 'Set{a}',
  340. ],
  341. [
  342. ['a', 'b'],
  343. 'Set{a, b}',
  344. ],
  345. [
  346. ['a', 'b', 'c', 'd', 'e'],
  347. 'Set{a, b, c, d, e}',
  348. ],
  349. [
  350. [1, 2, 'a', 'b', 3.14, 'hello', 'goodbye'],
  351. 'Set{1, 2, a, b, 3.14, hello, goodbye}',
  352. ],
  353. [
  354. [1, 2, 3, new Set([1, 2]), 'a', 'b'],
  355. 'Set{1, 2, 3, Set{1, 2}, a, b}',
  356. ],
  357. [
  358. ['a', 1, 'b', new Set([1, 'b']), new Set([3, 4, 5]), '4', 5],
  359. 'Set{a, 1, b, Set{1, b}, Set{3, 4, 5}, 4, 5}',
  360. ],
  361. [
  362. [1, 2, new Set([1, 2, new Set([1, 2])])],
  363. 'Set{1, 2, Set{1, 2, Set{1, 2}}}',
  364. ],
  365. [
  366. [1, 2, [1, 2, 3]],
  367. 'Set{1, 2, Array(a:3:{i:0;i:1;i:1;i:2;i:2;i:3;})}',
  368. ],
  369. [
  370. [1, 2, [1, 2, 3], [1, 2, 3]],
  371. 'Set{1, 2, Array(a:3:{i:0;i:1;i:1;i:2;i:2;i:3;})}',
  372. ],
  373. [
  374. [1, 2, $vector],
  375. "Set{1, 2, MathPHP\LinearAlgebra\Vector($vector_hash)}",
  376. ],
  377. [
  378. [1, 2, $vector, $vector],
  379. "Set{1, 2, MathPHP\LinearAlgebra\Vector($vector_hash)}",
  380. ],
  381. ];
  382. }
  383. /**
  384. * @test iterator interface
  385. */
  386. public function testIteratorInterface()
  387. {
  388. // Given
  389. $set = new Set([1, 2, 3, 4, 5]);
  390. $i = 1;
  391. foreach ($set as $key => $value) {
  392. // Then
  393. $this->assertEquals($i, $key);
  394. $this->assertEquals($i, $value);
  395. $i++;
  396. }
  397. }
  398. /**
  399. * @test iterator interface
  400. */
  401. public function testIteratorInterface2()
  402. {
  403. // Given
  404. $set = new Set([new Set([1, 2]), new Set([3, 4])]);
  405. $i = 1;
  406. foreach ($set as $key => $value) {
  407. // Then
  408. if ($i === 1) {
  409. $this->assertEquals(('Set{1, 2}'), $key);
  410. $this->assertEquals(new Set([1, 2]), $value);
  411. }
  412. if ($i === 2) {
  413. $this->assertEquals(('Set{3, 4}'), $key);
  414. $this->assertEquals(new Set([3, 4]), $value);
  415. }
  416. $i++;
  417. }
  418. }
  419. /**
  420. * @test Fluent interface
  421. */
  422. public function testFluentInterface()
  423. {
  424. // Given
  425. $A = new Set();
  426. $B = new Set([3, 4, 7, new Set([1, 2, 3])]);
  427. // When
  428. $A->add(1)
  429. ->add(2)
  430. ->add(3)
  431. ->remove(2)
  432. ->add(4)
  433. ->remove(1)
  434. ->addMulti([5, 6, 7])
  435. ->add(new Set([1, 2, 3]))
  436. ->removeMulti([5, 6]);
  437. // Then
  438. $this->assertEquals($B, $A);
  439. }
  440. }