Merge branch 'MDL-32426-master-1' of git://git.luns.net.uk/moodle
[moodle.git] / lib / phpunit / generatorlib.php
CommitLineData
a3d5830a
PS
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/**
18 * PHPUnit data generator class
19 *
20 * @package core
21 * @category phpunit
22 * @copyright 2012 Petr Skoda {@link http://skodak.org}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
3c4c5189 28
4b027431
PS
29/**
30 * Data generator for unit tests
3c4c5189
PS
31 *
32 * @package core
33 * @category phpunit
34 * @copyright 2012 Petr Skoda {@link http://skodak.org}
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4b027431 36 */
a3d5830a
PS
37class phpunit_data_generator {
38 protected $usercounter = 0;
39 protected $categorycount = 0;
40 protected $coursecount = 0;
4c6062ea 41 protected $scalecount = 0;
f15d4515
ARN
42 protected $groupcount = 0;
43 protected $groupingcount = 0;
a3d5830a 44
3c4c5189
PS
45 /** @var array list of plugin generators */
46 protected $generators = array();
47
4594a381
PS
48 /** @var array lis of common last names */
49 public $lastnames = array(
50 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'García', 'Rodríguez', 'Wilson',
51 'Müller', 'Schmidt', 'Schneider', 'Fischer', 'Meyer', 'Weber', 'Schulz', 'Wagner', 'Becker', 'Hoffmann',
52 'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházková', 'Kučerová', 'Veselá', 'Horáková', 'Němcová',
53 'Смирнов', 'Иванов', 'Кузнецов', 'Соколов', 'Попов', 'Лебедева', 'Козлова', 'Новикова', 'Морозова', 'Петрова',
54 '王', '李', '张', '刘', '陈', '楊', '黃', '趙', '吳', '周',
55 '佐藤', '鈴木', '高橋', '田中', '渡辺', '伊藤', '山本', '中村', '小林', '斎藤',
56 );
57
58 /** @var array lis of common first names */
59 public $firstnames = array(
60 'Jacob', 'Ethan', 'Michael', 'Jayden', 'William', 'Isabella', 'Sophia', 'Emma', 'Olivia', 'Ava',
61 'Lukas', 'Leon', 'Luca', 'Timm', 'Paul', 'Leonie', 'Leah', 'Lena', 'Hanna', 'Laura',
62 'Jakub', 'Jan', 'Tomáš', 'Lukáš', 'Matěj', 'Tereza', 'Eliška', 'Anna', 'Adéla', 'Karolína',
63 'Даниил', 'Максим', 'Артем', 'Иван', 'Александр', 'София', 'Анастасия', 'Дарья', 'Мария', 'Полина',
64 '伟', '伟', '芳', '伟', '秀英', '秀英', '娜', '秀英', '伟', '敏',
65 '翔', '大翔', '拓海', '翔太', '颯太', '陽菜', 'さくら', '美咲', '葵', '美羽',
66 );
67
68 public $loremipsum = <<<EOD
69Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla non arcu lacinia neque faucibus fringilla. Vivamus porttitor turpis ac leo. Integer in sapien. Nullam eget nisl. Aliquam erat volutpat. Cras elementum. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Integer malesuada. Nullam lectus justo, vulputate eget mollis sed, tempor sed magna. Mauris elementum mauris vitae tortor. Aliquam erat volutpat.
70Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Aliquam ante. Proin in tellus sit amet nibh dignissim sagittis. Vivamus porttitor turpis ac leo. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, eget facilisis enim ipsum id lacus. In sem justo, commodo ut, suscipit at, pharetra vitae, orci. Aliquam erat volutpat. Nulla est.
71Vivamus luctus egestas leo. Aenean fermentum risus id tortor. Mauris dictum facilisis augue. Aliquam erat volutpat. Aliquam ornare wisi eu metus. Aliquam id dolor. Duis condimentum augue id magna semper rutrum. Donec iaculis gravida nulla. Pellentesque ipsum. Etiam dictum tincidunt diam. Quisque tincidunt scelerisque libero. Etiam egestas wisi a erat.
72Integer lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris tincidunt sem sed arcu. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Aliquam id dolor. Maecenas sollicitudin. Et harum quidem rerum facilis est et expedita distinctio. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Nullam dapibus fermentum ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Pellentesque sapien. Duis risus. Mauris elementum mauris vitae tortor. Suspendisse nisl. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim.
73In laoreet, magna id viverra tincidunt, sem odio bibendum justo, vel imperdiet sapien wisi sed libero. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Maecenas lorem. Etiam posuere lacus quis dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Nam sed tellus id magna elementum tincidunt. Suspendisse nisl. Vivamus luctus egestas leo. Nulla non arcu lacinia neque faucibus fringilla. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Etiam dictum tincidunt diam. Etiam commodo dui eget wisi. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Pellentesque sapien.
74EOD;
75
a3d5830a
PS
76 /**
77 * To be called from data reset code only,
78 * do not use in tests.
79 * @return void
80 */
81 public function reset() {
82 $this->usercounter = 0;
83 $this->categorycount = 0;
84 $this->coursecount = 0;
4c6062ea 85 $this->scalecount = 0;
3c4c5189
PS
86
87 foreach($this->generators as $generator) {
88 $generator->reset();
89 }
90 }
91
920f4efe
PS
92 /**
93 * Return generator for given plugin
94 * @param string $component
95 * @return mixed plugin data generator
96 */
3c4c5189
PS
97 public function get_plugin_generator($component) {
98 list($type, $plugin) = normalize_component($component);
99
100 if ($type !== 'mod' and $type !== 'block') {
101 throw new coding_exception("Plugin type $type does not support generators yet");
102 }
103
104 $dir = get_plugin_directory($type, $plugin);
105
106 if (!isset($this->generators[$type.'_'.$plugin])) {
107 $lib = "$dir/tests/generator/lib.php";
108 if (!include_once($lib)) {
109 throw new coding_exception("Plugin $component does not support data generator, missing tests/generator/lib");
110 }
111 $classname = $type.'_'.$plugin.'_generator';
112 $this->generators[$type.'_'.$plugin] = new $classname($this);
113 }
114
115 return $this->generators[$type.'_'.$plugin];
a3d5830a
PS
116 }
117
118 /**
119 * Create a test user
120 * @param array|stdClass $record
121 * @param array $options
4b027431 122 * @return stdClass user record
a3d5830a
PS
123 */
124 public function create_user($record=null, array $options=null) {
125 global $DB, $CFG;
126
127 $this->usercounter++;
128 $i = $this->usercounter;
129
130 $record = (array)$record;
131
132 if (!isset($record['auth'])) {
133 $record['auth'] = 'manual';
134 }
135
4594a381
PS
136 if (!isset($record['firstname']) and !isset($record['lastname'])) {
137 $country = rand(0, 5);
138 $firstname = rand(0, 4);
139 $lastname = rand(0, 4);
140 $female = rand(0, 1);
141 $record['firstname'] = $this->firstnames[($country*10) + $firstname + ($female*5)];
142 $record['lastname'] = $this->lastnames[($country*10) + $lastname + ($female*5)];
143
144 } else if (!isset($record['firstname'])) {
a3d5830a 145 $record['firstname'] = 'Firstname'.$i;
a3d5830a 146
4594a381 147 } else if (!isset($record['lastname'])) {
a3d5830a
PS
148 $record['lastname'] = 'Lastname'.$i;
149 }
150
151 if (!isset($record['idnumber'])) {
152 $record['idnumber'] = '';
153 }
154
4594a381
PS
155 if (!isset($record['mnethostid'])) {
156 $record['mnethostid'] = $CFG->mnet_localhost_id;
157 }
158
a3d5830a 159 if (!isset($record['username'])) {
4594a381
PS
160 $record['username'] = textlib::strtolower($record['firstname']).textlib::strtolower($record['lastname']);
161 while ($DB->record_exists('user', array('username'=>$record['username'], 'mnethostid'=>$record['mnethostid']))) {
162 $record['username'] = $record['username'].'_'.$i;
163 }
a3d5830a
PS
164 }
165
166 if (!isset($record['password'])) {
167 $record['password'] = 'lala';
168 }
169
170 if (!isset($record['email'])) {
171 $record['email'] = $record['username'].'@example.com';
172 }
173
174 if (!isset($record['confirmed'])) {
175 $record['confirmed'] = 1;
176 }
177
a3d5830a
PS
178 if (!isset($record['lang'])) {
179 $record['lang'] = 'en';
180 }
181
182 if (!isset($record['maildisplay'])) {
183 $record['maildisplay'] = 1;
184 }
185
186 if (!isset($record['deleted'])) {
187 $record['deleted'] = 0;
188 }
189
190 $record['timecreated'] = time();
191 $record['timemodified'] = $record['timecreated'];
192 $record['lastip'] = '0.0.0.0';
193
194 $record['password'] = hash_internal_user_password($record['password']);
195
196 if ($record['deleted']) {
197 $delname = $record['email'].'.'.time();
198 while ($DB->record_exists('user', array('username'=>$delname))) {
199 $delname++;
200 }
201 $record['idnumber'] = '';
202 $record['email'] = md5($record['username']);
203 $record['username'] = $delname;
204 }
205
206 $userid = $DB->insert_record('user', $record);
4594a381 207
a3d5830a
PS
208 if (!$record['deleted']) {
209 context_user::instance($userid);
210 }
211
212 return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
213 }
214
215 /**
216 * Create a test course category
217 * @param array|stdClass $record
218 * @param array $options
4b027431 219 * @return stdClass course category record
a3d5830a
PS
220 */
221 function create_category($record=null, array $options=null) {
222 global $DB, $CFG;
223 require_once("$CFG->dirroot/course/lib.php");
224
225 $this->categorycount++;
226 $i = $this->categorycount;
227
228 $record = (array)$record;
229
230 if (!isset($record['name'])) {
231 $record['name'] = 'Course category '.$i;
232 }
233
234 if (!isset($record['idnumber'])) {
235 $record['idnumber'] = '';
236 }
237
238 if (!isset($record['description'])) {
4594a381 239 $record['description'] = "Test course category $i\n$this->loremipsum";
a3d5830a
PS
240 }
241
242 if (!isset($record['descriptionformat'])) {
243 $record['description'] = FORMAT_MOODLE;
244 }
245
246 if (!isset($record['parent'])) {
247 $record['descriptionformat'] = 0;
248 }
249
3c4c5189 250 if (empty($record['parent'])) {
a3d5830a
PS
251 $parent = new stdClass();
252 $parent->path = '';
253 $parent->depth = 0;
254 } else {
255 $parent = $DB->get_record('course_categories', array('id'=>$record['parent']), '*', MUST_EXIST);
256 }
257 $record['depth'] = $parent->depth+1;
258
259 $record['sortorder'] = 0;
260 $record['timemodified'] = time();
261 $record['timecreated'] = $record['timemodified'];
262
263 $catid = $DB->insert_record('course_categories', $record);
264 $path = $parent->path . '/' . $catid;
265 $DB->set_field('course_categories', 'path', $path, array('id'=>$catid));
266 context_coursecat::instance($catid);
267
268 fix_course_sortorder();
269
270 return $DB->get_record('course_categories', array('id'=>$catid), '*', MUST_EXIST);
271 }
272
273 /**
274 * Create a test course
275 * @param array|stdClass $record
354b214c
PS
276 * @param array $options with keys:
277 * 'createsections'=>bool precreate all sections
4b027431 278 * @return stdClass course record
a3d5830a
PS
279 */
280 function create_course($record=null, array $options=null) {
281 global $DB, $CFG;
282 require_once("$CFG->dirroot/course/lib.php");
283
284 $this->coursecount++;
285 $i = $this->coursecount;
286
287 $record = (array)$record;
288
289 if (!isset($record['fullname'])) {
290 $record['fullname'] = 'Test course '.$i;
291 }
292
293 if (!isset($record['shortname'])) {
294 $record['shortname'] = 'tc_'.$i;
295 }
296
297 if (!isset($record['idnumber'])) {
298 $record['idnumber'] = '';
299 }
300
301 if (!isset($record['format'])) {
302 $record['format'] = 'topics';
303 }
304
305 if (!isset($record['newsitems'])) {
306 $record['newsitems'] = 0;
307 }
308
309 if (!isset($record['numsections'])) {
310 $record['numsections'] = 5;
311 }
312
313 if (!isset($record['description'])) {
4594a381 314 $record['description'] = "Test course $i\n$this->loremipsum";
a3d5830a
PS
315 }
316
317 if (!isset($record['descriptionformat'])) {
318 $record['description'] = FORMAT_MOODLE;
319 }
320
321 if (!isset($record['category'])) {
322 $record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
323 }
324
325 $course = create_course((object)$record);
326 context_course::instance($course->id);
327
354b214c
PS
328 if (!empty($options['createsections'])) {
329 for($i=1; $i<$record['numsections']; $i++) {
330 self::create_course_section(array('course'=>$course->id, 'section'=>$i));
331 }
332 }
333
a3d5830a
PS
334 return $course;
335 }
336
354b214c
PS
337 /**
338 * Create course section if does not exist yet
339 * @param mixed $record
340 * @param array|null $options
341 * @return stdClass
342 * @throws coding_exception
343 */
344 public function create_course_section($record = null, array $options = null) {
345 global $DB;
346
347 $record = (array)$record;
348
349 if (empty($record['course'])) {
350 throw new coding_exception('course must be present in phpunit_util::create_course_section() $record');
351 }
352
353 if (!isset($record['section'])) {
354 throw new coding_exception('section must be present in phpunit_util::create_course_section() $record');
355 }
356
357 if (!isset($record['name'])) {
358 $record['name'] = '';
359 }
360
361 if (!isset($record['summary'])) {
362 $record['summary'] = '';
363 }
364
365 if (!isset($record['summaryformat'])) {
366 $record['summaryformat'] = FORMAT_MOODLE;
367 }
368
369 if ($section = $DB->get_record('course_sections', array('course'=>$record['course'], 'section'=>$record['section']))) {
370 return $section;
371 }
372
373 $section = new stdClass();
374 $section->course = $record['course'];
375 $section->section = $record['section'];
376 $section->name = $record['name'];
377 $section->summary = $record['summary'];
378 $section->summaryformat = $record['summaryformat'];
379 $id = $DB->insert_record('course_sections', $section);
380
381 return $DB->get_record('course_sections', array('id'=>$id));
382 }
383
a3d5830a
PS
384 /**
385 * Create a test block
386 * @param string $blockname
387 * @param array|stdClass $record
388 * @param array $options
4b027431 389 * @return stdClass block instance record
a3d5830a
PS
390 */
391 public function create_block($blockname, $record=null, array $options=null) {
3c4c5189
PS
392 $generator = $this->get_plugin_generator('block_'.$blockname);
393 return $generator->create_instance($record, $options);
a3d5830a
PS
394 }
395
396 /**
397 * Create a test module
398 * @param string $modulename
399 * @param array|stdClass $record
400 * @param array $options
4b027431 401 * @return stdClass activity record
a3d5830a
PS
402 */
403 public function create_module($modulename, $record=null, array $options=null) {
3c4c5189
PS
404 $generator = $this->get_plugin_generator('mod_'.$modulename);
405 return $generator->create_instance($record, $options);
a3d5830a 406 }
4c6062ea 407
f15d4515
ARN
408 /**
409 * Create a test group for the specified course
410 *
411 * @param array|stdClass $recrd
412 * @return stdClass group record
413 */
414 public function create_group($record) {
415 global $DB, $CFG;
416
417 require_once($CFG->dirroot . '/group/lib.php');
418
419 $this->groupcount++;
420 $i = $this->groupcount;
421
422 $record = (array)$record;
423
424 if (empty($record['courseid'])) {
425 throw new coding_exception('courseid must be present in phpunit_util::create_group() $record');
426 }
427
428 if (!isset($record['name'])) {
429 $record['name'] = 'group-' . $i;
430 }
431
432 if (!isset($record['description'])) {
433 $record['description'] = "Test Group $i\n{$this->loremipsum}";
434 }
435
436 if (!isset($record['descriptionformat'])) {
437 $record['descriptionformat'] = FORMAT_MOODLE;
438 }
439
440 $id = groups_create_group((object)$record);
441
442 return $DB->get_record('groups', array('id'=>$id));
443 }
444
445 /**
446 * Create a test grouping for the specified course
447 *
448 * @param array|stdClass $recrd
449 * @return stdClass grouping record
450 */
451 public function create_grouping($record) {
452 global $DB, $CFG;
453
454 require_once($CFG->dirroot . '/group/lib.php');
455
456 $this->groupingcount++;
457 $i = $this->groupingcount;
458
459 $record = (array)$record;
460
461 if (empty($record['courseid'])) {
462 throw new coding_exception('courseid must be present in phpunit_util::create_grouping() $record');
463 }
464
465 if (!isset($record['name'])) {
466 $record['name'] = 'grouping-' . $i;
467 }
468
469 if (!isset($record['description'])) {
470 $record['description'] = "Test Grouping $i\n{$this->loremipsum}";
471 }
472
473 if (!isset($record['descriptionformat'])) {
474 $record['descriptionformat'] = FORMAT_MOODLE;
475 }
476
477 $id = groups_create_grouping((object)$record);
478
479 return $DB->get_record('groupings', array('id'=>$id));
480 }
481
4c6062ea
PS
482 /**
483 * Create a test scale
484 * @param array|stdClass $record
485 * @param array $options
486 * @return stdClass block instance record
487 */
488 public function create_scale($record=null, array $options=null) {
489 global $DB;
490
491 $this->scalecount++;
492 $i = $this->scalecount;
493
494 $record = (array)$record;
495
496 if (!isset($record['name'])) {
497 $record['name'] = 'Test scale '.$i;
498 }
499
500 if (!isset($record['scale'])) {
501 $record['scale'] = 'A,B,C,D,F';
502 }
503
504 if (!isset($record['courseid'])) {
505 $record['courseid'] = 0;
506 }
507
508 if (!isset($record['userid'])) {
509 $record['userid'] = 0;
510 }
511
512 if (!isset($record['description'])) {
513 $record['description'] = 'Test scale description '.$i;
514 }
515
516 if (!isset($record['descriptionformat'])) {
517 $record['descriptionformat'] = FORMAT_MOODLE;
518 }
519
520 $record['timemodified'] = time();
521
522 if (isset($record['id'])) {
523 $DB->import_record('scale', $record);
524 $DB->get_manager()->reset_sequence('scale');
525 $id = $record['id'];
526 } else {
527 $id = $DB->insert_record('scale', $record);
528 }
529
530 return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
531 }
a3d5830a 532}
3c4c5189
PS
533
534
535/**
536 * Module generator base class.
537 *
538 * Extend in mod/xxxx/tests/generator/lib.php as class mod_xxxx_generator.
539 *
540 * @package core
541 * @category phpunit
542 * @copyright 2012 Petr Skoda {@link http://skodak.org}
543 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
544 */
545abstract class phpunit_module_generator {
546 /** @var phpunit_data_generator@var */
547 protected $datagenerator;
548
549 /** @var number of created instances */
550 protected $instancecount = 0;
551
552 public function __construct(phpunit_data_generator $datagenerator) {
553 $this->datagenerator = $datagenerator;
554 }
555
556 /**
557 * To be called from data reset code only,
558 * do not use in tests.
559 * @return void
560 */
561 public function reset() {
562 $this->instancecount = 0;
563 }
564
565 /**
566 * Returns module name
567 * @return string name of module that this class describes
568 * @throws coding_exception if class invalid
569 */
570 public function get_modulename() {
571 $matches = null;
572 if (!preg_match('/^mod_([a-z0-9]+)_generator$/', get_class($this), $matches)) {
573 throw new coding_exception('Invalid module generator class name: '.get_class($this));
574 }
575
576 if (empty($matches[1])) {
577 throw new coding_exception('Invalid module generator class name: '.get_class($this));
578 }
579 return $matches[1];
580 }
581
582 /**
583 * Create course module and link it to course
584 * @param stdClass $instance
585 * @param array $options: section, visible
586 * @return stdClass $cm instance
587 */
588 protected function create_course_module(stdClass $instance, array $options) {
589 global $DB, $CFG;
590 require_once("$CFG->dirroot/course/lib.php");
591
592 $modulename = $this->get_modulename();
593
594 $cm = new stdClass();
595 $cm->course = $instance->course;
596 $cm->module = $DB->get_field('modules', 'id', array('name'=>$modulename));
597 $cm->instance = $instance->id;
598 $cm->section = isset($options['section']) ? $options['section'] : 0;
599 $cm->idnumber = isset($options['idnumber']) ? $options['idnumber'] : 0;
600 $cm->added = time();
601
602 $columns = $DB->get_columns('course_modules');
603 foreach ($options as $key=>$value) {
604 if ($key === 'id' or !isset($columns[$key])) {
605 continue;
606 }
607 if (property_exists($cm, $key)) {
608 continue;
609 }
610 $cm->$key = $value;
611 }
612
613 $cm->id = $DB->insert_record('course_modules', $cm);
614 $cm->coursemodule = $cm->id;
615
616 add_mod_to_section($cm);
617
618 $cm = get_coursemodule_from_id($modulename, $cm->id, $cm->course, true, MUST_EXIST);
619
620 context_module::instance($cm->id);
621
622 return $cm;
920f4efe 623 }
3c4c5189
PS
624
625 /**
626 * Create a test module
627 * @param array|stdClass $record
628 * @param array $options
629 * @return stdClass activity record
630 */
631 abstract public function create_instance($record = null, array $options = null);
632}
633
634
635/**
636 * Block generator base class.
637 *
638 * Extend in blocks/xxxx/tests/generator/lib.php as class block_xxxx_generator.
639 *
640 * @package core
641 * @category phpunit
642 * @copyright 2012 Petr Skoda {@link http://skodak.org}
643 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
644 */
645abstract class phpunit_block_generator {
646 /** @var phpunit_data_generator@var */
647 protected $datagenerator;
648
649 /** @var number of created instances */
650 protected $instancecount = 0;
651
652 public function __construct(phpunit_data_generator $datagenerator) {
653 $this->datagenerator = $datagenerator;
654 }
655
656 /**
657 * To be called from data reset code only,
658 * do not use in tests.
659 * @return void
660 */
661 public function reset() {
662 $this->instancecount = 0;
663 }
664
665 /**
666 * Returns block name
667 * @return string name of block that this class describes
668 * @throws coding_exception if class invalid
669 */
670 public function get_blockname() {
671 $matches = null;
672 if (!preg_match('/^block_([a-z0-9_]+)_generator$/', get_class($this), $matches)) {
673 throw new coding_exception('Invalid block generator class name: '.get_class($this));
674 }
675
676 if (empty($matches[1])) {
677 throw new coding_exception('Invalid block generator class name: '.get_class($this));
678 }
679 return $matches[1];
680 }
681
682 /**
683 * Fill in record defaults
684 * @param stdClass $record
685 * @return stdClass
686 */
687 protected function prepare_record(stdClass $record) {
688 $record->blockname = $this->get_blockname();
689 if (!isset($record->parentcontextid)) {
690 $record->parentcontextid = context_system::instance()->id;
691 }
692 if (!isset($record->showinsubcontexts)) {
693 $record->showinsubcontexts = 1;
694 }
695 if (!isset($record->pagetypepattern)) {
696 $record->pagetypepattern = '';
697 }
698 if (!isset($record->subpagepattern)) {
699 $record->subpagepattern = null;
700 }
701 if (!isset($record->defaultregion)) {
702 $record->defaultregion = '';
703 }
704 if (!isset($record->defaultweight)) {
705 $record->defaultweight = '';
706 }
707 if (!isset($record->configdata)) {
708 $record->configdata = null;
709 }
710 return $record;
711 }
712
713 /**
714 * Create a test block
715 * @param array|stdClass $record
716 * @param array $options
717 * @return stdClass activity record
718 */
719 abstract public function create_instance($record = null, array $options = null);
f15d4515 720}