From 99c1bbc59822495626d4933398f3702ff9d9b856 Mon Sep 17 00:00:00 2001 From: jubianchi Date: Mon, 2 Oct 2017 23:58:27 +0200 Subject: [PATCH] feat: Add the dot report Closes #743 --- CHANGELOG.md | 1 + classes/cli/progressBar/dot.php | 70 ++++++++++ classes/report/fields/runner/event/cli/dot.php | 74 ++++++++++ classes/reports/realtime/cli/dot.php | 130 ++++++++++++++++++ classes/scripts/runner.php | 16 +++ tests/units/classes/cli/progressBar/dot.php | 183 +++++++++++++++++++++++++ tests/units/classes/scripts/coverage.php | 10 ++ tests/units/classes/scripts/runner.php | 10 ++ 8 files changed, 494 insertions(+) create mode 100644 classes/cli/progressBar/dot.php create mode 100644 classes/report/fields/runner/event/cli/dot.php create mode 100644 classes/reports/realtime/cli/dot.php create mode 100644 tests/units/classes/cli/progressBar/dot.php diff --git a/classes/cli/progressBar/dot.php b/classes/cli/progressBar/dot.php new file mode 100644 index 000000000..84914e1cf --- /dev/null +++ b/classes/cli/progressBar/dot.php @@ -0,0 +1,70 @@ +iterations = $iterations; + } + + public function reset() + { + $this->refresh = null; + $this->currentIteration = 0; + + return $this; + } + + public function setIterations($iterations) + { + $this->reset()->iterations = (int) $iterations; + + return $this; + } + + public function __toString() + { + $string = ''; + + if ($this->refresh !== '' && $this->currentIteration < $this->iterations) { + foreach ((array) $this->refresh as $char) { + $this->currentIteration++; + + $string .= $char; + + if ($this->currentIteration % self::width === 0) { + $string .= ' ' . self::formatCounter($this->iterations, $this->currentIteration) . PHP_EOL; + } + } + + if ($this->iterations > 0 && $this->currentIteration === $this->iterations && ($this->iterations % self::width) > 0) { + $string .= str_repeat(' ', round(self::width - ($this->iterations % self::width))) . ' ' . self::formatCounter($this->iterations, $this->currentIteration) . PHP_EOL; + } + + $this->refresh = ''; + } + + return $string; + } + + public function refresh($value) + { + $this->refresh .= $value; + + return $this; + } + + private static function formatCounter($iterations, $currentIteration) + { + return sprintf(sprintf(self::defaultCounterFormat, '%' . strlen($iterations) . 'd', '%d'), $currentIteration, $iterations); + } +} diff --git a/classes/report/fields/runner/event/cli/dot.php b/classes/report/fields/runner/event/cli/dot.php new file mode 100644 index 000000000..d3820c511 --- /dev/null +++ b/classes/report/fields/runner/event/cli/dot.php @@ -0,0 +1,74 @@ +progressBar = $progressBar ?: new progressBar\dot(); + } + + public function __toString() + { + $string = ''; + + if ($this->observable !== null) { + if ($this->event === runner::runStop) { + $string = PHP_EOL; + } else { + switch ($this->event) { + case runner::runStart: + $this->progressBar->reset()->setIterations($this->observable->getTestMethodNumber()); + break; + + case test::success: + $this->progressBar->refresh('.'); + break; + + case test::fail: + $this->progressBar->refresh('F'); + break; + + case test::void: + $this->progressBar->refresh('0'); + break; + + case test::error: + $this->progressBar->refresh('E'); + break; + + case test::exception: + $this->progressBar->refresh('X'); + break; + + case test::uncompleted: + $this->progressBar->refresh('U'); + break; + + case test::skipped: + $this->progressBar->refresh('-'); + break; + } + + $string = (string) $this->progressBar; + } + } + + return $string; + } + + public function getProgressBar() + { + return $this->progressBar; + } +} diff --git a/classes/reports/realtime/cli/dot.php b/classes/reports/realtime/cli/dot.php new file mode 100644 index 000000000..09d8590d6 --- /dev/null +++ b/classes/reports/realtime/cli/dot.php @@ -0,0 +1,130 @@ + '); + $secondLevelPrompt = new prompt('=> ', $firstLevelColorizer); + $thirdLevelPrompt = new prompt('==> ', $firstLevelColorizer); + + $this->addField(new runner\event\cli\dot()); + + $resultField = new runner\result\cli(); + $resultField + ->setSuccessColorizer(new colorizer('1;30', '42')) + ->setFailureColorizer(new colorizer('1;37', '41')) + ; + + $this->addField($resultField); + + $failureColorizer = new colorizer('0;31'); + $failurePrompt = clone $secondLevelPrompt; + $failurePrompt->setColorizer($failureColorizer); + + $failuresField = new runner\failures\cli(); + $failuresField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($firstLevelColorizer) + ->setMethodPrompt($secondLevelPrompt) + ; + + $this->addField($failuresField); + + $outputsField = new runner\outputs\cli(); + $outputsField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($firstLevelColorizer) + ->setMethodPrompt($secondLevelPrompt) + ; + + $this->addField($outputsField); + + $errorColorizer = new colorizer('0;33'); + $errorMethodPrompt = clone $secondLevelPrompt; + $errorMethodPrompt->setColorizer($errorColorizer); + $errorPrompt = clone $thirdLevelPrompt; + $errorPrompt->setColorizer($errorColorizer); + + $errorsField = new runner\errors\cli(); + $errorsField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($errorColorizer) + ->setMethodPrompt($errorMethodPrompt) + ->setErrorPrompt($errorPrompt) + ; + + $this->addField($errorsField); + + $exceptionColorizer = new colorizer('0;35'); + $exceptionMethodPrompt = clone $secondLevelPrompt; + $exceptionMethodPrompt->setColorizer($exceptionColorizer); + $exceptionPrompt = clone $thirdLevelPrompt; + $exceptionPrompt->setColorizer($exceptionColorizer); + + $exceptionsField = new runner\exceptions\cli(); + $exceptionsField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($exceptionColorizer) + ->setMethodPrompt($exceptionMethodPrompt) + ->setExceptionPrompt($exceptionPrompt) + ; + + $this->addField($exceptionsField); + + $uncompletedTestColorizer = new colorizer('0;37'); + $uncompletedTestMethodPrompt = clone $secondLevelPrompt; + $uncompletedTestMethodPrompt->setColorizer($uncompletedTestColorizer); + $uncompletedTestOutputPrompt = clone $thirdLevelPrompt; + $uncompletedTestOutputPrompt->setColorizer($uncompletedTestColorizer); + + $uncompletedTestField = new runner\tests\uncompleted\cli(); + $uncompletedTestField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($uncompletedTestColorizer) + ->setMethodPrompt($uncompletedTestMethodPrompt) + ->setOutputPrompt($uncompletedTestOutputPrompt) + ; + + $this->addField($uncompletedTestField); + + $voidTestColorizer = new colorizer('0;34'); + $voidTestMethodPrompt = clone $secondLevelPrompt; + $voidTestMethodPrompt->setColorizer($voidTestColorizer); + $voidTestOutputPrompt = clone $thirdLevelPrompt; + $voidTestOutputPrompt->setColorizer($voidTestColorizer); + + $voidTestField = new runner\tests\blank\cli(); + $voidTestField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($voidTestColorizer) + ->setMethodPrompt($voidTestMethodPrompt) + ; + + $this->addField($voidTestField); + + $skippedTestColorizer = new colorizer('0;90'); + $skippedTestMethodPrompt = clone $secondLevelPrompt; + $skippedTestMethodPrompt->setColorizer($skippedTestColorizer); + + $skippedTestField = new runner\tests\skipped\cli(); + $skippedTestField + ->setTitlePrompt($firstLevelPrompt) + ->setTitleColorizer($skippedTestColorizer) + ->setMethodPrompt($skippedTestMethodPrompt) + ; + + $this->addField($skippedTestField); + } +} diff --git a/classes/scripts/runner.php b/classes/scripts/runner.php index 72bdd5636..a60872cf9 100644 --- a/classes/scripts/runner.php +++ b/classes/scripts/runner.php @@ -1118,6 +1118,22 @@ function ($script, $argument, $values) { throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more information'), $argument, $script->getName())); } + $lightReport = new atoum\reports\realtime\cli\dot(); + $lightReport->addWriter($script->getOutputWriter()); + + $script->setReport($lightReport); + }, + ['-udr', '--use-dot-report'], + null, + $this->locale->_('Use "dot" CLI report'), + PHP_INT_MAX + ) + ->addArgumentHandler( + function ($script, $argument, $values) { + if (count($values) != 0) { + throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more information'), $argument, $script->getName())); + } + $tapReport = new atoum\reports\realtime\tap(); $tapReport->addWriter($script->getOutputWriter()); diff --git a/tests/units/classes/cli/progressBar/dot.php b/tests/units/classes/cli/progressBar/dot.php new file mode 100644 index 000000000..da0245509 --- /dev/null +++ b/tests/units/classes/cli/progressBar/dot.php @@ -0,0 +1,183 @@ +string(cli\progressBar::defaultCounterFormat)->isEqualTo('[%s/%s]') + ; + } + + public function test__construct() + { + $this + ->if($this->newTestedInstance) + ->then + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance(1)) + ->then + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance($count = rand(2, 9))) + ->then + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance($count = rand(10, 60))) + ->then + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance(61)) + ->then + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance($count = rand(100, PHP_INT_MAX))) + ->then + ->castToString($this->testedInstance)->isEmpty + ; + } + + public function testRefresh() + { + $this + ->if($this->newTestedInstance) + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance(1)) + ->then + ->castToString($this->testedInstance)->isEmpty() + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F' . str_repeat(' ', 59) . ' [1/1]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty + ->if($this->newTestedInstance(1)) + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F' . str_repeat(' ', 59) . ' [1/1]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEmpty() + ->if($this->newTestedInstance(60)) + ->then + ->castToString($this->testedInstance)->isEmpty() + ->if($this->testedInstance->refresh('F')) + ->then + ->castToString($this->testedInstance)->isEqualTo('F') + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 58; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F [60/60]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ; + + $this + ->if($this->newTestedInstance(61)) + ->then + ->castToString($this->testedInstance)->isEmpty() + ->if($this->testedInstance->refresh('F')) + ->then + ->castToString($this->testedInstance)->isEqualTo('F') + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 58; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F [60/61]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ->if($this->testedInstance->refresh('F')) + ->then + ->castToString($this->testedInstance)->isEqualTo('F' . str_repeat(' ', 59) . ' [61/61]' . PHP_EOL) + ->if($this->newTestedInstance(120)) + ->then + ->castToString($this->testedInstance)->isEmpty() + ->if($this->testedInstance->refresh('F')) + ->then + ->castToString($this->testedInstance)->isEqualTo('F') + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 58; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F [ 60/120]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 59; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F [120/120]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ->if($this->newTestedInstance(113)) + ->then + ->castToString($this->testedInstance)->isEmpty() + ->if($this->testedInstance->refresh('F')) + ->then + ->castToString($this->testedInstance)->isEqualTo('F') + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 58; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F [ 60/113]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ; + + for ($i = 0; $i < 52; $i++) { + $this + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F') + ; + } + + $this + ->then + ->object($this->testedInstance->refresh('F'))->isTestedInstance + ->castToString($this->testedInstance)->isEqualTo('F' . str_repeat(' ', 7) . ' [113/113]' . PHP_EOL) + ->castToString($this->testedInstance)->isEmpty() + ; + } +} diff --git a/tests/units/classes/scripts/coverage.php b/tests/units/classes/scripts/coverage.php index 70b232a61..e37311616 100644 --- a/tests/units/classes/scripts/coverage.php +++ b/tests/units/classes/scripts/coverage.php @@ -173,6 +173,11 @@ public function test__construct() 'Use "light" CLI report' ], [ + ['-udr', '--use-dot-report'], + null, + 'Use "dot" CLI report' + ], + [ ['-utr', '--use-tap-report'], null, 'Use TAP report' @@ -361,6 +366,11 @@ public function test__construct() 'Use "light" CLI report' ], [ + ['-udr', '--use-dot-report'], + null, + 'Use "dot" CLI report' + ], + [ ['-utr', '--use-tap-report'], null, 'Use TAP report' diff --git a/tests/units/classes/scripts/runner.php b/tests/units/classes/scripts/runner.php index d48ac5247..0e1b84b52 100644 --- a/tests/units/classes/scripts/runner.php +++ b/tests/units/classes/scripts/runner.php @@ -183,6 +183,11 @@ public function test__construct() 'Use "light" CLI report' ], [ + ['-udr', '--use-dot-report'], + null, + 'Use "dot" CLI report' + ], + [ ['-utr', '--use-tap-report'], null, 'Use TAP report' @@ -360,6 +365,11 @@ public function test__construct() 'Use "light" CLI report' ], [ + ['-udr', '--use-dot-report'], + null, + 'Use "dot" CLI report' + ], + [ ['-utr', '--use-tap-report'], null, 'Use TAP report'