PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeStyleTest.php

https://gitlab.com/DEVLINE/magento2
PHP | 256 lines | 162 code | 26 blank | 68 comment | 16 complexity | 7d333be6afb7c18a6e4a76e4d8586a93 MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. /**
  3. * Copyright © 2015 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Class to test composed Magento coding standard against different code cases.
  8. * Used to ensure, that Magento coding standard rules (sniffs) really do what they are intended to do.
  9. *
  10. */
  11. namespace Magento\Test\Php\Exemplar;
  12. class CodeStyleTest extends \PHPUnit_Framework_TestCase
  13. {
  14. /**
  15. * @var \Magento\TestFramework\CodingStandard\Tool\CodeSniffer
  16. */
  17. protected static $_cmd = null;
  18. private static $_reportFile = null;
  19. public static function setUpBeforeClass()
  20. {
  21. self::$_reportFile = __DIR__ . '/../../../tmp/phpcs_report.xml';
  22. $wrapper = new \Magento\TestFramework\CodingStandard\Tool\CodeSniffer\Wrapper();
  23. self::$_cmd = new \Magento\TestFramework\CodingStandard\Tool\CodeSniffer(
  24. realpath(__DIR__ . '/../_files/phpcs'),
  25. self::$_reportFile,
  26. $wrapper
  27. );
  28. }
  29. protected function setUp()
  30. {
  31. if (!is_dir(dirname(self::$_reportFile))) {
  32. mkdir(dirname(self::$_reportFile), 0777);
  33. }
  34. }
  35. protected function tearDown()
  36. {
  37. if (file_exists(self::$_reportFile)) {
  38. unlink(self::$_reportFile);
  39. }
  40. rmdir(dirname(self::$_reportFile));
  41. }
  42. public function testPhpCsAvailability()
  43. {
  44. $this->assertTrue(self::$_cmd->canRun(), 'PHP Code Sniffer command is not available.');
  45. }
  46. /**
  47. * @depends testPhpCsAvailability
  48. */
  49. public function testRule()
  50. {
  51. $invoker = new \Magento\Framework\Test\Utility\AggregateInvoker($this);
  52. $invoker(
  53. /**
  54. * @param string $inputFile
  55. * @param string $expectedResultFile
  56. */
  57. function ($inputFile, $expectedResultFile) {
  58. $expectedXml = simplexml_load_file($expectedResultFile);
  59. // rule is not implemented
  60. $elements = $expectedXml->xpath('/config/incomplete');
  61. if ($elements) {
  62. $message = (string)$elements[0];
  63. $this->markTestIncomplete("Rule for the fixture '{$inputFile}' is not implemented. {$message}");
  64. }
  65. // run additional methods before making test
  66. $elements = $expectedXml->xpath('/config/run');
  67. foreach ($elements as $element) {
  68. $method = (string)$element->attributes()->method;
  69. $this->{$method}();
  70. }
  71. self::$_cmd->run([$inputFile]);
  72. $resultXml = simplexml_load_file(self::$_reportFile);
  73. $this->_assertTotalErrorsAndWarnings($resultXml, $expectedXml);
  74. $this->_assertErrors($resultXml, $expectedXml);
  75. $this->_assertWarnings($resultXml, $expectedXml);
  76. // verify that there has been at least one assertion performed
  77. if ($this->getCount() == 0) {
  78. $this->fail("Broken test: there has no assertions been performed for the fixture '{$inputFile}'.");
  79. }
  80. },
  81. $this->ruleDataProvider()
  82. );
  83. }
  84. /**
  85. * @return array
  86. */
  87. public function ruleDataProvider()
  88. {
  89. $inputDir = __DIR__ . '/CodeStyleTest/phpcs/input/';
  90. $expectationDir = __DIR__ . '/CodeStyleTest/phpcs/expected/';
  91. return $this->_getTestsAndExpectations($inputDir, $expectationDir);
  92. }
  93. /**
  94. * Recursively searches paths and adds files and expectations to the list of fixtures for tests
  95. *
  96. * @param string $inputDir
  97. * @param string $expectationDir
  98. * @return array
  99. */
  100. protected function _getTestsAndExpectations($inputDir, $expectationDir)
  101. {
  102. $result = [];
  103. $skipFiles = ['.', '..'];
  104. $dir = dir($inputDir);
  105. do {
  106. $file = $dir->read();
  107. if ($file === false || in_array($file, $skipFiles)) {
  108. continue;
  109. }
  110. $inputFilePath = $inputDir . $file;
  111. $expectationFilePath = $expectationDir . $file;
  112. if (is_dir($inputFilePath)) {
  113. $more = $this->_getTestsAndExpectations($inputFilePath . '/', $expectationFilePath . '/');
  114. $result = array_merge($result, $more);
  115. continue;
  116. }
  117. $pathinfo = pathinfo($inputFilePath);
  118. $expectationFilePath = $expectationDir . $pathinfo['filename'] . '.xml';
  119. $result[] = [$inputFilePath, $expectationFilePath];
  120. } while ($file !== false);
  121. $dir->close();
  122. return $result;
  123. }
  124. /**
  125. * Assert total expected quantity of errors and warnings
  126. *
  127. * @param \SimpleXMLElement $report
  128. * @param \SimpleXMLElement $expected
  129. */
  130. protected function _assertTotalErrorsAndWarnings($report, $expected)
  131. {
  132. $elements = $expected->xpath('/config/total') ?: [];
  133. if (!$elements) {
  134. return;
  135. }
  136. list($numErrorsActual, $numWarningsActual) = $this->_calculateCountErrors($report);
  137. $element = $elements[0];
  138. $attributes = $element->attributes();
  139. if (isset($attributes->errors)) {
  140. $numErrorsExpected = (string)$attributes->errors;
  141. $this->assertEquals(
  142. $numErrorsExpected,
  143. $numErrorsActual,
  144. 'Expecting ' . $numErrorsExpected . ' errors, got ' . $numErrorsActual
  145. );
  146. }
  147. if (isset($attributes->warnings)) {
  148. $numWarningsExpected = (string)$attributes->warnings;
  149. $this->assertEquals(
  150. $numWarningsExpected,
  151. $numWarningsActual,
  152. 'Expecting ' . $numWarningsExpected . ' warnings, got ' . $numWarningsActual
  153. );
  154. }
  155. }
  156. /**
  157. * Calculate count errors and warnings
  158. *
  159. * @param \SimpleXMLElement $report
  160. * @return array
  161. */
  162. protected function _calculateCountErrors($report)
  163. {
  164. $errorNode = $report->xpath('/checkstyle/file/error[@severity="error"]') ?: [];
  165. $warningNode = $report->xpath('/checkstyle/file/error[@severity="warning"]') ?: [];
  166. $numErrorsActual = count($errorNode);
  167. $numWarningsActual = count($warningNode);
  168. return [$numErrorsActual, $numWarningsActual];
  169. }
  170. /**
  171. * Assert that errors correspond to expected errors
  172. *
  173. * @param \SimpleXMLElement $report
  174. * @param \SimpleXMLElement $expected
  175. */
  176. protected function _assertErrors($report, $expected)
  177. {
  178. $elements = $expected->xpath('/config/error') ?: [];
  179. foreach ($elements as $element) {
  180. $lineExpected = (string)$element->attributes()->line;
  181. $errorElement = $report->xpath('/checkstyle/file/error[@severity="error"][@line=' . $lineExpected . ']');
  182. $this->assertNotEmpty(
  183. $errorElement,
  184. 'Expected error at line ' . $lineExpected . ' is not detected by PHPCS.'
  185. );
  186. }
  187. }
  188. /**
  189. * Assert that warnings correspond to expected warnings
  190. *
  191. * @param \SimpleXMLElement $report
  192. * @param \SimpleXMLElement $expected
  193. */
  194. protected function _assertWarnings($report, $expected)
  195. {
  196. $elements = $expected->xpath('/config/warning') ?: [];
  197. foreach ($elements as $element) {
  198. $lineExpected = (string)$element->attributes()->line;
  199. $errorElement = $report->xpath('/checkstyle/file/error[@severity="warning"][@line=' . $lineExpected . ']');
  200. $this->assertNotEmpty(
  201. $errorElement,
  202. 'Expected warning at line ' . $lineExpected . ' is not detected by PHPCS.'
  203. );
  204. }
  205. }
  206. /**
  207. * Checks, whether short open tags are allowed.
  208. * Check-method, used by test-configs and executed before executing tests.
  209. *
  210. * @return null
  211. */
  212. protected function _checkShortTagsOn()
  213. {
  214. if (!ini_get('short_open_tag')) {
  215. $this->markTestSkipped('"short_open_tag" setting must be set to "On" to test this case.');
  216. }
  217. }
  218. /**
  219. * Checks, whether short open tags in ASP-style are allowed.
  220. * Check-method, used by test-configs and executed before executing tests.
  221. *
  222. * @return null
  223. */
  224. protected function _checkAspTagsOn()
  225. {
  226. if (!ini_get('asp_tags')) {
  227. $this->markTestSkipped('"asp tags" setting must be set to "On" to test this case.');
  228. }
  229. }
  230. }