summaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/source-viewer/measures-overlay.js
blob: 3a1cc491d9a027247572d075da2d3fbb0c7850f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
define([
  'common/modals',
  'templates/source-viewer'
], function (ModalView) {

  var $ = jQuery;


  return ModalView.extend({
    template: Templates['source-viewer-measures'],
    testsOrder: ['ERROR', 'FAILURE', 'OK', 'SKIPPED'],

    initialize: function () {
      var that = this,
          p = window.process.addBackgroundProcess(),
          requests = [this.requestMeasures(), this.requestIssues()];
      if (this.model.get('isUnitTest')) {
        requests.push(this.requestTests());
      }
      this.testsScroll = 0;
      $.when.apply($, requests).done(function () {
        that.render();
        window.process.finishBackgroundProcess(p);
      }).fail(function () {
        window.process.failBackgroundProcess(p);
      });
    },

    events: function () {
      return _.extend(ModalView.prototype.events.apply(this, arguments), {
        'click .js-sort-tests-by-duration': 'sortTestsByDuration',
        'click .js-sort-tests-by-name': 'sortTestsByName',
        'click .js-sort-tests-by-status': 'sortTestsByStatus',
        'click .js-show-test': 'showTest',
        'click .js-show-all-measures': 'showAllMeasures'
      });
    },

    onRender: function () {
      ModalView.prototype.onRender.apply(this, arguments);
      this.$('.js-pie-chart').pieChart();
      this.$('.js-test-list').scrollTop(this.testsScroll);
    },

    getMetrics: function () {
      var metrics = '',
          url = baseUrl + '/api/metrics';
      $.ajax({
        url: url,
        async: false
      }).done(function (data) {
        metrics = _.filter(data, function (metric) {
          return !metric.hidden && metric.val_type !== 'DATA';
        });
        metrics = _.sortBy(metrics, 'name');
      });
      return metrics;
    },


    calcAdditionalMeasures: function (measures) {
      if (measures.lines_to_cover && measures.uncovered_lines) {
        measures.covered_lines = measures.lines_to_cover - measures.uncovered_lines;
      }
      if (measures.conditions_to_cover && measures.uncovered_conditions) {
        measures.covered_conditions = measures.conditions_to_cover - measures.uncovered_conditions;
      }
      if (measures.it_lines_to_cover && measures.it_uncovered_lines) {
        measures.it_covered_lines = measures.it_lines_to_cover - measures.it_uncovered_lines;
      }
      if (measures.it_conditions_to_cover && measures.it_uncovered_conditions) {
        measures.it_covered_conditions = measures.it_conditions_to_cover - measures.it_uncovered_conditions;
      }
      return measures;
    },


    prepareMetrics: function (metrics) {
      metrics = _.filter(metrics, function (metric) {
        return metric.value != null;
      });
      return _.map(_.pairs(_.groupBy(metrics, 'domain')), function (domain) {
        return {
          name: domain[0],
          metrics: domain[1]
        };
      });
    },


    requestMeasures: function () {
      var that = this,
          url = baseUrl + '/api/resources',
          metrics = this.getMetrics(),
          options = {
            resource: this.model.key(),
            metrics: _.pluck(metrics, 'key').join()
          };
      return $.get(url, options).done(function (data) {
        var measuresList = data[0].msr || [],
            measures = that.model.get('measures') || {};
        measuresList.forEach(function (m) {
          var metric = _.findWhere(metrics, { key: m.key });
          metric.value = m.frmt_val || m.data;
          measures[m.key] = m.frmt_val || m.data;
          measures[m.key + '_raw'] = m.val;
        });
        measures = that.calcAdditionalMeasures(measures);
        that.model.set({
          measures: measures,
          measuresToDisplay: that.prepareMetrics(metrics)
        });
      });
    },

    requestIssues: function () {
      var that = this,
          url = baseUrl + '/api/issues/search',
          options = {
            componentUuids: this.model.id,
            resolved: false,
            ps: 1,
            facets: 'severities,tags'
          };
      return $.get(url, options).done(function (data) {
        var issuesFacets = {};
        data.facets.forEach(function (facet) {
          issuesFacets[facet.property] = facet.values;
        });
        var severityOrder = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'],
            maxCountBySeverity = _.max(issuesFacets.severities, function (s) {
              return s.count;
            }).count,
            maxCountByTag = _.max(issuesFacets.tags, function (s) {
              return s.count;
            }).count;
        issuesFacets.severities = _.sortBy(issuesFacets.severities, function (s) {
          return severityOrder.indexOf(s.val);
        });
        that.model.set({
          issuesFacets: issuesFacets,
          issuesCount: data.total,
          maxCountBySeverity: maxCountBySeverity,
          maxCountByTag: maxCountByTag
        });
      });
    },

    requestTests: function () {
      var that = this,
          url = baseUrl + '/api/tests/show',
          options = { key: this.model.key() };
      return $.get(url, options).done(function (data) {
        that.model.set({ tests: data.tests });
        that.testSorting = 'status';
        that.testAsc = true;
        that.sortTests(function (test) {
          return '' + that.testsOrder.indexOf(test.status) + '_______' + test.name;
        });
      });
    },

    sortTests: function (condition) {
      var tests = this.model.get('tests');
      if (_.isArray(tests)) {
        tests = _.sortBy(tests, condition);
        if (!this.testAsc) {
          tests.reverse();
        }
        this.model.set({ tests: tests });
      }
    },

    sortTestsByDuration: function () {
      if (this.testSorting === 'duration') {
        this.testAsc = !this.testAsc;
      }
      this.sortTests('durationInMs');
      this.testSorting = 'duration';
      this.render();
    },

    sortTestsByName: function () {
      if (this.testSorting === 'name') {
        this.testAsc = !this.testAsc;
      }
      this.sortTests('name');
      this.testSorting = 'name';
      this.render();
    },

    sortTestsByStatus: function () {
      var that = this;
      if (this.testSorting === 'status') {
        this.testAsc = !this.testAsc;
      }
      this.sortTests(function (test) {
        return '' + that.testsOrder.indexOf(test.status) + '_______' + test.name;
      });
      this.testSorting = 'status';
      this.render();
    },

    showTest: function (e) {
      var that = this,
          p = window.process.addBackgroundProcess(),
          name = $(e.currentTarget).data('name'),
          url = baseUrl + '/api/tests/covered_files',
          options = {
            key: this.model.key(),
            test: name
          };
      this.testsScroll = $(e.currentTarget).scrollParent().scrollTop();
      return $.get(url, options).done(function (data) {
        that.coveredFiles = data.files;
        that.selectedTest = _.findWhere(that.model.get('tests'), { name: name });
        that.render();
        window.process.finishBackgroundProcess(p);
      });
    },

    showAllMeasures: function () {
      this.$('.js-all-measures').removeClass('hidden');
      this.$('.js-show-all-measures').remove();
    },

    serializeData: function () {
      return _.extend(ModalView.prototype.serializeData.apply(this, arguments), {
        testSorting: this.testSorting,
        selectedTest: this.selectedTest,
        coveredFiles: this.coveredFiles || []
      });
    }
  });

});