weekly release 4.0dev
[moodle.git] / lib / tests / behat / behat_data_generators.php
CommitLineData
f0200d14 1<?php
f0200d14
DM
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 * Data generators for acceptance testing.
19 *
20 * @package core
21 * @category test
22 * @copyright 2012 David MonllaĆ³
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
27
28require_once(__DIR__ . '/../../behat/behat_base.php');
f0200d14
DM
29
30use Behat\Gherkin\Node\TableNode as TableNode;
134494e0 31use Behat\Behat\Tester\Exception\PendingException as PendingException;
f0200d14
DM
32
33/**
34 * Class to set up quickly a Given environment.
35 *
285c7036
TH
36 * The entry point is the Behat steps:
37 * the following "entity types" exist:
38 * | test | data |
f0200d14 39 *
285c7036
TH
40 * Entity type will either look like "users" or "activities" for core entities, or
41 * "mod_forum > subscription" or "core_message > message" for entities belonging
42 * to components.
43 *
44 * Generally, you only need to specify properties relevant to your test,
45 * and everything else gets set to sensible defaults.
46 *
47 * The actual generation of entities is done by {@link behat_generator_base}.
48 * There is one subclass for each component, e.g. {@link behat_core_generator}
49 * or {@link behat_mod_quiz_generator}. To see the types of entity
50 * that can be created for each component, look at the arrays returned
51 * by the get_creatable_entities() method in each class.
f0200d14 52 *
f0200d14
DM
53 * @package core
54 * @category test
55 * @copyright 2012 David MonllaĆ³
56 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
57 */
58class behat_data_generators extends behat_base {
59
46ac40cd 60 /**
285c7036 61 * Convert legacy entity names to the new component-specific form.
eb3884e4 62 *
285c7036
TH
63 * In the past, there was no support for plugins, and everything that
64 * could be created was handled by the core generator. Now, we can
65 * support plugins, and so some thing should probably be moved.
4d0ac716 66 *
285c7036
TH
67 * For example, in the future we should probably add
68 * 'message contacts' => 'core_message > contact'] to
69 * this array, and move generation of message contact
70 * from core to core_message.
81cd8572 71 *
285c7036 72 * @var array old entity type => new entity type.
81cd8572 73 */
285c7036
TH
74 protected $movedentitytypes = [
75 ];
81cd8572 76
d2eca4cd 77 /**
285c7036 78 * Creates the specified element.
72ddc05f 79 *
285c7036 80 * See the class comment for an overview.
72ddc05f 81 *
285c7036 82 * @Given /^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/
702851c0 83 *
285c7036
TH
84 * @param string $entitytype The name of the type entity to add
85 * @param TableNode $data
702851c0 86 */
285c7036
TH
87 public function the_following_entities_exist($entitytype, TableNode $data) {
88 if (isset($this->movedentitytypes[$entitytype])) {
89 $entitytype = $this->movedentitytypes[$entitytype];
702851c0 90 }
285c7036
TH
91 list($component, $entity) = $this->parse_entity_type($entitytype);
92 $this->get_instance_for_component($component)->generate_items($entity, $data);
702851c0
DM
93 }
94
9cc66e86 95 /**
285c7036 96 * Parse a full entity type like 'users' or 'mod_forum > subscription'.
9cc66e86 97 *
285c7036
TH
98 * E.g. parsing 'course' gives ['core', 'course'] and
99 * parsing 'core_message > message' gives ['core_message', 'message'].
0db16e08 100 *
285c7036
TH
101 * @param string $entitytype the entity type
102 * @return string[] with two elements, component and entity type.
0db16e08 103 */
285c7036
TH
104 protected function parse_entity_type(string $entitytype): array {
105 $dividercount = substr_count($entitytype, ' > ');
106 if ($dividercount === 0) {
107 return ['core', $entitytype];
108 } else if ($dividercount === 1) {
109 list($component, $type) = explode(' > ', $entitytype);
110 if ($component === 'core') {
111 throw new coding_exception('Do not specify the component "core > ..." for entity types.');
6e73157a 112 }
285c7036
TH
113 return [$component, $type];
114 } else {
115 throw new coding_exception('The entity type must be in the form ' .
116 '"{entity-type}" for core entities, or "{component} > {entity-type}" ' .
117 'for entities belonging to other components. ' .
118 'For example "users" or "mod_forum > subscriptions".');
6e73157a 119 }
173be485
AA
120 }
121
122 /**
285c7036 123 * Get an instance of the appropriate subclass of this class for a given component.
173be485 124 *
285c7036
TH
125 * @param string $component The name of the component to generate entities for.
126 * @return behat_generator_base the subclass of this class for the requested component.
173be485 127 */
285c7036
TH
128 protected function get_instance_for_component(string $component): behat_generator_base {
129 global $CFG;
f0e8f0a5 130
285c7036
TH
131 // Ensure the generator class is loaded.
132 require_once($CFG->libdir . '/behat/classes/behat_generator_base.php');
133 if ($component === 'core') {
134 $lib = $CFG->libdir . '/behat/classes/behat_core_generator.php';
135 } else {
136 $dir = core_component::get_component_directory($component);
137 $lib = $dir . '/tests/generator/behat_' . $component . '_generator.php';
138 if (!$dir || !is_readable($lib)) {
139 throw new coding_exception("Component {$component} does not support " .
140 "behat generators yet. Missing {$lib}.");
f0e8f0a5
AA
141 }
142 }
285c7036 143 require_once($lib);
f0e8f0a5 144
285c7036
TH
145 // Create an instance.
146 $componentclass = "behat_{$component}_generator";
147 if (!class_exists($componentclass)) {
148 throw new PendingException($component .
149 ' does not yet support the Behat data generator mechanism. Class ' .
150 $componentclass . ' not found in file ' . $lib . '.');
f0e8f0a5 151 }
285c7036
TH
152 $instance = new $componentclass($component);
153 return $instance;
a9e58c14 154 }
f0200d14 155}