@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Begin making Harbormaster unit test results a little easier to read

Summary: Ref T10457. These lack color and iconography and are difficult to parse. Make them easier to read.

Test Plan:
Before:

{F1135396}

After:

{F1135399}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10457

Differential Revision: https://secure.phabricator.com/D15362

+184 -84
+2
src/__phutil_library_map__.php
··· 1147 1147 'HarbormasterURIArtifact' => 'applications/harbormaster/artifact/HarbormasterURIArtifact.php', 1148 1148 'HarbormasterUnitMessagesController' => 'applications/harbormaster/controller/HarbormasterUnitMessagesController.php', 1149 1149 'HarbormasterUnitPropertyView' => 'applications/harbormaster/view/HarbormasterUnitPropertyView.php', 1150 + 'HarbormasterUnitStatus' => 'applications/harbormaster/constants/HarbormasterUnitStatus.php', 1150 1151 'HarbormasterUploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php', 1151 1152 'HarbormasterWaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php', 1152 1153 'HarbormasterWorker' => 'applications/harbormaster/worker/HarbormasterWorker.php', ··· 5314 5315 'HarbormasterURIArtifact' => 'HarbormasterArtifact', 5315 5316 'HarbormasterUnitMessagesController' => 'HarbormasterController', 5316 5317 'HarbormasterUnitPropertyView' => 'AphrontView', 5318 + 'HarbormasterUnitStatus' => 'Phobject', 5317 5319 'HarbormasterUploadArtifactBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 5318 5320 'HarbormasterWaitForPreviousBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 5319 5321 'HarbormasterWorker' => 'PhabricatorWorker',
+15 -51
src/applications/differential/customfield/DifferentialUnitField.php
··· 54 54 $this->getModernUnitMessageDictionary($message)); 55 55 } 56 56 57 - protected function newHarbormasterMessageView(array $messages) { 57 + protected function newHarbormasterMessageView(array $all_messages) { 58 + $messages = $all_messages; 59 + 58 60 foreach ($messages as $key => $message) { 59 61 switch ($message->getResult()) { 60 62 case ArcanistUnitTestResult::RESULT_PASS: ··· 71 73 return null; 72 74 } 73 75 74 - return id(new HarbormasterUnitPropertyView()) 75 - ->setLimit(10) 76 - ->setUnitMessages($messages); 76 + $table = id(new HarbormasterUnitPropertyView()) 77 + ->setLimit(5) 78 + ->setUnitMessages($all_messages); 79 + 80 + $diff = $this->getObject()->getActiveDiff(); 81 + $buildable = $diff->getBuildable(); 82 + if ($buildable) { 83 + $full_results = '/harbormaster/unit/'.$buildable->getID().'/'; 84 + $table->setFullResultsURI($full_results); 85 + } 86 + 87 + return $table; 77 88 } 78 89 79 90 public function getWarningsForDetailView() { ··· 111 122 $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff); 112 123 113 124 $note = array(); 114 - 115 - $groups = mgroup($messages, 'getResult'); 116 - 117 - $groups = array_select_keys( 118 - $groups, 119 - array( 120 - ArcanistUnitTestResult::RESULT_FAIL, 121 - ArcanistUnitTestResult::RESULT_BROKEN, 122 - ArcanistUnitTestResult::RESULT_UNSOUND, 123 - ArcanistUnitTestResult::RESULT_SKIP, 124 - ArcanistUnitTestResult::RESULT_PASS, 125 - )) + $groups; 126 - 127 - foreach ($groups as $result => $group) { 128 - $count = phutil_count($group); 129 - switch ($result) { 130 - case ArcanistUnitTestResult::RESULT_PASS: 131 - $note[] = pht('%s Passed Test(s)', $count); 132 - break; 133 - case ArcanistUnitTestResult::RESULT_FAIL: 134 - $note[] = pht('%s Failed Test(s)', $count); 135 - break; 136 - case ArcanistUnitTestResult::RESULT_SKIP: 137 - $note[] = pht('%s Skipped Test(s)', $count); 138 - break; 139 - case ArcanistUnitTestResult::RESULT_BROKEN: 140 - $note[] = pht('%s Broken Test(s)', $count); 141 - break; 142 - case ArcanistUnitTestResult::RESULT_UNSOUND: 143 - $note[] = pht('%s Unsound Test(s)', $count); 144 - break; 145 - default: 146 - $note[] = pht('%s Other Test(s)', $count); 147 - break; 148 - } 149 - } 150 - 151 - $buildable = $diff->getBuildable(); 152 - if ($buildable) { 153 - $full_results = '/harbormaster/unit/'.$buildable->getID().'/'; 154 - $note[] = phutil_tag( 155 - 'a', 156 - array( 157 - 'href' => $full_results, 158 - ), 159 - pht('View Full Results')); 160 - } 161 125 162 126 $excuse = $diff->getProperty('arc:unit-excuse'); 163 127 if (strlen($excuse)) {
+89
src/applications/harbormaster/constants/HarbormasterUnitStatus.php
··· 1 + <?php 2 + 3 + final class HarbormasterUnitStatus 4 + extends Phobject { 5 + 6 + public static function getUnitStatusIcon($status) { 7 + $map = self::getUnitStatusDictionary($status); 8 + $default = 'fa-question-circle'; 9 + return idx($map, 'icon', $default); 10 + } 11 + 12 + public static function getUnitStatusColor($status) { 13 + $map = self::getUnitStatusDictionary($status); 14 + $default = 'violet'; 15 + return idx($map, 'color', $default); 16 + } 17 + 18 + public static function getUnitStatusLabel($status) { 19 + $map = self::getUnitStatusDictionary($status); 20 + $default = pht('Unknown Status ("%s")', $status); 21 + return idx($map, 'label', $default); 22 + } 23 + 24 + public static function getUnitStatusSort($status) { 25 + $map = self::getUnitStatusDictionary($status); 26 + $default = 'N'; 27 + return idx($map, 'sort', $default); 28 + } 29 + 30 + private static function getUnitStatusDictionary($status) { 31 + $map = self::getUnitStatusMap(); 32 + $default = array(); 33 + return idx($map, $status, $default); 34 + } 35 + 36 + public static function getUnitStatusCountLabel($status, $count) { 37 + $count = new PhutilNumber($count); 38 + 39 + switch ($status) { 40 + case ArcanistUnitTestResult::RESULT_FAIL: 41 + return pht('%s Failed Test(s)', $count); 42 + case ArcanistUnitTestResult::RESULT_BROKEN: 43 + return pht('%s Broken Test(s)', $count); 44 + case ArcanistUnitTestResult::RESULT_UNSOUND: 45 + return pht('%s Unsound Test(s)', $count); 46 + case ArcanistUnitTestResult::RESULT_SKIP: 47 + return pht('%s Skipped Test(s)', $count); 48 + case ArcanistUnitTestResult::RESULT_PASS: 49 + return pht('%s Passed Test(s)', $count); 50 + } 51 + 52 + return pht('%s Other Test(s)', $count); 53 + } 54 + 55 + private static function getUnitStatusMap() { 56 + return array( 57 + ArcanistUnitTestResult::RESULT_FAIL => array( 58 + 'label' => pht('Failed'), 59 + 'icon' => 'fa-times', 60 + 'color' => 'red', 61 + 'sort' => 'A', 62 + ), 63 + ArcanistUnitTestResult::RESULT_BROKEN => array( 64 + 'label' => pht('Broken'), 65 + 'icon' => 'fa-bomb', 66 + 'color' => 'indigo', 67 + 'sort' => 'B', 68 + ), 69 + ArcanistUnitTestResult::RESULT_UNSOUND => array( 70 + 'label' => pht('Unsound'), 71 + 'icon' => 'fa-exclamation-triangle', 72 + 'color' => 'yellow', 73 + 'sort' => 'C', 74 + ), 75 + ArcanistUnitTestResult::RESULT_SKIP => array( 76 + 'label' => pht('Skipped'), 77 + 'icon' => 'fa-fast-forward', 78 + 'color' => 'blue', 79 + ), 80 + ArcanistUnitTestResult::RESULT_PASS => array( 81 + 'label' => pht('Passed'), 82 + 'icon' => 'fa-check', 83 + 'color' => 'green', 84 + 'sort' => 'Z', 85 + ), 86 + ); 87 + } 88 + 89 + }
+20 -3
src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
··· 336 336 } 337 337 338 338 if ($unit_data) { 339 + $unit_href = $this->getApplicationURI('unit/'.$buildable->getID().'/'); 340 + 339 341 $unit_table = id(new HarbormasterUnitPropertyView()) 340 342 ->setUser($viewer) 341 - ->setLimit(25) 342 - ->setUnitMessages($unit_data); 343 + ->setLimit(5) 344 + ->setUnitMessages($unit_data) 345 + ->setFullResultsURI($unit_href); 346 + 347 + $unit_data = msort($unit_data, 'getSortKey'); 348 + $head_unit = head($unit_data); 349 + if ($head_unit) { 350 + $status = $head_unit->getResult(); 351 + 352 + $tag_text = HarbormasterUnitStatus::getUnitStatusLabel($status); 353 + $tag_color = HarbormasterUnitStatus::getUnitStatusColor($status); 354 + $tag_icon = HarbormasterUnitStatus::getUnitStatusIcon($status); 343 355 344 - $unit_href = $this->getApplicationURI('unit/'.$buildable->getID().'/'); 356 + } else { 357 + $tag_text = pht('No Unit Tests'); 358 + $tag_color = 'grey'; 359 + $tag_icon = 'fa-ban'; 360 + } 345 361 346 362 $unit_header = id(new PHUIHeaderView()) 347 363 ->setHeader(pht('Unit Tests')) 364 + ->setStatus($tag_icon, $tag_color, $tag_text) 348 365 ->addActionLink( 349 366 id(new PHUIButtonView()) 350 367 ->setTag('a')
+3 -10
src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php
··· 136 136 } 137 137 138 138 public function getSortKey() { 139 - // TODO: Maybe use more numeric values after T6861. 140 - $map = array( 141 - ArcanistUnitTestResult::RESULT_FAIL => 'A', 142 - ArcanistUnitTestResult::RESULT_BROKEN => 'B', 143 - ArcanistUnitTestResult::RESULT_UNSOUND => 'C', 144 - ArcanistUnitTestResult::RESULT_PASS => 'Z', 145 - ); 146 - 147 - $result = idx($map, $this->getResult(), 'N'); 139 + $status = $this->getResult(); 140 + $sort = HarbormasterUnitStatus::getUnitStatusSort($status); 148 141 149 142 $parts = array( 150 - $result, 143 + $sort, 151 144 $this->getEngine(), 152 145 $this->getNamespace(), 153 146 $this->getName(),
+55 -20
src/applications/harbormaster/view/HarbormasterUnitPropertyView.php
··· 5 5 private $pathURIMap = array(); 6 6 private $unitMessages = array(); 7 7 private $limit; 8 + private $fullResultsURI; 8 9 9 10 public function setPathURIMap(array $map) { 10 11 $this->pathURIMap = $map; ··· 22 23 return $this; 23 24 } 24 25 26 + public function setFullResultsURI($full_results_uri) { 27 + $this->fullResultsURI = $full_results_uri; 28 + return $this; 29 + } 30 + 25 31 public function render() { 26 32 $messages = $this->unitMessages; 27 33 $messages = msort($messages, 'getSortKey'); 28 34 35 + $limit = $this->limit; 36 + 29 37 if ($this->limit) { 30 - $messages = array_slice($messages, 0, $this->limit); 38 + $display_messages = array_slice($messages, 0, $limit); 39 + } else { 40 + $display_messages = $messages; 31 41 } 32 42 33 43 $rows = array(); 34 44 $any_duration = false; 35 - foreach ($messages as $message) { 36 - $result = $this->renderResult($message->getResult()); 45 + foreach ($display_messages as $message) { 46 + $status = $message->getResult(); 47 + 48 + $icon_icon = HarbormasterUnitStatus::getUnitStatusIcon($status); 49 + $icon_color = HarbormasterUnitStatus::getUnitStatusColor($status); 50 + $icon_label = HarbormasterUnitStatus::getUnitStatusLabel($status); 51 + 52 + $result_icon = id(new PHUIIconView()) 53 + ->setIcon("{$icon_icon} {$icon_color}") 54 + ->addSigil('has-tooltip') 55 + ->setMetadata( 56 + array( 57 + 'tip' => $icon_label, 58 + )); 37 59 38 60 $duration = $message->getDuration(); 39 61 if ($duration !== null) { ··· 54 76 } 55 77 56 78 $rows[] = array( 57 - $result, 79 + $result_icon, 58 80 $duration, 59 81 $name, 60 82 ); 61 83 } 62 84 85 + $full_uri = $this->fullResultsURI; 86 + if ($full_uri && (count($messages) > $limit)) { 87 + $counts = array(); 88 + 89 + $groups = mgroup($messages, 'getResult'); 90 + foreach ($groups as $status => $group) { 91 + $counts[] = HarbormasterUnitStatus::getUnitStatusCountLabel( 92 + $status, 93 + count($group)); 94 + } 95 + 96 + $link_text = pht( 97 + 'View Full Test Results (%s)', 98 + implode(" \xC2\xB7 ", $counts)); 99 + 100 + $full_link = phutil_tag( 101 + 'a', 102 + array( 103 + 'href' => $full_uri, 104 + ), 105 + $link_text); 106 + 107 + $link_icon = id(new PHUIIconView()) 108 + ->setIcon('fa-ellipsis-h lightgreytext'); 109 + 110 + $rows[] = array($link_icon, null, $full_link); 111 + } 112 + 63 113 $table = id(new AphrontTableView($rows)) 64 114 ->setHeaders( 65 115 array( 66 - pht('Result'), 116 + null, 67 117 pht('Time'), 68 118 pht('Test'), 69 119 )) ··· 80 130 )); 81 131 82 132 return $table; 83 - } 84 - 85 - private function renderResult($result) { 86 - $names = array( 87 - ArcanistUnitTestResult::RESULT_BROKEN => pht('Broken'), 88 - ArcanistUnitTestResult::RESULT_FAIL => pht('Failed'), 89 - ArcanistUnitTestResult::RESULT_UNSOUND => pht('Unsound'), 90 - ArcanistUnitTestResult::RESULT_SKIP => pht('Skipped'), 91 - ArcanistUnitTestResult::RESULT_PASS => pht('Passed'), 92 - ); 93 - $result = idx($names, $result, $result); 94 - 95 - // TODO: Add some color. 96 - 97 - return $result; 98 133 } 99 134 100 135 }