SortIteratorTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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\TestSuite\TestCase;
  19. /**
  20. * SortIterator Test
  21. *
  22. */
  23. class SortIteratorTest extends TestCase
  24. {
  25. /**
  26. * Tests sorting numbers with an identity callbacks
  27. *
  28. * @return void
  29. */
  30. public function testSortNumbersIdentity()
  31. {
  32. $items = new ArrayObject([3, 5, 1, 2, 4]);
  33. $identity = function ($a) {
  34. return $a;
  35. };
  36. $sorted = new SortIterator($items, $identity);
  37. $expected = array_combine(range(4, 0), range(5, 1));
  38. $this->assertEquals($expected, iterator_to_array($sorted));
  39. $sorted = new SortIterator($items, $identity, SORT_ASC);
  40. $expected = array_combine(range(4, 0), range(1, 5));
  41. $this->assertEquals($expected, iterator_to_array($sorted));
  42. }
  43. /**
  44. * Tests sorting numbers with custom callback
  45. *
  46. * @return void
  47. */
  48. public function testSortNumbersCustom()
  49. {
  50. $items = new ArrayObject([3, 5, 1, 2, 4]);
  51. $callback = function ($a) {
  52. return $a * -1;
  53. };
  54. $sorted = new SortIterator($items, $callback);
  55. $expected = array_combine(range(4, 0), [1, 2, 3, 4, 5]);
  56. $this->assertEquals($expected, iterator_to_array($sorted));
  57. $sorted = new SortIterator($items, $callback, SORT_ASC);
  58. $expected = array_combine(range(4, 0), [5, 4, 3, 2, 1]);
  59. $this->assertEquals($expected, iterator_to_array($sorted));
  60. }
  61. /**
  62. * Tests sorting a complex structure with numeric sort
  63. *
  64. * @return void
  65. */
  66. public function testSortComplexNumeric()
  67. {
  68. $items = new ArrayObject([
  69. ['foo' => 1, 'bar' => 'a'],
  70. ['foo' => 10, 'bar' => 'a'],
  71. ['foo' => 2, 'bar' => 'a'],
  72. ['foo' => 13, 'bar' => 'a'],
  73. ]);
  74. $callback = function ($a) {
  75. return $a['foo'];
  76. };
  77. $sorted = new SortIterator($items, $callback, SORT_DESC, SORT_NUMERIC);
  78. $expected = [
  79. 3 => ['foo' => 13, 'bar' => 'a'],
  80. 2 => ['foo' => 10, 'bar' => 'a'],
  81. 1 => ['foo' => 2, 'bar' => 'a'],
  82. 0 => ['foo' => 1, 'bar' => 'a'],
  83. ];
  84. $this->assertEquals($expected, iterator_to_array($sorted));
  85. $sorted = new SortIterator($items, $callback, SORT_ASC, SORT_NUMERIC);
  86. $expected = [
  87. 3 => ['foo' => 1, 'bar' => 'a'],
  88. 2 => ['foo' => 2, 'bar' => 'a'],
  89. 1 => ['foo' => 10, 'bar' => 'a'],
  90. 0 => ['foo' => 13, 'bar' => 'a'],
  91. ];
  92. $this->assertEquals($expected, iterator_to_array($sorted));
  93. }
  94. /**
  95. * Tests sorting a complex structure with natural sort
  96. *
  97. * @return void
  98. */
  99. public function testSortComplexNatural()
  100. {
  101. $items = new ArrayObject([
  102. ['foo' => 'foo_1', 'bar' => 'a'],
  103. ['foo' => 'foo_10', 'bar' => 'a'],
  104. ['foo' => 'foo_2', 'bar' => 'a'],
  105. ['foo' => 'foo_13', 'bar' => 'a'],
  106. ]);
  107. $callback = function ($a) {
  108. return $a['foo'];
  109. };
  110. $sorted = new SortIterator($items, $callback, SORT_DESC, SORT_NATURAL);
  111. $expected = [
  112. 3 => ['foo' => 'foo_13', 'bar' => 'a'],
  113. 2 => ['foo' => 'foo_10', 'bar' => 'a'],
  114. 1 => ['foo' => 'foo_2', 'bar' => 'a'],
  115. 0 => ['foo' => 'foo_1', 'bar' => 'a'],
  116. ];
  117. $this->assertEquals($expected, iterator_to_array($sorted));
  118. $sorted = new SortIterator($items, $callback, SORT_ASC, SORT_NATURAL);
  119. $expected = [
  120. 3 => ['foo' => 'foo_1', 'bar' => 'a'],
  121. 2 => ['foo' => 'foo_2', 'bar' => 'a'],
  122. 1 => ['foo' => 'foo_10', 'bar' => 'a'],
  123. 0 => ['foo' => 'foo_13', 'bar' => 'a'],
  124. ];
  125. $this->assertEquals($expected, iterator_to_array($sorted));
  126. $this->assertEquals($expected, iterator_to_array($sorted), 'Iterator should rewind');
  127. }
  128. /**
  129. * Tests sorting a complex structure with natural sort with string callback
  130. *
  131. * @return void
  132. */
  133. public function testSortComplexNaturalWithPath()
  134. {
  135. $items = new ArrayObject([
  136. ['foo' => 'foo_1', 'bar' => 'a'],
  137. ['foo' => 'foo_10', 'bar' => 'a'],
  138. ['foo' => 'foo_2', 'bar' => 'a'],
  139. ['foo' => 'foo_13', 'bar' => 'a'],
  140. ]);
  141. $sorted = new SortIterator($items, 'foo', SORT_DESC, SORT_NATURAL);
  142. $expected = [
  143. 3 => ['foo' => 'foo_13', 'bar' => 'a'],
  144. 2 => ['foo' => 'foo_10', 'bar' => 'a'],
  145. 1 => ['foo' => 'foo_2', 'bar' => 'a'],
  146. 0 => ['foo' => 'foo_1', 'bar' => 'a'],
  147. ];
  148. $this->assertEquals($expected, iterator_to_array($sorted));
  149. $sorted = new SortIterator($items, 'foo', SORT_ASC, SORT_NATURAL);
  150. $expected = [
  151. 3 => ['foo' => 'foo_1', 'bar' => 'a'],
  152. 2 => ['foo' => 'foo_2', 'bar' => 'a'],
  153. 1 => ['foo' => 'foo_10', 'bar' => 'a'],
  154. 0 => ['foo' => 'foo_13', 'bar' => 'a'],
  155. ];
  156. $this->assertEquals($expected, iterator_to_array($sorted));
  157. $this->assertEquals($expected, iterator_to_array($sorted), 'Iterator should rewind');
  158. }
  159. /**
  160. * Tests sorting a complex structure with a deep path
  161. *
  162. * @return void
  163. */
  164. public function testSortComplexDeepPath()
  165. {
  166. $items = new ArrayObject([
  167. ['foo' => ['bar' => 1], 'bar' => 'a'],
  168. ['foo' => ['bar' => 12], 'bar' => 'a'],
  169. ['foo' => ['bar' => 10], 'bar' => 'a'],
  170. ['foo' => ['bar' => 2], 'bar' => 'a'],
  171. ]);
  172. $sorted = new SortIterator($items, 'foo.bar', SORT_ASC, SORT_NUMERIC);
  173. $expected = [
  174. 3 => ['foo' => ['bar' => 1], 'bar' => 'a'],
  175. 2 => ['foo' => ['bar' => 2], 'bar' => 'a'],
  176. 1 => ['foo' => ['bar' => 10], 'bar' => 'a'],
  177. 0 => ['foo' => ['bar' => 12], 'bar' => 'a'],
  178. ];
  179. $this->assertEquals($expected, iterator_to_array($sorted));
  180. }
  181. /**
  182. * Tests top
  183. *
  184. * @return void
  185. */
  186. public function testTop()
  187. {
  188. $items = new ArrayObject([3, 5, 1, 2, 4]);
  189. $identity = function ($a) {
  190. return $a;
  191. };
  192. $sorted = new SortIterator($items, $identity);
  193. $this->assertEquals(5, $sorted->top());
  194. $sorted = new SortIterator([], $identity);
  195. $this->assertNull($sorted->top());
  196. }
  197. }