weekly release 2.6dev
[moodle.git] / lib / tests / component_test.php
CommitLineData
9e19a0f0
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 * core_component related tests.
19 *
20 * @package core
21 * @category phpunit
22 * @copyright 2013 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
28
29/**
30 * Class core_component_testcase.
31 */
32class core_component_testcase extends advanced_testcase {
33
34 // To be changed if number of subsystems increases/decreases,
35 // this is defined here to annoy devs that try to add more without any thinking,
36 // always verify that it does not collide with any existing add-on modules and subplugins!!!
79252219 37 const SUBSYSTEMCOUNT = 62;
9e19a0f0
PS
38
39 public function test_get_core_subsystems() {
40 global $CFG;
41
42 $subsystems = core_component::get_core_subsystems();
43
44 $this->assertCount(self::SUBSYSTEMCOUNT, $subsystems, 'Oh, somebody added or removed a core subsystem, think twice before doing that!');
45
46 // Make sure all paths are full/null, exist and are inside dirroot.
2058e797 47 foreach ($subsystems as $subsystem => $fulldir) {
9e19a0f0
PS
48 $this->assertFalse(strpos($subsystem, '_'), 'Core subsystems must be one work without underscores');
49 if ($fulldir === null) {
84192d78 50 if ($subsystem === 'filepicker' or $subsystem === 'help') {
9e19a0f0
PS
51 // Arrgghh, let's not introduce more subsystems for no real reason...
52 } else {
53 // Lang strings.
54 $this->assertFileExists("$CFG->dirroot/lang/en/$subsystem.php", 'Core subsystems without fulldir are usually used for lang strings.');
55 }
56 continue;
57 }
58 $this->assertFileExists($fulldir);
59 // Check that base uses realpath() separators and "/" in the subdirs.
60 $this->assertStringStartsWith($CFG->dirroot.'/', $fulldir);
61 $reldir = substr($fulldir, strlen($CFG->dirroot)+1);
62 $this->assertFalse(strpos($reldir, '\\'));
63 }
64
65 // Make sure all core language files are also subsystems!
66 $items = new DirectoryIterator("$CFG->dirroot/lang/en");
67 foreach ($items as $item) {
68 if ($item->isDot() or $item->isDir()) {
69 continue;
70 }
71 $file = $item->getFilename();
72 if ($file === 'moodle.php') {
73 // Do not add new lang strings unless really necessary!!!
74 continue;
75 }
76
77 if (substr($file, -4) !== '.php') {
78 continue;
79 }
80 $file = substr($file, 0, strlen($file)-4);
81 $this->assertArrayHasKey($file, $subsystems, 'All core lang files should be subsystems, think twice before adding anything!');
82 }
83 unset($item);
84 unset($items);
85
86 }
87
88 public function test_deprecated_get_core_subsystems() {
89 global $CFG;
90
91 $subsystems = core_component::get_core_subsystems();
92
93 $this->assertSame($subsystems, get_core_subsystems(true));
94
95 $realsubsystems = get_core_subsystems();
96 $this->assertDebuggingCalled();
97 $this->assertSame($realsubsystems, get_core_subsystems(false));
98 $this->assertDebuggingCalled();
99
100 $this->assertEquals(count($subsystems), count($realsubsystems));
101
102 foreach ($subsystems as $subsystem => $fulldir) {
103 $this->assertArrayHasKey($subsystem, $realsubsystems);
104 if ($fulldir === null) {
105 $this->assertNull($realsubsystems[$subsystem]);
106 continue;
107 }
108 $this->assertSame($fulldir, $CFG->dirroot.'/'.$realsubsystems[$subsystem]);
109 }
110 }
111
112 public function test_get_plugin_types() {
113 global $CFG;
114
115 $this->assertTrue(empty($CFG->themedir), 'Non-empty $CFG->themedir is not covered by any tests yet, you need to disable it.');
116
117 $plugintypes = core_component::get_plugin_types();
118
2058e797 119 foreach ($plugintypes as $plugintype => $fulldir) {
9e19a0f0
PS
120 $this->assertStringStartsWith("$CFG->dirroot/", $fulldir);
121 }
122 }
123
124 public function test_deprecated_get_plugin_types() {
125 global $CFG;
126
127 $plugintypes = core_component::get_plugin_types();
128
129 $this->assertSame($plugintypes, get_plugin_types());
130 $this->assertSame($plugintypes, get_plugin_types(true));
131
132 $realplugintypes = get_plugin_types(false);
133 $this->assertDebuggingCalled();
134
2058e797 135 foreach ($plugintypes as $plugintype => $fulldir) {
9e19a0f0
PS
136 $this->assertSame($fulldir, $CFG->dirroot.'/'.$realplugintypes[$plugintype]);
137 }
138 }
139
140 public function test_get_plugin_list() {
141 global $CFG;
142
143 $plugintypes = core_component::get_plugin_types();
144
145 foreach ($plugintypes as $plugintype => $fulldir) {
146 $plugins = core_component::get_plugin_list($plugintype);
2058e797 147 foreach ($plugins as $pluginname => $plugindir) {
9e19a0f0
PS
148 $this->assertStringStartsWith("$CFG->dirroot/", $plugindir);
149 }
150 if ($plugintype !== 'auth') {
151 // Let's crosscheck it with independent implementation (auth/db is an exception).
152 $reldir = substr($fulldir, strlen($CFG->dirroot)+1);
153 $dirs = get_list_of_plugins($reldir);
402a974e 154 $dirs = array_values($dirs);
9e19a0f0
PS
155 $this->assertDebuggingCalled();
156 $this->assertSame($dirs, array_keys($plugins));
157 }
158 }
159 }
160
161 public function test_deprecated_get_plugin_list() {
162 $plugintypes = core_component::get_plugin_types();
163
164 foreach ($plugintypes as $plugintype => $fulldir) {
165 $plugins = core_component::get_plugin_list($plugintype);
166 $this->assertSame($plugins, get_plugin_list($plugintype));
167 }
168 }
169
170 public function test_get_plugin_directory() {
171 $plugintypes = core_component::get_plugin_types();
172
173 foreach ($plugintypes as $plugintype => $fulldir) {
174 $plugins = core_component::get_plugin_list($plugintype);
2058e797 175 foreach ($plugins as $pluginname => $plugindir) {
9e19a0f0
PS
176 $this->assertSame($plugindir, core_component::get_plugin_directory($plugintype, $pluginname));
177 }
178 }
179 }
180
181 public function test_deprecated_get_plugin_directory() {
182 $plugintypes = core_component::get_plugin_types();
183
184 foreach ($plugintypes as $plugintype => $fulldir) {
185 $plugins = core_component::get_plugin_list($plugintype);
2058e797 186 foreach ($plugins as $pluginname => $plugindir) {
9e19a0f0
PS
187 $this->assertSame(core_component::get_plugin_directory($plugintype, $pluginname), get_plugin_directory($plugintype, $pluginname));
188 }
189 }
190 }
191
192 public function test_get_subsystem_directory() {
193 $subsystems = core_component::get_core_subsystems();
194 foreach ($subsystems as $subsystem => $fulldir) {
195 $this->assertSame($fulldir, core_component::get_subsystem_directory($subsystem));
196 }
197 }
198
199 public function test_is_valid_plugin_name() {
200 $this->assertTrue(core_component::is_valid_plugin_name('mod', 'example1'));
201 $this->assertFalse(core_component::is_valid_plugin_name('mod', '1example'));
202 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example.xx'));
203 $this->assertFalse(core_component::is_valid_plugin_name('mod', '.example'));
204 $this->assertFalse(core_component::is_valid_plugin_name('mod', '_example'));
205 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example_x1'));
206 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example-x1'));
207 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'role'));
208
209 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example1'));
210 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1'));
211 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1_xxx'));
212 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'role'));
213 $this->assertFalse(core_component::is_valid_plugin_name('tool', '1example'));
214 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example.xx'));
215 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example-xx'));
216 $this->assertFalse(core_component::is_valid_plugin_name('tool', '.example'));
217 $this->assertFalse(core_component::is_valid_plugin_name('tool', '_example'));
218 }
219
220 public function test_normalize_component() {
9e19a0f0
PS
221 // Moodle core.
222 $this->assertSame(array('core', null), core_component::normalize_component('core'));
223 $this->assertSame(array('core', null), core_component::normalize_component('moodle'));
224 $this->assertSame(array('core', null), core_component::normalize_component(''));
225
226 // Moodle core subsystems.
227 $this->assertSame(array('core', 'admin'), core_component::normalize_component('admin'));
228 $this->assertSame(array('core', 'admin'), core_component::normalize_component('core_admin'));
229 $this->assertSame(array('core', 'admin'), core_component::normalize_component('moodle_admin'));
230
231 // Activity modules and their subplugins.
232 $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('workshop'));
233 $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('mod_workshop'));
234 $this->assertSame(array('workshopform', 'accumulative'), core_component::normalize_component('workshopform_accumulative'));
235 $this->assertSame(array('mod', 'quiz'), core_component::normalize_component('quiz'));
236 $this->assertSame(array('quiz', 'grading'), core_component::normalize_component('quiz_grading'));
237 $this->assertSame(array('mod', 'data'), core_component::normalize_component('data'));
238 $this->assertSame(array('datafield', 'checkbox'), core_component::normalize_component('datafield_checkbox'));
239
240 // Other plugin types.
241 $this->assertSame(array('auth', 'mnet'), core_component::normalize_component('auth_mnet'));
242 $this->assertSame(array('enrol', 'self'), core_component::normalize_component('enrol_self'));
243 $this->assertSame(array('block', 'html'), core_component::normalize_component('block_html'));
244 $this->assertSame(array('block', 'mnet_hosts'), core_component::normalize_component('block_mnet_hosts'));
245 $this->assertSame(array('local', 'amos'), core_component::normalize_component('local_amos'));
246 $this->assertSame(array('local', 'admin'), core_component::normalize_component('local_admin'));
247
248 // Unknown words without underscore are supposed to be activity modules.
249 $this->assertSame(array('mod', 'whothefuckwouldcomewithsuchastupidnameofcomponent'),
250 core_component::normalize_component('whothefuckwouldcomewithsuchastupidnameofcomponent'));
251 // Module names can not contain underscores, this must be a subplugin.
252 $this->assertSame(array('whothefuck', 'wouldcomewithsuchastupidnameofcomponent'),
253 core_component::normalize_component('whothefuck_wouldcomewithsuchastupidnameofcomponent'));
254 $this->assertSame(array('whothefuck', 'would_come_withsuchastupidnameofcomponent'),
255 core_component::normalize_component('whothefuck_would_come_withsuchastupidnameofcomponent'));
256 }
257
258 public function test_deprecated_normalize_component() {
9e19a0f0
PS
259 // Moodle core.
260 $this->assertSame(array('core', null), normalize_component('core'));
261 $this->assertSame(array('core', null), normalize_component(''));
262 $this->assertSame(array('core', null), normalize_component('moodle'));
263
264 // Moodle core subsystems.
265 $this->assertSame(array('core', 'admin'), normalize_component('admin'));
266 $this->assertSame(array('core', 'admin'), normalize_component('core_admin'));
267 $this->assertSame(array('core', 'admin'), normalize_component('moodle_admin'));
268
269 // Activity modules and their subplugins.
270 $this->assertSame(array('mod', 'workshop'), normalize_component('workshop'));
271 $this->assertSame(array('mod', 'workshop'), normalize_component('mod_workshop'));
272 $this->assertSame(array('workshopform', 'accumulative'), normalize_component('workshopform_accumulative'));
273 $this->assertSame(array('mod', 'quiz'), normalize_component('quiz'));
274 $this->assertSame(array('quiz', 'grading'), normalize_component('quiz_grading'));
275 $this->assertSame(array('mod', 'data'), normalize_component('data'));
276 $this->assertSame(array('datafield', 'checkbox'), normalize_component('datafield_checkbox'));
277
278 // Other plugin types.
279 $this->assertSame(array('auth', 'mnet'), normalize_component('auth_mnet'));
280 $this->assertSame(array('enrol', 'self'), normalize_component('enrol_self'));
281 $this->assertSame(array('block', 'html'), normalize_component('block_html'));
282 $this->assertSame(array('block', 'mnet_hosts'), normalize_component('block_mnet_hosts'));
283 $this->assertSame(array('local', 'amos'), normalize_component('local_amos'));
284 $this->assertSame(array('local', 'admin'), normalize_component('local_admin'));
285
286 // Unknown words without underscore are supposed to be activity modules.
287 $this->assertSame(array('mod', 'whothefuckwouldcomewithsuchastupidnameofcomponent'),
288 normalize_component('whothefuckwouldcomewithsuchastupidnameofcomponent'));
289 // Module names can not contain underscores, this must be a subplugin.
290 $this->assertSame(array('whothefuck', 'wouldcomewithsuchastupidnameofcomponent'),
291 normalize_component('whothefuck_wouldcomewithsuchastupidnameofcomponent'));
292 $this->assertSame(array('whothefuck', 'would_come_withsuchastupidnameofcomponent'),
293 normalize_component('whothefuck_would_come_withsuchastupidnameofcomponent'));
294 }
295
9e19a0f0
PS
296 public function test_get_component_directory() {
297 $plugintypes = core_component::get_plugin_types();
298 foreach ($plugintypes as $plugintype => $fulldir) {
299 $plugins = core_component::get_plugin_list($plugintype);
2058e797 300 foreach ($plugins as $pluginname => $plugindir) {
9e19a0f0
PS
301 $this->assertSame($plugindir, core_component::get_component_directory(($plugintype.'_'.$pluginname)));
302 }
303 }
304
305 $subsystems = core_component::get_core_subsystems();
2058e797 306 foreach ($subsystems as $subsystem => $fulldir) {
9e19a0f0
PS
307 $this->assertSame($fulldir, core_component::get_component_directory(('core_'.$subsystem)));
308 }
309 }
310
311 public function test_deprecated_get_component_directory() {
312 $plugintypes = core_component::get_plugin_types();
313 foreach ($plugintypes as $plugintype => $fulldir) {
314 $plugins = core_component::get_plugin_list($plugintype);
2058e797 315 foreach ($plugins as $pluginname => $plugindir) {
9e19a0f0
PS
316 $this->assertSame($plugindir, get_component_directory(($plugintype.'_'.$pluginname)));
317 }
318 }
319
320 $subsystems = core_component::get_core_subsystems();
2058e797 321 foreach ($subsystems as $subsystem => $fulldir) {
9e19a0f0
PS
322 $this->assertSame($fulldir, get_component_directory(('core_'.$subsystem)));
323 }
324 }
3601c5f0
PS
325
326 public function test_get_plugin_types_with_subplugins() {
327 global $CFG;
328
329 $types = core_component::get_plugin_types_with_subplugins();
330
2058e797 331 // Hardcode it here to detect if anybody hacks the code to include more subplugin types.
3601c5f0
PS
332 $expected = array(
333 'mod' => "$CFG->dirroot/mod",
334 'editor' => "$CFG->dirroot/lib/editor",
335 'local' => "$CFG->dirroot/local",
336 );
337
338 $this->assertSame($expected, $types);
339 }
9e19a0f0 340}