SortIteratorTest.php 6.0 KB

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