| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 | 
							- <?php
 
- /**
 
-  * Copyright © Magento, Inc. All rights reserved.
 
-  * See COPYING.txt for license details.
 
-  */
 
- namespace Magento\Test\Php;
 
- use Magento\Framework\App\Utility\Files;
 
- use Magento\Framework\Component\ComponentRegistrar;
 
- use Magento\TestFramework\CodingStandard\Tool\CodeMessDetector;
 
- use Magento\TestFramework\CodingStandard\Tool\CodeSniffer;
 
- use Magento\TestFramework\CodingStandard\Tool\CodeSniffer\Wrapper;
 
- use Magento\TestFramework\CodingStandard\Tool\CopyPasteDetector;
 
- use PHPMD\TextUI\Command;
 
- /**
 
-  * Set of tests for static code analysis, e.g. code style, code complexity, copy paste detecting, etc.
 
-  */
 
- class LiveCodeTest extends \PHPUnit\Framework\TestCase
 
- {
 
-     /**
 
-      * @var string
 
-      */
 
-     protected static $reportDir = '';
 
-     /**
 
-      * @var string
 
-      */
 
-     protected static $pathToSource = '';
 
-     /**
 
-      * Setup basics for all tests
 
-      *
 
-      * @return void
 
-      */
 
-     public static function setUpBeforeClass()
 
-     {
 
-         self::$pathToSource = BP;
 
-         self::$reportDir = self::$pathToSource . '/dev/tests/static/report';
 
-         if (!is_dir(self::$reportDir)) {
 
-             mkdir(self::$reportDir);
 
-         }
 
-     }
 
-     /**
 
-      * Returns base folder for suite scope
 
-      *
 
-      * @return string
 
-      */
 
-     private static function getBaseFilesFolder()
 
-     {
 
-         return __DIR__;
 
-     }
 
-     /**
 
-      * Returns base directory for whitelisted files
 
-      *
 
-      * @return string
 
-      */
 
-     private static function getChangedFilesBaseDir()
 
-     {
 
-         return __DIR__ . '/..';
 
-     }
 
-     /**
 
-      * Returns whitelist based on blacklist and git changed files
 
-      *
 
-      * @param array $fileTypes
 
-      * @param string $changedFilesBaseDir
 
-      * @param string $baseFilesFolder
 
-      * @param string $whitelistFile
 
-      * @return array
 
-      */
 
-     public static function getWhitelist(
 
-         $fileTypes = ['php'],
 
-         $changedFilesBaseDir = '',
 
-         $baseFilesFolder = '',
 
-         $whitelistFile = '/_files/whitelist/common.txt'
 
-     ) {
 
-         $changedFiles = self::getChangedFilesList($changedFilesBaseDir);
 
-         if (empty($changedFiles)) {
 
-             return [];
 
-         }
 
-         $globPatternsFolder = ('' !== $baseFilesFolder) ? $baseFilesFolder : self::getBaseFilesFolder();
 
-         try {
 
-             $directoriesToCheck = Files::init()->readLists($globPatternsFolder . $whitelistFile);
 
-         } catch (\Exception $e) {
 
-             // no directories matched white list
 
-             return [];
 
-         }
 
-         $targetFiles = self::filterFiles($changedFiles, $fileTypes, $directoriesToCheck);
 
-         return $targetFiles;
 
-     }
 
-     /**
 
-      * This method loads list of changed files.
 
-      *
 
-      * List may be generated by:
 
-      *  - dev/tests/static/get_github_changes.php utility (allow to generate diffs between branches),
 
-      *  - CLI command "git diff --name-only > dev/tests/static/testsuite/Magento/Test/_files/changed_files_local.txt",
 
-      *
 
-      * If no generated changed files list found "git diff" will be used to find not committed changed
 
-      * (tests should be invoked from target gir repo).
 
-      *
 
-      * Note: "static" modifier used for compatibility with legacy implementation of self::getWhitelist method
 
-      *
 
-      * @param string $changedFilesBaseDir Base dir with previously generated list files
 
-      * @return string[] List of changed files
 
-      */
 
-     private static function getChangedFilesList($changedFilesBaseDir)
 
-     {
 
-         return self::getFilesFromListFile(
 
-             $changedFilesBaseDir,
 
-             'changed_files*',
 
-             function () {
 
-                 // if no list files, probably, this is the dev environment
 
-                 @exec('git diff --name-only', $changedFiles);
 
-                 @exec('git diff --cached --name-only', $addedFiles);
 
-                 $changedFiles = array_unique(array_merge($changedFiles, $addedFiles));
 
-                 return $changedFiles;
 
-             }
 
-         );
 
-     }
 
-     /**
 
-      * This method loads list of added files.
 
-      *
 
-      * @param string $changedFilesBaseDir
 
-      * @return string[]
 
-      */
 
-     private static function getAddedFilesList($changedFilesBaseDir)
 
-     {
 
-         return self::getFilesFromListFile(
 
-             $changedFilesBaseDir,
 
-             'changed_files*.added.*',
 
-             function () {
 
-                 // if no list files, probably, this is the dev environment
 
-                 @exec('git diff --cached --name-only', $addedFiles);
 
-                 return $addedFiles;
 
-             }
 
-         );
 
-     }
 
-     /**
 
-      * Read files from generated lists.
 
-      *
 
-      * @param string $listsBaseDir
 
-      * @param string $listFilePattern
 
-      * @param callable $noListCallback
 
-      * @return string[]
 
-      */
 
-     private static function getFilesFromListFile($listsBaseDir, $listFilePattern, $noListCallback)
 
-     {
 
-         $filesDefinedInList = [];
 
-         $globFilesListPattern = ($listsBaseDir ?: self::getChangedFilesBaseDir())
 
-             . '/_files/' . $listFilePattern;
 
-         $listFiles = glob($globFilesListPattern);
 
-         if (count($listFiles)) {
 
-             foreach ($listFiles as $listFile) {
 
-                 $filesDefinedInList = array_merge(
 
-                     $filesDefinedInList,
 
-                     file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
 
-                 );
 
-             }
 
-         } else {
 
-             $filesDefinedInList = call_user_func($noListCallback);
 
-         }
 
-         array_walk(
 
-             $filesDefinedInList,
 
-             function (&$file) {
 
-                 $file = BP . '/' . $file;
 
-             }
 
-         );
 
-         $filesDefinedInList = array_values(array_unique($filesDefinedInList));
 
-         return $filesDefinedInList;
 
-     }
 
-     /**
 
-      * Filter list of files.
 
-      *
 
-      * File removed from list:
 
-      *  - if it not exists,
 
-      *  - if allowed types are specified and file has another type (extension),
 
-      *  - if allowed directories specified and file not located in one of them.
 
-      *
 
-      * Note: "static" modifier used for compatibility with legacy implementation of self::getWhitelist method
 
-      *
 
-      * @param string[] $files List of file paths to filter
 
-      * @param string[] $allowedFileTypes List of allowed file extensions (pass empty array to allow all)
 
-      * @param string[] $allowedDirectories List of allowed directories (pass empty array to allow all)
 
-      * @return string[] Filtered file paths
 
-      */
 
-     private static function filterFiles(array $files, array $allowedFileTypes, array $allowedDirectories)
 
-     {
 
-         if (empty($allowedFileTypes)) {
 
-             $fileHasAllowedType = function () {
 
-                 return true;
 
-             };
 
-         } else {
 
-             $fileHasAllowedType = function ($file) use ($allowedFileTypes) {
 
-                 return in_array(pathinfo($file, PATHINFO_EXTENSION), $allowedFileTypes);
 
-             };
 
-         }
 
-         if (empty($allowedDirectories)) {
 
-             $fileIsInAllowedDirectory = function () {
 
-                 return true;
 
-             };
 
-         } else {
 
-             $allowedDirectories = array_map('realpath', $allowedDirectories);
 
-             usort($allowedDirectories, function ($dir1, $dir2) {
 
-                 return strlen($dir1) - strlen($dir2);
 
-             });
 
-             $fileIsInAllowedDirectory = function ($file) use ($allowedDirectories) {
 
-                 foreach ($allowedDirectories as $directory) {
 
-                     if (strpos($file, $directory) === 0) {
 
-                         return true;
 
-                     }
 
-                 }
 
-                 return false;
 
-             };
 
-         }
 
-         $filtered = array_filter(
 
-             $files,
 
-             function ($file) use ($fileHasAllowedType, $fileIsInAllowedDirectory) {
 
-                 $file = realpath($file);
 
-                 if (false === $file) {
 
-                     return false;
 
-                 }
 
-                 return $fileHasAllowedType($file) && $fileIsInAllowedDirectory($file);
 
-             }
 
-         );
 
-         return $filtered;
 
-     }
 
-     /**
 
-      * Retrieves full list of codebase paths without any files/folders filtered out
 
-      *
 
-      * @return array
 
-      */
 
-     private function getFullWhitelist()
 
-     {
 
-         try {
 
-             return Files::init()->readLists(__DIR__ . '/_files/whitelist/common.txt');
 
-         } catch (\Exception $e) {
 
-             // nothing is whitelisted
 
-             return [];
 
-         }
 
-     }
 
-     /**
 
-      * Test code quality using phpcs
 
-      */
 
-     public function testCodeStyle()
 
-     {
 
-         $isFullScan = defined('TESTCODESTYLE_IS_FULL_SCAN') && TESTCODESTYLE_IS_FULL_SCAN === '1';
 
-         $reportFile = self::$reportDir . '/phpcs_report.txt';
 
-         if (!file_exists($reportFile)) {
 
-             touch($reportFile);
 
-         }
 
-         $codeSniffer = new CodeSniffer('Magento', $reportFile, new Wrapper());
 
-         $result = $codeSniffer->run($isFullScan ? $this->getFullWhitelist() : self::getWhitelist(['php', 'phtml']));
 
-         $report = file_get_contents($reportFile);
 
-         $this->assertEquals(
 
-             0,
 
-             $result,
 
-             "PHP Code Sniffer detected {$result} violation(s): " . PHP_EOL . $report
 
-         );
 
-     }
 
-     /**
 
-      * Test code quality using phpmd
 
-      */
 
-     public function testCodeMess()
 
-     {
 
-         $reportFile = self::$reportDir . '/phpmd_report.txt';
 
-         $codeMessDetector = new CodeMessDetector(realpath(__DIR__ . '/_files/phpmd/ruleset.xml'), $reportFile);
 
-         if (!$codeMessDetector->canRun()) {
 
-             $this->markTestSkipped('PHP Mess Detector is not available.');
 
-         }
 
-         $result = $codeMessDetector->run(self::getWhitelist(['php']));
 
-         $output = "";
 
-         if (file_exists($reportFile)) {
 
-             $output = file_get_contents($reportFile);
 
-         }
 
-         $this->assertEquals(
 
-             Command::EXIT_SUCCESS,
 
-             $result,
 
-             "PHP Code Mess has found error(s):" . PHP_EOL . $output
 
-         );
 
-         // delete empty reports
 
-         if (file_exists($reportFile)) {
 
-             unlink($reportFile);
 
-         }
 
-     }
 
-     /**
 
-      * Test code quality using phpcpd
 
-      */
 
-     public function testCopyPaste()
 
-     {
 
-         $reportFile = self::$reportDir . '/phpcpd_report.xml';
 
-         $copyPasteDetector = new CopyPasteDetector($reportFile);
 
-         if (!$copyPasteDetector->canRun()) {
 
-             $this->markTestSkipped('PHP Copy/Paste Detector is not available.');
 
-         }
 
-         $blackList = [];
 
-         foreach (glob(__DIR__ . '/_files/phpcpd/blacklist/*.txt') as $list) {
 
-             $blackList = array_merge($blackList, file($list, FILE_IGNORE_NEW_LINES));
 
-         }
 
-         $copyPasteDetector->setBlackList($blackList);
 
-         $result = $copyPasteDetector->run([BP]);
 
-         $output = "";
 
-         if (file_exists($reportFile)) {
 
-             $output = file_get_contents($reportFile);
 
-         }
 
-         $this->assertTrue(
 
-             $result,
 
-             "PHP Copy/Paste Detector has found error(s):" . PHP_EOL . $output
 
-         );
 
-     }
 
-     /**
 
-      * Tests whitelisted files for strict type declarations.
 
-      */
 
-     public function testStrictTypes()
 
-     {
 
-         $changedFiles = self::getAddedFilesList('');
 
-         try {
 
-             $blackList = Files::init()->readLists(
 
-                 self::getBaseFilesFolder() . '/_files/blacklist/strict_type.txt'
 
-             );
 
-         } catch (\Exception $e) {
 
-             // nothing matched black list
 
-             $blackList = [];
 
-         }
 
-         $toBeTestedFiles = array_diff(
 
-             self::filterFiles($changedFiles, ['php'], []),
 
-             $blackList
 
-         );
 
-         $filesMissingStrictTyping = [];
 
-         foreach ($toBeTestedFiles as $fileName) {
 
-             $file = file_get_contents($fileName);
 
-             if (strstr($file, 'strict_types=1') === false) {
 
-                 $filesMissingStrictTyping[] = $fileName;
 
-             }
 
-         }
 
-         $this->assertEquals(
 
-             0,
 
-             count($filesMissingStrictTyping),
 
-             "Following files are missing strict type declaration:"
 
-             . PHP_EOL
 
-             . implode(PHP_EOL, $filesMissingStrictTyping)
 
-         );
 
-     }
 
- }
 
 
  |