2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Test iterator that skips future documents
20 * @package core_search
22 * @copyright 2017 The Open University
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 namespace core_search
;
28 defined('MOODLE_INTERNAL') ||
die();
31 * Test iterator that skips future documents
33 * @package core_search
35 * @copyright 2017 The Open University
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 class skip_future_documents_iterator_testcase
extends \basic_testcase
{
41 * Test normal case with all documents in the past.
43 public function test_iterator_all_in_past() {
44 $past = strtotime('2017-11-01');
46 self
::make_doc($past, 1),
47 self
::make_doc($past +
1, 2),
48 self
::make_doc($past +
2, 3)
50 $this->assertEquals('mod_x-frog-1.mod_x-frog-2.mod_x-frog-3.',
51 self
::do_iterator($documents));
55 * Confirm that the iterator does not call its parent iterator current() function too many
58 public function test_iterator_performance() {
59 $counter = new test_counting_iterator();
60 $iterator = new skip_future_documents_iterator($counter);
62 foreach ($iterator as $value) {
63 $this->assertEquals(false, $value);
66 $this->assertEquals(3, $items);
67 $this->assertEquals(3, $counter->get_count());
71 * Test with no documents at all.
73 public function test_iterator_empty() {
74 $this->assertEquals('', self
::do_iterator([]));
78 * Test if some documents are in the future.
80 public function test_iterator_some_in_future() {
81 $past = strtotime('2017-11-01');
82 $future = time() +
1000;
84 self
::make_doc($past, 1),
85 self
::make_doc($past +
1, 2),
86 self
::make_doc($future, 3)
88 $this->assertEquals('mod_x-frog-1.mod_x-frog-2.',
89 self
::do_iterator($documents));
93 * Test if all documents are in the future.
95 public function test_iterator_all_in_future() {
96 $future = time() +
1000;
98 self
::make_doc($future, 1),
99 self
::make_doc($future +
1, 2),
100 self
::make_doc($future +
2, 3)
102 $this->assertEquals('', self
::do_iterator($documents));
106 * Test when some documents return error.
108 public function test_iterator_some_false() {
109 $past = strtotime('2017-11-01');
111 self
::make_doc($past, 1),
113 self
::make_doc($past +
2, 3)
115 $this->assertEquals('mod_x-frog-1.false.mod_x-frog-3.',
116 self
::do_iterator($documents));
120 * Test when all documents return error.
122 public function test_iterator_all_false() {
128 $this->assertEquals('false.false.false.',
129 self
::do_iterator($documents));
133 * Test iterator with all cases.
135 public function test_iterator_past_false_and_future() {
136 $past = strtotime('2017-11-01');
137 $future = time() +
1000;
140 self
::make_doc($past, 1),
142 self
::make_doc($past +
1, 2),
144 self
::make_doc($future, 3),
147 $this->assertEquals('false.mod_x-frog-1.false.mod_x-frog-2.false.',
148 self
::do_iterator($documents));
152 * Helper function to create a search document.
154 * @param int $time Modified time
155 * @param int $index Item id
156 * @return document Search document
158 protected static function make_doc($time, $index) {
159 $doc = new document($index, 'mod_x', 'frog');
160 $doc->set('modified', $time);
165 * Puts documents through the iterator and returns result as a string for easy testing.
167 * @param document[] $documents Array of documents
168 * @return string Documents converted to string
170 protected static function do_iterator(array $documents) {
171 $parent = new \
ArrayIterator($documents);
172 $iterator = new skip_future_documents_iterator($parent);
174 foreach ($iterator as $rec) {
178 $result .= $rec->get('id') . '.';
186 * Fake iterator just for counting how many times current() is called. It returns 'false' 3 times.
188 * @package core_search
190 * @copyright 2017 The Open University
191 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
193 class test_counting_iterator
implements \Iterator
{
195 /** @var int Current position in iterator */
197 /** @var int Number of calls to current() function */
198 protected $count = 0;
201 * Returns the current element.
203 * @return mixed Can return any type.
205 public function current() {
211 * Counts iterator usage.
213 * @return int Number of times current() was called
215 public function get_count() {
220 * Goes on to the next element.
222 public function next() {
227 * Gets the key (not supported)
229 * @throws \coding_exception Always
231 public function key() {
232 throw new \
coding_exception('Unsupported');
236 * Checks if iterato is valid (still has entries).
238 * @return bool True if still valid
240 public function valid() {
241 return $this->pos
< 3;
245 * Rewinds the iterator.
247 public function rewind() {