1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 05:50:55 +01:00

Restore coverage reporting to Diffusion browse UI

Summary:
Depends on D19377. Ref T13125. Ref T13124. Ref T13105. Coverage reporting in Diffusion didn't initially survive the transition to Document Engine; restore it.

This adds some tentative/theoretical support for multiple columns of coverage, but no way to actually produce them in the UI. For now, the labels, codes, and colors are hard coded.

Test Plan:
Added coverage with `diffusion.updatecoverage`, saw coverage in the UI:

{F5525542}

Hovered over coverage, got labels and highlighting.

Double-checked labels for "N" (Not Executable) and "U" (Uncovered). See PHI577.

Faked some multi-column coverage, but you can't currently get this yourself today:

{F5525544}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13125, T13124, T13105

Differential Revision: https://secure.phabricator.com/D19378
This commit is contained in:
epriestley 2018-04-17 06:40:41 -07:00
parent 21bb0215db
commit 665529ab60
10 changed files with 159 additions and 15 deletions

View file

@ -119,7 +119,7 @@ return array(
'rsrc/css/font/font-lato.css' => 'c7ccd872',
'rsrc/css/font/phui-font-icon-base.css' => '870a7360',
'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97',
'rsrc/css/layout/phabricator-source-code-view.css' => '09368218',
'rsrc/css/layout/phabricator-source-code-view.css' => 'fdbefca0',
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
'rsrc/css/phui/button/phui-button.css' => '1863cc6e',
@ -388,7 +388,7 @@ return array(
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc',
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '1db13e70',
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
'rsrc/js/application/files/behavior-document-engine.js' => '0333c0b6',
'rsrc/js/application/files/behavior-document-engine.js' => 'ee0deff8',
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909',
@ -600,7 +600,7 @@ return array(
'javelin-behavior-diffusion-commit-graph' => '75b83cbb',
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc',
'javelin-behavior-document-engine' => '0333c0b6',
'javelin-behavior-document-engine' => 'ee0deff8',
'javelin-behavior-doorkeeper-tag' => '1db13e70',
'javelin-behavior-drydock-live-operation-status' => '901935ef',
'javelin-behavior-durable-column' => '2ae077e1',
@ -776,7 +776,7 @@ return array(
'phabricator-search-results-css' => '505dd8cf',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => '09368218',
'phabricator-source-code-view-css' => 'fdbefca0',
'phabricator-standard-page-view' => '34ee718b',
'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c',
@ -905,11 +905,6 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'0333c0b6' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
),
'040fce04' => array(
'javelin-behavior',
'javelin-request',
@ -2110,6 +2105,11 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'ee0deff8' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
),
'efe49472' => array(
'javelin-install',
'javelin-util',

View file

@ -4,7 +4,6 @@ final class DiffusionBrowseController extends DiffusionController {
private $lintCommit;
private $lintMessages;
private $coverage;
private $corpusButtons = array();
public function shouldAllowPublic() {
@ -182,7 +181,6 @@ final class DiffusionBrowseController extends DiffusionController {
$corpus = $this->buildGitLFSCorpus($lfs_ref);
} else {
$this->coverage = $drequest->loadCoverage();
$show_editor = true;
$ref = id(new PhabricatorDocumentRef())

View file

@ -81,6 +81,11 @@ final class DiffusionDocumentRenderingEngine
$ref
->setSymbolMetadata($this->getSymbolMetadata())
->setBlameURI($blame_uri);
$coverage = $drequest->loadCoverage();
if (strlen($coverage)) {
$ref->addCoverage($coverage);
}
}
private function getSymbolMetadata() {

View file

@ -10,6 +10,7 @@ final class PhabricatorDocumentRef
private $snippet;
private $symbolMetadata = array();
private $blameURI;
private $coverage = array();
public function setFile(PhabricatorFile $file) {
$this->file = $file;
@ -151,4 +152,15 @@ final class PhabricatorDocumentRef
return $this->blameURI;
}
public function addCoverage($coverage) {
$this->coverage[] = array(
'data' => $coverage,
);
return $this;
}
public function getCoverage() {
return $this->coverage;
}
}

View file

@ -57,6 +57,10 @@ final class PhabricatorSourceDocumentEngine
$options['blame'] = $blame;
}
if ($ref->getCoverage()) {
$options['coverage'] = $ref->getCoverage();
}
return array(
$messages,
$this->newTextDocumentContent($ref, $content, $options),

View file

@ -22,6 +22,7 @@ abstract class PhabricatorTextDocumentEngine
$options,
array(
'blame' => 'optional wild',
'coverage' => 'optional list<wild>',
));
if (is_array($content)) {
@ -40,6 +41,11 @@ abstract class PhabricatorTextDocumentEngine
$view->setBlameMap($blame);
}
$coverage = idx($options, 'coverage');
if ($coverage !== null) {
$view->setCoverage($coverage);
}
$message = null;
if ($this->encodingMessage !== null) {
$message = $this->newMessage($this->encodingMessage);

View file

@ -145,6 +145,17 @@ abstract class PhabricatorDocumentRenderingEngine
'uri' => $ref->getBlameURI(),
'value' => null,
),
'coverage' => array(
'labels' => array(
// TODO: Modularize this properly, see T13125.
array(
'C' => pht('Covered'),
'U' => pht('Not Covered'),
'N' => pht('Not Executable'),
'X' => pht('Not Reachable'),
),
),
),
);
$view_button = id(new PHUIButtonView())

View file

@ -10,6 +10,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
private $truncatedFirstLines = false;
private $symbolMetadata;
private $blameMap;
private $coverage = array();
public function setLines(array $lines) {
$this->lines = $lines;
@ -59,6 +60,15 @@ final class PhabricatorSourceCodeView extends AphrontView {
return $this->blameMap;
}
public function setCoverage(array $coverage) {
$this->coverage = $coverage;
return $this;
}
public function getCoverage() {
return $this->coverage;
}
public function render() {
$blame_map = $this->getBlameMap();
$has_blame = ($blame_map !== null);
@ -97,6 +107,19 @@ final class PhabricatorSourceCodeView extends AphrontView {
$base_uri = (string)$this->uri;
$wrote_anchor = false;
$coverage = $this->getCoverage();
$coverage_count = count($coverage);
$coverage_data = ipull($coverage, 'data');
// TODO: Modularize this properly, see T13125.
$coverage_map = array(
'C' => 'background: #66bbff;',
'U' => 'background: #dd8866;',
'N' => 'background: #ddeeff;',
'X' => 'background: #aa00aa;',
);
foreach ($lines as $line) {
$row_attributes = array();
if (isset($this->highlights[$line_number])) {
@ -157,6 +180,25 @@ final class PhabricatorSourceCodeView extends AphrontView {
$blame_cells = null;
}
$coverage_cells = array();
foreach ($coverage as $coverage_idx => $coverage_spec) {
if (isset($coverage_spec['data'][$line_number - 1])) {
$coverage_char = $coverage_spec['data'][$line_number - 1];
} else {
$coverage_char = null;
}
$coverage_style = idx($coverage_map, $coverage_char, null);
$coverage_cells[] = phutil_tag(
'th',
array(
'class' => 'phabricator-source-coverage',
'style' => $coverage_style,
'data-coverage' => $coverage_idx.'/'.$coverage_char,
));
}
$rows[] = phutil_tag(
'tr',
$row_attributes,
@ -174,6 +216,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
'class' => 'phabricator-source-code',
),
$line),
$coverage_cells,
));
$line_number++;

View file

@ -6,7 +6,6 @@
overflow-x: auto;
overflow-y: hidden;
border: 1px solid {$paste.border};
border-radius: 3px;
}
.phui-oi .phabricator-source-code-container {
@ -47,10 +46,12 @@ th.phabricator-source-line a:hover {
text-decoration: none;
}
.phabricator-source-coverage-highlight .phabricator-source-code,
.phabricator-source-highlight .phabricator-source-code {
background: {$paste.highlight};
}
.phabricator-source-coverage-highlight .phabricator-source-line,
.phabricator-source-highlight .phabricator-source-line {
background: {$paste.border};
}
@ -96,7 +97,7 @@ th.phabricator-source-line a:hover {
.phabricator-source-blame-info a {
color: {$darkbluetext};
text-shadow: 1px 1px rgba(0, 0, 0, 0.111);
text-shadow: 1px 1px rgba(0, 0, 0, 0.05);
}
.phabricator-source-blame-skip a {
@ -123,3 +124,10 @@ th.phabricator-source-line a:hover {
background-size: 100% 100%;
background-repeat: no-repeat;
}
th.phabricator-source-coverage {
padding: 0 8px;
border-left: 1px solid {$thinblueborder};
background: {$lightgreybackground};
cursor: w-resize;
}

View file

@ -322,7 +322,7 @@ JX.behavior('document-engine', function(config, statics) {
var h_max = 0.44;
var h = h_min + ((h_max - h_min) * epoch_value);
var s = 0.44;
var s = 0.25;
var v_min = 0.92;
var v_max = 1.00;
@ -357,6 +357,57 @@ JX.behavior('document-engine', function(config, statics) {
return 'rgb(' + r + ', ' + g + ', ' + b + ')';
}
function onhovercoverage(data, e) {
if (e.getType() === 'mouseout') {
redraw_coverage(data, null);
return;
}
var target = e.getNode('tag:th');
var coverage = target.getAttribute('data-coverage');
if (!coverage) {
return;
}
redraw_coverage(data, target);
}
var coverage_row = null;
function redraw_coverage(data, node) {
if (coverage_row) {
JX.DOM.alterClass(
coverage_row,
'phabricator-source-coverage-highlight',
false);
coverage_row = null;
}
if (!node) {
JX.Tooltip.hide();
return;
}
var coverage = node.getAttribute('data-coverage');
coverage = coverage.split('/');
var idx = parseInt(coverage[0], 10);
var chr = coverage[1];
var map = data.coverage.labels[idx];
if (map) {
var label = map[chr];
if (label) {
JX.Tooltip.show(node, 300, 'W', label);
coverage_row = JX.DOM.findAbove(node, 'tr');
JX.DOM.alterClass(
coverage_row,
'phabricator-source-coverage-highlight',
true);
}
}
}
if (!statics.initialized) {
JX.Stratcom.listen('click', 'document-engine-view-dropdown', onmenu);
statics.initialized = true;
@ -374,6 +425,12 @@ JX.behavior('document-engine', function(config, statics) {
blame(data);
break;
}
JX.DOM.listen(
JX.$(data.viewportID),
['mouseover', 'mouseout'],
'tag:th',
JX.bind(null, onhovercoverage, data));
}
});