See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 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. 8 // 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. 13 // 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/>. 16 17 /** 18 * Unit tests for our utf-8 aware collator which is used for sorting. 19 * 20 * @package core 21 * @category test 22 * @copyright 2011 Sam Hemelryk 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace core; 27 28 use core_collator; 29 30 defined('MOODLE_INTERNAL') || die(); 31 32 /** 33 * Unit tests for our utf-8 aware collator which is used for sorting. 34 * 35 * @package core 36 * @category test 37 * @copyright 2011 Sam Hemelryk 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class collator_test extends \advanced_testcase { 41 42 /** 43 * @var string The initial lang, stored because we change it during testing 44 */ 45 protected $initiallang = null; 46 47 /** 48 * @var string The last error that has occurred 49 */ 50 protected $error = null; 51 52 /** 53 * Prepares things for this test case. 54 */ 55 protected function setUp(): void { 56 global $SESSION; 57 if (isset($SESSION->lang)) { 58 $this->initiallang = $SESSION->lang; 59 } 60 $SESSION->lang = 'en'; // Make sure we test en language to get consistent results, hopefully all systems have this locale. 61 if (extension_loaded('intl')) { 62 $this->error = 'Collation aware sorting not supported'; 63 } else { 64 $this->error = 'Collation aware sorting not supported, PHP extension "intl" is not available.'; 65 } 66 parent::setUp(); 67 } 68 69 /** 70 * Cleans things up after this test case has run. 71 */ 72 protected function tearDown(): void { 73 global $SESSION; 74 parent::tearDown(); 75 if ($this->initiallang !== null) { 76 $SESSION->lang = $this->initiallang; 77 $this->initiallang = null; 78 } else { 79 unset($SESSION->lang); 80 } 81 } 82 83 /** 84 * Tests the static asort method. 85 */ 86 public function test_asort() { 87 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc'); 88 $result = core_collator::asort($arr); 89 $this->assertSame(array('aa', 'ab', 'cc'), array_values($arr)); 90 $this->assertSame(array(1, 'b', 0), array_keys($arr)); 91 $this->assertTrue($result); 92 93 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc'); 94 $result = core_collator::asort($arr, core_collator::SORT_STRING); 95 $this->assertSame(array('aa', 'ab', 'cc'), array_values($arr)); 96 $this->assertSame(array(1, 'b', 0), array_keys($arr)); 97 $this->assertTrue($result); 98 99 $arr = array('b' => 'aac', 1 => 'Aac', 0 => 'cc'); 100 $result = core_collator::asort($arr, (core_collator::SORT_STRING | core_collator::CASE_SENSITIVE)); 101 $this->assertSame(array('Aac', 'aac', 'cc'), array_values($arr)); 102 $this->assertSame(array(1, 'b', 0), array_keys($arr)); 103 $this->assertTrue($result); 104 105 $arr = array('b' => 'a1', 1 => 'a10', 0 => 'a3b'); 106 $result = core_collator::asort($arr); 107 $this->assertSame(array('a1', 'a10', 'a3b'), array_values($arr)); 108 $this->assertSame(array('b', 1, 0), array_keys($arr)); 109 $this->assertTrue($result); 110 111 $arr = array('b' => 'a1', 1 => 'a10', 0 => 'a3b'); 112 $result = core_collator::asort($arr, core_collator::SORT_NATURAL); 113 $this->assertSame(array('a1', 'a3b', 'a10'), array_values($arr)); 114 $this->assertSame(array('b', 0, 1), array_keys($arr)); 115 $this->assertTrue($result); 116 117 $arr = array('b' => '1.1.1', 1 => '1.2', 0 => '1.20.2'); 118 $result = core_collator::asort($arr, core_collator::SORT_NATURAL); 119 $this->assertSame(array_values($arr), array('1.1.1', '1.2', '1.20.2')); 120 $this->assertSame(array_keys($arr), array('b', 1, 0)); 121 $this->assertTrue($result); 122 123 $arr = array('b' => '-1', 1 => 1000, 0 => -1.2, 3 => 1, 4 => false); 124 $result = core_collator::asort($arr, core_collator::SORT_NUMERIC); 125 $this->assertSame(array(-1.2, '-1', false, 1, 1000), array_values($arr)); 126 $this->assertSame(array(0, 'b', 4, 3, 1), array_keys($arr)); 127 $this->assertTrue($result); 128 129 $arr = array('b' => array(1), 1 => array(2, 3), 0 => 1); 130 $result = core_collator::asort($arr, core_collator::SORT_REGULAR); 131 $this->assertSame(array(1, array(1), array(2, 3)), array_values($arr)); 132 $this->assertSame(array(0, 'b', 1), array_keys($arr)); 133 $this->assertTrue($result); 134 135 // Test sorting of array of arrays - first element should be used for actual comparison. 136 $arr = array(0=>array('bb', 'z'), 1=>array('ab', 'a'), 2=>array('zz', 'x')); 137 $result = core_collator::asort($arr, core_collator::SORT_REGULAR); 138 $this->assertSame(array(1, 0, 2), array_keys($arr)); 139 $this->assertTrue($result); 140 141 $arr = array('a' => 'áb', 'b' => 'ab', 1 => 'aa', 0=>'cc', 'x' => 'Áb'); 142 $result = core_collator::asort($arr); 143 $this->assertSame(array('aa', 'ab', 'áb', 'Áb', 'cc'), array_values($arr), $this->error); 144 $this->assertSame(array(1, 'b', 'a', 'x', 0), array_keys($arr), $this->error); 145 $this->assertTrue($result); 146 147 $a = array(2=>'b', 1=>'c'); 148 $c =& $a; 149 $b =& $a; 150 core_collator::asort($b); 151 $this->assertSame($a, $b); 152 $this->assertSame($c, $b); 153 } 154 155 /** 156 * Tests the static asort_objects_by_method method. 157 */ 158 public function test_asort_objects_by_method() { 159 $objects = array( 160 'b' => new string_test_class('ab'), 161 1 => new string_test_class('aa'), 162 0 => new string_test_class('cc') 163 ); 164 $result = core_collator::asort_objects_by_method($objects, 'get_protected_name'); 165 $this->assertSame(array(1, 'b', 0), array_keys($objects)); 166 $this->assertSame(array('aa', 'ab', 'cc'), $this->get_ordered_names($objects, 'get_protected_name')); 167 $this->assertTrue($result); 168 169 $objects = array( 170 'b' => new string_test_class('a20'), 171 1 => new string_test_class('a1'), 172 0 => new string_test_class('a100') 173 ); 174 $result = core_collator::asort_objects_by_method($objects, 'get_protected_name', core_collator::SORT_NATURAL); 175 $this->assertSame(array(1, 'b', 0), array_keys($objects)); 176 $this->assertSame(array('a1', 'a20', 'a100'), $this->get_ordered_names($objects, 'get_protected_name')); 177 $this->assertTrue($result); 178 } 179 180 /** 181 * Tests the static asort_objects_by_method method. 182 */ 183 public function test_asort_objects_by_property() { 184 $objects = array( 185 'b' => new string_test_class('ab'), 186 1 => new string_test_class('aa'), 187 0 => new string_test_class('cc') 188 ); 189 $result = core_collator::asort_objects_by_property($objects, 'publicname'); 190 $this->assertSame(array(1, 'b', 0), array_keys($objects)); 191 $this->assertSame(array('aa', 'ab', 'cc'), $this->get_ordered_names($objects, 'publicname')); 192 $this->assertTrue($result); 193 194 $objects = array( 195 'b' => new string_test_class('a20'), 196 1 => new string_test_class('a1'), 197 0 => new string_test_class('a100') 198 ); 199 $result = core_collator::asort_objects_by_property($objects, 'publicname', core_collator::SORT_NATURAL); 200 $this->assertSame(array(1, 'b', 0), array_keys($objects)); 201 $this->assertSame(array('a1', 'a20', 'a100'), $this->get_ordered_names($objects, 'publicname')); 202 $this->assertTrue($result); 203 } 204 205 /** 206 * Tests the sorting of an array of arrays by key. 207 */ 208 public function test_asort_array_of_arrays_by_key() { 209 $array = array( 210 'a' => array('name' => 'bravo'), 211 'b' => array('name' => 'charlie'), 212 'c' => array('name' => 'alpha') 213 ); 214 $this->assertSame(array('a', 'b', 'c'), array_keys($array)); 215 $this->assertTrue(core_collator::asort_array_of_arrays_by_key($array, 'name')); 216 $this->assertSame(array('c', 'a', 'b'), array_keys($array)); 217 218 $array = array( 219 'a' => array('name' => 'b'), 220 'b' => array('name' => 1), 221 'c' => array('name' => 0) 222 ); 223 $this->assertSame(array('a', 'b', 'c'), array_keys($array)); 224 $this->assertTrue(core_collator::asort_array_of_arrays_by_key($array, 'name')); 225 $this->assertSame(array('c', 'b', 'a'), array_keys($array)); 226 227 $array = array( 228 'a' => array('name' => 'áb'), 229 'b' => array('name' => 'ab'), 230 1 => array('name' => 'aa'), 231 'd' => array('name' => 'cc'), 232 0 => array('name' => 'Áb') 233 ); 234 $this->assertSame(array('a', 'b', 1, 'd', 0), array_keys($array)); 235 $this->assertTrue(core_collator::asort_array_of_arrays_by_key($array, 'name')); 236 $this->assertSame(array(1, 'b', 'a', 0, 'd'), array_keys($array)); 237 $this->assertSame(array( 238 1 => array('name' => 'aa'), 239 'b' => array('name' => 'ab'), 240 'a' => array('name' => 'áb'), 241 0 => array('name' => 'Áb'), 242 'd' => array('name' => 'cc') 243 ), $array); 244 245 } 246 247 /** 248 * Returns an array of sorted names. 249 * @param array $objects 250 * @param string $methodproperty 251 * @return array 252 */ 253 protected function get_ordered_names($objects, $methodproperty = 'get_protected_name') { 254 $return = array(); 255 foreach ($objects as $object) { 256 if ($methodproperty == 'publicname') { 257 $return[] = $object->publicname; 258 } else { 259 $return[] = $object->$methodproperty(); 260 } 261 } 262 return $return; 263 } 264 265 /** 266 * Tests the static ksort method. 267 */ 268 public function test_ksort() { 269 $arr = array('b' => 'ab', 1 => 'aa', 0 => 'cc'); 270 $result = core_collator::ksort($arr); 271 $this->assertSame(array(0, 1, 'b'), array_keys($arr)); 272 $this->assertSame(array('cc', 'aa', 'ab'), array_values($arr)); 273 $this->assertTrue($result); 274 275 $obj = new \stdClass(); 276 $arr = array('1.1.1'=>array(), '1.2'=>$obj, '1.20.2'=>null); 277 $result = core_collator::ksort($arr, core_collator::SORT_NATURAL); 278 $this->assertSame(array('1.1.1', '1.2', '1.20.2'), array_keys($arr)); 279 $this->assertSame(array(array(), $obj, null), array_values($arr)); 280 $this->assertTrue($result); 281 282 $a = array(2=>'b', 1=>'c'); 283 $c =& $a; 284 $b =& $a; 285 core_collator::ksort($b); 286 $this->assertSame($a, $b); 287 $this->assertSame($c, $b); 288 } 289 290 } 291 292 293 /** 294 * Simple class used to work with the unit test. 295 * 296 * @package core 297 * @category phpunit 298 * @copyright 2011 Sam Hemelryk 299 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 300 */ 301 class string_test_class extends \stdClass { 302 /** 303 * @var string A public property 304 */ 305 public $publicname; 306 /** 307 * @var string A protected property 308 */ 309 protected $protectedname; 310 /** 311 * @var string A private property 312 */ 313 private $privatename; 314 /** 315 * Constructs the test instance. 316 * @param string $name 317 */ 318 public function __construct($name) { 319 $this->publicname = $name; 320 $this->protectedname = $name; 321 $this->privatename = $name; 322 } 323 /** 324 * Returns the protected property. 325 * @return string 326 */ 327 public function get_protected_name() { 328 return $this->protectedname; 329 } 330 /** 331 * Returns the protected property. 332 * @return string 333 */ 334 public function get_private_name() { 335 return $this->publicname; 336 } 337 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body