Merge branch 'MDL-48467-28' of git://github.com/merrill-oakland/moodle into MOODLE_28...
[moodle.git] / lib / tests / component_test.php
blobb6b1c6e4f9d03f005cc79a11f6a6befbdb17e623
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 * core_component related tests.
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
26 defined('MOODLE_INTERNAL') || die();
29 /**
30 * Class core_component_testcase.
32 class core_component_testcase extends advanced_testcase {
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!!!
37 const SUBSYSTEMCOUNT = 62;
39 public function test_get_core_subsystems() {
40 global $CFG;
42 $subsystems = core_component::get_core_subsystems();
44 $this->assertCount(self::SUBSYSTEMCOUNT, $subsystems, 'Oh, somebody added or removed a core subsystem, think twice before doing that!');
46 // Make sure all paths are full/null, exist and are inside dirroot.
47 foreach ($subsystems as $subsystem => $fulldir) {
48 $this->assertFalse(strpos($subsystem, '_'), 'Core subsystems must be one work without underscores');
49 if ($fulldir === null) {
50 if ($subsystem === 'filepicker' or $subsystem === 'help') {
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.');
56 continue;
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, '\\'));
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;
71 $file = $item->getFilename();
72 if ($file === 'moodle.php') {
73 // Do not add new lang strings unless really necessary!!!
74 continue;
77 if (substr($file, -4) !== '.php') {
78 continue;
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!');
83 unset($item);
84 unset($items);
88 public function test_deprecated_get_core_subsystems() {
89 global $CFG;
91 $subsystems = core_component::get_core_subsystems();
93 $this->assertSame($subsystems, get_core_subsystems(true));
95 $realsubsystems = get_core_subsystems();
96 $this->assertDebuggingCalled();
97 $this->assertSame($realsubsystems, get_core_subsystems(false));
98 $this->assertDebuggingCalled();
100 $this->assertEquals(count($subsystems), count($realsubsystems));
102 foreach ($subsystems as $subsystem => $fulldir) {
103 $this->assertArrayHasKey($subsystem, $realsubsystems);
104 if ($fulldir === null) {
105 $this->assertNull($realsubsystems[$subsystem]);
106 continue;
108 $this->assertSame($fulldir, $CFG->dirroot.'/'.$realsubsystems[$subsystem]);
112 public function test_get_plugin_types() {
113 global $CFG;
115 $this->assertTrue(empty($CFG->themedir), 'Non-empty $CFG->themedir is not covered by any tests yet, you need to disable it.');
117 $plugintypes = core_component::get_plugin_types();
119 foreach ($plugintypes as $plugintype => $fulldir) {
120 $this->assertStringStartsWith("$CFG->dirroot/", $fulldir);
124 public function test_deprecated_get_plugin_types() {
125 global $CFG;
127 $plugintypes = core_component::get_plugin_types();
129 $this->assertSame($plugintypes, get_plugin_types());
130 $this->assertSame($plugintypes, get_plugin_types(true));
132 $realplugintypes = get_plugin_types(false);
133 $this->assertDebuggingCalled();
135 foreach ($plugintypes as $plugintype => $fulldir) {
136 $this->assertSame($fulldir, $CFG->dirroot.'/'.$realplugintypes[$plugintype]);
140 public function test_get_plugin_list() {
141 global $CFG;
143 $plugintypes = core_component::get_plugin_types();
145 foreach ($plugintypes as $plugintype => $fulldir) {
146 $plugins = core_component::get_plugin_list($plugintype);
147 foreach ($plugins as $pluginname => $plugindir) {
148 $this->assertStringStartsWith("$CFG->dirroot/", $plugindir);
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);
154 $dirs = array_values($dirs);
155 $this->assertDebuggingCalled();
156 $this->assertSame($dirs, array_keys($plugins));
161 public function test_deprecated_get_plugin_list() {
162 $plugintypes = core_component::get_plugin_types();
164 foreach ($plugintypes as $plugintype => $fulldir) {
165 $plugins = core_component::get_plugin_list($plugintype);
166 $this->assertSame($plugins, get_plugin_list($plugintype));
170 public function test_get_plugin_directory() {
171 $plugintypes = core_component::get_plugin_types();
173 foreach ($plugintypes as $plugintype => $fulldir) {
174 $plugins = core_component::get_plugin_list($plugintype);
175 foreach ($plugins as $pluginname => $plugindir) {
176 $this->assertSame($plugindir, core_component::get_plugin_directory($plugintype, $pluginname));
181 public function test_deprecated_get_plugin_directory() {
182 $plugintypes = core_component::get_plugin_types();
184 foreach ($plugintypes as $plugintype => $fulldir) {
185 $plugins = core_component::get_plugin_list($plugintype);
186 foreach ($plugins as $pluginname => $plugindir) {
187 $this->assertSame(core_component::get_plugin_directory($plugintype, $pluginname), get_plugin_directory($plugintype, $pluginname));
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));
199 public function test_is_valid_plugin_name() {
200 $this->assertTrue(core_component::is_valid_plugin_name('mod', 'example1'));
201 $this->assertTrue(core_component::is_valid_plugin_name('mod', 'feedback360'));
202 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'feedback_360'));
203 $this->assertFalse(core_component::is_valid_plugin_name('mod', '2feedback'));
204 $this->assertFalse(core_component::is_valid_plugin_name('mod', '1example'));
205 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example.xx'));
206 $this->assertFalse(core_component::is_valid_plugin_name('mod', '.example'));
207 $this->assertFalse(core_component::is_valid_plugin_name('mod', '_example'));
208 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example_'));
209 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example_x1'));
210 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example-x1'));
211 $this->assertFalse(core_component::is_valid_plugin_name('mod', 'role'));
213 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example1'));
214 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1'));
215 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1_xxx'));
216 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'feedback360'));
217 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'feed_back360'));
218 $this->assertTrue(core_component::is_valid_plugin_name('tool', 'role'));
219 $this->assertFalse(core_component::is_valid_plugin_name('tool', '1example'));
220 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example.xx'));
221 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example-xx'));
222 $this->assertFalse(core_component::is_valid_plugin_name('tool', '.example'));
223 $this->assertFalse(core_component::is_valid_plugin_name('tool', '_example'));
224 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example_'));
225 $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example__x1'));
228 public function test_normalize_componentname() {
229 // Moodle core.
230 $this->assertSame('core', core_component::normalize_componentname('core'));
231 $this->assertSame('core', core_component::normalize_componentname('moodle'));
232 $this->assertSame('core', core_component::normalize_componentname(''));
234 // Moodle core subsystems.
235 $this->assertSame('core_admin', core_component::normalize_componentname('admin'));
236 $this->assertSame('core_admin', core_component::normalize_componentname('core_admin'));
237 $this->assertSame('core_admin', core_component::normalize_componentname('moodle_admin'));
239 // Activity modules and their subplugins.
240 $this->assertSame('mod_workshop', core_component::normalize_componentname('workshop'));
241 $this->assertSame('mod_workshop', core_component::normalize_componentname('mod_workshop'));
242 $this->assertSame('workshopform_accumulative', core_component::normalize_componentname('workshopform_accumulative'));
243 $this->assertSame('mod_quiz', core_component::normalize_componentname('quiz'));
244 $this->assertSame('quiz_grading', core_component::normalize_componentname('quiz_grading'));
245 $this->assertSame('mod_data', core_component::normalize_componentname('data'));
246 $this->assertSame('datafield_checkbox', core_component::normalize_componentname('datafield_checkbox'));
248 // Other plugin types.
249 $this->assertSame('auth_mnet', core_component::normalize_componentname('auth_mnet'));
250 $this->assertSame('enrol_self', core_component::normalize_componentname('enrol_self'));
251 $this->assertSame('block_html', core_component::normalize_componentname('block_html'));
252 $this->assertSame('block_mnet_hosts', core_component::normalize_componentname('block_mnet_hosts'));
253 $this->assertSame('local_amos', core_component::normalize_componentname('local_amos'));
254 $this->assertSame('local_admin', core_component::normalize_componentname('local_admin'));
256 // Unknown words without underscore are supposed to be activity modules.
257 $this->assertSame('mod_whoonearthwouldcomewithsuchastupidnameofcomponent',
258 core_component::normalize_componentname('whoonearthwouldcomewithsuchastupidnameofcomponent'));
259 // Module names can not contain underscores, this must be a subplugin.
260 $this->assertSame('whoonearth_wouldcomewithsuchastupidnameofcomponent',
261 core_component::normalize_componentname('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
262 $this->assertSame('whoonearth_would_come_withsuchastupidnameofcomponent',
263 core_component::normalize_componentname('whoonearth_would_come_withsuchastupidnameofcomponent'));
266 public function test_normalize_component() {
267 // Moodle core.
268 $this->assertSame(array('core', null), core_component::normalize_component('core'));
269 $this->assertSame(array('core', null), core_component::normalize_component('moodle'));
270 $this->assertSame(array('core', null), core_component::normalize_component(''));
272 // Moodle core subsystems.
273 $this->assertSame(array('core', 'admin'), core_component::normalize_component('admin'));
274 $this->assertSame(array('core', 'admin'), core_component::normalize_component('core_admin'));
275 $this->assertSame(array('core', 'admin'), core_component::normalize_component('moodle_admin'));
277 // Activity modules and their subplugins.
278 $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('workshop'));
279 $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('mod_workshop'));
280 $this->assertSame(array('workshopform', 'accumulative'), core_component::normalize_component('workshopform_accumulative'));
281 $this->assertSame(array('mod', 'quiz'), core_component::normalize_component('quiz'));
282 $this->assertSame(array('quiz', 'grading'), core_component::normalize_component('quiz_grading'));
283 $this->assertSame(array('mod', 'data'), core_component::normalize_component('data'));
284 $this->assertSame(array('datafield', 'checkbox'), core_component::normalize_component('datafield_checkbox'));
286 // Other plugin types.
287 $this->assertSame(array('auth', 'mnet'), core_component::normalize_component('auth_mnet'));
288 $this->assertSame(array('enrol', 'self'), core_component::normalize_component('enrol_self'));
289 $this->assertSame(array('block', 'html'), core_component::normalize_component('block_html'));
290 $this->assertSame(array('block', 'mnet_hosts'), core_component::normalize_component('block_mnet_hosts'));
291 $this->assertSame(array('local', 'amos'), core_component::normalize_component('local_amos'));
292 $this->assertSame(array('local', 'admin'), core_component::normalize_component('local_admin'));
294 // Unknown words without underscore are supposed to be activity modules.
295 $this->assertSame(array('mod', 'whoonearthwouldcomewithsuchastupidnameofcomponent'),
296 core_component::normalize_component('whoonearthwouldcomewithsuchastupidnameofcomponent'));
297 // Module names can not contain underscores, this must be a subplugin.
298 $this->assertSame(array('whoonearth', 'wouldcomewithsuchastupidnameofcomponent'),
299 core_component::normalize_component('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
300 $this->assertSame(array('whoonearth', 'would_come_withsuchastupidnameofcomponent'),
301 core_component::normalize_component('whoonearth_would_come_withsuchastupidnameofcomponent'));
304 public function test_deprecated_normalize_component() {
305 // Moodle core.
306 $this->assertSame(array('core', null), normalize_component('core'));
307 $this->assertSame(array('core', null), normalize_component(''));
308 $this->assertSame(array('core', null), normalize_component('moodle'));
310 // Moodle core subsystems.
311 $this->assertSame(array('core', 'admin'), normalize_component('admin'));
312 $this->assertSame(array('core', 'admin'), normalize_component('core_admin'));
313 $this->assertSame(array('core', 'admin'), normalize_component('moodle_admin'));
315 // Activity modules and their subplugins.
316 $this->assertSame(array('mod', 'workshop'), normalize_component('workshop'));
317 $this->assertSame(array('mod', 'workshop'), normalize_component('mod_workshop'));
318 $this->assertSame(array('workshopform', 'accumulative'), normalize_component('workshopform_accumulative'));
319 $this->assertSame(array('mod', 'quiz'), normalize_component('quiz'));
320 $this->assertSame(array('quiz', 'grading'), normalize_component('quiz_grading'));
321 $this->assertSame(array('mod', 'data'), normalize_component('data'));
322 $this->assertSame(array('datafield', 'checkbox'), normalize_component('datafield_checkbox'));
324 // Other plugin types.
325 $this->assertSame(array('auth', 'mnet'), normalize_component('auth_mnet'));
326 $this->assertSame(array('enrol', 'self'), normalize_component('enrol_self'));
327 $this->assertSame(array('block', 'html'), normalize_component('block_html'));
328 $this->assertSame(array('block', 'mnet_hosts'), normalize_component('block_mnet_hosts'));
329 $this->assertSame(array('local', 'amos'), normalize_component('local_amos'));
330 $this->assertSame(array('local', 'admin'), normalize_component('local_admin'));
332 // Unknown words without underscore are supposed to be activity modules.
333 $this->assertSame(array('mod', 'whoonearthwouldcomewithsuchastupidnameofcomponent'),
334 normalize_component('whoonearthwouldcomewithsuchastupidnameofcomponent'));
335 // Module names can not contain underscores, this must be a subplugin.
336 $this->assertSame(array('whoonearth', 'wouldcomewithsuchastupidnameofcomponent'),
337 normalize_component('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
338 $this->assertSame(array('whoonearth', 'would_come_withsuchastupidnameofcomponent'),
339 normalize_component('whoonearth_would_come_withsuchastupidnameofcomponent'));
342 public function test_get_component_directory() {
343 $plugintypes = core_component::get_plugin_types();
344 foreach ($plugintypes as $plugintype => $fulldir) {
345 $plugins = core_component::get_plugin_list($plugintype);
346 foreach ($plugins as $pluginname => $plugindir) {
347 $this->assertSame($plugindir, core_component::get_component_directory(($plugintype.'_'.$pluginname)));
351 $subsystems = core_component::get_core_subsystems();
352 foreach ($subsystems as $subsystem => $fulldir) {
353 $this->assertSame($fulldir, core_component::get_component_directory(('core_'.$subsystem)));
357 public function test_deprecated_get_component_directory() {
358 $plugintypes = core_component::get_plugin_types();
359 foreach ($plugintypes as $plugintype => $fulldir) {
360 $plugins = core_component::get_plugin_list($plugintype);
361 foreach ($plugins as $pluginname => $plugindir) {
362 $this->assertSame($plugindir, get_component_directory(($plugintype.'_'.$pluginname)));
366 $subsystems = core_component::get_core_subsystems();
367 foreach ($subsystems as $subsystem => $fulldir) {
368 $this->assertSame($fulldir, get_component_directory(('core_'.$subsystem)));
372 public function test_get_subtype_parent() {
373 global $CFG;
375 $this->assertNull(core_component::get_subtype_parent('mod'));
377 // Any plugin with more subtypes is ok here.
378 $this->assertFileExists("$CFG->dirroot/mod/assign/db/subplugins.php");
379 $this->assertSame('mod_assign', core_component::get_subtype_parent('assignsubmission'));
380 $this->assertSame('mod_assign', core_component::get_subtype_parent('assignfeedback'));
381 $this->assertNull(core_component::get_subtype_parent('assignxxxxx'));
384 public function test_get_subplugins() {
385 global $CFG;
387 // Any plugin with more subtypes is ok here.
388 $this->assertFileExists("$CFG->dirroot/mod/assign/db/subplugins.php");
390 $subplugins = core_component::get_subplugins('mod_assign');
391 $this->assertSame(array('assignsubmission', 'assignfeedback'), array_keys($subplugins));
393 $subs = core_component::get_plugin_list('assignsubmission');
394 $feeds = core_component::get_plugin_list('assignfeedback');
396 $this->assertSame(array_keys($subs), $subplugins['assignsubmission']);
397 $this->assertSame(array_keys($feeds), $subplugins['assignfeedback']);
399 // Any plugin without subtypes is ok here.
400 $this->assertFileExists("$CFG->dirroot/mod/choice");
401 $this->assertFileNotExists("$CFG->dirroot/mod/choice/db/subplugins.php");
403 $this->assertNull(core_component::get_subplugins('mod_choice'));
405 $this->assertNull(core_component::get_subplugins('xxxx_yyyy'));
408 public function test_get_plugin_types_with_subplugins() {
409 global $CFG;
411 $types = core_component::get_plugin_types_with_subplugins();
413 // Hardcode it here to detect if anybody hacks the code to include more subplugin types.
414 $expected = array(
415 'mod' => "$CFG->dirroot/mod",
416 'editor' => "$CFG->dirroot/lib/editor",
417 'tool' => "$CFG->dirroot/$CFG->admin/tool",
418 'local' => "$CFG->dirroot/local",
421 $this->assertSame($expected, $types);
425 public function test_get_plugin_list_with_file() {
426 $this->resetAfterTest(true);
428 // No extra reset here because core_component reset automatically.
430 $expected = array();
431 $reports = core_component::get_plugin_list('report');
432 foreach ($reports as $name => $fulldir) {
433 if (file_exists("$fulldir/lib.php")) {
434 $expected[] = $name;
438 // Test cold.
439 $list = core_component::get_plugin_list_with_file('report', 'lib.php', false);
440 $this->assertEquals($expected, array_keys($list));
442 // Test hot.
443 $list = core_component::get_plugin_list_with_file('report', 'lib.php', false);
444 $this->assertEquals($expected, array_keys($list));
446 // Test with include.
447 $list = core_component::get_plugin_list_with_file('report', 'lib.php', true);
448 $this->assertEquals($expected, array_keys($list));
450 // Test missing.
451 $list = core_component::get_plugin_list_with_file('report', 'idontexist.php', true);
452 $this->assertEquals(array(), array_keys($list));