PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/search/tests/skip_future_documents_iterator_test.php

https://gitlab.com/unofficial-mirrors/moodle
PHP | 250 lines | 124 code | 22 blank | 104 comment | 3 complexity | 6bb6a261e74e10274f32a61f778aa89b 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. * Test iterator that skips future documents
  18. *
  19. * @package core_search
  20. * @category test
  21. * @copyright 2017 The Open University
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. namespace core_search;
  25. defined('MOODLE_INTERNAL') || die();
  26. /**
  27. * Test iterator that skips future documents
  28. *
  29. * @package core_search
  30. * @category test
  31. * @copyright 2017 The Open University
  32. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33. */
  34. class skip_future_documents_iterator_testcase extends \basic_testcase {
  35. /**
  36. * Test normal case with all documents in the past.
  37. */
  38. public function test_iterator_all_in_past() {
  39. $past = strtotime('2017-11-01');
  40. $documents = [
  41. self::make_doc($past, 1),
  42. self::make_doc($past + 1, 2),
  43. self::make_doc($past + 2, 3)
  44. ];
  45. $this->assertEquals('mod_x-frog-1.mod_x-frog-2.mod_x-frog-3.',
  46. self::do_iterator($documents));
  47. }
  48. /**
  49. * Confirm that the iterator does not call its parent iterator current() function too many
  50. * times.
  51. */
  52. public function test_iterator_performance() {
  53. $counter = new test_counting_iterator();
  54. $iterator = new skip_future_documents_iterator($counter);
  55. $items = 0;
  56. foreach ($iterator as $value) {
  57. $this->assertEquals(false, $value);
  58. $items++;
  59. }
  60. $this->assertEquals(3, $items);
  61. $this->assertEquals(3, $counter->get_count());
  62. }
  63. /**
  64. * Test with no documents at all.
  65. */
  66. public function test_iterator_empty() {
  67. $this->assertEquals('', self::do_iterator([]));
  68. }
  69. /**
  70. * Test if some documents are in the future.
  71. */
  72. public function test_iterator_some_in_future() {
  73. $past = strtotime('2017-11-01');
  74. $future = time() + 1000;
  75. $documents = [
  76. self::make_doc($past, 1),
  77. self::make_doc($past + 1, 2),
  78. self::make_doc($future, 3)
  79. ];
  80. $this->assertEquals('mod_x-frog-1.mod_x-frog-2.',
  81. self::do_iterator($documents));
  82. }
  83. /**
  84. * Test if all documents are in the future.
  85. */
  86. public function test_iterator_all_in_future() {
  87. $future = time() + 1000;
  88. $documents = [
  89. self::make_doc($future, 1),
  90. self::make_doc($future + 1, 2),
  91. self::make_doc($future + 2, 3)
  92. ];
  93. $this->assertEquals('', self::do_iterator($documents));
  94. }
  95. /**
  96. * Test when some documents return error.
  97. */
  98. public function test_iterator_some_false() {
  99. $past = strtotime('2017-11-01');
  100. $documents = [
  101. self::make_doc($past, 1),
  102. false,
  103. self::make_doc($past + 2, 3)
  104. ];
  105. $this->assertEquals('mod_x-frog-1.false.mod_x-frog-3.',
  106. self::do_iterator($documents));
  107. }
  108. /**
  109. * Test when all documents return error.
  110. */
  111. public function test_iterator_all_false() {
  112. $documents = [
  113. false,
  114. false,
  115. false
  116. ];
  117. $this->assertEquals('false.false.false.',
  118. self::do_iterator($documents));
  119. }
  120. /**
  121. * Test iterator with all cases.
  122. */
  123. public function test_iterator_past_false_and_future() {
  124. $past = strtotime('2017-11-01');
  125. $future = time() + 1000;
  126. $documents = [
  127. false,
  128. self::make_doc($past, 1),
  129. false,
  130. self::make_doc($past + 1, 2),
  131. false,
  132. self::make_doc($future, 3),
  133. false
  134. ];
  135. $this->assertEquals('false.mod_x-frog-1.false.mod_x-frog-2.false.',
  136. self::do_iterator($documents));
  137. }
  138. /**
  139. * Helper function to create a search document.
  140. *
  141. * @param int $time Modified time
  142. * @param int $index Item id
  143. * @return document Search document
  144. */
  145. protected static function make_doc($time, $index) {
  146. $doc = new document($index, 'mod_x', 'frog');
  147. $doc->set('modified', $time);
  148. return $doc;
  149. }
  150. /**
  151. * Puts documents through the iterator and returns result as a string for easy testing.
  152. *
  153. * @param document[] $documents Array of documents
  154. * @return string Documents converted to string
  155. */
  156. protected static function do_iterator(array $documents) {
  157. $parent = new \ArrayIterator($documents);
  158. $iterator = new skip_future_documents_iterator($parent);
  159. $result = '';
  160. foreach ($iterator as $rec) {
  161. if (!$rec) {
  162. $result .= 'false.';
  163. } else {
  164. $result .= $rec->get('id') . '.';
  165. }
  166. }
  167. return $result;
  168. }
  169. }
  170. /**
  171. * Fake iterator just for counting how many times current() is called. It returns 'false' 3 times.
  172. *
  173. * @package core_search
  174. * @category test
  175. * @copyright 2017 The Open University
  176. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  177. */
  178. class test_counting_iterator implements \Iterator {
  179. /** @var int Current position in iterator */
  180. protected $pos = 0;
  181. /** @var int Number of calls to current() function */
  182. protected $count = 0;
  183. /**
  184. * Returns the current element.
  185. *
  186. * @return mixed Can return any type.
  187. */
  188. public function current() {
  189. $this->count++;
  190. return false;
  191. }
  192. /**
  193. * Counts iterator usage.
  194. *
  195. * @return int Number of times current() was called
  196. */
  197. public function get_count() {
  198. return $this->count;
  199. }
  200. /**
  201. * Goes on to the next element.
  202. */
  203. public function next() {
  204. $this->pos++;
  205. }
  206. /**
  207. * Gets the key (not supported)
  208. *
  209. * @throws \coding_exception Always
  210. */
  211. public function key() {
  212. throw new \coding_exception('Unsupported');
  213. }
  214. /**
  215. * Checks if iterato is valid (still has entries).
  216. *
  217. * @return bool True if still valid
  218. */
  219. public function valid() {
  220. return $this->pos < 3;
  221. }
  222. /**
  223. * Rewinds the iterator.
  224. */
  225. public function rewind() {
  226. $this->pos = 0;
  227. }
  228. }