2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Collator unit tests.
22 * @copyright 2011 Sam Hemelryk
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
29 * Unit tests for our utf-8 aware collator which is used for sorting.
33 * @copyright 2011 Sam Hemelryk
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 class core_collator_testcase
extends advanced_testcase
{
39 * @var string The initial lang, stored because we change it during testing
41 protected $initiallang = null;
44 * @var string The last error that has occurred
46 protected $error = null;
49 * Prepares things for this test case.
51 protected function setUp() {
53 if (isset($SESSION->lang
)) {
54 $this->initiallang
= $SESSION->lang
;
56 $SESSION->lang
= 'en'; // Make sure we test en language to get consistent results, hopefully all systems have this locale.
57 if (extension_loaded('intl')) {
58 $this->error
= 'Collation aware sorting not supported';
60 $this->error
= 'Collation aware sorting not supported, PHP extension "intl" is not available.';
66 * Cleans things up after this test case has run.
68 protected function tearDown() {
71 if ($this->initiallang
!== null) {
72 $SESSION->lang
= $this->initiallang
;
73 $this->initiallang
= null;
75 unset($SESSION->lang
);
80 * Tests the static asort method.
82 public function test_asort() {
83 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc');
84 $result = core_collator
::asort($arr);
85 $this->assertSame(array('aa', 'ab', 'cc'), array_values($arr));
86 $this->assertSame(array(1, 'b', 0), array_keys($arr));
87 $this->assertTrue($result);
89 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc');
90 $result = core_collator
::asort($arr, core_collator
::SORT_STRING
);
91 $this->assertSame(array('aa', 'ab', 'cc'), array_values($arr));
92 $this->assertSame(array(1, 'b', 0), array_keys($arr));
93 $this->assertTrue($result);
95 $arr = array('b' => 'aac', 1 => 'Aac', 0 => 'cc');
96 $result = core_collator
::asort($arr, (core_collator
::SORT_STRING | core_collator
::CASE_SENSITIVE
));
97 $this->assertSame(array('Aac', 'aac', 'cc'), array_values($arr));
98 $this->assertSame(array(1, 'b', 0), array_keys($arr));
99 $this->assertTrue($result);
101 $arr = array('b' => 'a1', 1 => 'a10', 0 => 'a3b');
102 $result = core_collator
::asort($arr);
103 $this->assertSame(array('a1', 'a10', 'a3b'), array_values($arr));
104 $this->assertSame(array('b', 1, 0), array_keys($arr));
105 $this->assertTrue($result);
107 $arr = array('b' => 'a1', 1 => 'a10', 0 => 'a3b');
108 $result = core_collator
::asort($arr, core_collator
::SORT_NATURAL
);
109 $this->assertSame(array('a1', 'a3b', 'a10'), array_values($arr));
110 $this->assertSame(array('b', 0, 1), array_keys($arr));
111 $this->assertTrue($result);
113 $arr = array('b' => '1.1.1', 1 => '1.2', 0 => '1.20.2');
114 $result = core_collator
::asort($arr, core_collator
::SORT_NATURAL
);
115 $this->assertSame(array_values($arr), array('1.1.1', '1.2', '1.20.2'));
116 $this->assertSame(array_keys($arr), array('b', 1, 0));
117 $this->assertTrue($result);
119 $arr = array('b' => '-1', 1 => 1000, 0 => -1.2, 3 => 1, 4 => false);
120 $result = core_collator
::asort($arr, core_collator
::SORT_NUMERIC
);
121 $this->assertSame(array(-1.2, '-1', false, 1, 1000), array_values($arr));
122 $this->assertSame(array(0, 'b', 4, 3, 1), array_keys($arr));
123 $this->assertTrue($result);
125 $arr = array('b' => array(1), 1 => array(2, 3), 0 => 1);
126 $result = core_collator
::asort($arr, core_collator
::SORT_REGULAR
);
127 $this->assertSame(array(1, array(1), array(2, 3)), array_values($arr));
128 $this->assertSame(array(0, 'b', 1), array_keys($arr));
129 $this->assertTrue($result);
131 // Test sorting of array of arrays - first element should be used for actual comparison.
132 $arr = array(0=>array('bb', 'z'), 1=>array('ab', 'a'), 2=>array('zz', 'x'));
133 $result = core_collator
::asort($arr, core_collator
::SORT_REGULAR
);
134 $this->assertSame(array(1, 0, 2), array_keys($arr));
135 $this->assertTrue($result);
137 $arr = array('a' => 'áb', 'b' => 'ab', 1 => 'aa', 0=>'cc', 'x' => 'Áb');
138 $result = core_collator
::asort($arr);
139 $this->assertSame(array('aa', 'ab', 'áb', 'Áb', 'cc'), array_values($arr), $this->error
);
140 $this->assertSame(array(1, 'b', 'a', 'x', 0), array_keys($arr), $this->error
);
141 $this->assertTrue($result);
143 $a = array(2=>'b', 1=>'c');
146 core_collator
::asort($b);
147 $this->assertSame($a, $b);
148 $this->assertSame($c, $b);
152 * Tests the static asort_objects_by_method method.
154 public function test_asort_objects_by_method() {
156 'b' => new string_test_class('ab'),
157 1 => new string_test_class('aa'),
158 0 => new string_test_class('cc')
160 $result = core_collator
::asort_objects_by_method($objects, 'get_protected_name');
161 $this->assertSame(array(1, 'b', 0), array_keys($objects));
162 $this->assertSame(array('aa', 'ab', 'cc'), $this->get_ordered_names($objects, 'get_protected_name'));
163 $this->assertTrue($result);
166 'b' => new string_test_class('a20'),
167 1 => new string_test_class('a1'),
168 0 => new string_test_class('a100')
170 $result = core_collator
::asort_objects_by_method($objects, 'get_protected_name', core_collator
::SORT_NATURAL
);
171 $this->assertSame(array(1, 'b', 0), array_keys($objects));
172 $this->assertSame(array('a1', 'a20', 'a100'), $this->get_ordered_names($objects, 'get_protected_name'));
173 $this->assertTrue($result);
177 * Tests the static asort_objects_by_method method.
179 public function test_asort_objects_by_property() {
181 'b' => new string_test_class('ab'),
182 1 => new string_test_class('aa'),
183 0 => new string_test_class('cc')
185 $result = core_collator
::asort_objects_by_property($objects, 'publicname');
186 $this->assertSame(array(1, 'b', 0), array_keys($objects));
187 $this->assertSame(array('aa', 'ab', 'cc'), $this->get_ordered_names($objects, 'publicname'));
188 $this->assertTrue($result);
191 'b' => new string_test_class('a20'),
192 1 => new string_test_class('a1'),
193 0 => new string_test_class('a100')
195 $result = core_collator
::asort_objects_by_property($objects, 'publicname', core_collator
::SORT_NATURAL
);
196 $this->assertSame(array(1, 'b', 0), array_keys($objects));
197 $this->assertSame(array('a1', 'a20', 'a100'), $this->get_ordered_names($objects, 'publicname'));
198 $this->assertTrue($result);
202 * Tests the sorting of an array of arrays by key.
204 public function test_asort_array_of_arrays_by_key() {
206 'a' => array('name' => 'bravo'),
207 'b' => array('name' => 'charlie'),
208 'c' => array('name' => 'alpha')
210 $this->assertSame(array('a', 'b', 'c'), array_keys($array));
211 $this->assertTrue(core_collator
::asort_array_of_arrays_by_key($array, 'name'));
212 $this->assertSame(array('c', 'a', 'b'), array_keys($array));
215 'a' => array('name' => 'b'),
216 'b' => array('name' => 1),
217 'c' => array('name' => 0)
219 $this->assertSame(array('a', 'b', 'c'), array_keys($array));
220 $this->assertTrue(core_collator
::asort_array_of_arrays_by_key($array, 'name'));
221 $this->assertSame(array('c', 'b', 'a'), array_keys($array));
224 'a' => array('name' => 'áb'),
225 'b' => array('name' => 'ab'),
226 1 => array('name' => 'aa'),
227 'd' => array('name' => 'cc'),
228 0 => array('name' => 'Áb')
230 $this->assertSame(array('a', 'b', 1, 'd', 0), array_keys($array));
231 $this->assertTrue(core_collator
::asort_array_of_arrays_by_key($array, 'name'));
232 $this->assertSame(array(1, 'b', 'a', 0, 'd'), array_keys($array));
233 $this->assertSame(array(
234 1 => array('name' => 'aa'),
235 'b' => array('name' => 'ab'),
236 'a' => array('name' => 'áb'),
237 0 => array('name' => 'Áb'),
238 'd' => array('name' => 'cc')
244 * Returns an array of sorted names.
245 * @param array $objects
246 * @param string $methodproperty
249 protected function get_ordered_names($objects, $methodproperty = 'get_protected_name') {
251 foreach ($objects as $object) {
252 if ($methodproperty == 'publicname') {
253 $return[] = $object->publicname
;
255 $return[] = $object->$methodproperty();
262 * Tests the static ksort method.
264 public function test_ksort() {
265 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc');
266 $result = core_collator
::ksort($arr);
267 $this->assertSame(array(0, 1, 'b'), array_keys($arr));
268 $this->assertSame(array('cc', 'aa', 'ab'), array_values($arr));
269 $this->assertTrue($result);
271 $obj = new stdClass();
272 $arr = array('1.1.1'=>array(), '1.2'=>$obj, '1.20.2'=>null);
273 $result = core_collator
::ksort($arr, core_collator
::SORT_NATURAL
);
274 $this->assertSame(array('1.1.1', '1.2', '1.20.2'), array_keys($arr));
275 $this->assertSame(array(array(), $obj, null), array_values($arr));
276 $this->assertTrue($result);
278 $a = array(2=>'b', 1=>'c');
281 core_collator
::ksort($b);
282 $this->assertSame($a, $b);
283 $this->assertSame($c, $b);
290 * Simple class used to work with the unit test.
294 * @copyright 2011 Sam Hemelryk
295 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
297 class string_test_class
extends stdClass
{
299 * @var string A public property
303 * @var string A protected property
305 protected $protectedname;
307 * @var string A private property
309 private $privatename;
311 * Constructs the test instance.
312 * @param string $name
314 public function __construct($name) {
315 $this->publicname
= $name;
316 $this->protectedname
= $name;
317 $this->privatename
= $name;
320 * Returns the protected property.
323 public function get_protected_name() {
324 return $this->protectedname
;
327 * Returns the protected property.
330 public function get_private_name() {
331 return $this->publicname
;