diff --git a/lib/pluginlib.php b/lib/pluginlib.php index 52a42333778..0a0a4d8dc5e 100644 --- a/lib/pluginlib.php +++ b/lib/pluginlib.php @@ -544,6 +544,39 @@ class plugin_manager { } +/** + * Factory class producing required subclasses of {@link plugininfo_base} + */ +class plugininfo_default_factory { + + /** + * Makes a new instance of the plugininfo class + * + * @param string $type the plugin type, eg. 'mod' + * @param string $typerootdir full path to the location of all the plugins of this type + * @param string $name the plugin name, eg. 'workshop' + * @param string $namerootdir full path to the location of the plugin + * @param string $typeclass the name of class that holds the info about the plugin + * @return plugininfo_base the instance of $typeclass + */ + public static function make($type, $typerootdir, $name, $namerootdir, $typeclass) { + $plugin = new $typeclass(); + $plugin->type = $type; + $plugin->typerootdir = $typerootdir; + $plugin->name = $name; + $plugin->rootdir = $namerootdir; + + $plugin->init_display_name(); + $plugin->load_disk_version(); + $plugin->load_db_version(); + $plugin->load_required_main_version(); + $plugin->init_is_standard(); + + return $plugin; + } +} + + /** * Base class providing access to the information about a plugin * @@ -579,10 +612,6 @@ abstract class plugininfo_base { /** * Gathers and returns the information about all plugins of the given type * - * Passing the parameter $typeclass allows us to reach the same effect as with the - * late binding in PHP 5.3. Once PHP 5.3 is required, we can refactor this to use - * {@example $plugin = new static();} instead of {@example $plugin = new $typeclass()} - * * @param string $type the name of the plugintype, eg. mod, auth or workshopform * @param string $typerootdir full path to the location of the plugin dir * @param string $typeclass the name of the actually called class @@ -594,19 +623,8 @@ abstract class plugininfo_base { $plugins = get_plugin_list($type); $ondisk = array(); foreach ($plugins as $pluginname => $pluginrootdir) { - $plugin = new $typeclass(); - $plugin->type = $type; - $plugin->typerootdir = $typerootdir; - $plugin->name = $pluginname; - $plugin->rootdir = $pluginrootdir; - - $plugin->init_display_name(); - $plugin->load_disk_version(); - $plugin->load_db_version(); - $plugin->load_required_main_version(); - $plugin->init_is_standard(); - - $ondisk[$pluginname] = $plugin; + $ondisk[$pluginname] = plugininfo_default_factory::make($type, $typerootdir, + $pluginname, $pluginrootdir, $typeclass); } return $ondisk; } diff --git a/lib/simpletest/testpluginlib.php b/lib/simpletest/testpluginlib.php new file mode 100644 index 00000000000..7c94917ab60 --- /dev/null +++ b/lib/simpletest/testpluginlib.php @@ -0,0 +1,127 @@ +. + +/** + * Unit tests for the lib/pluginlib.php library + * + * @package core + * @category test + * @copyright 2012 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +if (empty($CFG->unittestprefix)) { + die('You must define $CFG->unittestprefix to run these unit tests.'); +} + +require_once($CFG->libdir.'/pluginlib.php'); + +/** + * Modified {@link plugininfo_mod} suitable for testing purposes + */ +class testable_plugininfo_mod extends plugininfo_mod { + + public function init_display_name() { + $this->displayname = ucfirst($this->name); + } + + public function load_disk_version() { + $this->versiondisk = 2012030500; + } + + protected function load_version_php() { + return (object)array( + 'version' => 2012030500, + 'requires' => 2012010100, + 'component' => $this->type.'_'.$this->name); + } + + public function load_db_version() { + $this->versiondb = 2012022900; + } +} + + +/** + * Modified {@link plugin_manager} suitable for testing purposes + */ +class testable_plugin_manager extends plugin_manager { + + /** + * Factory method for this class + * + * @return plugin_manager the singleton instance + */ + public static function instance() { + global $CFG; + + if (is_null(self::$singletoninstance)) { + self::$singletoninstance = new self(); + } + return self::$singletoninstance; + } + + /** + * A version of {@link plugin_manager::get_plugins()} that prepares some faked + * testable instances. + * + * @param bool $disablecache ignored in this class + * @return array + */ + public function get_plugins($disablecache=false) { + global $CFG; + + $this->pluginsinfo = array( + 'mod' => array( + 'foo' => plugininfo_default_factory::make('mod', $CFG->dirroot.'/mod', 'foo', + $CFG->dirroot.'/mod/foo', 'testable_plugininfo_mod'), + ) + ); + + return $this->pluginsinfo; + } +} + + +/** + * Test cases for the pluginlib API + * + * These are basic tests to document the basic API of the plugin manager. + */ +class plugin_manager_test extends UnitTestCase { + + public function test_plugin_manager_instance() { + $pluginman = testable_plugin_manager::instance(); + $this->assertTrue($pluginman instanceof testable_plugin_manager); + } + + public function test_get_plugins() { + $pluginman = testable_plugin_manager::instance(); + $plugins = $pluginman->get_plugins(); + $this->assertTrue(isset($plugins['mod']['foo'])); + $this->assertTrue($plugins['mod']['foo'] instanceof testable_plugininfo_mod); + } + + public function test_get_status() { + $pluginman = testable_plugin_manager::instance(); + $plugins = $pluginman->get_plugins(); + $modfoo = $plugins['mod']['foo']; + $this->assertEqual($modfoo->get_status(), plugin_manager::PLUGIN_STATUS_UPGRADE); + } +}