Merge branch 'MDL-77559-39-2' of https://github.com/andrewnicols/moodle into MOODLE_3...
[moodle.git] / search / tests / skip_future_documents_iterator_test.php
blob3e9a40b49c754a106cfa3d2b689f5cf30ef32f03
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.
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/>.
17 /**
18 * Test iterator that skips future documents
20 * @package core_search
21 * @category test
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();
30 /**
31 * Test iterator that skips future documents
33 * @package core_search
34 * @category test
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 {
40 /**
41 * Test normal case with all documents in the past.
43 public function test_iterator_all_in_past() {
44 $past = strtotime('2017-11-01');
45 $documents = [
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));
54 /**
55 * Confirm that the iterator does not call its parent iterator current() function too many
56 * times.
58 public function test_iterator_performance() {
59 $counter = new test_counting_iterator();
60 $iterator = new skip_future_documents_iterator($counter);
61 $items = 0;
62 foreach ($iterator as $value) {
63 $this->assertEquals(false, $value);
64 $items++;
66 $this->assertEquals(3, $items);
67 $this->assertEquals(3, $counter->get_count());
70 /**
71 * Test with no documents at all.
73 public function test_iterator_empty() {
74 $this->assertEquals('', self::do_iterator([]));
77 /**
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;
83 $documents = [
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));
92 /**
93 * Test if all documents are in the future.
95 public function test_iterator_all_in_future() {
96 $future = time() + 1000;
97 $documents = [
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');
110 $documents = [
111 self::make_doc($past, 1),
112 false,
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() {
123 $documents = [
124 false,
125 false,
126 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;
138 $documents = [
139 false,
140 self::make_doc($past, 1),
141 false,
142 self::make_doc($past + 1, 2),
143 false,
144 self::make_doc($future, 3),
145 false
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);
161 return $doc;
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);
173 $result = '';
174 foreach ($iterator as $rec) {
175 if (!$rec) {
176 $result .= 'false.';
177 } else {
178 $result .= $rec->get('id') . '.';
181 return $result;
186 * Fake iterator just for counting how many times current() is called. It returns 'false' 3 times.
188 * @package core_search
189 * @category test
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 */
196 protected $pos = 0;
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() {
206 $this->count++;
207 return false;
211 * Counts iterator usage.
213 * @return int Number of times current() was called
215 public function get_count() {
216 return $this->count;
220 * Goes on to the next element.
222 public function next() {
223 $this->pos++;
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() {
248 $this->pos = 0;