AutorÃa | Ultima modificación | Ver Log |
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_table\local\filter;
use advanced_testcase;
use InvalidArgumentException;
/**
* Unit tests for core_table\local\filter\filter.
*
* @package core_table
* @category test
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_table\local\filter\filter
*/
class filter_test extends advanced_testcase {
/**
* Test that the constructor correctly handles a number of conditions.
*
* @dataProvider constructor_provider
* @param array $args
* @param int $jointype
* @param array $values
*/
public function test_constructor(array $args, int $jointype, array $values): void {
$filter = new filter(...$args);
// We should always get a filter.
$this->assertInstanceOf(filter::class, $filter);
// We should always get the correct join type.
$this->assertEquals($jointype, $filter->get_join_type());
// The values should be the expected ones.
$this->assertSame($values, $filter->get_filter_values());
}
/**
* Data provider for the constructor providing a range of valid constructor arguments.
*
* @return array
*/
public function constructor_provider(): array {
return [
'Name without values' => [['keyword'], filter::JOINTYPE_DEFAULT, []],
'Name with valid join type ANY' => [[
'keyword',
filter::JOINTYPE_ANY,
], filter::JOINTYPE_ANY, []],
'Name with valid join type ALL' => [[
'keyword',
filter::JOINTYPE_ALL,
], filter::JOINTYPE_ALL, []],
'Name with valid join type NONE' => [[
'keyword',
filter::JOINTYPE_NONE,
], filter::JOINTYPE_NONE, []],
'Name, no join type, with set of values' => [
[
'keyword',
null,
[
's1',
'janine',
],
],
filter::JOINTYPE_DEFAULT,
[
'janine',
's1',
],
],
'Name, and ANY, with set of values' => [
[
'keyword',
filter::JOINTYPE_ANY,
[
's1',
'kevin',
'james',
'janine',
],
],
filter::JOINTYPE_ANY,
[
'james',
'janine',
'kevin',
's1',
],
],
'Name, and ANY, with set of values which contains duplicates' => [
[
'keyword',
filter::JOINTYPE_ANY,
[
's1',
'kevin',
'james',
'janine',
'kevin',
],
],
filter::JOINTYPE_ANY,
[
'james',
'janine',
'kevin',
's1',
],
],
];
}
/**
* Test that the constructor throws a relevant exception when passed an invalid join.
*
* @dataProvider constructor_invalid_join_provider
* @param mixed $jointype
*/
public function test_constructor_invalid_joins($jointype): void {
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid join type specified');
new filter('invalid', $jointype);
}
/**
* Data provider for the constructor providing a range of invalid join types to the constructor.
*
* @return array
*/
public function constructor_invalid_join_provider(): array {
return [
'Too low' => [-1],
'Too high' => [4],
];
}
/**
* Enusre that adding filter values works as expected.
*/
public function test_add_filter_value(): void {
$filter = new filter('example');
// Initially an empty list.
$this->assertEmpty($filter->get_filter_values());
// Adding null should do nothing.
$filter->add_filter_value(null);
$this->assertEmpty($filter->get_filter_values());
// Adding empty string should do nothing.
$filter->add_filter_value('');
$this->assertEmpty($filter->get_filter_values());
// Adding a value should return that value.
$filter->add_filter_value('rosie');
$this->assertSame([
'rosie',
], $filter->get_filter_values());
// Adding a second value should add that value.
// The values should sorted.
$filter->add_filter_value('arthur');
$this->assertSame([
'arthur',
'rosie',
], $filter->get_filter_values());
// Adding a duplicate value should not lead to that value being added again.
$filter->add_filter_value('arthur');
$this->assertSame([
'arthur',
'rosie',
], $filter->get_filter_values());
}
/**
* Ensure that it is possibly to set the join type.
*/
public function test_set_join_type(): void {
$filter = new filter('example');
// Initial set with the default type should just work.
// The setter should be chainable.
$this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_DEFAULT));
$this->assertEquals(filter::JOINTYPE_DEFAULT, $filter->get_join_type());
// It should be possible to update the join type later.
$this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_NONE));
$this->assertEquals(filter::JOINTYPE_NONE, $filter->get_join_type());
$this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_ANY));
$this->assertEquals(filter::JOINTYPE_ANY, $filter->get_join_type());
$this->assertEquals($filter, $filter->set_join_type(filter::JOINTYPE_ALL));
$this->assertEquals(filter::JOINTYPE_ALL, $filter->get_join_type());
}
/**
* Ensure that it is not possible to provide a value out of bounds when setting the join type.
*/
public function test_set_join_type_invalid_low(): void {
$filter = new filter('example');
// Valid join types are current 0, 1, or 2.
// A value too low should be rejected.
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Invalid join type specified");
$filter->set_join_type(-1);
}
/**
* Ensure that it is not possible to provide a value out of bounds when setting the join type.
*/
public function test_set_join_type_invalid_high(): void {
$filter = new filter('example');
// Valid join types are current 0, 1, or 2.
// A value too low should be rejected.
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Invalid join type specified");
$filter->set_join_type(4);
}
/**
* Ensure that the name getter is callable.
*/
public function test_get_name(): void {
$filter = new filter('examplename');
$this->assertEquals('examplename', $filter->get_name());
}
/**
* Data provider for the countable tests.
*
* @return array
*/
public function filter_value_provider(): array {
return [
'Empty' => [[], 0],
'Single value' => [[10], 1],
'Single repeated value' => [[10, 10, 10, 10], 1],
'Multiple values, no repeats' => [[1, 2, 3, 4, 5], 5],
'Multiple values, including repeats' => [[1, 2, 1, 3, 1, 3, 4, 1, 5], 5],
];
}
/**
* Ensure that the filter is countable.
*
* @dataProvider filter_value_provider
* @param array $values List of context IDs
* @param int $count Expected count
*/
public function test_countable($values, $count): void {
$filter = new filter('example', null, $values);
$this->assertCount($count, $filter);
}
/**
* Ensure that the contextlist_base iterates over the set of contexts.
*/
public function test_filter_iteration(): void {
$filter = new filter('example');
// The iterator position should be at the start.
$this->assertEquals(0, $filter->key());
foreach ($filter as $filtervalue) {
// This should not be called.
$this->assertFalse(true);
}
// The iterator position should still be at the start.
$this->assertEquals(0, $filter->key());
// Adding filter values should cause the values in the Iterator to be sorted.
$filter = new filter('example');
$filter->add_filter_value(6);
$filter->add_filter_value(5);
$filter->add_filter_value(4);
$filter->add_filter_value(3);
$filter->add_filter_value(2);
// The iterator position should be at the start after adding values.
$this->assertEquals(0, $filter->key());
$foundvalues = [];
foreach ($filter as $filtervalue) {
$foundvalues[] = $filtervalue;
}
$this->assertEquals([2, 3, 4, 5, 6], $foundvalues);
// The iterator position should now be at position 5.
// The position is automatically updated prior to moving.
$this->assertEquals(5, $filter->key());
// Adding another value shoudl cause the Iterator to be re-sorted.
$filter->add_filter_value(1);
// The iterator position should be at the start after adding values.
$this->assertEquals(0, $filter->key());
$foundvalues = [];
foreach ($filter as $filtervalue) {
$foundvalues[] = $filtervalue;
}
$this->assertEquals([1, 2, 3, 4, 5, 6], $foundvalues);
// The iterator position should now be at position 6.
$this->assertEquals(6, $filter->key());
}
/**
* Tests for the count function of a filter.
*/
public function test_filter_current(): void {
$filter = new filter('example', null, [42]);
$this->assertEquals(42, $filter->current());
}
}