PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Codeception/Configuration.php

https://github.com/instalic/Codeception
PHP | 190 lines | 156 code | 32 blank | 2 comment | 21 complexity | 64860d3408de40f84fe2549b1b69fe9d MD5 | raw file
  1. <?php
  2. namespace Codeception;
  3. use Symfony\Component\Yaml\Yaml;
  4. use Symfony\Component\Finder\Finder;
  5. class Configuration
  6. {
  7. protected static $suites = array();
  8. protected static $config = null;
  9. protected static $logDir = null;
  10. protected static $dataDir = null;
  11. protected static $helpersDir = null;
  12. protected static $testsDir = null;
  13. protected static $dir = null;
  14. public static function config($config = null)
  15. {
  16. if (self::$config) return self::$config;
  17. if ($config === null) {
  18. $dir = getcwd();
  19. $config = file_exists('codeception.yml') ? Yaml::parse('codeception.yml') : array();
  20. } else {
  21. $dir = dirname($config);
  22. $config = file_exists($config) ? Yaml::parse($config) : array();
  23. }
  24. $distConfig = file_exists('codeception.dist.yml') ? Yaml::parse('codeception.dist.yml') : array();
  25. $config = array_merge($distConfig, $config);
  26. if (empty($config)) throw new \Codeception\Exception\Configuration("Configuration file is invalid");
  27. if (!isset($config['paths'])) throw new \Codeception\Exception\Configuration('Paths are not defined');
  28. if (!isset($config['paths']['tests'])) throw new \Codeception\Exception\Configuration('Tests directory path is not defined');
  29. if (!isset($config['paths']['data'])) throw new \Codeception\Exception\Configuration('Data path is not defined');
  30. if (!isset($config['paths']['log'])) throw new \Codeception\Exception\Configuration('Log path is not defined');
  31. if (isset($config['paths']['helpers'])) {
  32. // Helpers
  33. $helpers = Finder::create()->files()->name('*Helper.php')->in($dir . DIRECTORY_SEPARATOR .$config['paths']['helpers']);
  34. foreach ($helpers as $helper) include_once($helper);
  35. }
  36. if (!isset($config['suites'])) {
  37. $suites = Finder::create()->files()->name('*.suite.yml')->in($dir . DIRECTORY_SEPARATOR .$config['paths']['tests'])->depth(0);
  38. $config['suites'] = array();
  39. foreach ($suites as $suite) {
  40. preg_match('~(.*?)(\.suite|\.suite\.dist)\.yml~', $suite->getFilename(), $matches);
  41. $config['suites'][] = $matches[1];
  42. }
  43. }
  44. ini_set('memory_limit', isset($config['settings']['memory_limit']) ? $config['settings']['memory_limit'] : '1024M');
  45. self::$suites = $config['suites'];
  46. self::$config = $config;
  47. self::$dataDir = $config['paths']['data'];
  48. self::$logDir = $config['paths']['log'];
  49. self::$helpersDir = $config['paths']['helpers'];
  50. self::$dir = $dir;
  51. return $config;
  52. }
  53. public static function dataDir()
  54. {
  55. if (!self::$dataDir) throw new \Codeception\Exception\Configuration("Path for data not specified. Please, set data path in global config");
  56. return self::$dir . DIRECTORY_SEPARATOR . self::$dataDir . DIRECTORY_SEPARATOR;
  57. }
  58. public static function helpersDir()
  59. {
  60. return self::$dir . DIRECTORY_SEPARATOR . self::$helpersDir . DIRECTORY_SEPARATOR;
  61. }
  62. public static function logDir()
  63. {
  64. if (!self::$logDir) throw new \Codeception\Exception\Configuration("Path for logs not specified. Please, set log path in global config");
  65. $dir = realpath(self::$dir . DIRECTORY_SEPARATOR . self::$logDir) . DIRECTORY_SEPARATOR;
  66. if (!is_writable($dir)) {
  67. @mkdir($dir);
  68. @chmod($dir, 777);
  69. }
  70. if (!is_writable($dir)) {
  71. throw new \Codeception\Exception\Configuration("Path for logs is not writable. Please, set appropriate access mode for log path.");
  72. }
  73. return $dir;
  74. }
  75. public static function projectDir()
  76. {
  77. return self::$dir . DIRECTORY_SEPARATOR;
  78. }
  79. public static function suiteSettings($suite, $config)
  80. {
  81. if (!in_array($suite, self::$suites)) throw new \Exception("Suite $suite was not loaded");
  82. $globalConf = $config['settings'];
  83. $globalConf['coverage'] = isset($config['coverage'])
  84. ? $config['coverage']
  85. : array();
  86. $moduleConf = array('modules' => isset($config['modules']) ? $config['modules'] : array());
  87. $path = $config['paths']['tests'];
  88. $suiteConf = file_exists(self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.yml") ? Yaml::parse(self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.yml") : array();
  89. $suiteDistconf = file_exists(self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.dist.yml") ? Yaml::parse(self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "$suite.suite.dist.yml") : array();
  90. $settings = self::mergeConfigs($globalConf, $moduleConf);
  91. $settings = self::mergeConfigs($settings, $suiteDistconf);
  92. $settings = self::mergeConfigs($settings, $suiteConf);
  93. $settings['path'] = self::$dir . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . $suite . DIRECTORY_SEPARATOR;
  94. return $settings;
  95. }
  96. public static function suites()
  97. {
  98. return self::$suites;
  99. }
  100. public static function modules($settings)
  101. {
  102. $defaults = array('modules' => array('enabled' => array(), 'config' => array()));
  103. if (!isset($settings['modules'])) throw new \Codeception\Exception\Configuration('No modules configured!');
  104. if (file_exists($guy = $settings['path'] . DIRECTORY_SEPARATOR . $settings['class_name'] . '.php')) require_once $guy;
  105. // if (!class_exists($settings['class_name'])) throw new \Codeception\Exception\Configuration("No guys were found. Tried to find {$settings['class_name']} but he was not there.");
  106. $modules = array();
  107. $settings = self::mergeConfigs($defaults, $settings);
  108. $moduleNames = $settings['modules']['enabled'];
  109. foreach ($moduleNames as $moduleName) {
  110. $classname = '\Codeception\Module\\' . $moduleName;
  111. $module = new $classname;
  112. $modules[$moduleName] = $module;
  113. if (isset($settings['modules']['config'][$moduleName])) {
  114. $module->_setConfig($settings['modules']['config'][$moduleName]);
  115. } else {
  116. if ($module->_hasRequiredFields()) throw new \Codeception\Exception\ModuleConfig($moduleName, "Module $moduleName is not configured. Please check out it's required fields");
  117. }
  118. }
  119. return $modules;
  120. }
  121. public static function actions($modules)
  122. {
  123. $actions = array();
  124. foreach ($modules as $modulename => $module) {
  125. $module->_initialize();
  126. $class = new \ReflectionClass('\Codeception\Module\\' . $modulename);
  127. $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
  128. foreach ($methods as $method) {
  129. if (strpos($method->name, '_') === 0) continue;
  130. $actions[$method->name] = $modulename;
  131. }
  132. }
  133. return $actions;
  134. }
  135. protected static function mergeConfigs($a1, $a2)
  136. {
  137. if (!is_array($a1) || !is_array($a2))
  138. return $a2;
  139. $res = array();
  140. foreach ($a2 as $k2 => $v2)
  141. {
  142. if (!isset($a1[$k2])) { // if no such key
  143. $res[$k2] = $v2;
  144. continue;
  145. }
  146. $res[$k2] = self::mergeConfigs($a1[$k2], $v2);
  147. unset($a1[$k2]);
  148. }
  149. foreach ($a1 as $k1 => $v1) // only single elements here left
  150. $res[$k1] = $v1;
  151. return $res;
  152. }
  153. }