See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310]
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 declare(strict_types=1); 18 19 namespace core_table\local\filter; 20 21 use advanced_testcase; 22 use InvalidArgumentException; 23 24 /** 25 * Unit tests for core_table\local\filter\filter. 26 * 27 * @package core_table 28 * @category test 29 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 30 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 31 * @covers \core_table\local\filter\filter 32 */ 33 class filter_test extends advanced_testcase { 34 /** 35 * Test that the constructor correctly handles a number of conditions. 36 * 37 * @dataProvider constructor_provider 38 * @param array $args 39 * @param int $jointype 40 * @param array $values 41 */ 42 public function test_constructor(array $args, int $jointype, array $values): void { 43 $filter = new filter(...$args); 44 45 // We should always get a filter. 46 $this->assertInstanceOf(filter::class, $filter); 47 48 // We should always get the correct join type. 49 $this->assertEquals($jointype, $filter->get_join_type()); 50 51 // The values should be the expected ones. 52 $this->assertSame($values, $filter->get_filter_values()); 53 } 54 55 /** 56 * Data provider for the constructor providing a range of valid constructor arguments. 57 * 58 * @return array 59 */ 60 public function constructor_provider(): array { 61 return [ 62 'Name without values' => [['keyword'], filter::JOINTYPE_DEFAULT, []], 63 'Name with valid join type ANY' => [[ 64 'keyword', 65 filter::JOINTYPE_ANY, 66 ], filter::JOINTYPE_ANY, []], 67 'Name with valid join type ALL' => [[ 68 'keyword', 69 filter::JOINTYPE_ALL, 70 ], filter::JOINTYPE_ALL, []], 71 'Name with valid join type NONE' => [[ 72 'keyword', 73 filter::JOINTYPE_NONE, 74 ], filter::JOINTYPE_NONE, []], 75 'Name, no join type, with set of values' => [ 76 [ 77 'keyword', 78 null, 79 [ 80 's1', 81 'janine', 82 ], 83 ], 84 filter::JOINTYPE_DEFAULT, 85 [ 86 'janine', 87 's1', 88 ], 89 ], 90 'Name, and ANY, with set of values' => [ 91 [ 92 'keyword', 93 filter::JOINTYPE_ANY, 94 [ 95 's1', 96 'kevin', 97 'james', 98 'janine', 99 ], 100 ], 101 filter::JOINTYPE_ANY, 102 [ 103 'james', 104 'janine', 105 'kevin', 106 's1', 107 ], 108 ], 109 'Name, and ANY, with set of values which contains duplicates' => [ 110 [ 111 'keyword', 112 filter::JOINTYPE_ANY, 113 [ 114 's1', 115 'kevin', 116 'james', 117 'janine', 118 'kevin', 119 ], 120 ], 121 filter::JOINTYPE_ANY, 122 [ 123 'james', 124 'janine', 125 'kevin', 126 's1', 127 ], 128 ], 129 ]; 130 } 131 132 /** 133 * Test that the constructor throws a relevant exception when passed an invalid join. 134 * 135 * @dataProvider constructor_invalid_join_provider 136 * @param mixed $jointype 137 */ 138 public function test_constructor_invalid_joins($jointype): void { 139 $this->expectException(InvalidArgumentException::class); 140 $this->expectExceptionMessage('Invalid join type specified'); 141 142 new filter('invalid', $jointype); 143 } 144 145 /** 146 * Data provider for the constructor providing a range of invalid join types to the constructor. 147 * 148 * @return array 149 */ 150 public function constructor_invalid_join_provider(): array { 151 return [ 152 'Too low' => [-1], 153 'Too high' => [4], 154 ]; 155 } 156 157 /** 158 * Enusre that adding filter values works as expected. 159 */ 160 public function test_add_filter_value(): void { 161 $filter = new filter('example'); 162 163 // Initially an empty list. 164 $this->assertEmpty($filter->get_filter_values()); 165 166 // Adding null should do nothing. 167 $filter->add_filter_value(null); 168 $this->assertEmpty($filter->get_filter_values()); 169 170 // Adding empty string should do nothing. 171 $filter->add_filter_value(''); 172 $this->assertEmpty($filter->get_filter_values()); 173 174 // Adding a value should return that value. 175 $filter->add_filter_value('rosie'); 176 $this->assertSame([ 177 'rosie', 178 ], $filter->get_filter_values()); 179 180 // Adding a second value should add that value. 181 // The values should sorted. 182 $filter->add_filter_value('arthur'); 183 $this->assertSame([ 184 'arthur', 185 'rosie', 186 ], $filter->get_filter_values()); 187 188 // Adding a duplicate value should not lead to that value being added again. 189 $filter->add_filter_value('arthur'); 190 $this->assertSame([ 191 'arthur', 192 'rosie', 193 ], $filter->get_filter_values()); 194 } 195 196 /** 197 * Ensure that it is possibly to set the join type. 198 */ 199 public function test_set_join_type(): void { 200 $filter = new filter('example'); 201 202 // Initial set with the default type should just work. 203 // The setter should be chainable. 204 $this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_DEFAULT)); 205 $this->assertEquals(filter::JOINTYPE_DEFAULT, $filter->get_join_type()); 206 207 // It should be possible to update the join type later. 208 $this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_NONE)); 209 $this->assertEquals(filter::JOINTYPE_NONE, $filter->get_join_type()); 210 211 $this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_ANY)); 212 $this->assertEquals(filter::JOINTYPE_ANY, $filter->get_join_type()); 213 214 $this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_ALL)); 215 $this->assertEquals(filter::JOINTYPE_ALL, $filter->get_join_type()); 216 } 217 218 /** 219 * Ensure that it is not possible to provide a value out of bounds when setting the join type. 220 */ 221 public function test_set_join_type_invalid_low(): void { 222 $filter = new filter('example'); 223 224 // Valid join types are current 0, 1, or 2. 225 // A value too low should be rejected. 226 $this->expectException(InvalidArgumentException::class); 227 $this->expectExceptionMessage("Invalid join type specified"); 228 $filter->set_join_type(-1); 229 } 230 231 /** 232 * Ensure that it is not possible to provide a value out of bounds when setting the join type. 233 */ 234 public function test_set_join_type_invalid_high(): void { 235 $filter = new filter('example'); 236 237 // Valid join types are current 0, 1, or 2. 238 // A value too low should be rejected. 239 $this->expectException(InvalidArgumentException::class); 240 $this->expectExceptionMessage("Invalid join type specified"); 241 $filter->set_join_type(4); 242 } 243 244 /** 245 * Ensure that the name getter is callable. 246 */ 247 public function test_get_name(): void { 248 $filter = new filter('examplename'); 249 250 $this->assertEquals('examplename', $filter->get_name()); 251 } 252 253 /** 254 * Data provider for the countable tests. 255 * 256 * @return array 257 */ 258 public function filter_value_provider(): array { 259 return [ 260 'Empty' => [[], 0], 261 'Single value' => [[10], 1], 262 'Single repeated value' => [[10, 10, 10, 10], 1], 263 'Multiple values, no repeats' => [[1, 2, 3, 4, 5], 5], 264 'Multiple values, including repeats' => [[1, 2, 1, 3, 1, 3, 4, 1, 5], 5], 265 ]; 266 } 267 268 /** 269 * Ensure that the filter is countable. 270 * 271 * @dataProvider filter_value_provider 272 * @param array $values List of context IDs 273 * @param int $count Expected count 274 */ 275 public function test_countable($values, $count): void { 276 $filter = new filter('example', null, $values); 277 278 $this->assertCount($count, $filter); 279 } 280 281 /** 282 * Ensure that the contextlist_base iterates over the set of contexts. 283 */ 284 public function test_filter_iteration(): void { 285 $filter = new filter('example'); 286 287 // The iterator position should be at the start. 288 $this->assertEquals(0, $filter->key()); 289 290 foreach ($filter as $filtervalue) { 291 // This should not be called. 292 $this->assertFalse(true); 293 } 294 295 // The iterator position should still be at the start. 296 $this->assertEquals(0, $filter->key()); 297 298 // Adding filter values should cause the values in the Iterator to be sorted. 299 $filter = new filter('example'); 300 $filter->add_filter_value(6); 301 $filter->add_filter_value(5); 302 $filter->add_filter_value(4); 303 $filter->add_filter_value(3); 304 $filter->add_filter_value(2); 305 306 // The iterator position should be at the start after adding values. 307 $this->assertEquals(0, $filter->key()); 308 309 $foundvalues = []; 310 foreach ($filter as $filtervalue) { 311 $foundvalues[] = $filtervalue; 312 } 313 314 $this->assertEquals([2, 3, 4, 5, 6], $foundvalues); 315 316 // The iterator position should now be at position 5. 317 // The position is automatically updated prior to moving. 318 $this->assertEquals(5, $filter->key()); 319 320 // Adding another value shoudl cause the Iterator to be re-sorted. 321 $filter->add_filter_value(1); 322 323 // The iterator position should be at the start after adding values. 324 $this->assertEquals(0, $filter->key()); 325 326 $foundvalues = []; 327 foreach ($filter as $filtervalue) { 328 $foundvalues[] = $filtervalue; 329 } 330 331 $this->assertEquals([1, 2, 3, 4, 5, 6], $foundvalues); 332 333 // The iterator position should now be at position 6. 334 $this->assertEquals(6, $filter->key()); 335 } 336 337 /** 338 * Tests for the count function of a filter. 339 */ 340 public function test_filter_current(): void { 341 $filter = new filter('example', null, [42]); 342 $this->assertEquals(42, $filter->current()); 343 } 344 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body