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 core_table\local\filter\numeric_comparison_filter. 19 * 20 * @package core_table 21 * @category test 22 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License 24 */ 25 26 declare(strict_types=1); 27 28 namespace core_table\local\filter; 29 30 use advanced_testcase; 31 use InvalidArgumentException; 32 use TypeError; 33 34 /** 35 * Unit tests for core_table\local\filter\numeric_comparison_filter. 36 * 37 * @package core_table 38 * @category test 39 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class numeric_comparison_filter_test extends advanced_testcase { 43 /** 44 * Ensure that the add_filter_value function works as expected with valid values. 45 */ 46 public function test_add_filter_value_valid(): void { 47 $filter = new numeric_comparison_filter('example'); 48 49 // Initially an empty list. 50 $this->assertEmpty($filter->get_filter_values()); 51 52 // Adding a value should return that value. 53 $filter->add_filter_value(json_encode((object) [ 54 'direction' => '>', 55 'value' => 100, 56 ])); 57 $this->assertEquals([ 58 (object) [ 59 'direction' => '>', 60 'value' => 100, 61 ], 62 ], $filter->get_filter_values()); 63 64 // Adding a second value should add that value. 65 // The values should sorted. 66 $filter->add_filter_value(json_encode((object) [ 67 'direction' => '<=', 68 'value' => 1000, 69 ])); 70 $this->assertEquals([ 71 (object) [ 72 'direction' => '<=', 73 'value' => 1000, 74 ], 75 (object) [ 76 'direction' => '>', 77 'value' => 100, 78 ], 79 ], $filter->get_filter_values()); 80 81 // Adding a duplicate value should not lead to that value being added again. 82 $filter->add_filter_value(json_encode((object) [ 83 'direction' => '>', 84 'value' => 100, 85 ])); 86 $this->assertEquals([ 87 (object) [ 88 'direction' => '<=', 89 'value' => 1000, 90 ], 91 (object) [ 92 'direction' => '>', 93 'value' => 100, 94 ], 95 ], $filter->get_filter_values()); 96 } 97 98 /** 99 * Ensure that the add_filter_value function rejects invalid types. 100 * 101 * @dataProvider add_filter_value_invalid_types_provider 102 * @param mixed $values 103 * @param string $exceptiontype 104 * @param string $exceptionmessage 105 */ 106 public function test_add_filter_value_type_invalid($values, string $exceptiontype, string $exceptionmessage): void { 107 $filter = new numeric_comparison_filter('example'); 108 109 // Adding empty string is not supported. 110 $this->expectException($exceptiontype); 111 $this->expectExceptionMessage($exceptionmessage); 112 call_user_func_array([$filter, 'add_filter_value'], $values); 113 } 114 115 /** 116 * Data provider for add_filter_value tests with invalid types. 117 * 118 * @return array 119 */ 120 public function add_filter_value_invalid_types_provider(): array { 121 return [ 122 'Null' => [ 123 [null], 124 TypeError::class, 125 "The value supplied was of type 'NULL'. A string representing a json-encoded value was expected.", 126 ], 127 'Single value string' => [ 128 [''], 129 InvalidArgumentException::class, 130 "A json-encoded object containing both a direction, and comparison value was expected.", 131 ], 132 'Single value integer' => [ 133 [42], 134 TypeError::class, 135 "The value supplied was of type 'integer'. A string representing a json-encoded value was expected.", 136 ], 137 'Single value float' => [ 138 [4.2], 139 TypeError::class, 140 "The value supplied was of type 'double'. A string representing a json-encoded value was expected.", 141 ], 142 'Single value bool' => [ 143 [false], 144 TypeError::class, 145 "The value supplied was of type 'boolean'. A string representing a json-encoded value was expected.", 146 ], 147 'Single value array' => [ 148 [[]], 149 TypeError::class, 150 "The value supplied was of type 'array'. A string representing a json-encoded value was expected.", 151 ], 152 'Single value object' => [ 153 [(object) []], 154 TypeError::class, 155 "The value supplied was of type 'stdClass'. A string representing a json-encoded value was expected.", 156 ], 157 'Single value class' => [ 158 [new filter('example')], 159 TypeError::class, 160 "The value supplied was of type '" . filter::class . "'. A string representing a json-encoded value was expected.", 161 ], 162 163 'json-encoded single value null' => [ 164 // Note a json-encoded null is the stringy 'null'. 165 [json_encode(null)], 166 InvalidArgumentException::class, 167 "A json-encoded object containing both a direction, and comparison value was expected.", 168 ], 169 'json-encoded single value string' => [ 170 [json_encode('')], 171 InvalidArgumentException::class, 172 "The value supplied was a json encoded 'string'. " . 173 "An object containing both a direction, and comparison value was expected.", 174 ], 175 'json-encoded single value integer' => [ 176 [json_encode(42)], 177 InvalidArgumentException::class, 178 "The value supplied was a json encoded 'string'. " . 179 "An object containing both a direction, and comparison value was expected.", 180 ], 181 'json-encoded single value double' => [ 182 [json_encode(4.2)], 183 InvalidArgumentException::class, 184 "The value supplied was a json encoded 'string'. " . 185 "An object containing both a direction, and comparison value was expected.", 186 ], 187 'json-encoded single value bool' => [ 188 [json_encode(false)], 189 InvalidArgumentException::class, 190 "The value supplied was a json encoded 'string'. " . 191 "An object containing both a direction, and comparison value was expected.", 192 ], 193 'json-encoded single value array' => [ 194 [json_encode([])], 195 InvalidArgumentException::class, 196 "The value supplied was a json encoded 'string'. " . 197 "An object containing both a direction, and comparison value was expected.", 198 ], 199 200 'json-encoded empty object' => [ 201 [json_encode((object) [])], 202 InvalidArgumentException::class, 203 "A 'direction' must be provided.", 204 ], 205 'json-encoded single value class' => [ 206 // A class will contain any public properties when json-encoded. It is treated in the same was a stdClass. 207 [json_encode(new filter('example'))], 208 InvalidArgumentException::class, 209 "A 'direction' must be provided.", 210 ], 211 212 'Direction provided, value missing' => [ 213 [json_encode([ 214 'direction' => '>', 215 ])], 216 InvalidArgumentException::class, 217 "A 'value' must be provided.", 218 ], 219 220 'Direction invalid +' => [ 221 [json_encode([ 222 'direction' => '+', 223 'value' => 100, 224 ])], 225 InvalidArgumentException::class, 226 "Invalid direction specified '+'." 227 ], 228 'Direction invalid -' => [ 229 [json_encode([ 230 'direction' => '-', 231 'value' => 100, 232 ])], 233 InvalidArgumentException::class, 234 "Invalid direction specified '-'." 235 ], 236 237 'Value string' => [ 238 [json_encode([ 239 'direction' => '>', 240 'value' => "example", 241 ])], 242 TypeError::class, 243 "The value supplied was of type 'string'. A numeric value was expected." 244 ], 245 'Value bool' => [ 246 [json_encode([ 247 'direction' => '>', 248 'value' => false, 249 ])], 250 TypeError::class, 251 "The value supplied was of type 'boolean'. A numeric value was expected." 252 ], 253 'Value array' => [ 254 [json_encode([ 255 'direction' => '>', 256 'value' => [], 257 ])], 258 TypeError::class, 259 "The value supplied was of type 'array'. A numeric value was expected." 260 ], 261 'Value stdClass' => [ 262 [json_encode([ 263 'direction' => '>', 264 'value' => (object) [], 265 ])], 266 TypeError::class, 267 "The value supplied was of type 'stdClass'. A numeric value was expected." 268 ], 269 'Value class' => [ 270 // A class will contain any public properties when json-encoded. It is treated in the same was a stdClass. 271 [json_encode([ 272 'direction' => '>', 273 'value' => new filter('example'), 274 ])], 275 TypeError::class, 276 "The value supplied was of type 'stdClass'. A numeric value was expected." 277 ], 278 ]; 279 } 280 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body