diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -498,6 +498,7 @@ 'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php', 'ArcanistSubversionWorkingCopy' => 'workingcopy/ArcanistSubversionWorkingCopy.php', 'ArcanistSummaryLintRenderer' => 'lint/renderer/ArcanistSummaryLintRenderer.php', + 'ArcanistSummaryUnitRenderer' => 'unit/renderer/ArcanistSummaryUnitRenderer.php', 'ArcanistSymbolEngine' => 'ref/symbol/ArcanistSymbolEngine.php', 'ArcanistSymbolRef' => 'ref/symbol/ArcanistSymbolRef.php', 'ArcanistSyntaxErrorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSyntaxErrorXHPASTLinterRule.php', @@ -1556,6 +1557,7 @@ 'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI', 'ArcanistSubversionWorkingCopy' => 'ArcanistWorkingCopy', 'ArcanistSummaryLintRenderer' => 'ArcanistLintRenderer', + 'ArcanistSummaryUnitRenderer' => 'ArcanistUnitRenderer', 'ArcanistSymbolEngine' => 'Phobject', 'ArcanistSymbolRef' => 'ArcanistRef', 'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', diff --git a/src/unit/renderer/ArcanistSummaryUnitRenderer.php b/src/unit/renderer/ArcanistSummaryUnitRenderer.php new file mode 100644 --- /dev/null +++ b/src/unit/renderer/ArcanistSummaryUnitRenderer.php @@ -0,0 +1,22 @@ + true, + ArcanistUnitTestResult::RESULT_BROKEN => true, + ); + + public function setProxyRenderer(ArcanistUnitRenderer $renderer) { + $this->renderer = $renderer; + return $this; + } + + public function renderUnitResult(ArcanistUnitTestResult $result) { + if (idx($this->statusesToShow, $result->getResult(), false)) { + return $this->renderer->renderUnitResult($result); + } + return null; + } +} diff --git a/src/workflow/ArcanistUnitWorkflow.php b/src/workflow/ArcanistUnitWorkflow.php --- a/src/workflow/ArcanistUnitWorkflow.php +++ b/src/workflow/ArcanistUnitWorkflow.php @@ -75,7 +75,8 @@ 'output' => array( 'param' => 'format', 'help' => pht( - "With 'full', show full pretty report (Default). ". + "With 'summary', show a summary report (Default). ". + "With 'full', show full pretty report. ". "With 'json', report results in JSON format. ". "With 'ugly', use uglier (but more efficient) JSON formatting. ". "With 'none', don't print results."), @@ -155,7 +156,13 @@ $this->engine->setPaths($paths); } + $output_format = $this->getOutputFormat(); + $renderer = new ArcanistUnitConsoleRenderer(); + if ($output_format === 'summary') { + $renderer = id(new ArcanistSummaryUnitRenderer()) + ->setProxyRenderer($renderer); + } $this->engine->setRenderer($renderer); $enable_coverage = null; // Means "default". @@ -175,16 +182,34 @@ $console = PhutilConsole::getConsole(); - $output_format = $this->getOutputFormat(); - - if ($output_format !== 'full') { - $console->disableOut(); + $console_disabled = false; + switch ($output_format) { + case 'ugly': + case 'json': + case 'none': + $console->disableOut(); + $console_disabled = true; + break; + case 'full': + case 'summary': + break; } $unresolved = array(); $coverage = array(); + $summary = array( + ArcanistUnitTestResult::RESULT_PASS => 0, + ArcanistUnitTestResult::RESULT_FAIL => 0, + ArcanistUnitTestResult::RESULT_BROKEN => 0, + ArcanistUnitTestResult::RESULT_SKIP => 0, + ArcanistUnitTestResult::RESULT_UNSOUND => 0, + 'total_count' => 0, + ); foreach ($results as $result) { $result_code = $result->getResult(); + $summary[$result_code] += 1; + $summary['total_count'] += 1; + if ($this->engine->shouldEchoTestResults()) { $console->writeOut('%s', $renderer->renderUnitResult($result)); } @@ -198,6 +223,8 @@ } } + $console->writeOut($this->renderTestSummary($summary)); + if ($coverage) { $file_coverage = array_fill_keys( $paths, @@ -252,9 +279,10 @@ } } - if ($output_format !== 'full') { + if ($console_disabled) { $console->enableOut(); } + $data = array_values(mpull($results, 'toDictionary')); switch ($output_format) { case 'ugly': @@ -330,6 +358,24 @@ return $out; } + private function renderTestSummary($summary) { + return pht( + 'Test results: '. + '%d tests passed, '. + '%d tests failed, '. + '%d tests broken, '. + '%d tests unsound, '. + '%d tests skipped. '. + 'Total: %d tests.'. + "\n", + idx($summary, ArcanistUnitTestResult::RESULT_PASS), + idx($summary, ArcanistUnitTestResult::RESULT_FAIL), + idx($summary, ArcanistUnitTestResult::RESULT_BROKEN), + idx($summary, ArcanistUnitTestResult::RESULT_UNSOUND), + idx($summary, ArcanistUnitTestResult::RESULT_SKIP), + idx($summary, 'total_count')); + } + private function getOutputFormat() { if ($this->getArgument('ugly')) { return 'ugly'; @@ -342,9 +388,10 @@ 'none' => 'none', 'json' => 'json', 'ugly' => 'ugly', + 'summary' => 'summary', 'full' => 'full', ); - return idx($known_formats, $format, 'full'); + return idx($known_formats, $format, 'summary'); }