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 @@ -1147,6 +1147,7 @@ 'HarbormasterURIArtifact' => 'applications/harbormaster/artifact/HarbormasterURIArtifact.php', 'HarbormasterUnitMessagesController' => 'applications/harbormaster/controller/HarbormasterUnitMessagesController.php', 'HarbormasterUnitPropertyView' => 'applications/harbormaster/view/HarbormasterUnitPropertyView.php', + 'HarbormasterUnitStatus' => 'applications/harbormaster/constants/HarbormasterUnitStatus.php', 'HarbormasterUploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php', 'HarbormasterWaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php', 'HarbormasterWorker' => 'applications/harbormaster/worker/HarbormasterWorker.php', @@ -5314,6 +5315,7 @@ 'HarbormasterURIArtifact' => 'HarbormasterArtifact', 'HarbormasterUnitMessagesController' => 'HarbormasterController', 'HarbormasterUnitPropertyView' => 'AphrontView', + 'HarbormasterUnitStatus' => 'Phobject', 'HarbormasterUploadArtifactBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 'HarbormasterWaitForPreviousBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 'HarbormasterWorker' => 'PhabricatorWorker', diff --git a/src/applications/differential/customfield/DifferentialUnitField.php b/src/applications/differential/customfield/DifferentialUnitField.php --- a/src/applications/differential/customfield/DifferentialUnitField.php +++ b/src/applications/differential/customfield/DifferentialUnitField.php @@ -54,7 +54,9 @@ $this->getModernUnitMessageDictionary($message)); } - protected function newHarbormasterMessageView(array $messages) { + protected function newHarbormasterMessageView(array $all_messages) { + $messages = $all_messages; + foreach ($messages as $key => $message) { switch ($message->getResult()) { case ArcanistUnitTestResult::RESULT_PASS: @@ -71,9 +73,18 @@ return null; } - return id(new HarbormasterUnitPropertyView()) - ->setLimit(10) - ->setUnitMessages($messages); + $table = id(new HarbormasterUnitPropertyView()) + ->setLimit(5) + ->setUnitMessages($all_messages); + + $diff = $this->getObject()->getActiveDiff(); + $buildable = $diff->getBuildable(); + if ($buildable) { + $full_results = '/harbormaster/unit/'.$buildable->getID().'/'; + $table->setFullResultsURI($full_results); + } + + return $table; } public function getWarningsForDetailView() { @@ -112,53 +123,6 @@ $note = array(); - $groups = mgroup($messages, 'getResult'); - - $groups = array_select_keys( - $groups, - array( - ArcanistUnitTestResult::RESULT_FAIL, - ArcanistUnitTestResult::RESULT_BROKEN, - ArcanistUnitTestResult::RESULT_UNSOUND, - ArcanistUnitTestResult::RESULT_SKIP, - ArcanistUnitTestResult::RESULT_PASS, - )) + $groups; - - foreach ($groups as $result => $group) { - $count = phutil_count($group); - switch ($result) { - case ArcanistUnitTestResult::RESULT_PASS: - $note[] = pht('%s Passed Test(s)', $count); - break; - case ArcanistUnitTestResult::RESULT_FAIL: - $note[] = pht('%s Failed Test(s)', $count); - break; - case ArcanistUnitTestResult::RESULT_SKIP: - $note[] = pht('%s Skipped Test(s)', $count); - break; - case ArcanistUnitTestResult::RESULT_BROKEN: - $note[] = pht('%s Broken Test(s)', $count); - break; - case ArcanistUnitTestResult::RESULT_UNSOUND: - $note[] = pht('%s Unsound Test(s)', $count); - break; - default: - $note[] = pht('%s Other Test(s)', $count); - break; - } - } - - $buildable = $diff->getBuildable(); - if ($buildable) { - $full_results = '/harbormaster/unit/'.$buildable->getID().'/'; - $note[] = phutil_tag( - 'a', - array( - 'href' => $full_results, - ), - pht('View Full Results')); - } - $excuse = $diff->getProperty('arc:unit-excuse'); if (strlen($excuse)) { $excuse = array( diff --git a/src/applications/harbormaster/constants/HarbormasterUnitStatus.php b/src/applications/harbormaster/constants/HarbormasterUnitStatus.php new file mode 100644 --- /dev/null +++ b/src/applications/harbormaster/constants/HarbormasterUnitStatus.php @@ -0,0 +1,89 @@ + array( + 'label' => pht('Failed'), + 'icon' => 'fa-times', + 'color' => 'red', + 'sort' => 'A', + ), + ArcanistUnitTestResult::RESULT_BROKEN => array( + 'label' => pht('Broken'), + 'icon' => 'fa-bomb', + 'color' => 'indigo', + 'sort' => 'B', + ), + ArcanistUnitTestResult::RESULT_UNSOUND => array( + 'label' => pht('Unsound'), + 'icon' => 'fa-exclamation-triangle', + 'color' => 'yellow', + 'sort' => 'C', + ), + ArcanistUnitTestResult::RESULT_SKIP => array( + 'label' => pht('Skipped'), + 'icon' => 'fa-fast-forward', + 'color' => 'blue', + ), + ArcanistUnitTestResult::RESULT_PASS => array( + 'label' => pht('Passed'), + 'icon' => 'fa-check', + 'color' => 'green', + 'sort' => 'Z', + ), + ); + } + +} diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php --- a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php @@ -336,15 +336,32 @@ } if ($unit_data) { + $unit_href = $this->getApplicationURI('unit/'.$buildable->getID().'/'); + $unit_table = id(new HarbormasterUnitPropertyView()) ->setUser($viewer) - ->setLimit(25) - ->setUnitMessages($unit_data); + ->setLimit(5) + ->setUnitMessages($unit_data) + ->setFullResultsURI($unit_href); - $unit_href = $this->getApplicationURI('unit/'.$buildable->getID().'/'); + $unit_data = msort($unit_data, 'getSortKey'); + $head_unit = head($unit_data); + if ($head_unit) { + $status = $head_unit->getResult(); + + $tag_text = HarbormasterUnitStatus::getUnitStatusLabel($status); + $tag_color = HarbormasterUnitStatus::getUnitStatusColor($status); + $tag_icon = HarbormasterUnitStatus::getUnitStatusIcon($status); + + } else { + $tag_text = pht('No Unit Tests'); + $tag_color = 'grey'; + $tag_icon = 'fa-ban'; + } $unit_header = id(new PHUIHeaderView()) ->setHeader(pht('Unit Tests')) + ->setStatus($tag_icon, $tag_color, $tag_text) ->addActionLink( id(new PHUIButtonView()) ->setTag('a') diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php b/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php --- a/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php +++ b/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php @@ -136,18 +136,11 @@ } public function getSortKey() { - // TODO: Maybe use more numeric values after T6861. - $map = array( - ArcanistUnitTestResult::RESULT_FAIL => 'A', - ArcanistUnitTestResult::RESULT_BROKEN => 'B', - ArcanistUnitTestResult::RESULT_UNSOUND => 'C', - ArcanistUnitTestResult::RESULT_PASS => 'Z', - ); - - $result = idx($map, $this->getResult(), 'N'); + $status = $this->getResult(); + $sort = HarbormasterUnitStatus::getUnitStatusSort($status); $parts = array( - $result, + $sort, $this->getEngine(), $this->getNamespace(), $this->getName(), diff --git a/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php b/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php --- a/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php +++ b/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php @@ -5,6 +5,7 @@ private $pathURIMap = array(); private $unitMessages = array(); private $limit; + private $fullResultsURI; public function setPathURIMap(array $map) { $this->pathURIMap = $map; @@ -22,18 +23,39 @@ return $this; } + public function setFullResultsURI($full_results_uri) { + $this->fullResultsURI = $full_results_uri; + return $this; + } + public function render() { $messages = $this->unitMessages; $messages = msort($messages, 'getSortKey'); + $limit = $this->limit; + if ($this->limit) { - $messages = array_slice($messages, 0, $this->limit); + $display_messages = array_slice($messages, 0, $limit); + } else { + $display_messages = $messages; } $rows = array(); $any_duration = false; - foreach ($messages as $message) { - $result = $this->renderResult($message->getResult()); + foreach ($display_messages as $message) { + $status = $message->getResult(); + + $icon_icon = HarbormasterUnitStatus::getUnitStatusIcon($status); + $icon_color = HarbormasterUnitStatus::getUnitStatusColor($status); + $icon_label = HarbormasterUnitStatus::getUnitStatusLabel($status); + + $result_icon = id(new PHUIIconView()) + ->setIcon("{$icon_icon} {$icon_color}") + ->addSigil('has-tooltip') + ->setMetadata( + array( + 'tip' => $icon_label, + )); $duration = $message->getDuration(); if ($duration !== null) { @@ -54,16 +76,44 @@ } $rows[] = array( - $result, + $result_icon, $duration, $name, ); } + $full_uri = $this->fullResultsURI; + if ($full_uri && (count($messages) > $limit)) { + $counts = array(); + + $groups = mgroup($messages, 'getResult'); + foreach ($groups as $status => $group) { + $counts[] = HarbormasterUnitStatus::getUnitStatusCountLabel( + $status, + count($group)); + } + + $link_text = pht( + 'View Full Test Results (%s)', + implode(" \xC2\xB7 ", $counts)); + + $full_link = phutil_tag( + 'a', + array( + 'href' => $full_uri, + ), + $link_text); + + $link_icon = id(new PHUIIconView()) + ->setIcon('fa-ellipsis-h lightgreytext'); + + $rows[] = array($link_icon, null, $full_link); + } + $table = id(new AphrontTableView($rows)) ->setHeaders( array( - pht('Result'), + null, pht('Time'), pht('Test'), )) @@ -82,19 +132,4 @@ return $table; } - private function renderResult($result) { - $names = array( - ArcanistUnitTestResult::RESULT_BROKEN => pht('Broken'), - ArcanistUnitTestResult::RESULT_FAIL => pht('Failed'), - ArcanistUnitTestResult::RESULT_UNSOUND => pht('Unsound'), - ArcanistUnitTestResult::RESULT_SKIP => pht('Skipped'), - ArcanistUnitTestResult::RESULT_PASS => pht('Passed'), - ); - $result = idx($names, $result, $result); - - // TODO: Add some color. - - return $result; - } - }