From ab407394d273e65d049fb5a5d7d4d6bb490d6b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Andor?= Date: Sun, 30 Jul 2017 15:27:04 +0200 Subject: [PATCH] Split TsLintRunTask::run into smaller functions --- src/Task/TsLintRunTask.php | 179 ++++++++++++++++++-------- tests/unit/Task/TsLintRunTaskTest.php | 38 +++++- 2 files changed, 157 insertions(+), 60 deletions(-) diff --git a/src/Task/TsLintRunTask.php b/src/Task/TsLintRunTask.php index 2d4a17c..dfe33d1 100644 --- a/src/Task/TsLintRunTask.php +++ b/src/Task/TsLintRunTask.php @@ -46,10 +46,27 @@ class TsLintRunTask extends BaseTask implements */ const EXIT_CODE_ERROR = 2; + /** + * Couldn't create the output directory. + */ + const EXIT_CODE_OUTPUT_DIR = 3; + /** * Something is invalid. */ - const EXIT_CODE_INVALID = 3; + const EXIT_CODE_INVALID = 4; + + /** + * Exit code and error message mapping. + * + * @var string + */ + protected $taskExitMessages = [ + 0 => 'No lints were found', + 1 => 'Lints with a severity of warning were reported (no errors)', + 2 => 'One or more errors were reported (and any number of warnings)', + 3 => 'Extra lint reporters can be used only if the output format is "json".', + ]; /** * @todo Some kind of dependency injection would be awesome. @@ -465,11 +482,37 @@ public function removeLintReporter(string $id) // endregion // endregion + /** + * Process exit code. + * + * @var int + */ + protected $lintExitCode = 0; + + /** + * Process stdOutput. + * + * @var string + */ + protected $lintStdOutput = ''; + + /** + * Process stdError. + * + * @var string + */ + protected $lintStdError = ''; + + /** + * @var string + */ + protected $command = ''; + /** * @var array */ protected $assets = [ - 'report' => [], + 'report' => null, ]; protected $options = [ @@ -484,25 +527,6 @@ public function removeLintReporter(string $id) 'type-check' => 'flag', ]; - /** - * Process exit code. - * - * @var int - */ - protected $exitCode = 0; - - /** - * Exit code and error message mapping. - * - * @var string - */ - protected $exitMessages = [ - 0 => 'No lints were found', - 1 => 'Lints with a severity of warning were reported (no errors)', - 2 => 'One or more errors were reported (and any number of warnings)', - 3 => 'Extra lint reporters can be used only if the output format is "json".', - ]; - /** * TaskTsLintRun constructor. * @@ -621,45 +645,85 @@ protected function createIncludeList($items, bool $include): array */ public function run() { - $lintReporters = $this->initLintReporters(); - if ($lintReporters && $this->getFormat() === '') { + return $this + ->runPrepare() + ->runHeader() + ->runDoIt() + ->runProcessOutput() + ->runReturn(); + } + + /** + * @return $this + */ + protected function runPrepare() + { + $this->initLintReporters(); + if ($this->getLintReporters() && $this->getFormat() === '') { $this->setFormat('json'); } - $command = $this->getCommand(); + $this->command = $this->getCommand(); + + return $this; + } + + /** + * @return $this + */ + protected function runHeader() + { $this->printTaskInfo( 'TsLint task runs: {command} in directory "{workingDirectory}"', [ - 'command' => $command, + 'command' => $this->command, 'workingDirectory' => $this->workingDirectory ?: '.', ] ); + return $this; + } + + /** + * @return $this + */ + public function runDoIt() + { + $lintReporters = $this->getLintReporters(); if ($lintReporters && !$this->isOutputFormatMachineReadable()) { - $this->exitCode = static::EXIT_CODE_INVALID; + $this->lintExitCode = static::EXIT_CODE_INVALID; - return new Result($this, $this->exitCode, $this->getExitMessage($this->exitCode)); + return $this; } /** @var Process $process */ - $process = new $this->processClass($command); + $process = new $this->processClass($this->command); + // @todo Add the "mkdir -p 'foo' command to the ::getCommand()." $result = $this->prepareOutputDirectory(); if (!$result->wasSuccessful()) { - return $result; + $this->lintExitCode = static::EXIT_CODE_OUTPUT_DIR; + + return $this; } - $this->exitCode = $process->run(); + $this->lintExitCode = $process->run(); + $this->lintStdOutput = $process->getOutput(); + $this->lintStdError = $process->getErrorOutput(); + + return $this; + } - $numOfErrors = $this->exitCode; - $numOfWarnings = 0; + /** + * @return $this + */ + public function runProcessOutput() + { if ($this->isLintSuccess()) { - $originalOutput = $process->getOutput(); + $lintReporters = $this->getLintReporters(); if ($this->isOutputFormatMachineReadable()) { - $machineOutput = ($this->out ? file_get_contents($this->out) : $originalOutput); + $machineOutput = ($this->out ? file_get_contents($this->out) : $this->lintStdOutput); $reportWrapper = $this->decodeOutput($machineOutput); - $numOfErrors = $reportWrapper->numOfErrors(); - $numOfWarnings = $reportWrapper->numOfWarnings(); if ($this->isLintSuccess()) { $this->assets['report'] = $reportWrapper; @@ -673,16 +737,19 @@ public function run() } if (!$lintReporters) { - $this->output()->write($originalOutput); + $this->output()->write($this->lintStdOutput); } } - $exitCode = $this->getTaskExitCode($numOfErrors, $numOfWarnings); + return $this; + } + protected function runReturn(): Result + { return new Result( $this, - $exitCode, - $this->getExitMessage($exitCode) ?: $process->getErrorOutput(), + $this->getTaskExitCode(), + $this->getTaskExitMessage(), $this->getAssetsWithPrefixedNames() ); } @@ -768,14 +835,16 @@ protected function decodeOutput(string $output): ReportWrapperInterface } /** - * @return \Sweetchuck\LintReport\ReporterInterface[] + * @return $this */ - protected function initLintReporters(): array + protected function initLintReporters() { $lintReporters = []; $c = $this->getContainer(); foreach ($this->getLintReporters() as $id => $lintReporter) { if ($lintReporter === false) { + unset($this->lintReporters[$id]); + continue; } @@ -793,17 +862,25 @@ protected function initLintReporters(): array ->setDestination($this->output()); } } + + $this->lintReporters[$id] = $lintReporter; } - return $lintReporters; + return $this; } /** * Get the exit code regarding the failOn settings. */ - protected function getTaskExitCode(int $numOfErrors, int $numOfWarnings): int + protected function getTaskExitCode(): int { - if ($this->isLintSuccess()) { + /** @var \Sweetchuck\LintReport\ReportWrapperInterface $report */ + $report = $this->assets['report'] ?? null; + + if ($report) { + $numOfErrors = $report->numOfErrors(); + $numOfWarnings = $report->numOfWarnings(); + switch ($this->getFailOn()) { case 'never': return static::EXIT_CODE_OK; @@ -820,16 +897,12 @@ protected function getTaskExitCode(int $numOfErrors, int $numOfWarnings): int } } - return $this->exitCode; + return $this->lintExitCode; } - protected function getExitMessage(int $exitCode): ?string + protected function getTaskExitMessage(): string { - if (isset($this->exitMessages[$exitCode])) { - return $this->exitMessages[$exitCode]; - } - - return null; + return $this->taskExitMessages[$this->lintExitCode] ?? $this->lintStdError; } /** @@ -839,7 +912,7 @@ protected function getExitMessage(int $exitCode): ?string */ protected function isLintSuccess(): bool { - return in_array($this->exitCode, $this->lintSuccessExitCodes()); + return in_array($this->lintExitCode, $this->lintSuccessExitCodes()); } /** diff --git a/tests/unit/Task/TsLintRunTaskTest.php b/tests/unit/Task/TsLintRunTaskTest.php index 988c808..3cd1bc8 100644 --- a/tests/unit/Task/TsLintRunTaskTest.php +++ b/tests/unit/Task/TsLintRunTaskTest.php @@ -5,6 +5,7 @@ use Codeception\Test\Unit; use Codeception\Util\Stub; use Robo\Robo; +use Sweetchuck\Robo\TsLint\LintReportWrapper\ReportWrapper; use Sweetchuck\Robo\TsLint\Task\TsLintRunTask as RunTask; use \Sweetchuck\Codeception\Module\RoboTaskRunner\DummyOutput; use Sweetchuck\Robo\TsLint\Test\Helper\Dummy\DummyProcess; @@ -219,7 +220,8 @@ public function testExitCodeConstants(): void static::assertEquals(0, RunTask::EXIT_CODE_OK); static::assertEquals(1, RunTask::EXIT_CODE_WARNING); static::assertEquals(2, RunTask::EXIT_CODE_ERROR); - static::assertEquals(3, RunTask::EXIT_CODE_INVALID); + static::assertEquals(3, RunTask::EXIT_CODE_OUTPUT_DIR); + static::assertEquals(4, RunTask::EXIT_CODE_INVALID); } public function casesGetTaskExitCode(): array @@ -300,22 +302,41 @@ public function testGetTaskExitCode( string $failOn, int $numOfErrors, int $numOfWarnings, - int $exitCode + int $lintExitCode ): void { + $reportWrapper = null; + if ($lintExitCode < 3) { + $report = []; + foreach (['error' => $numOfErrors, 'warning' => $numOfWarnings] as $severity => $amount) { + for ($i = 0; $i < $amount; $i++) { + $report[] = [ + 'severity' => $severity, + 'name' => 'a.ts', + ]; + } + } + $reportWrapper = new ReportWrapper($report); + } + /** @var RunTask $runTask */ $runTask = Stub::construct( RunTask::class, [['failOn' => $failOn]], - ['exitCode' => $exitCode] + [ + 'lintExitCode' => $lintExitCode, + 'assets' => [ + 'report' => $reportWrapper, + ], + ] ); static::assertEquals( $expected, - static::getMethod('getTaskExitCode')->invokeArgs($runTask, [$numOfErrors, $numOfWarnings]) + static::getMethod('getTaskExitCode')->invokeArgs($runTask, []) ); } - public function casesRun(): array + public function casesRunSuccess(): array { $reportBase = []; @@ -391,6 +412,7 @@ public function casesRun(): array $c['c'], [ 'failOn' => $c['f'], + 'assetNamePrefix' => ($c['c'] === 0 ? 'foo' : ''), ], json_encode($report) ]; @@ -402,9 +424,9 @@ public function casesRun(): array /** * This way cannot be tested those cases when the lint process failed. * - * @dataProvider casesRun + * @dataProvider casesRunSuccess */ - public function testRun( + public function testRunSuccess( int $exitCode, array $options, string $expectedStdOutput @@ -437,6 +459,7 @@ public function testRun( DummyProcess::$prophecy[$processIndex] = [ 'exitCode' => $exitCode, 'stdOutput' => $expectedStdOutput, + 'stdError' => '', ]; $task->setLogger($container->get('logger')); @@ -499,6 +522,7 @@ public function testRunFailed(): void DummyProcess::$prophecy[$processIndex] = [ 'exitCode' => $exitCode, 'stdOutput' => $expectedReportJson, + 'stdError' => '', ]; $task->setConfig(Robo::config());