[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Utils to set Behat config 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 defined('MOODLE_INTERNAL') || die(); 27 28 require_once (__DIR__ . '/../lib.php'); 29 require_once (__DIR__ . '/behat_command.php'); 30 require_once (__DIR__ . '/../../testing/classes/tests_finder.php'); 31 32 /** 33 * Behat configuration manager 34 * 35 * Creates/updates Behat config files getting tests 36 * and steps from Moodle codebase 37 * 38 * @package core 39 * @category test 40 * @copyright 2012 David Monllaó 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 class behat_config_manager { 44 45 /** 46 * Updates a config file 47 * 48 * The tests runner and the steps definitions list uses different 49 * config files to avoid problems with concurrent executions. 50 * 51 * The steps definitions list can be filtered by component so it's 52 * behat.yml is different from the $CFG->dirroot one. 53 * 54 * @param string $component Restricts the obtained steps definitions to the specified component 55 * @param string $testsrunner If the config file will be used to run tests 56 * @return void 57 */ 58 public static function update_config_file($component = '', $testsrunner = true) { 59 global $CFG; 60 61 // Behat must have a separate behat.yml to have access to the whole set of features and steps definitions. 62 if ($testsrunner === true) { 63 $configfilepath = behat_command::get_behat_dir() . '/behat.yml'; 64 } else { 65 // Alternative for steps definitions filtering, one for each user. 66 $configfilepath = self::get_steps_list_config_filepath(); 67 } 68 69 // Gets all the components with features. 70 $features = array(); 71 $components = tests_finder::get_components_with_tests('features'); 72 if ($components) { 73 foreach ($components as $componentname => $path) { 74 $path = self::clean_path($path) . self::get_behat_tests_path(); 75 if (empty($featurespaths[$path]) && file_exists($path)) { 76 77 // Standarizes separator (some dirs. comes with OS-dependant separator). 78 $uniquekey = str_replace('\\', '/', $path); 79 $featurespaths[$uniquekey] = $path; 80 } 81 } 82 $features = array_values($featurespaths); 83 } 84 85 // Optionally include features from additional directories. 86 if (!empty($CFG->behat_additionalfeatures)) { 87 $features = array_merge($features, array_map("realpath", $CFG->behat_additionalfeatures)); 88 } 89 90 // Gets all the components with steps definitions. 91 $stepsdefinitions = array(); 92 $steps = self::get_components_steps_definitions(); 93 if ($steps) { 94 foreach ($steps as $key => $filepath) { 95 if ($component == '' || $component === $key) { 96 $stepsdefinitions[$key] = $filepath; 97 } 98 } 99 } 100 101 // We don't want the deprecated steps definitions here. 102 if (!$testsrunner) { 103 unset($stepsdefinitions['behat_deprecated']); 104 } 105 106 // Behat config file specifing the main context class, 107 // the required Behat extensions and Moodle test wwwroot. 108 $contents = self::get_config_file_contents($features, $stepsdefinitions); 109 110 // Stores the file. 111 if (!file_put_contents($configfilepath, $contents)) { 112 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'File ' . $configfilepath . ' can not be created'); 113 } 114 115 } 116 117 /** 118 * Gets the list of Moodle steps definitions 119 * 120 * Class name as a key and the filepath as value 121 * 122 * Externalized from update_config_file() to use 123 * it from the steps definitions web interface 124 * 125 * @return array 126 */ 127 public static function get_components_steps_definitions() { 128 129 $components = tests_finder::get_components_with_tests('stepsdefinitions'); 130 if (!$components) { 131 return false; 132 } 133 134 $stepsdefinitions = array(); 135 foreach ($components as $componentname => $componentpath) { 136 $componentpath = self::clean_path($componentpath); 137 138 if (!file_exists($componentpath . self::get_behat_tests_path())) { 139 continue; 140 } 141 $diriterator = new DirectoryIterator($componentpath . self::get_behat_tests_path()); 142 $regite = new RegexIterator($diriterator, '|behat_.*\.php$|'); 143 144 // All behat_*.php inside behat_config_manager::get_behat_tests_path() are added as steps definitions files. 145 foreach ($regite as $file) { 146 $key = $file->getBasename('.php'); 147 $stepsdefinitions[$key] = $file->getPathname(); 148 } 149 } 150 151 return $stepsdefinitions; 152 } 153 154 /** 155 * Returns the behat config file path used by the steps definition list 156 * 157 * @return string 158 */ 159 public static function get_steps_list_config_filepath() { 160 global $USER; 161 162 // We don't cygwin-it as it is called using exec() which uses cmd.exe. 163 $userdir = behat_command::get_behat_dir() . '/users/' . $USER->id; 164 make_writable_directory($userdir); 165 166 return $userdir . '/behat.yml'; 167 } 168 169 /** 170 * Returns the behat config file path used by the behat cli command. 171 * 172 * @return string 173 */ 174 public static function get_behat_cli_config_filepath() { 175 global $CFG; 176 177 $command = $CFG->behat_dataroot . DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR . 'behat.yml'; 178 179 // Cygwin uses linux-style directory separators. 180 if (testing_is_cygwin()) { 181 $command = str_replace('\\', '/', $command); 182 } 183 184 return $command; 185 } 186 187 /** 188 * Behat config file specifing the main context class, 189 * the required Behat extensions and Moodle test wwwroot. 190 * 191 * @param array $features The system feature files 192 * @param array $stepsdefinitions The system steps definitions 193 * @return string 194 */ 195 protected static function get_config_file_contents($features, $stepsdefinitions) { 196 global $CFG; 197 198 // We require here when we are sure behat dependencies are available. 199 require_once($CFG->dirroot . '/vendor/autoload.php'); 200 201 // It is possible that it has no value as we don't require a full behat setup to list the step definitions. 202 if (empty($CFG->behat_wwwroot)) { 203 $CFG->behat_wwwroot = 'http://itwillnotbeused.com'; 204 } 205 206 $basedir = $CFG->dirroot . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'behat'; 207 $config = array( 208 'default' => array( 209 'paths' => array( 210 'features' => $basedir . DIRECTORY_SEPARATOR . 'features', 211 'bootstrap' => $basedir . DIRECTORY_SEPARATOR . 'features' . DIRECTORY_SEPARATOR . 'bootstrap', 212 ), 213 'context' => array( 214 'class' => 'behat_init_context' 215 ), 216 'extensions' => array( 217 'Behat\MinkExtension\Extension' => array( 218 'base_url' => $CFG->behat_wwwroot, 219 'goutte' => null, 220 'selenium2' => null 221 ), 222 'Moodle\BehatExtension\Extension' => array( 223 'formatters' => array( 224 'moodle_progress' => 'Moodle\BehatExtension\Formatter\MoodleProgressFormatter' 225 ), 226 'features' => $features, 227 'steps_definitions' => $stepsdefinitions 228 ) 229 ), 230 'formatter' => array( 231 'name' => 'moodle_progress' 232 ) 233 ) 234 ); 235 236 // In case user defined overrides respect them over our default ones. 237 if (!empty($CFG->behat_config)) { 238 $config = self::merge_config($config, $CFG->behat_config); 239 } 240 241 return Symfony\Component\Yaml\Yaml::dump($config, 10, 2); 242 } 243 244 /** 245 * Overrides default config with local config values 246 * 247 * array_merge does not merge completely the array's values 248 * 249 * @param mixed $config The node of the default config 250 * @param mixed $localconfig The node of the local config 251 * @return mixed The merge result 252 */ 253 protected static function merge_config($config, $localconfig) { 254 255 if (!is_array($config) && !is_array($localconfig)) { 256 return $localconfig; 257 } 258 259 // Local overrides also deeper default values. 260 if (is_array($config) && !is_array($localconfig)) { 261 return $localconfig; 262 } 263 264 foreach ($localconfig as $key => $value) { 265 266 // If defaults are not as deep as local values let locals override. 267 if (!is_array($config)) { 268 unset($config); 269 } 270 271 // Add the param if it doesn't exists or merge branches. 272 if (empty($config[$key])) { 273 $config[$key] = $value; 274 } else { 275 $config[$key] = self::merge_config($config[$key], $localconfig[$key]); 276 } 277 } 278 279 return $config; 280 } 281 282 /** 283 * Cleans the path returned by get_components_with_tests() to standarize it 284 * 285 * @see tests_finder::get_all_directories_with_tests() it returns the path including /tests/ 286 * @param string $path 287 * @return string The string without the last /tests part 288 */ 289 protected final static function clean_path($path) { 290 291 $path = rtrim($path, DIRECTORY_SEPARATOR); 292 293 $parttoremove = DIRECTORY_SEPARATOR . 'tests'; 294 295 $substr = substr($path, strlen($path) - strlen($parttoremove)); 296 if ($substr == $parttoremove) { 297 $path = substr($path, 0, strlen($path) - strlen($parttoremove)); 298 } 299 300 return rtrim($path, DIRECTORY_SEPARATOR); 301 } 302 303 /** 304 * The relative path where components stores their behat tests 305 * 306 * @return string 307 */ 308 protected final static function get_behat_tests_path() { 309 return DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'behat'; 310 } 311 312 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |