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

/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Factory/AbstractFactory.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 342 lines | 244 code | 28 blank | 70 comment | 8 complexity | 748dd4dcade8f10554b4f24635ad4a92 MD5 | raw file
  1. <?php
  2. /**
  3. * @api
  4. * Copyright © 2016 Magento. All rights reserved.
  5. * See COPYING.txt for license details.
  6. */
  7. namespace Magento\Mtf\Util\Generate\Factory;
  8. use Magento\Framework\Filesystem\DriverInterface;
  9. /**
  10. * Class AbstractFactory
  11. *
  12. * Abstract Factory Generator
  13. *
  14. */
  15. abstract class AbstractFactory
  16. {
  17. protected $type = '';
  18. protected $cnt = 0;
  19. protected $factoryContent = '';
  20. protected $_checkList = [];
  21. /**
  22. * @return mixed
  23. */
  24. /**
  25. * Generate Blocks
  26. */
  27. public function launch()
  28. {
  29. $this->startFactory($this->type);
  30. $this->generateContent();
  31. $this->endFactory($this->type);
  32. \Magento\Mtf\Util\Generate\GenerateResult::addResult($this->type, $this->cnt);
  33. }
  34. abstract protected function generateContent();
  35. /**
  36. * Add header content
  37. *
  38. * @param string $type
  39. */
  40. protected function startFactory($type)
  41. {
  42. $this->factoryContent = "<?php\n\n";
  43. $this->factoryContent .= "namespace Magento\Mtf\\{$type}; \n\n";
  44. $this->factoryContent .= "use Magento\Mtf\\Fixture\\FixtureInterface; \n\n";
  45. $this->factoryContent .= "class {$type}FactoryDeprecated\n";
  46. $this->factoryContent .= "{\n";
  47. $this->factoryContent .= " /**
  48. * Object Manager
  49. *
  50. * @var \\Magento\Mtf\\ObjectManager
  51. */
  52. protected \$objectManager;
  53. /**
  54. * Constructor
  55. *
  56. */
  57. public function __construct()
  58. {
  59. \$this->objectManager = \\Magento\Mtf\\ObjectManager::getInstance();
  60. }\n";
  61. }
  62. /**
  63. * Add header content
  64. *
  65. * @param $type
  66. * @return $this
  67. * @throws \RuntimeException
  68. */
  69. protected function endFactory($type)
  70. {
  71. if (!$this->cnt) {
  72. return $this;
  73. }
  74. $this->checkAndCreateFolder(MTF_BP . "/generated/Magento/Mtf/{$type}");
  75. $this->factoryContent .= "}\n";
  76. $file = MTF_BP . "/generated/Magento/Mtf/{$type}/{$type}FactoryDeprecated.php";
  77. if (false === file_put_contents($file, $this->factoryContent)) {
  78. throw new \RuntimeException("Can't write content to {$file} file");
  79. }
  80. }
  81. /**
  82. * Create directory if not exist
  83. *
  84. * @param string $folder
  85. * @param int $mode
  86. * @return bool
  87. * @throws \Exception
  88. */
  89. protected function checkAndCreateFolder($folder, $mode = 0777)
  90. {
  91. if (is_dir($folder)) {
  92. return true;
  93. }
  94. if (!is_dir(dirname($folder))) {
  95. $this->checkAndCreateFolder(dirname($folder), $mode);
  96. }
  97. if (!is_dir($folder) && !$this->mkDir($folder, $mode)) {
  98. throw new \Exception("Unable to create directory '{$folder}'. Access forbidden.");
  99. }
  100. return true;
  101. }
  102. /**
  103. * Create directory
  104. *
  105. * @param string $dir
  106. * @param int $mode
  107. * @param bool $recursive
  108. * @return bool
  109. */
  110. protected function mkDir($dir, $mode = 0777, $recursive = true)
  111. {
  112. return @mkdir($dir, $mode, $recursive);
  113. }
  114. /**
  115. * Search collect files
  116. *
  117. * @param string $type
  118. * @return array
  119. * @SuppressWarnings(PHPMD.NPathComplexity)
  120. */
  121. protected function collectItems($type)
  122. {
  123. $items = [];
  124. $rewrites = [];
  125. $fallbacks = [
  126. ['path' => 'tests/app'],
  127. ['path' => 'generated'],
  128. ];
  129. while ($fallback = array_pop($fallbacks)) {
  130. $path = isset($fallback['path']) ? $fallback['path'] : '';
  131. $ns = isset($fallback['namespace']) ? $fallback['namespace'] : '';
  132. $location = $path . ($ns ? ('/' . str_replace('\\', '/', $ns)) : '');
  133. $pattern = $this->_getPattern($type, $location);
  134. $filesIterator = glob($pattern, GLOB_BRACE);
  135. foreach ($filesIterator as $filePath) {
  136. if (!is_dir($filePath)) {
  137. $this->_processItem($items, $rewrites, $filePath, $location, $path);
  138. } else {
  139. $dirIterator = new \RegexIterator(
  140. new \RecursiveIteratorIterator(
  141. new \RecursiveDirectoryIterator(
  142. $filePath,
  143. \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
  144. )
  145. ),
  146. '/.php$/i'
  147. );
  148. foreach ($dirIterator as $info) {
  149. /** @var $info \SplFileInfo */
  150. $realPath = $info->getPathname();
  151. if (is_link($realPath)) {
  152. $realPath = readlink($realPath);
  153. }
  154. $this->_processItem($items, $rewrites, $realPath, $location, $path);
  155. }
  156. }
  157. }
  158. }
  159. return $items;
  160. }
  161. /**
  162. * Handling file
  163. *
  164. * @param array $items
  165. * @param array $rewrites
  166. * @param string $filename
  167. * @param string $location
  168. * @param string $path
  169. * @throws \Exception
  170. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  171. */
  172. protected function _processItem(& $items, & $rewrites, $filename, $location, $path)
  173. {
  174. $filename = str_replace('\\', '/', $filename);
  175. $posTestsPath = strpos($filename, $path);
  176. $posClassName = $posTestsPath + strlen($path);
  177. $classPath = str_replace('.php', '', $filename);
  178. $className = str_replace('/', '\\', substr($classPath, $posClassName));
  179. $reflectionClass = new \ReflectionClass($className);
  180. if ($reflectionClass->isAbstract()) {
  181. return;
  182. }
  183. $annotations = \PHPUnit_Util_Test::parseTestMethodAnnotations($className);
  184. list(, $targetClassName) = explode($location . '/', $filename);
  185. $targetClassName = str_replace('.php', '', $targetClassName);
  186. $targetClassName = str_replace('/', '\\', $targetClassName);
  187. if (isset($this->_checkList[$targetClassName])) {
  188. $annotations['class']['rewrite'][0] = $this->_checkList[$targetClassName];
  189. $this->_checkList[$targetClassName] = $className;
  190. } else {
  191. $this->_checkList[$targetClassName] = $className;
  192. }
  193. if (isset($annotations['class']['rewrite'])) {
  194. $original = $annotations['class']['rewrite'][0];
  195. if (isset($items[$original])) {
  196. if (isset($items[$original]['fallback'])) {
  197. $message = "Class '{$className}' rewrites class '{$original}'.\n";
  198. $prevClass = key($items[$original]['fallback']);
  199. $message .= "Class '{$prevClass}' also rewrites class '$original'";
  200. throw new \Exception("Multiple rewrites detected:\n" . $message);
  201. }
  202. if (isset($items[$className])) {
  203. $items[$original]['fallback'][$className] = $items[$className];
  204. } else {
  205. $items[$original]['fallback'][$className]['class'] = $className;
  206. }
  207. $rewrites[$className] = &$items[$original]['fallback'][$className];
  208. if (isset($items[$className])) {
  209. unset($items[$className]);
  210. }
  211. } elseif (isset($rewrites[$original])) {
  212. if (isset($rewrites[$original]['fallback'])) {
  213. $message = "Class '{$className}' rewrites class '{$original}'.\n";
  214. $prevClass = key($rewrites[$original]['fallback']);
  215. $message .= "Class '{$prevClass}' also rewrites class '$original'";
  216. throw new \Exception("Multiple rewrites detected:\n" . $message);
  217. }
  218. if (isset($items[$className])) {
  219. $rewrites[$original]['fallback'][$className] = $items[$className];
  220. } else {
  221. $rewrites[$original]['fallback'][$className]['class'] = $className;
  222. }
  223. $rewrites[$className] = &$rewrites[$original]['fallback'][$className];
  224. if (isset($items[$className])) {
  225. unset($items[$className]);
  226. }
  227. } else {
  228. $items[$original]['class'] = $original;
  229. if (isset($items[$className])) {
  230. $items[$original]['fallback'][$className] = $items[$className];
  231. } else {
  232. $items[$original]['fallback'][$className]['class'] = $className;
  233. }
  234. $rewrites[$className] = &$items[$original]['fallback'][$className];
  235. if (isset($items[$className])) {
  236. unset($items[$className]);
  237. }
  238. }
  239. } else {
  240. $items[$className]['class'] = $className;
  241. }
  242. }
  243. /**
  244. * Convert class name to camel-case
  245. *
  246. * @param string $class
  247. * @return string
  248. */
  249. protected function _toCamelCase($class)
  250. {
  251. $class = str_replace('_', ' ', $class);
  252. $class = str_replace('\\', ' ', $class);
  253. $class = str_replace('/', ' ', $class);
  254. return str_replace(' ', '', ucwords($class));
  255. }
  256. /**
  257. * Find class depends on fallback configuration
  258. *
  259. * @param array $item
  260. * @return string
  261. */
  262. protected function _resolveClass(array $item)
  263. {
  264. if (isset($item['fallback'])) {
  265. return $this->_resolveClass(reset($item['fallback']));
  266. }
  267. return $item['class'];
  268. }
  269. /**
  270. * Return comment text for item
  271. *
  272. * @param array $item
  273. * @param string $arguments
  274. * @return string
  275. */
  276. protected function _buildFallbackComment(array $item, $arguments = '')
  277. {
  278. if (isset($item['fallback'])) {
  279. $returnComment = "\n //return new \\" . $item['class'] . "({$arguments});";
  280. return $this->_buildFallbackComment(reset($item['fallback']), $arguments) . $returnComment;
  281. }
  282. }
  283. /**
  284. * Return pattern depends on configuration
  285. *
  286. * @param string $type
  287. * @param string $location
  288. * @throws \RuntimeException
  289. * @return string
  290. */
  291. protected function _getPattern($type, $location)
  292. {
  293. $globPath = MTF_BP . '/' . $location . '/*/*/Test/' . $type;
  294. return $globPath;
  295. }
  296. }