diff --git a/lib/testing/generator/block_generator.php b/lib/testing/generator/block_generator.php index 02a22882b60..711a4ae8e55 100644 --- a/lib/testing/generator/block_generator.php +++ b/lib/testing/generator/block_generator.php @@ -34,21 +34,10 @@ * @copyright 2012 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class testing_block_generator { - /** @var testing_data_generator */ - protected $datagenerator; - +abstract class testing_block_generator extends component_generator_base { /** @var number of created instances */ protected $instancecount = 0; - /** - * Dumb constructor to throw the deprecated notification - * @param testing_data_generator $datagenerator - */ - public function __construct(testing_data_generator $datagenerator) { - $this->datagenerator = $datagenerator; - } - /** * To be called from data reset code only, * do not use in tests. diff --git a/lib/testing/generator/component_generator_base.php b/lib/testing/generator/component_generator_base.php new file mode 100644 index 00000000000..07669148149 --- /dev/null +++ b/lib/testing/generator/component_generator_base.php @@ -0,0 +1,59 @@ +. + +/** + * Component generator base class. + * + * @package core + * @category test + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +/** + * Component generator base class. + * + * Extend in path/to/component/tests/generator/lib.php as + * class type_plugin_generator extends component_generator_base + * Note that there are more specific classes to extend for mods and blocks. + * + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class component_generator_base { + + /** + * @var testing_data_generator + */ + protected $datagenerator; + + /** + * Constructor. + * @param testing_data_generator $datagenerator + */ + public function __construct(testing_data_generator $datagenerator) { + $this->datagenerator = $datagenerator; + } + + /** + * To be called from data reset code only, + * do not use in tests. + * @return void + */ + public function reset() { + } +} diff --git a/lib/testing/generator/data_generator.php b/lib/testing/generator/data_generator.php index 5e3d1d312b5..129dfa5996e 100644 --- a/lib/testing/generator/data_generator.php +++ b/lib/testing/generator/data_generator.php @@ -89,29 +89,40 @@ EOD; } /** - * Return generator for given plugin - * @param string $component - * @return mixed plugin data generator + * Return generator for given plugin or component. + * @param string $component the component name, e.g. 'mod_forum' or 'core_question'. + * @return component_generator_base or rather an instance of the appropriate subclass. */ public function get_plugin_generator($component) { list($type, $plugin) = normalize_component($component); - - if ($type !== 'mod' and $type !== 'block') { - throw new coding_exception("Plugin type $type does not support generators yet"); + $cleancomponent = $type . '_' . $plugin; + if ($cleancomponent != $component) { + debugging("Please specify the component you want a generator for as " . + "{$cleancomponent}, not {$component}.", DEBUG_DEVELOPER); + $component = $cleancomponent; } - $dir = get_plugin_directory($type, $plugin); - - if (!isset($this->generators[$type.'_'.$plugin])) { - $lib = "$dir/tests/generator/lib.php"; - if (!include_once($lib)) { - throw new coding_exception("Plugin $component does not support data generator, missing tests/generator/lib"); - } - $classname = $type.'_'.$plugin.'_generator'; - $this->generators[$type.'_'.$plugin] = new $classname($this); + if (isset($this->generators[$component])) { + return $this->generators[$component]; } - return $this->generators[$type.'_'.$plugin]; + $dir = get_component_directory($component); + $lib = $dir . '/tests/generator/lib.php'; + if (!$dir || !is_readable($lib)) { + throw new coding_exception("Component {$component} does not support " . + "generators yet. Missing tests/generator/lib.php."); + } + + include_once($lib); + $classname = $component . '_generator'; + + if (!class_exists($classname)) { + throw new coding_exception("Component {$component} does not support " . + "data generators yet. Class {$classname} not found."); + } + + $this->generators[$component] = new $classname($this); + return $this->generators[$component]; } /** @@ -595,6 +606,26 @@ EOD; return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST); } + /** + * Helper method which combines $defaults with the values specified in $record. + * If $record is an object, it is converted to an array. + * Then, for each key that is in $defaults, but not in $record, the value + * from $defaults is copied. + * @param array $defaults the default value for each field with + * @param array|stdClass $record + * @return array updated $record. + */ + public function combine_defaults_and_record(array $defaults, $record) { + $record = (array) $record; + + foreach ($defaults as $key => $defaults) { + if (!array_key_exists($key, $record)) { + $record[$key] = $defaults; + } + } + return $record; + } + /** * Simplified enrolment of user to course using default options. * diff --git a/lib/testing/generator/lib.php b/lib/testing/generator/lib.php index 3afbff2c89a..99c6a9ad49b 100644 --- a/lib/testing/generator/lib.php +++ b/lib/testing/generator/lib.php @@ -26,6 +26,7 @@ // NOTE: MOODLE_INTERNAL is not verified here because we load this before setup.php! require_once(__DIR__.'/data_generator.php'); +require_once(__DIR__.'/component_generator_base.php'); require_once(__DIR__.'/module_generator.php'); require_once(__DIR__.'/block_generator.php'); diff --git a/lib/testing/generator/module_generator.php b/lib/testing/generator/module_generator.php index c499f96d81c..44910bd20ac 100644 --- a/lib/testing/generator/module_generator.php +++ b/lib/testing/generator/module_generator.php @@ -34,26 +34,13 @@ * @copyright 2012 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class testing_module_generator { - - /** - * @var testing_data_generator - */ - protected $datagenerator; +abstract class testing_module_generator extends component_generator_base { /** * @var number of created instances */ protected $instancecount = 0; - /** - * Dumb constructor to throw the deprecated notification - * @param testing_data_generator $datagenerator - */ - public function __construct(testing_data_generator $datagenerator) { - $this->datagenerator = $datagenerator; - } - /** * To be called from data reset code only, * do not use in tests. diff --git a/lib/testing/tests/generator_test.php b/lib/testing/tests/generator_test.php index 19acca666f9..6b056c3bfd2 100644 --- a/lib/testing/tests/generator_test.php +++ b/lib/testing/tests/generator_test.php @@ -35,6 +35,24 @@ defined('MOODLE_INTERNAL') || die(); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class core_test_generator_testcase extends advanced_testcase { + public function test_get_plugin_generator_good_case() { + $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); + $this->assertInstanceOf('core_question_generator', $generator); + } + + public function test_get_plugin_generator_sloppy_name() { + $generator = $this->getDataGenerator()->get_plugin_generator('quiz'); + $this->assertDebuggingCalled('Please specify the component you want a generator for as ' . + 'mod_quiz, not quiz.', DEBUG_DEVELOPER); + $this->assertInstanceOf('mod_quiz_generator', $generator); + } + + public function test_get_plugin_generator_no_component_dir() { + $this->setExpectedException('coding_exception', 'Component core_completion does not support ' . + 'generators yet. Missing tests/generator/lib.php.'); + $generator = $this->getDataGenerator()->get_plugin_generator('core_completion'); + } + public function test_create() { global $DB; diff --git a/question/tests/generator/lib.php b/question/tests/generator/lib.php new file mode 100644 index 00000000000..2fd9f28fb8d --- /dev/null +++ b/question/tests/generator/lib.php @@ -0,0 +1,62 @@ +. + +defined('MOODLE_INTERNAL') || die(); + +/** + * Quiz module test data generator class + * + * @package moodlecore + * @subpackage question + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_question_generator extends component_generator_base { + + /** + * @var number of created instances + */ + protected $categorycount = 0; + + public function reset() { + $this->categorycount = 0; + } + + /** + * Create a new question category. + * @param array|stdClass $record + * @return stdClass question_categories record. + */ + public function create_question_category($record = null) { + global $DB; + + $this->categorycount++; + + $defaults = array( + 'name' => 'Test question category ' . $this->categorycount, + 'contextid' => context_system::instance()->id, + 'info' => '', + 'infoformat' => FORMAT_HTML, + 'stamp' => '', + 'parent' => 0, + 'sortorder' => 999, + ); + + $record = $this->datagenerator->combine_defaults_and_record($defaults, $record); + $record['id'] = $DB->insert_record('question_categories', $record); + return (object) $record; + } +} diff --git a/question/tests/generator_test.php b/question/tests/generator_test.php new file mode 100644 index 00000000000..f89d5bb3a10 --- /dev/null +++ b/question/tests/generator_test.php @@ -0,0 +1,52 @@ +. + +/** + * Data generators tests + * + * @package moodlecore + * @subpackage questionengine + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + + +/** + * Test data generator + * + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_question_generator_testcase extends advanced_testcase { + public function test_create() { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); + + $count = $DB->count_records('question_categories'); + + $cat = $generator->create_question_category(); + $this->assertEquals($count + 1, $DB->count_records('question_categories')); + + $cat = $generator->create_question_category(array( + 'name' => 'My category', 'sortorder' => 1)); + $this->assertSame('My category', $cat->name); + $this->assertSame(1, $cat->sortorder); + } +}