Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
     */
11 efrain 86
    public function test_asort(): void {
1 efrain 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
     */
11 efrain 158
    public function test_asort_objects_by_method(): void {
1 efrain 159
        $objects = array(
160
            'b' => new string_test_class('ab'),
161
            1 => new string_test_class('aa'),
162
 
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
 
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
     */
11 efrain 183
    public function test_asort_objects_by_property(): void {
1 efrain 184
        $objects = array(
185
            'b' => new string_test_class('ab'),
186
            1 => new string_test_class('aa'),
187
 
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
 
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
     */
11 efrain 208
    public function test_asort_array_of_arrays_by_key(): void {
1 efrain 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
 
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
 
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
     */
11 efrain 268
    public function test_ksort(): void {
1 efrain 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
}