diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2014-06-04 17:42:18 +0600 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2014-06-04 17:42:28 +0600 |
commit | 676fb3abd8a4dc595163d5fd4b19cdd8690c0d79 (patch) | |
tree | 088a50ddd96071aa0f7ad37fb0351835a6a09bb7 | |
parent | 19262cd01b85fd1292b15c87e342d20ec43c17a9 (diff) | |
download | sonarqube-676fb3abd8a4dc595163d5fd4b19cdd8690c0d79.tar.gz sonarqube-676fb3abd8a4dc595163d5fd4b19cdd8690c0d79.zip |
SONAR-5209 Display test information on test files
13 files changed, 180 insertions, 24 deletions
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index f4af31ef927..5122a8da03f 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2664,4 +2664,7 @@ component_viewer.header.toggle_coverage=Toggle coverage component_viewer.header.toggle_duplications=Toggle duplications component_viewer.transition.coverage=Covered By +component_viewer.transition.covers=Covers component_viewer.transition.duplication=Duplicated By + +component_viewer.x_lines_are_covered={0} lines are covered diff --git a/sonar-server/src/main/coffee/component-viewer/covered-files-popup.coffee b/sonar-server/src/main/coffee/component-viewer/covered-files-popup.coffee new file mode 100644 index 00000000000..745aa699c14 --- /dev/null +++ b/sonar-server/src/main/coffee/component-viewer/covered-files-popup.coffee @@ -0,0 +1,39 @@ +define [ + 'backbone.marionette' + 'templates/component-viewer' + 'component-viewer/popup' + 'component-viewer/utils' +], ( + Marionette + Templates + Popup + utils +) -> + + $ = jQuery + + + class CoveredFilesPopupView extends Popup + template: Templates['covered-files-popup'] + + + events: + 'click a[data-key]': 'goToFile' + + + goToFile: (e) -> + key = $(e.currentTarget).data 'key' + files = @collection.toJSON() + @options.main.addTransition 'covers', _.map files, (file) -> + x = utils.splitLongName file.longName + key: file.key + name: x.name + subname: x.dir + active: file.key == key + @options.main._open key + + + serializeData: -> + items: @collection.toJSON().map (file) -> + _.extend file, utils.splitLongName file.longName + test: @options.test diff --git a/sonar-server/src/main/coffee/component-viewer/header.coffee b/sonar-server/src/main/coffee/component-viewer/header.coffee index 0b2057032e7..c0797d46226 100644 --- a/sonar-server/src/main/coffee/component-viewer/header.coffee +++ b/sonar-server/src/main/coffee/component-viewer/header.coffee @@ -1,18 +1,21 @@ define [ 'backbone.marionette' 'templates/component-viewer' + 'component-viewer/covered-files-popup' 'common/handlebars-extensions' ], ( Marionette Templates + CoveredFilesPopupView ) -> $ = jQuery API_FAVORITE = "#{baseUrl}/api/favourites" + API_TESTS_COVERED_FILES = "#{baseUrl}/api/tests/covered_files" - class HeaderView extends Marionette.ItemView + class HeaderView extends Marionette.Layout template: Templates['header'] @@ -60,6 +63,8 @@ define [ 'click .js-filter-duplications': 'filterByDuplications' + 'click .js-unit-test': 'showCoveredFiles' + initialize: (options) -> options.main.settings.on 'change', => @changeSettings() @@ -101,7 +106,10 @@ define [ @ui.expandedBars.hide() if scope unless @options.main.component.has 'msr' - @options.main.requestMeasures(@options.main.key).done => + req = @options.main.requestMeasures(@options.main.key) + if @options.main.component.get('q') == 'UTS' + req = $.when req, @options.main.requestTests(@options.main.key) + req.done => @render() @ui.expandLinks.filter("[data-scope=#{scope}]").addClass 'active' @ui.expandedBars.filter("[data-scope=#{scope}]").show() @@ -182,6 +190,21 @@ define [ filterByDuplications: (e) -> @filterLines e, 'filterByDuplications' + showCoveredFiles: (e) -> + e.stopPropagation() + $('body').click() + testName = $(e.currentTarget).data 'name' + test = _.findWhere @options.main.component.get('tests'), name: testName + key = @options.main.component.get('key') + $.get API_TESTS_COVERED_FILES, key: key, test: testName, (data) => + popup = new CoveredFilesPopupView + triggerEl: $(e.currentTarget) + collection: new Backbone.Collection data.files + test: test + main: @options.main + popup.render() + + serializeData: -> component = @options.main.component.toJSON() if component.measures @@ -197,7 +220,7 @@ define [ order = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'] component.severities = _.sortBy component.severities, (s) -> order.indexOf s[0] - settings: @options.main.settings.toJSON() showSettings: @showSettings - component: component
\ No newline at end of file + component: component + currentIssue: @options.main.currentIssue
\ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/main.coffee b/sonar-server/src/main/coffee/component-viewer/main.coffee index f44c5014563..fce9f3710c0 100644 --- a/sonar-server/src/main/coffee/component-viewer/main.coffee +++ b/sonar-server/src/main/coffee/component-viewer/main.coffee @@ -27,6 +27,7 @@ define [ API_SCM = "#{baseUrl}/api/sources/scm" API_MEASURES = "#{baseUrl}/api/resources" API_DUPLICATIONS = "#{baseUrl}/api/duplications/show" + API_TESTS = "#{baseUrl}/api/tests/show" LINES_AROUND_ISSUE = 4 LINES_AROUND_COVERED_LINE = 1 @@ -109,6 +110,7 @@ define [ requestComponent: (key) -> $.get API_COMPONENT, key: key, (data) => + @component.clear() @component.set data @component.set 'dir', utils.splitLongName(data.path).dir @@ -170,20 +172,27 @@ define [ @source.set duplicationFiles: data.files + requestTests: (key) -> + $.get API_TESTS, key: key, (data) => + @component.set 'tests', data.tests + + open: (key) -> @workspace.reset [] - @_open key + @_open key, false - _open: (key) -> + _open: (key, showFullSource = true) -> @key = key @sourceView.showSpinner() source = @requestSource key component = @requestComponent key + @currentIssue = null $.when(source, component).done => @workspace.where(key: key).forEach (model) => model.set 'component': @component.toJSON() @render() + @showAllLines() if showFullSource if @settings.get('issues') then @showIssues() else @hideIssues() if @settings.get('coverage') then @showCoverage() else @hideCoverage() if @settings.get('duplications') then @showDuplications() else @hideDuplications() @@ -229,6 +238,7 @@ define [ @currentIssue = issue.key @source.set 'issues', [issue] @filterByCurrentIssue() + @headerView.render() else @sourceView.render() @@ -270,6 +280,7 @@ define [ showAllLines: -> + console.log 1 @sourceView.resetShowBlocks() @sourceView.showBlocks.push from: 0, to: _.size @source.get 'source' @sourceView.render() diff --git a/sonar-server/src/main/coffee/component-viewer/source.coffee b/sonar-server/src/main/coffee/component-viewer/source.coffee index 76aa7a46ecc..817ab9fb5cd 100644 --- a/sonar-server/src/main/coffee/component-viewer/source.coffee +++ b/sonar-server/src/main/coffee/component-viewer/source.coffee @@ -19,7 +19,7 @@ define [ $ = jQuery - API_COVERAGE_TESTS = "#{baseUrl}/api/tests/testable" + API_COVERAGE_TESTS = "#{baseUrl}/api/tests/test_cases" class SourceView extends Marionette.ItemView diff --git a/sonar-server/src/main/hbs/component-viewer/header.hbs b/sonar-server/src/main/hbs/component-viewer/header.hbs index 31829c78d35..0eb219181c9 100644 --- a/sonar-server/src/main/hbs/component-viewer/header.hbs +++ b/sonar-server/src/main/hbs/component-viewer/header.hbs @@ -25,6 +25,18 @@ </div> <div class="component-viewer-header-measures"> + {{#eq component.q 'UTS'}} + <div class="component-viewer-header-measures-scope"> + <a data-scope="tests" class="component-viewer-header-measures-expand"> + <div class="component-viewer-header-measure"> + <span class="component-viewer-header-measure-value">{{component.measures.fTests}}</span> + <span class="component-viewer-header-measure-label">{{t 'metric.tests.name'}}</span> + </div> + <i class="icon-dropdown"></i> + </a> + </div> + {{/eq}} + {{#notEq component.q 'UTS'}} <div class="component-viewer-header-measures-scope"> <span data-scope="basic" class="js-toggle-coverage component-viewer-header-measures-toggle-scope inactive"></span> @@ -102,18 +114,6 @@ {{/if}} {{/notEq}} - {{#eq component.q 'UTS'}} - <div class="component-viewer-header-measures-scope"> - <a data-scope="duplications" class="component-viewer-header-measures-expand"> - <div class="component-viewer-header-measure"> - <span class="component-viewer-header-measure-value">{{component.measures.tests}}</span> - <span class="component-viewer-header-measure-label">{{t 'metric.tests.name'}}</span> - </div> - <i class="icon-dropdown"></i> - </a> - </div> - {{/eq}} - <div class="component-viewer-header-measures-scope"> <span data-scope="scm" class="component-viewer-header-measures-expand"> <div class="component-viewer-header-measure"> diff --git a/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs b/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs index ba2ff445156..544832869bb 100644 --- a/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs +++ b/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs @@ -37,10 +37,12 @@ {{t 'component_viewer.measure_section.issues'}} </div> <ul class="component-viewer-header-expanded-bar-section-list"> - <li><a class="item js-filter-current-issue"> - <span>{{t 'component_viewer.issues.current_issue'}}</span> - <i class="icon-chevron-right"></i> - </a></li> + {{#if currentIssue}} + <li><a class="item js-filter-current-issue"> + <span>{{t 'component_viewer.issues.current_issue'}}</span> + <i class="icon-chevron-right"></i> + </a></li> + {{/if}} {{#if component.measures.fIssues}} <li><a class="item js-filter-unresolved-issues"> <span>{{t 'component_viewer.issues.unresolved_issues'}}</span> diff --git a/sonar-server/src/main/hbs/component-viewer/header/_tests-header.hbs b/sonar-server/src/main/hbs/component-viewer/header/_tests-header.hbs index e69de29bb2d..c19c7501c57 100644 --- a/sonar-server/src/main/hbs/component-viewer/header/_tests-header.hbs +++ b/sonar-server/src/main/hbs/component-viewer/header/_tests-header.hbs @@ -0,0 +1,18 @@ +<div class="component-viewer-header-expanded-bar-section large"> + <div class="component-viewer-header-expanded-bar-section-title justify"> + <span class="ib">{{t 'component_viewer.measure_section.unit_tests'}}</span> + <span class="ib">Covered Lines</span> + </div> + <ul class="component-viewer-header-expanded-bar-section-list"> + {{#each component.tests}} + <li><a class="item js-unit-test" data-name="{{name}}"> + <span class="label">{{testStatusIcon status}} <span class="subtitle">{{durationInMs}}ms</span> + {{name}}</span> + {{#eq status 'OK'}} + <span class="number">{{coveredLines}}</span> + {{/eq}} + <i class="icon-chevron-right"></i> + </a></li> + {{/each}} + </ul> +</div>
\ No newline at end of file diff --git a/sonar-server/src/main/hbs/component-viewer/header/covered-files-popup.hbs b/sonar-server/src/main/hbs/component-viewer/header/covered-files-popup.hbs new file mode 100644 index 00000000000..43f904b0bd5 --- /dev/null +++ b/sonar-server/src/main/hbs/component-viewer/header/covered-files-popup.hbs @@ -0,0 +1,24 @@ +<div class="component-viewer-popup-container"> + +{{#eq test.status 'OK'}} + <div class="component-viewer-popup-title">{{t 'component_viewer.transition.covers'}}</div> + + {{#each items}} + <div class="component-viewer-popup-section"> + <a class="component-viewer-popup-test-file link-action" data-key="{{key}}" title="{{name}}">{{name}}</a> + <span class="subtitle">{{tp 'component_viewer.x_lines_are_covered' coveredLines}}</span> + <br><span class="subtitle" title="{{dir}}">{{dir}}</span> + </div> + {{else}} + {{t 'none'}} + {{/each}} + + </div> +{{else}} + {{#if test.message}} + <div class="component-viewer-popup-title">{{test.message}}</div> + {{/if}} + <pre>{{test.stackTrace}}</pre> +{{/eq}} + +<div class="component-viewer-popup-arrow"></div>
\ No newline at end of file diff --git a/sonar-server/src/main/js/common/handlebars-extensions.js b/sonar-server/src/main/js/common/handlebars-extensions.js index b088af5e282..8deac86c643 100644 --- a/sonar-server/src/main/js/common/handlebars-extensions.js +++ b/sonar-server/src/main/js/common/handlebars-extensions.js @@ -45,6 +45,12 @@ define(['handlebars', 'moment'], function (Handlebars, moment) { ); }); + Handlebars.registerHelper('testStatusIcon', function(status) { + return new Handlebars.SafeString( + '<i class="icon-test-status-' + status.toLowerCase() + '"></i>' + ); + }); + Handlebars.registerHelper('alertIconClass', function(alert) { return new Handlebars.SafeString( 'icon-alert-' + alert.toLowerCase() diff --git a/sonar-server/src/main/less/component-viewer.less b/sonar-server/src/main/less/component-viewer.less index bb4b4033bbc..2ffbc65f668 100644 --- a/sonar-server/src/main/less/component-viewer.less +++ b/sonar-server/src/main/less/component-viewer.less @@ -448,6 +448,8 @@ display: inline-block; vertical-align: top; width: 250px; + + &.large { width: 350px; } } .component-viewer-header-expanded-bar-section-actions { @@ -473,6 +475,8 @@ & > .number { position: absolute; right: 25px; + top: 50%; + margin-top: -8px; } & > i { @@ -571,8 +575,9 @@ } .component-viewer-popup-container { + min-width: 560px; max-height: 300px; - overflow-y: auto; + overflow: auto; } .component-viewer-popup-title { diff --git a/sonar-server/src/main/less/icons.less b/sonar-server/src/main/less/icons.less index 695fe31a8d3..d5032be70a7 100644 --- a/sonar-server/src/main/less/icons.less +++ b/sonar-server/src/main/less/icons.less @@ -121,6 +121,22 @@ a[class^="icon-"], a[class*=" icon-"] { /* + * Test Status + */ + +.icon-test-status-ok:before { + content: "\f013"; + color: @green; + font-size: @iconFontSize; +} +.icon-test-status-failure:before { + content: "\f057"; + color: @red; + font-size: @iconFontSize; +} + + +/* * Alert */ diff --git a/sonar-server/src/main/less/ui.less b/sonar-server/src/main/less/ui.less index 5ae0eebeeec..67a4ab3e781 100644 --- a/sonar-server/src/main/less/ui.less +++ b/sonar-server/src/main/less/ui.less @@ -57,6 +57,15 @@ select::-moz-focus-inner, input::-moz-focus-inner, button::-moz-focus-inner { white-space: nowrap; } +.justify { + margin-bottom: -1em; + text-align: justify; + + & > .ib { display: inline-block; } + + &:after { display: inline-block; width: 100%; content: " "; } +} + /* * Links |