PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/table/tests/local/filter/numeric_comparison_filter_test.php

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