SortIteratorTest.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Collection\Iterator;
  16. use ArrayObject;
  17. use Cake\Collection\Iterator\SortIterator;
  18. use Cake\TestSuite\TestCase;
  19. /**
  20. * SortIterator Test
  21. */
  22. class SortIteratorTest extends TestCase
  23. {
  24. /**
  25. * Tests sorting numbers with an identity callbacks
  26. *
  27. * @return void
  28. */
  29. public function testSortNumbersIdentity()
  30. {
  31. $items = new ArrayObject([3, 5, 1, 2, 4]);
  32. $identity = function ($a) {
  33. return $a;
  34. };
  35. $sorted = new SortIterator($items, $identity);
  36. $expected = range(5, 1);
  37. $this->assertEquals($expected, $sorted->toList());
  38. $sorted = new SortIterator($items, $identity, SORT_ASC);
  39. $expected = range(1, 5);
  40. $this->assertEquals($expected, $sorted->toList());
  41. }
  42. /**
  43. * Tests sorting numbers with custom callback
  44. *
  45. * @return void
  46. */
  47. public function testSortNumbersCustom()
  48. {
  49. $items = new ArrayObject([3, 5, 1, 2, 4]);
  50. $callback = function ($a) {
  51. return $a * -1;
  52. };
  53. $sorted = new SortIterator($items, $callback);
  54. $expected = range(1, 5);
  55. $this->assertEquals($expected, $sorted->toList());
  56. $sorted = new SortIterator($items, $callback, SORT_ASC);
  57. $expected = range(5, 1);
  58. $this->assertEquals($expected, $sorted->toList());
  59. }
  60. /**
  61. * Tests sorting a complex structure with numeric sort
  62. *
  63. * @return void
  64. */
  65. public function testSortComplexNumeric()
  66. {
  67. $items = new ArrayObject([
  68. ['foo' => 1, 'bar' => 'a'],
  69. ['foo' => 10, 'bar' => 'a'],
  70. ['foo' => 2, 'bar' => 'a'],
  71. ['foo' => 13, 'bar' => 'a'],
  72. ]);
  73. $callback = function ($a) {
  74. return $a['foo'];
  75. };
  76. $sorted = new SortIterator($items, $callback, SORT_DESC, SORT_NUMERIC);
  77. $expected = [
  78. ['foo' => 13, 'bar' => 'a'],
  79. ['foo' => 10, 'bar' => 'a'],
  80. ['foo' => 2, 'bar' => 'a'],
  81. ['foo' => 1, 'bar' => 'a'],
  82. ];
  83. $this->assertEquals($expected, $sorted->toList());
  84. $sorted = new SortIterator($items, $callback, SORT_ASC, SORT_NUMERIC);
  85. $expected = [
  86. ['foo' => 1, 'bar' => 'a'],
  87. ['foo' => 2, 'bar' => 'a'],
  88. ['foo' => 10, 'bar' => 'a'],
  89. ['foo' => 13, 'bar' => 'a'],
  90. ];
  91. $this->assertEquals($expected, $sorted->toList());
  92. }
  93. /**
  94. * Tests sorting a complex structure with natural sort
  95. *
  96. * @return void
  97. */
  98. public function testSortComplexNatural()
  99. {
  100. $items = new ArrayObject([
  101. ['foo' => 'foo_1', 'bar' => 'a'],
  102. ['foo' => 'foo_10', 'bar' => 'a'],
  103. ['foo' => 'foo_2', 'bar' => 'a'],
  104. ['foo' => 'foo_13', 'bar' => 'a'],
  105. ]);
  106. $callback = function ($a) {
  107. return $a['foo'];
  108. };
  109. $sorted = new SortIterator($items, $callback, SORT_DESC, SORT_NATURAL);
  110. $expected = [
  111. ['foo' => 'foo_13', 'bar' => 'a'],
  112. ['foo' => 'foo_10', 'bar' => 'a'],
  113. ['foo' => 'foo_2', 'bar' => 'a'],
  114. ['foo' => 'foo_1', 'bar' => 'a'],
  115. ];
  116. $this->assertEquals($expected, $sorted->toList());
  117. $sorted = new SortIterator($items, $callback, SORT_ASC, SORT_NATURAL);
  118. $expected = [
  119. ['foo' => 'foo_1', 'bar' => 'a'],
  120. ['foo' => 'foo_2', 'bar' => 'a'],
  121. ['foo' => 'foo_10', 'bar' => 'a'],
  122. ['foo' => 'foo_13', 'bar' => 'a'],
  123. ];
  124. $this->assertEquals($expected, $sorted->toList());
  125. $this->assertEquals($expected, $sorted->toList(), 'Iterator should rewind');
  126. }
  127. /**
  128. * Tests sorting a complex structure with natural sort with string callback
  129. *
  130. * @return void
  131. */
  132. public function testSortComplexNaturalWithPath()
  133. {
  134. $items = new ArrayObject([
  135. ['foo' => 'foo_1', 'bar' => 'a'],
  136. ['foo' => 'foo_10', 'bar' => 'a'],
  137. ['foo' => 'foo_2', 'bar' => 'a'],
  138. ['foo' => 'foo_13', 'bar' => 'a'],
  139. ]);
  140. $sorted = new SortIterator($items, 'foo', SORT_DESC, SORT_NATURAL);
  141. $expected = [
  142. ['foo' => 'foo_13', 'bar' => 'a'],
  143. ['foo' => 'foo_10', 'bar' => 'a'],
  144. ['foo' => 'foo_2', 'bar' => 'a'],
  145. ['foo' => 'foo_1', 'bar' => 'a'],
  146. ];
  147. $this->assertEquals($expected, $sorted->toList());
  148. $sorted = new SortIterator($items, 'foo', SORT_ASC, SORT_NATURAL);
  149. $expected = [
  150. ['foo' => 'foo_1', 'bar' => 'a'],
  151. ['foo' => 'foo_2', 'bar' => 'a'],
  152. ['foo' => 'foo_10', 'bar' => 'a'],
  153. ['foo' => 'foo_13', 'bar' => 'a'],
  154. ];
  155. $this->assertEquals($expected, $sorted->toList());
  156. $this->assertEquals($expected, $sorted->toList(), 'Iterator should rewind');
  157. }
  158. /**
  159. * Tests sorting a complex structure with a deep path
  160. *
  161. * @return void
  162. */
  163. public function testSortComplexDeepPath()
  164. {
  165. $items = new ArrayObject([
  166. ['foo' => ['bar' => 1], 'bar' => 'a'],
  167. ['foo' => ['bar' => 12], 'bar' => 'a'],
  168. ['foo' => ['bar' => 10], 'bar' => 'a'],
  169. ['foo' => ['bar' => 2], 'bar' => 'a'],
  170. ]);
  171. $sorted = new SortIterator($items, 'foo.bar', SORT_ASC, SORT_NUMERIC);
  172. $expected = [
  173. ['foo' => ['bar' => 1], 'bar' => 'a'],
  174. ['foo' => ['bar' => 2], 'bar' => 'a'],
  175. ['foo' => ['bar' => 10], 'bar' => 'a'],
  176. ['foo' => ['bar' => 12], 'bar' => 'a'],
  177. ];
  178. $this->assertEquals($expected, $sorted->toList());
  179. }
  180. /**
  181. * Tests sorting datetime
  182. *
  183. * @return void
  184. */
  185. public function testSortDateTime()
  186. {
  187. $items = new ArrayObject([
  188. new \DateTime('2014-07-21'),
  189. new \DateTime('2015-06-30'),
  190. new \DateTimeImmutable('2013-08-12')
  191. ]);
  192. $callback = function ($a) {
  193. return $a->add(new \DateInterval('P1Y'));
  194. };
  195. $sorted = new SortIterator($items, $callback);
  196. $expected = [
  197. new \DateTime('2016-06-30'),
  198. new \DateTime('2015-07-21'),
  199. new \DateTimeImmutable('2013-08-12')
  200. ];
  201. $this->assertEquals($expected, $sorted->toList());
  202. $items = new ArrayObject([
  203. new \DateTime('2014-07-21'),
  204. new \DateTime('2015-06-30'),
  205. new \DateTimeImmutable('2013-08-12')
  206. ]);
  207. $sorted = new SortIterator($items, $callback, SORT_ASC);
  208. $expected = [
  209. new \DateTimeImmutable('2013-08-12'),
  210. new \DateTime('2015-07-21'),
  211. new \DateTime('2016-06-30'),
  212. ];
  213. $this->assertEquals($expected, $sorted->toList());
  214. }
  215. }