getProjectRoot()); } public function shouldUseInterpreter() { return true; } public function getDefaultInterpreter() { return "bash"; } public function getInstallInstructions() { return pht('The test/lint/lint-tests.sh script is part of the bitcoin-abc '. 'project'); } public function shouldExpectCommandErrors() { return false; } protected function getMandatoryFlags() { return array(); } protected function parseLinterOutput($path, $err, $stdout, $stderr) { /* * Stdout contains 2 sections: * 1/ Section with name mismatches, in the form: * :BOOST_FIXTURE_TEST_SUITE(, ... * 2/ Section with duplicated test names: * */ /* * Extract infos from the path * * Note: the files are already filtered by path thanks to the .arclint * configuration. If the file is not a test, the grep will find nothing and * there will be no error to parse. */ $pathinfo = pathinfo($path); $testName = $pathinfo['filename']; $fileName = $pathinfo['basename']; $messages = []; /* Search for mismatch, using the line pattern */ $pattern = '/'.$fileName.':BOOST_FIXTURE_TEST_SUITE\(([\w]+)/'; $mismatch = preg_match($pattern, $stdout, $matches); if ($mismatch) { /* * Expect a single result as we are testing against a single file. * - $matches[0] contains the full mask * - $matches[1] contains the captured match */ if (count($matches) != 2) { throw new Exception( pht('Found multiple matches for a single file, lint-tests.sh output '. 'is not formatted as expected, aborting.')); } $mismatchName = $matches[1]; $messages[] = id(new ArcanistLintMessage()) ->setGranularity(ArcanistLinter::GRANULARITY_FILE) ->setCode('TESTS') ->setPath($path) ->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR) ->setName('Name mismatch') ->setDescription( 'The Boost test suite name must match the file name (set to "'. $mismatchName.'", should be "'.$testName.'").'); } /* * Search for unicity, searching for test name alone on its line. * The test name can be whether the one extracted from the file name or the * one extracted from the BOOST_FIXTURE_TEST_SUITE content. */ if ($mismatch) { $pattern = '/^'.$testName.'|'.$mismatchName.'$/'; } else { $pattern = '/^'.$testName.'$/'; } $notUnique = preg_match($pattern, $stdout, $matches); /* * Do not check the number of matches here. * Because it is a test against unicity, there is a global search which can * possibly return an output matching our expected test name AND our actual * test name. This would be weird, but not impossible. * Just returning an error for the first one is enough, as the linter will * be rerun after the name is fix and the other match will then eventually * get catched. */ if ($notUnique) { $messages[] = id(new ArcanistLintMessage()) ->setGranularity(ArcanistLinter::GRANULARITY_FILE) ->setCode('TESTS') ->setPath($path) ->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR) ->setName('Duplicated name') ->setDescription('The test name "'.$matches[0].'" already exists'); } return $messages; } }