SortIteratorTest.php 7.4 KB

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