aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/source-viewer/measures-overlay.js
blob: 6d6de2a7adfcb2f1ff4d812de6cadfe1c4d6d273 (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
define([
  'common/overlay',
  'templates/source-viewer'
], function (Overlay, Templates) {

  var $ = jQuery;


  return Overlay.extend({
    className: 'overlay-popup source-viewer-measures-overlay',
    template: Templates['source-viewer-measures'],

    events: function () {
      return _.extend(Overlay.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'
      });
    },

    onRender: function () {
      Overlay.prototype.onRender.apply(this, arguments);
      this.$('.js-pie-chart').pieChart();
      if (this.selectedTest != null) {
        this.scrollToTest();
      }
    },

    scrollToTest: function () {
      var position = this.$('.js-selected-test').offset().top - this.$el.offset().top - 50;
      this.$el.scrollTop(position);
    },

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

    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.sortTests('name');
        that.testSorting = 'name';
      });
    },

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

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

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

    sortTestsByStatus: function () {
      this.sortTests('status');
      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
          };
      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);
      });
    },

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

});