]> source.dussan.org Git - sonarqube.git/commitdiff
add some tests for the source viewer
authorStas Vilchik <vilchiks@gmail.com>
Wed, 22 Apr 2015 10:33:17 +0000 (12:33 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Wed, 22 Apr 2015 10:35:19 +0000 (12:35 +0200)
31 files changed:
server/sonar-web/src/main/hbs/source-viewer/measures/_source-viewer-measures-coverage.hbs
server/sonar-web/src/main/js/source-viewer/measures-overlay.js
server/sonar-web/src/main/js/source-viewer/viewer.js
server/sonar-web/src/test/js/source-viewer-coverage.js
server/sonar-web/src/test/js/source-viewer-create-manual-issue.js
server/sonar-web/src/test/js/source-viewer-duplications.js
server/sonar-web/src/test/js/source-viewer-issues.js [new file with mode: 0644]
server/sonar-web/src/test/js/source-viewer-link-to-raw-spec.js.disabled [deleted file]
server/sonar-web/src/test/js/source-viewer-scm.js
server/sonar-web/src/test/js/source-viewer-should-open-in-new-window-with-line.js.disabled [deleted file]
server/sonar-web/src/test/js/source-viewer-should-open-in-new-window.js.disabled [deleted file]
server/sonar-web/src/test/js/source-viewer-spec.js
server/sonar-web/src/test/json/source-viewer-coverage/app.json
server/sonar-web/src/test/json/source-viewer-coverage/lines.json
server/sonar-web/src/test/json/source-viewer-coverage/test-cases.json
server/sonar-web/src/test/json/source-viewer-duplications/app.json
server/sonar-web/src/test/json/source-viewer-duplications/duplications-removed.json
server/sonar-web/src/test/json/source-viewer-duplications/duplications.json
server/sonar-web/src/test/json/source-viewer-issues/app.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-issues/issues.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-issues/lines.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-scm/app.json
server/sonar-web/src/test/json/source-viewer-spec/app-test.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/app.json
server/sonar-web/src/test/json/source-viewer-spec/covered-files.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/issues-details.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/lines.json
server/sonar-web/src/test/json/source-viewer-spec/measures-test.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/measures.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/metrics.json [new file with mode: 0644]
server/sonar-web/src/test/json/source-viewer-spec/tests.json [new file with mode: 0644]

index b1fbadd7c735d2fdee629045eec42b9ae67879d3..72d2002690f97c059ae38f0af2c300bfc61121f1 100644 (file)
@@ -8,7 +8,7 @@
             data-base-color="#d4333f"
             data-size="47"></span>
     </div>
-    <div class="measure measure-big">
+    <div class="measure measure-big" data-metric="coverage">
       <span class="measure-value">{{default measures.overall_coverage measures.coverage measures.it_coverage}}</span>
       <span class="measure-name">{{t 'metric.coverage.name'}}</span>
     </div>
         <div class="measure measure-one-line">
           <span class="measure-name">Covered by Unit Tests</span>
         </div>
-        <div class="measure measure-one-line">
+        <div class="measure measure-one-line" data-metric="lines_to_cover">
           <span class="measure-name">Lines</span>
           <span class="measure-value">{{measures.covered_lines}}/{{measures.lines_to_cover}}</span>
         </div>
         {{#if measures.conditions_to_cover}}
-          <div class="measure measure-one-line">
+          <div class="measure measure-one-line" data-metric="conditions_to_cover">
             <span class="measure-name">Conditions</span>
             <span class="measure-value">{{default measures.covered_conditions 0}}/{{measures.conditions_to_cover}}</span>
           </div>
         <div class="measure measure-one-line">
           <span class="measure-name">Covered by Integration Tests</span>
         </div>
-        <div class="measure measure-one-line">
+        <div class="measure measure-one-line" data-metric="it_lines_to_cover">
           <span class="measure-name">Lines</span>
           <span class="measure-value">{{measures.it_uncovered_lines}}/{{measures.it_lines_to_cover}}</span>
         </div>
         {{#if measures.it_conditions_to_cover}}
-          <div class="measure measure-one-line">
+          <div class="measure measure-one-line" data-metric="it_conditions_to_cover">
             <span class="measure-name">Conditions</span>
             <span class="measure-value">{{default measures.it_uncovered_conditions 0}}/{{measures.it_conditions_to_cover}}</span>
           </div>
index 37822ac56bc44005ecd9e4827d4d228e6f81a8cc..04fdcc0cf9cd11dfa58d3727be1d58fc1b3b8dad 100644 (file)
@@ -65,7 +65,7 @@ define([
         async: false
       }).done(function (data) {
         metrics = _.filter(data, function (metric) {
-          return !metric.hidden && metric.val_type !== 'DATA';
+          return metric.val_type !== 'DATA';
         });
         metrics = _.sortBy(metrics, 'name');
       });
index 8b92da692a1ce7e61a809aa392d81894610a5067..8fab3b00d255755da47e924f5ae8b975dadf7917 100644 (file)
@@ -313,10 +313,6 @@ define([
           this.model.addMeta(issuesPerLine);
         },
 
-        limitIssues: function (issues) {
-          return issues.first(this.ISSUES_LIMIT);
-        },
-
         renderIssues: function () {
           this.$('.issue-list').addClass('hidden');
         },
index 521ecdccdaded6cda2ea7e5d8ee61d4cac982ba7..f0b8501439014d45877abdafe26fae3183184ad5 100644 (file)
 
 
 var lib = require('../lib'),
-    testName = lib.testName('Source Viewer');
+    testName = lib.testName('Source Viewer', 'Coverage');
 
 lib.initMessages();
 lib.changeWorkingDirectory('source-viewer-coverage');
 lib.configureCasper();
 
 
-casper.test.begin(testName('Coverage'), 4, function (test) {
+casper.test.begin(testName(), 12, function (test) {
   casper
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
 
 
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
-        lib.mockRequestFromFile('/api/tests/test_cases', 'test-cases.json');
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+        lib.mockRequestFromFile('/api/tests/test_cases', 'test-cases.json', { data: { uuid: 'uuid', line: '11' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
@@ -51,8 +52,20 @@ casper.test.begin(testName('Coverage'), 4, function (test) {
       })
 
       .then(function () {
-        test.assertElementCount('.source-line-covered', 1);
-        casper.click('.source-line-covered');
+        test.assertExists('.source-line-covered[data-line-number="6"]');
+        test.assertExists('.source-line-covered[data-line-number="8"]');
+        test.assertExists('.source-line-covered[data-line-number="11"]');
+        test.assertExists('.source-line-covered[data-line-number="12"]');
+
+        test.assertExists('.source-line-partially-covered[data-line-number="5"]');
+        test.assertExists('.source-line-partially-covered[data-line-number="7"]');
+
+        test.assertExists('.source-line-uncovered[data-line-number="1"]');
+        test.assertExists('.source-line-uncovered[data-line-number="2"]');
+      })
+
+      .then(function () {
+        casper.click('.source-line-covered[data-line-number="11"]');
         casper.waitForSelector('.bubble-popup');
       })
 
@@ -62,6 +75,15 @@ casper.test.begin(testName('Coverage'), 4, function (test) {
         test.assertExists('.bubble-popup .icon-test-status-ok');
       })
 
+      .then(function () {
+        casper.click('[data-uuid="uuid"]');
+        casper.waitForSelector('.workspace-viewer .source-line');
+      })
+
+      .then(function () {
+        test.assertElementCount('.workspace-viewer .source-line', 17);
+      })
+
       .then(function () {
         lib.sendCoverage();
       })
index f897c471bf8b48e7e3a540287fd50ba0fae79986..ad382aff6cefe5e761f33285791193bc03691d76 100644 (file)
@@ -63,10 +63,10 @@ casper.test.begin(testName('source-viewer-create-manual-issue'), function (test)
 
       .then(function () {
         casper.evaluate(function () {
-                 jQuery('.js-manual-issue-form [name="rule"]').val('manual:api');
-                 jQuery('.js-manual-issue-form [name="message"]').val('An issue message');
-                 jQuery('.js-manual-issue-form input[type="submit"]').click();
-               });
+          jQuery('.js-manual-issue-form [name="rule"]').val('manual:api');
+          jQuery('.js-manual-issue-form [name="message"]').val('An issue message');
+          jQuery('.js-manual-issue-form input[type="submit"]').click();
+        });
       })
 
       .then(function () {
index d4a3bca6f71a966496c9d91c334b101e9eedbc4a..809ed6ee6e1a9b07b665d3693ac733d58a65fdef 100644 (file)
@@ -28,20 +28,20 @@ lib.changeWorkingDirectory('source-viewer-duplications');
 lib.configureCasper();
 
 
-casper.test.begin(testName(), 4, function (test) {
+casper.test.begin(testName(), 5, function (test) {
   casper
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
 
-
         lib.mockRequestFromFile('/api/components/app', 'app.json');
         lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
         lib.mockRequestFromFile('/api/issues/search', 'issues.json');
-        lib.mockRequestFromFile('/api/duplications/show', 'duplications.json');
+        lib.mockRequestFromFile('/api/duplications/show', 'duplications.json', { data: { uuid: 'uuid' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
@@ -66,6 +66,15 @@ casper.test.begin(testName(), 4, function (test) {
         test.assertSelectorContains('.bubble-popup', '16');
       })
 
+      .then(function () {
+        casper.click('[data-uuid="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbbb"]');
+        casper.waitForSelector('.workspace-viewer .source-line');
+      })
+
+      .then(function () {
+        test.assertElementCount('.workspace-viewer .source-line', 21);
+      })
+
       .then(function () {
         lib.sendCoverage();
       })
@@ -81,15 +90,15 @@ casper.test.begin(testName('In Removed Component'), 2, function (test) {
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
 
-
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
-        lib.mockRequestFromFile('/api/duplications/show', 'duplications-removed.json');
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+        lib.mockRequestFromFile('/api/duplications/show', 'duplications-removed.json', { data: { uuid: 'uuid' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
diff --git a/server/sonar-web/src/test/js/source-viewer-issues.js b/server/sonar-web/src/test/js/source-viewer-issues.js
new file mode 100644 (file)
index 0000000..46a2605
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+/* global casper:false */
+
+
+var lib = require('../lib'),
+    testName = lib.testName('Source Viewer', 'Issues');
+
+lib.initMessages();
+lib.changeWorkingDirectory('source-viewer-issues');
+lib.configureCasper();
+
+
+casper.test.begin(testName(), 16, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+        lib.mockRequest('/api/issues/set_severity', '{}',
+            { data: { issue: '59fc17f7-c977-4cb6-8f04-fbe88e4b9186', severity: 'CRITICAL' } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        test.assertElementCount('.source-line-with-issues', 5);
+        test.assertExists('.source-line-with-issues[data-line-number="0"]');
+        test.assertExists('.source-line-with-issues[data-line-number="2"]');
+        test.assertExists('.source-line-with-issues[data-line-number="12"]');
+        test.assertExists('.source-line-with-issues[data-line-number="14"]');
+        test.assertExists('.source-line-with-issues[data-line-number="15"]');
+        test.assertNotVisible('.issue');
+      })
+
+      .then(function () {
+        casper.click('.source-line-with-issues[data-line-number="2"]');
+        test.assertVisible('#issue-e4de6481-7bfb-460a-8b3c-24459f9561d3');
+        test.assertVisible('#issue-59fc17f7-c977-4cb6-8f04-fbe88e4b9186');
+        test.assertElementCount('.issue-inner', 2);
+      })
+
+      .then(function () {
+        test.assertExists('.source-line-with-issues[data-line-number="2"] .icon-severity-minor');
+
+        casper.click('#issue-59fc17f7-c977-4cb6-8f04-fbe88e4b9186 .js-issue-set-severity');
+        casper.waitForSelector('.bubble-popup');
+      })
+
+      .then(function () {
+        casper.click('.bubble-popup .js-issue-severity[data-value="CRITICAL"]');
+        casper.waitForSelector('#issue-59fc17f7-c977-4cb6-8f04-fbe88e4b9186 .icon-severity-critical');
+      })
+
+      .then(function () {
+        test.assertExists('.source-line-with-issues[data-line-number="2"] .icon-severity-critical');
+      })
+
+      .then(function () {
+        // hide issues
+        casper.click('.source-line-with-issues[data-line-number="2"]');
+        test.assertNotVisible('#issue-e4de6481-7bfb-460a-8b3c-24459f9561d3');
+        test.assertNotVisible('#issue-59fc17f7-c977-4cb6-8f04-fbe88e4b9186');
+
+        // show issues again
+        casper.click('.source-line-with-issues[data-line-number="2"]');
+        test.assertVisible('#issue-e4de6481-7bfb-460a-8b3c-24459f9561d3');
+        test.assertVisible('#issue-59fc17f7-c977-4cb6-8f04-fbe88e4b9186');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
diff --git a/server/sonar-web/src/test/js/source-viewer-link-to-raw-spec.js.disabled b/server/sonar-web/src/test/js/source-viewer-link-to-raw-spec.js.disabled
deleted file mode 100644 (file)
index dc385f4..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/* global casper:false */
-
-var lib = require('../lib'),
-    testName = lib.testName('Source Viewer');
-
-lib.initMessages();
-lib.changeWorkingDirectory('source-viewer-spec');
-lib.configureCasper();
-
-
-casper.test.begin(testName('Link to Raw'), function (test) {
-  casper
-      .start(lib.buildUrl('source-viewer'), function () {
-        lib.setDefaultViewport();
-
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
-      })
-
-      .then(function () {
-        casper.waitForSelector('.source-line');
-      })
-
-      .then(function () {
-        casper.click('.js-actions');
-        casper.waitForSelector('.js-raw-source', function () {
-          casper.click('.js-raw-source');
-        });
-      })
-
-      .then(function () {
-        casper.withPopup(/Cache\.java/, function () {
-          this.test.assertUrlMatch('org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java');
-        });
-      })
-
-      .then(function () {
-        lib.sendCoverage();
-      })
-
-      .run(function () {
-        test.done();
-      });
-});
index f53a3ed56435cbc1af4708512769206734bd78f0..047e08a93093bc89d4b4a4eb930e92392b3df66a 100644 (file)
@@ -34,13 +34,14 @@ casper.test.begin(testName('SCM'), 4, function (test) {
         lib.setDefaultViewport();
 
 
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
diff --git a/server/sonar-web/src/test/js/source-viewer-should-open-in-new-window-with-line.js.disabled b/server/sonar-web/src/test/js/source-viewer-should-open-in-new-window-with-line.js.disabled
deleted file mode 100644 (file)
index 1a5b077..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/* global casper:false */
-
-var lib = require('../lib'),
-    testName = lib.testName('Source Viewer');
-
-lib.initMessages();
-lib.changeWorkingDirectory('source-viewer-should-open-in-new-window');
-lib.configureCasper();
-
-
-casper.test.begin(testName('source-viewer-should-open-in-new-window-with-line'), function (test) {
-  casper
-      .start(lib.buildUrl('source-viewer'), function () {
-        lib.setDefaultViewport();
-
-
-        lib.mockRequestFromFile('/api/components/app', 'api-components-app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'api-sources-lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'api-issues-search.json');
-      })
-
-      .then(function () {
-        casper.waitForSelector('.source-line');
-      })
-
-      .then(function () {
-        casper.click('.source-line-number[data-line-number="6"]');
-        casper.waitForSelector('.bubble-popup');
-      })
-
-      .then(function () {
-        casper.click('.js-actions');
-        casper.waitForSelector('.js-new-window', function () {
-          casper.click('.js-new-window');
-        });
-      })
-
-      .then(function () {
-        casper.withPopup(/Simplest\.java/, function () {
-          this.test.assertUrlMatch('test:fake-project-for-tests:src/main/java/foo/Simplest.java');
-          this.test.assertUrlMatch('line=6');
-        });
-      })
-
-      .then(function () {
-        lib.sendCoverage();
-      })
-
-      .run(function () {
-        test.done();
-      });
-});
diff --git a/server/sonar-web/src/test/js/source-viewer-should-open-in-new-window.js.disabled b/server/sonar-web/src/test/js/source-viewer-should-open-in-new-window.js.disabled
deleted file mode 100644 (file)
index 5603ee3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/* global casper:false */
-
-var lib = require('../lib'),
-    testName = lib.testName('Source Viewer');
-
-lib.initMessages();
-lib.changeWorkingDirectory('source-viewer-should-open-in-new-window');
-lib.configureCasper();
-
-
-casper.test.begin(testName('source-viewer-should-open-in-new-window'), function (test) {
-  casper
-      .start(lib.buildUrl('source-viewer'), function () {
-        lib.setDefaultViewport();
-
-
-        lib.mockRequestFromFile('/api/components/app', 'api-components-app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'api-sources-lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'api-issues-search.json');
-      })
-
-      .then(function () {
-        casper.waitForSelector('.source-line');
-      })
-
-      .then(function () {
-        casper.click('.js-actions');
-        casper.waitForSelector('.js-new-window', function () {
-          casper.click('.js-new-window');
-        });
-      })
-
-      .then(function () {
-        casper.withPopup(/Simplest\.java/, function () {
-          this.test.assertUrlMatch('test:fake-project-for-tests:src/main/java/foo/Simplest.java');
-        });
-      })
-
-      .then(function () {
-        lib.sendCoverage();
-      })
-
-      .run(function () {
-        test.done();
-      });
-});
index b7aa2ac70ee84cb46bef2e2c0cc413b8733d42c0..6b3afb95a92077f4d23cbb7d4f3dd01be3411583 100644 (file)
@@ -28,19 +28,19 @@ lib.changeWorkingDirectory('source-viewer-spec');
 lib.configureCasper();
 
 
-casper.test.begin(testName('Base'), function (test) {
+casper.test.begin(testName('Base'), 14, function (test) {
   casper
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
 
-
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
@@ -56,8 +56,7 @@ casper.test.begin(testName('Base'), function (test) {
           test.assertExists('.source-viewer-header-actions');
 
           // Check main measures
-          // FIXME enable lines check
-          //test.assertSelectorContains('.source-viewer-header-measure', '379');
+          test.assertSelectorContains('.source-viewer-header-measure', '378');
           test.assertSelectorContains('.source-viewer-header-measure', 'A');
           test.assertSelectorContains('.source-viewer-header-measure', '2h 10min');
           test.assertSelectorContains('.source-viewer-header-measure', '6');
@@ -65,9 +64,8 @@ casper.test.begin(testName('Base'), function (test) {
           test.assertSelectorContains('.source-viewer-header-measure', '5.8%');
 
           // Check source
-          // FIXME enable source lines count check
-          //test.assertElementCount('.source-line', 518);
-          test.assertSelectorContains('.source-viewer', 'public class Cache');
+          test.assertElementCount('.source-line', 519);
+          test.assertSelectorContains('.source-viewer', 'import com.google.common.collect.Sets');
         });
       })
 
@@ -81,19 +79,19 @@ casper.test.begin(testName('Base'), function (test) {
 });
 
 
-casper.test.begin(testName('Decoration'), function (test) {
+casper.test.begin(testName('Decoration'), 8, function (test) {
   casper
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
 
-
-        lib.mockRequestFromFile('/api/components/app', 'app.json');
-        lib.mockRequestFromFile('/api/sources/lines', 'lines.json');
-        lib.mockRequestFromFile('/api/issues/search', 'issues.json');
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
       })
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
@@ -136,7 +134,7 @@ casper.test.begin(testName('Decoration'), function (test) {
 });
 
 
-casper.test.begin(testName('Test File'), function (test) {
+casper.test.begin(testName('Test File'), 1, function (test) {
   casper
       .start(lib.buildUrl('source-viewer'), function () {
         lib.setDefaultViewport();
@@ -149,6 +147,7 @@ casper.test.begin(testName('Test File'), function (test) {
 
       .then(function () {
         casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
           require(['/js/source-viewer/app.js']);
         });
       })
@@ -169,3 +168,321 @@ casper.test.begin(testName('Test File'), function (test) {
         test.done();
       });
 });
+
+
+casper.test.begin(testName('Highlight Usages'), 6, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        test.assertElementCount('.sym-9999', 3);
+        test.assertElementCount('.sym.highlighted', 0);
+
+        casper.click('.sym-9999');
+        test.assertElementCount('.sym-9999.highlighted', 3);
+        test.assertElementCount('.sym.highlighted', 3);
+
+        casper.click('.sym-9999');
+        test.assertElementCount('.sym-9999.highlighted', 0);
+        test.assertElementCount('.sym.highlighted', 0);
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Line Permalink'), 1, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        casper.click('.source-line-number[data-line-number="3"]');
+        casper.waitForSelector('.js-get-permalink');
+      })
+
+      .then(function () {
+        casper.click('.js-get-permalink');
+
+        // TODO check raw url
+        test.assert(true);
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Link to Raw'), 1, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues.json', { data: { componentUuids: 'uuid' } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        casper.click('.js-actions');
+        casper.waitForSelector('.js-raw-source');
+      })
+
+      .then(function () {
+        casper.click('.js-raw-source');
+
+        // TODO check raw url
+        test.assert(true);
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Details'), 15, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/components/app', 'app.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues-details.json', { data: { componentUuids: 'uuid' } });
+        lib.mockRequestFromFile('/api/metrics', 'metrics.json');
+        lib.mockRequestFromFile('/api/resources', 'measures.json',
+            { data: { resource: 'org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java' } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        casper.click('.js-actions');
+        casper.waitForSelector('.js-measures');
+      })
+
+      .then(function () {
+        casper.click('.js-measures');
+        casper.waitForSelector('.measure[data-metric="function_complexity"]');
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.measure[data-metric="lines"]', '92');
+        test.assertSelectorContains('.measure[data-metric="ncloc"]', '57');
+        test.assertSelectorContains('.measure[data-metric="comment_lines"]', '19.7% / 14');
+        test.assertSelectorContains('.measure[data-metric="complexity"]', '22');
+        test.assertSelectorContains('.measure[data-metric="function_complexity"]', '4.9');
+
+        test.assertSelectorContains('.measure[data-metric="sqale_rating"]', 'A');
+        test.assertSelectorContains('.measure[data-metric="sqale_index"]', '0');
+        test.assertSelectorContains('.measure[data-metric="violations"]', '6');
+
+        test.assertSelectorContains('.measure[data-metric="coverage"]', '11.3%');
+        test.assertSelectorContains('.measure[data-metric="lines_to_cover"]', '6/38');
+        test.assertSelectorContains('.measure[data-metric="conditions_to_cover"]', '6/38');
+        test.assertSelectorContains('.measure[data-metric="it_lines_to_cover"]', '31/37');
+        test.assertSelectorContains('.measure[data-metric="it_conditions_to_cover"]', '30/35');
+      })
+
+      .then(function () {
+        test.assertNotVisible('.measure[data-metric="file_complexity"]');
+        casper.click('.js-show-all-measures');
+        test.assertVisible('.measure[data-metric="file_complexity"]');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Details', 'Tests'), 39, function (test) {
+  casper
+      .start(lib.buildUrl('source-viewer'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/components/app', 'app-test.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/sources/lines', 'lines.json', { data: { uuid: 'uuid' } });
+        lib.mockRequestFromFile('/api/issues/search', 'issues-details.json', { data: { componentUuids: 'uuid' } });
+        lib.mockRequestFromFile('/api/metrics', 'metrics.json');
+        lib.mockRequestFromFile('/api/resources', 'measures-test.json',
+            { data: { resource: 'org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java' } });
+        lib.mockRequestFromFile('/api/tests/show', 'tests.json',
+            { data: { key: 'org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java' } });
+        lib.mockRequestFromFile('/api/tests/covered_files', 'covered-files.json', { data: {
+          key: 'org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java',
+          test: 'test1'
+        } });
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          window.file = { uuid: 'uuid', key: 'key' };
+          require(['/js/source-viewer/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.source-line');
+      })
+
+      .then(function () {
+        casper.click('.js-actions');
+        casper.waitForSelector('.js-measures');
+      })
+
+      .then(function () {
+        casper.click('.js-measures');
+        casper.waitForSelector('.measure[data-metric="tests"]');
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.measure[data-metric="tests"]', '1');
+        test.assertSelectorContains('.measure[data-metric="test_execution_time"]', '15 ms');
+
+        casper.waitForSelector('.source-viewer-test-name');
+      })
+
+      .then(function () {
+        test.assertElementCount('.source-viewer-test-name', 5);
+
+        test.assertElementCount('.source-viewer-test-status .icon-test-status-ok', 2);
+        test.assertElementCount('.source-viewer-test-status .icon-test-status-failure', 1);
+        test.assertElementCount('.source-viewer-test-status .icon-test-status-error', 1);
+        test.assertElementCount('.source-viewer-test-status .icon-test-status-skipped', 1);
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test4');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test1');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test5');
+
+        casper.click('.js-sort-tests-by-status');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test5');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test1');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test4');
+        casper.click('.js-sort-tests-by-status');
+
+        casper.click('.js-sort-tests-by-duration');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test4');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test1');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test5');
+
+        casper.click('.js-sort-tests-by-duration');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test5');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test1');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test4');
+
+        casper.click('.js-sort-tests-by-name');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test5');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test4');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test1');
+
+        casper.click('.js-sort-tests-by-name');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(2)', 'test1');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(3)', 'test2');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(4)', 'test3');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(5)', 'test4');
+        test.assertSelectorContains('.source-viewer-tests-list tr:nth-child(6)', 'test5');
+      })
+
+      .then(function () {
+        casper.click('.js-show-test[data-name="test1"]');
+        casper.waitForText('src/main/java/com/sonar/CoveredFile1.java');
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.js-selected-test', 'src/main/java/com/sonar/CoveredFile1.java');
+        test.assertSelectorContains('.js-selected-test', '2');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
index bfee785a15c63219317f83615e48d7cf1dfdff19..7fad540b881c8386eef3cdd43397b6d38c1c5f77 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa",
+  "uuid": "uuid",
   "key": "sample:sample",
   "path": "sample/path",
   "name": "Sample",
index 3b0947ab08bf093aef2e4d54520e65627e0e5e53..2ad6687a262c6f8aef273a8aaf10d6e157e86b88 100644 (file)
@@ -1,18 +1,18 @@
 {"sources": [
-  { "line": 1,  "code": "line 1" },
-  { "line": 2,  "code": "line 2" },
+  { "line": 1,  "code": "line 1", "utConditions": 2, "utCoveredConditions": 0 },
+  { "line": 2,  "code": "line 2", "itConditions": 2, "itCoveredConditions": 0 },
   { "line": 3,  "code": "line 3" },
   { "line": 4,  "code": "line 4" },
-  { "line": 5,  "code": "line 5" },
-  { "line": 6,  "code": "line 6" },
-  { "line": 7,  "code": "line 7" },
-  { "line": 8,  "code": "line 8" },
+  { "line": 5,  "code": "line 5", "utLineHits": 1, "utConditions": 2, "utCoveredConditions": 1 },
+  { "line": 6,  "code": "line 6", "utLineHits": 1, "utConditions": 2, "utCoveredConditions": 2 },
+  { "line": 7,  "code": "line 7", "itLineHits": 1, "itConditions": 2, "itCoveredConditions": 1 },
+  { "line": 8,  "code": "line 8", "itLineHits": 1, "itConditions": 2, "itCoveredConditions": 2 },
   { "line": 9,  "code": "line 9" },
   { "line": 10, "code": "line 10" },
   { "line": 11, "code": "line 11", "utLineHits": 3 },
-  { "line": 16, "code": "line 16" },
-  { "line": 17, "code": "line 17" },
-  { "line": 18, "code": "line 18" },
-  { "line": 19, "code": "line 19" },
-  { "line": 20, "code": "line 20" }
+  { "line": 12, "code": "line 12", "itLineHits": 1 },
+  { "line": 13, "code": "line 13" },
+  { "line": 14, "code": "line 14" },
+  { "line": 15, "code": "line 15" },
+  { "line": 16, "code": "line 16" }
 ]}
index db0ef3fb827e4ab1ae55afbb31a42b382e02e42b..92b9644fcbf3c41e27d7ac351715e20d1daa348e 100644 (file)
@@ -9,7 +9,7 @@
   ],
   "files": {
     "1": {
-      "uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbbb",
+      "uuid": "uuid",
       "key": "test:sample",
       "longName": "SampleTest"
     }
index bfee785a15c63219317f83615e48d7cf1dfdff19..7fad540b881c8386eef3cdd43397b6d38c1c5f77 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa",
+  "uuid": "uuid",
   "key": "sample:sample",
   "path": "sample/path",
   "name": "Sample",
index 8d4f832697a99a9dcebb90f06fd6cfef16465f69..172dd3a90ea8521f0a45a8134971762cbf51bbd6 100644 (file)
@@ -16,7 +16,7 @@
   ],
   "files": {
     "1": {
-      "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa",
+      "uuid": "uuid",
       "key": "sample:sample",
       "name": "Sample",
       "longName": "Sample",
index 7da4385b3a50351a3659796ac620db316742afda..8b16733fbf64ce7e3726069e5a77c668d2561f8b 100644 (file)
@@ -27,7 +27,7 @@
       "projectName": "Duplicated Project"
     },
     "1": {
-      "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa",
+      "uuid": "uuid",
       "key": "sample:sample",
       "name": "Sample",
       "longName": "Sample",
diff --git a/server/sonar-web/src/test/json/source-viewer-issues/app.json b/server/sonar-web/src/test/json/source-viewer-issues/app.json
new file mode 100644 (file)
index 0000000..2e32ef0
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "uuid": "uuid",
+  "key": "sample:sample",
+  "path": "sample/path",
+  "name": "Sample",
+  "longName": "Sample",
+  "q": "FIL",
+  "subProject": "sample:subproject",
+  "subProjectName": "Sample Sub-Project",
+  "project": "sample:project",
+  "projectName": "Sample Project",
+  "fav": false,
+  "canMarkAsFavourite": true,
+  "canCreateManualIssue": true,
+  "measures": {
+    "lines": "20",
+    "issues": "17"
+  }
+}
diff --git a/server/sonar-web/src/test/json/source-viewer-issues/issues.json b/server/sonar-web/src/test/json/source-viewer-issues/issues.json
new file mode 100644 (file)
index 0000000..6cde710
--- /dev/null
@@ -0,0 +1,272 @@
+{
+  "total": 6,
+  "p": 1,
+  "ps": 100,
+  "projects": [
+    {
+      "uuid": "69e57151-be0d-4157-adff-c06741d88879",
+      "key": "org.codehaus.sonar:sonar",
+      "id": 2865,
+      "qualifier": "TRK",
+      "name": "SonarQube",
+      "longName": "SonarQube"
+    }
+  ],
+  "components": [
+    {
+      "uuid": "83379565-7af3-4047-8d1a-ed42b10309b0",
+      "key": "org.codehaus.sonar:sonar-batch",
+      "id": 1624,
+      "enabled": true,
+      "qualifier": "BRC",
+      "name": "SonarQube :: Batch",
+      "longName": "SonarQube :: Batch",
+      "path": "sonar-batch",
+      "projectId": 2865,
+      "subProjectId": 2865
+    },
+    {
+      "uuid": "69e57151-be0d-4157-adff-c06741d88879",
+      "key": "org.codehaus.sonar:sonar",
+      "id": 2865,
+      "enabled": true,
+      "qualifier": "TRK",
+      "name": "SonarQube",
+      "longName": "SonarQube"
+    },
+    {
+      "uuid": "uuid",
+      "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "id": 19983,
+      "enabled": true,
+      "qualifier": "FIL",
+      "name": "Cache.java",
+      "longName": "src/main/java/org/sonar/batch/index/Cache.java",
+      "path": "src/main/java/org/sonar/batch/index/Cache.java",
+      "projectId": 2865,
+      "subProjectId": 1624
+    }
+  ],
+  "issues": [
+    {
+      "key": "20002ec7-b647-44da-bdf5-4d9fbf4b7c58",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "common-java:DuplicatedBlocks",
+      "status": "CONFIRMED",
+      "severity": "MAJOR",
+      "message": "2 duplicated blocks of code.",
+      "debt": "2h",
+      "creationDate": "2014-05-01T23:38:31+0200",
+      "updateDate": "2014-07-01T17:48:47+0200",
+      "fUpdateAge": "5 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    },
+    {
+      "key": "e4de6481-7bfb-460a-8b3c-24459f9561d3",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "squid:S1135",
+      "status": "CONFIRMED",
+      "severity": "INFO",
+      "message": "Complete the task associated to this TODO comment.",
+      "line": 2,
+      "author": "Simon Brandhof",
+      "creationDate": "2013-08-09T16:04:33+0200",
+      "updateDate": "2014-07-29T23:15:18+0200",
+      "fUpdateAge": "4 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    },
+    {
+      "key": "59fc17f7-c977-4cb6-8f04-fbe88e4b9186",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "squid:S1192",
+      "status": "CONFIRMED",
+      "severity": "MINOR",
+      "message": "Define a constant instead of duplicating this literal \"Fail to get keys from cache \" 3 times.",
+      "line": 2,
+      "debt": "10min",
+      "author": "simon.brandhof@gmail.com",
+      "creationDate": "2014-02-20T07:48:16+0100",
+      "updateDate": "2014-02-24T16:57:34+0100",
+      "fUpdateAge": "9 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    },
+    {
+      "key": "71a26f48-a90d-4a76-a745-4f6e6e8b1773",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "squid:S1135",
+      "status": "CONFIRMED",
+      "severity": "INFO",
+      "message": "Complete the task associated to this TODO comment.",
+      "line": 12,
+      "author": "simon.brandhof@gmail.com",
+      "creationDate": "2013-10-10T23:51:33+0200",
+      "updateDate": "2014-07-29T23:15:18+0200",
+      "fUpdateAge": "4 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    },
+    {
+      "key": "01461208-6c1e-4cdf-9f27-b7afa78e76ec",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "squid:S1135",
+      "status": "CONFIRMED",
+      "severity": "INFO",
+      "message": "Complete the task associated to this TODO comment.",
+      "line": 14,
+      "author": "simon.brandhof@gmail.com",
+      "creationDate": "2013-10-10T23:51:33+0200",
+      "updateDate": "2014-07-29T23:15:18+0200",
+      "fUpdateAge": "4 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    },
+    {
+      "key": "75419c88-0e3c-4311-aa47-fe5731e67558",
+      "component": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+      "componentId": 19983,
+      "project": "org.codehaus.sonar:sonar",
+      "subProject": "org.codehaus.sonar:sonar-batch",
+      "rule": "squid:S1135",
+      "status": "CONFIRMED",
+      "severity": "INFO",
+      "message": "Complete the task associated to this TODO comment.",
+      "line": 15,
+      "author": "simon.brandhof@gmail.com",
+      "creationDate": "2013-10-10T23:51:33+0200",
+      "updateDate": "2014-07-29T23:15:18+0200",
+      "fUpdateAge": "4 months",
+      "actions": [
+        "comment",
+        "assign",
+        "assign_to_me",
+        "plan",
+        "set_severity"
+      ],
+      "transitions": [
+        "unconfirm",
+        "resolve",
+        "falsepositive"
+      ]
+    }
+  ],
+  "rules": [
+    {
+      "key": "common-java:DuplicatedBlocks",
+      "name": "Duplicated blocks",
+      "lang": "java",
+      "desc": "<p>An issue is created on a file as soon as there is a block of duplicated code on this file. It gives the number of blocks in the file.</p>",
+      "status": "READY",
+      "langName": "Java"
+    },
+    {
+      "key": "squid:S1192",
+      "name": "String literals should not be duplicated",
+      "lang": "java",
+      "desc": "<p>\n  Duplicated string literals make the process of refactoring error-prone, since you must be sure to update all occurrences.\n  On the other hand, constants can be referenced from many places, but only need to be updated in a single place.\n</p>\n\n<h2>Non Compliant Code Example</h2>\n\n<pre>\npublic void run() {\n  prepare(\"action1\");                              // Non-Compliant - \"action1\" is duplicated 3 times\n  execute(\"action1\");\n  release(\"action1\");\n}\n\n@SuppressWarning(\"all\")                            // Compliant - annotations are excluded\nprivate void method1() { /* ... */ }\n@SuppressWarning(\"all\")\nprivate void method2() { /* ... */ }\n\npublic String method3(String a) {\n  System.out.println(\"'\" + a + \"'\");               // Compliant - literal \"'\" has less than 5 characters and is excluded\n  return \"\";                                       // Compliant - literal \"\" has less than 5 characters and is excluded\n}\n</pre>\n\n<h2>Compliant Code Example</h2>\n\n<pre>\nprivate static final String ACTION_1 = \"action1\";  // Compliant\n\npublic void run() {\n  prepare(ACTION_1);                               // Compliant\n  execute(ACTION_1);\n  release(ACTION_1);\n}\n</pre>\n\n<h2>Exceptions</h2>\n<p>To prevent generating some false-positives, literals having less than 5 characters are excluded.</p>",
+      "status": "READY",
+      "langName": "Java"
+    },
+    {
+      "key": "squid:S1135",
+      "name": "TODO tags should be handled",
+      "lang": "java",
+      "desc": "<p>\n<code>TODO</code> tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.\nSometimes the developer will not have the time or will simply forget to get back to that tag.\nThis rule is meant to track those tags, and ensure that they do not go unnoticed.\n</p>\n\n<p>The following code illustrates this rule:</p>\n\n<pre>\nvoid doSomething() {\n  // TODO\n}\n</pre>",
+      "status": "READY",
+      "langName": "Java"
+    }
+  ],
+  "users": [
+    {
+      "login": "admin",
+      "name": "Admin Admin",
+      "active": true,
+      "email": "admin@sonarsource.com"
+    }
+  ],
+  "languages": [
+    {
+      "key": "js",
+      "name": "JavaScript"
+    },
+    {
+      "key": "java",
+      "name": "Java"
+    }
+  ],
+  "maxResultsReached": false,
+  "paging": {
+    "pageIndex": 1,
+    "pageSize": 100,
+    "total": 6,
+    "fTotal": "6",
+    "pages": 1
+  }
+}
diff --git a/server/sonar-web/src/test/json/source-viewer-issues/lines.json b/server/sonar-web/src/test/json/source-viewer-issues/lines.json
new file mode 100644 (file)
index 0000000..7c753b2
--- /dev/null
@@ -0,0 +1,18 @@
+{"sources": [
+  { "line": 1,  "code": "line 1" },
+  { "line": 2,  "code": "line 2" },
+  { "line": 3,  "code": "line 3" },
+  { "line": 4,  "code": "line 4" },
+  { "line": 5,  "code": "line 5" },
+  { "line": 6,  "code": "line 6" },
+  { "line": 7,  "code": "line 7" },
+  { "line": 8,  "code": "line 8" },
+  { "line": 9,  "code": "line 9" },
+  { "line": 10, "code": "line 10" },
+  { "line": 11, "code": "line 11" },
+  { "line": 12, "code": "line 12" },
+  { "line": 13, "code": "line 13" },
+  { "line": 14, "code": "line 14" },
+  { "line": 15, "code": "line 15" },
+  { "line": 16, "code": "line 16" }
+]}
index bfee785a15c63219317f83615e48d7cf1dfdff19..7fad540b881c8386eef3cdd43397b6d38c1c5f77 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa",
+  "uuid": "uuid",
   "key": "sample:sample",
   "path": "sample/path",
   "name": "Sample",
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/app-test.json b/server/sonar-web/src/test/json/source-viewer-spec/app-test.json
new file mode 100644 (file)
index 0000000..a51b743
--- /dev/null
@@ -0,0 +1,24 @@
+{
+  "uuid": "uuid",
+  "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+  "path": "src/main/java/org/sonar/batch/index/Cache.java",
+  "name": "Cache.java",
+  "longName": "src/main/java/org/sonar/batch/index/Cache.java",
+  "q": "UTS",
+  "subProject": "org.codehaus.sonar:sonar-batch",
+  "subProjectName": "SonarQube :: Batch",
+  "project": "org.codehaus.sonar:sonar",
+  "projectName": "SonarQube",
+  "fav": false,
+  "canMarkAsFavourite": true,
+  "canCreateManualIssue": true,
+  "measures": {
+    "lines": "378",
+    "coverage": "74.3%",
+    "duplicationDensity": "5.8%",
+    "debt": "2h 10min",
+    "sqaleRating": "A",
+    "debtRatio": "1.1%",
+    "issues": "6"
+  }
+}
index dd6a3fb900feebfe1346320cdfe534e189cc65b6..2e4139e4d0eb65b2580c2f11016c9b7a50a20208 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "uuid": "12345",
+  "uuid": "uuid",
   "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
   "path": "src/main/java/org/sonar/batch/index/Cache.java",
   "name": "Cache.java",
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/covered-files.json b/server/sonar-web/src/test/json/source-viewer-spec/covered-files.json
new file mode 100644 (file)
index 0000000..210d080
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "key": "covered-file1",
+      "longName": "src/main/java/com/sonar/CoveredFile1.java",
+      "coveredLines": 2
+    }
+  ]
+}
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/issues-details.json b/server/sonar-web/src/test/json/source-viewer-spec/issues-details.json
new file mode 100644 (file)
index 0000000..201535b
--- /dev/null
@@ -0,0 +1,46 @@
+{
+  "total": 6,
+  "p": 1,
+  "ps": 100,
+  "issues": [],
+  "facets": [
+    {
+      "property": "severities",
+      "values": [
+        {
+          "val": "INFO",
+          "count": 5
+        },
+        {
+          "val": "MINOR",
+          "count": 4
+        },
+        {
+          "val": "MAJOR",
+          "count": 3
+        },
+        {
+          "val": "CRITICAL",
+          "count": 2
+        },
+        {
+          "val": "BLOCKER",
+          "count": 1
+        }
+      ]
+    },
+    {
+      "property": "tags",
+      "values": [
+        {
+          "val": "bug",
+          "count": 8
+        },
+        {
+          "val": "sql",
+          "count": 7
+        }
+      ]
+    }
+  ]
+}
index 2983d8e4728e9a5521b6f3e65b3aa5581b85b09e..2e50415266c455211e11fb8d6e10588693257bec 100644 (file)
   },
   {
     "line": 22,
-    "code": "<span class=\"k\">import </span>com.google.common.collect.<span class=\"sym-1 sym\">Sets</span>;",
+    "code": "<span class=\"k\">import </span>com.google.common.collect.<span class=\"sym-9999 sym\">Sets</span>;",
     "scmAuthor": "simon.brandhof@gmail.com",
     "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb",
     "scmDate": "2013-04-16T17:26:34+0200"
   },
   {
     "line": 24,
-    "code": "<span class=\"k\">import </span>com.persistit.<span class=\"sym-3 sym\">Key</span>;",
+    "code": "<span class=\"k\">import </span>com.persistit.<span class=\"sym-9999 sym\">Key</span>;",
     "scmAuthor": "simon.brandhof@gmail.com",
     "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb",
     "scmDate": "2013-04-16T17:26:34+0200"
   },
   {
     "line": 25,
-    "code": "<span class=\"k\">import </span>com.persistit.<span class=\"sym-4 sym\">KeyFilter</span>;",
+    "code": "<span class=\"k\">import </span>com.persistit.<span class=\"sym-9999 sym\">KeyFilter</span>;",
     "scmAuthor": "julien.henry@sonarsource.com",
     "scmRevision": "cc071cc29e8c4d4592282313a3ca2ec376fd7f71",
     "scmDate": "2014-05-01T00:00:12+0200"
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/measures-test.json b/server/sonar-web/src/test/json/source-viewer-spec/measures-test.json
new file mode 100644 (file)
index 0000000..db45276
--- /dev/null
@@ -0,0 +1,25 @@
+[
+  {
+    "id": 33667,
+    "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+    "name": "Cache.java",
+    "scope": "FIL",
+    "qualifier": "FIL",
+    "date": "2015-04-22T10:40:40+0200",
+    "creationDate": "2014-07-11T23:32:19+0200",
+    "lname": "src/main/java/org/sonar/batch/index/Cache.java",
+    "lang": "java",
+    "msr": [
+      {
+        "key": "tests",
+        "val": 1,
+        "frmt_val": "1"
+      },
+      {
+        "key": "test_execution_time",
+        "val": 15,
+        "frmt_val": "15 ms"
+      }
+    ]
+  }
+]
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/measures.json b/server/sonar-web/src/test/json/source-viewer-spec/measures.json
new file mode 100644 (file)
index 0000000..4b56c11
--- /dev/null
@@ -0,0 +1,136 @@
+[
+  {
+    "id": 33667,
+    "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java",
+    "name": "Cache.java",
+    "scope": "FIL",
+    "qualifier": "FIL",
+    "date": "2015-04-22T10:40:40+0200",
+    "creationDate": "2014-07-11T23:32:19+0200",
+    "lname": "src/main/java/org/sonar/batch/index/Cache.java",
+    "lang": "java",
+    "msr": [
+      {
+        "key": "lines",
+        "val": 92,
+        "frmt_val": "92"
+      },
+      {
+        "key": "ncloc",
+        "val": 57,
+        "frmt_val": "57"
+      },
+      {
+        "key": "classes",
+        "val": 0,
+        "frmt_val": "0"
+      },
+      {
+        "key": "files",
+        "val": 1,
+        "frmt_val": "1"
+      },
+      {
+        "key": "functions",
+        "val": 12,
+        "frmt_val": "12"
+      },
+      {
+        "key": "statements",
+        "val": 34,
+        "frmt_val": "34"
+      },
+      {
+        "key": "comment_lines",
+        "val": 14,
+        "frmt_val": "14"
+      },
+      {
+        "key": "comment_lines_density",
+        "val": 19.7,
+        "frmt_val": "19.7%"
+      },
+      {
+        "key": "complexity",
+        "val": 22,
+        "frmt_val": "22"
+      },
+      {
+        "key": "function_complexity",
+        "val": 4.9,
+        "frmt_val": "4.9"
+      },
+      {
+        "key": "file_complexity",
+        "val": 22,
+        "frmt_val": "22.0"
+      },
+      {
+        "key": "coverage",
+        "val": 11.3,
+        "frmt_val": "11.3%"
+      },
+      {
+        "key": "lines_to_cover",
+        "val": 38,
+        "frmt_val": "38"
+      },
+      {
+        "key": "uncovered_lines",
+        "val": 32,
+        "frmt_val": "32"
+      },
+      {
+        "key": "it_lines_to_cover",
+        "val": 37,
+        "frmt_val": "37"
+      },
+      {
+        "key": "it_uncovered_lines",
+        "val": 31,
+        "frmt_val": "31"
+      },
+      {
+        "key": "line_coverage",
+        "val": 15.8,
+        "frmt_val": "15.8%"
+      },
+      {
+        "key": "uncovered_conditions",
+        "val": 15,
+        "frmt_val": "15"
+      },
+      {
+        "key": "branch_coverage",
+        "val": 0,
+        "frmt_val": "0.0%"
+      },
+      {
+        "key": "conditions_to_cover",
+        "val": 38,
+        "frmt_val": "38"
+      },
+      {
+        "key": "uncovered_conditions",
+        "val": 32,
+        "frmt_val": "32"
+      },
+      {
+        "key": "it_conditions_to_cover",
+        "val": 35,
+        "frmt_val": "35"
+      },
+      {
+        "key": "it_uncovered_conditions",
+        "val": 30,
+        "frmt_val": "30"
+      },
+      {
+        "key": "sqale_rating",
+        "val": 1,
+        "frmt_val": "A",
+        "data": "A"
+      }
+    ]
+  }
+]
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/metrics.json b/server/sonar-web/src/test/json/source-viewer-spec/metrics.json
new file mode 100644 (file)
index 0000000..1951c52
--- /dev/null
@@ -0,0 +1,1839 @@
+[
+  {
+    "key": "burned_budget",
+    "name": "Burned budget",
+    "description": "",
+    "domain": "Management",
+    "qualitative": false,
+    "user_managed": true,
+    "direction": 0,
+    "val_type": "FLOAT",
+    "hidden": false
+  },
+  {
+    "key": "business_value",
+    "name": "Business value",
+    "description": "",
+    "domain": "Management",
+    "qualitative": true,
+    "user_managed": true,
+    "direction": 1,
+    "val_type": "FLOAT",
+    "hidden": false
+  },
+  {
+    "key": "team_size",
+    "name": "Team size",
+    "description": "",
+    "domain": "Management",
+    "qualitative": false,
+    "user_managed": true,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "conditions_by_line",
+    "name": "Conditions by line",
+    "description": "Conditions by line",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "public_undocumented_api",
+    "name": "Public undocumented API",
+    "description": "Public undocumented classes, functions and variables",
+    "domain": "Documentation",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "complexity",
+    "name": "Complexity",
+    "description": "Cyclomatic complexity",
+    "domain": "Complexity",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "tests",
+    "name": "Unit tests",
+    "description": "Number of unit tests",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "files",
+    "name": "Files",
+    "description": "Number of files",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "coverage_line_hits_data",
+    "name": "Coverage hits by line",
+    "description": "Coverage hits by line",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "function_complexity_distribution",
+    "name": "Functions distribution /complexity",
+    "description": "Functions distribution /complexity",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": false
+  },
+  {
+    "key": "functions",
+    "name": "Functions",
+    "description": "Functions",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "quality_gate_details",
+    "name": "Quality Gate Details",
+    "description": "The project detailed status with regard to its quality gate.",
+    "domain": "General",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "package_tangles",
+    "name": "File dependencies to cut",
+    "description": "File dependencies to cut",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "projects_in_warning",
+    "name": "List of projects in warning",
+    "description": "",
+    "domain": null,
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "STRING",
+    "hidden": true
+  },
+  {
+    "key": "false_positive_issues",
+    "name": "False positive issues",
+    "description": "False positive issues",
+    "domain": "Issues",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "comment_lines",
+    "name": "Comment lines",
+    "description": "Number of comment lines",
+    "domain": "Documentation",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "skipped_tests",
+    "name": "Skipped unit tests",
+    "description": "Number of skipped unit tests",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "duplicated_lines",
+    "name": "Duplicated lines",
+    "description": "Duplicated lines",
+    "domain": "Duplication",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "overall_covered_conditions_by_line",
+    "name": "Overall covered conditions by line",
+    "description": "Overall covered conditions by all tests and by line",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "branch_coverage",
+    "name": "Condition coverage",
+    "description": "Condition coverage",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "blocker_remediation_cost",
+    "name": "Blocker Technical Debt",
+    "description": "Remediation cost required to remove all blocker issues.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "it_line_coverage",
+    "name": "IT line coverage",
+    "description": "Line coverage by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "package_cycles",
+    "name": "Package cycles",
+    "description": "Package cycles",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "directories",
+    "name": "Directories",
+    "description": "Directories",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_it_uncovered_conditions",
+    "name": "Uncovered conditions by IT on new code",
+    "description": "New conditions that are not covered by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "lines",
+    "name": "Lines",
+    "description": "Lines",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "complexity_in_classes",
+    "name": "Complexity in classes",
+    "description": "Cyclomatic complexity in classes",
+    "domain": "Complexity",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "clirr_total_api_changes",
+    "name": "Total API Changes",
+    "description": "Number of API changes",
+    "domain": "API compatibility",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "it_coverage_line_hits_data",
+    "name": "IT coverage hits by line",
+    "description": "Coverage hits by line by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "new_minor_violations",
+    "name": "New Minor issues",
+    "description": "New Minor issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "packages",
+    "name": "Packages",
+    "description": "Packages",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_major_violations",
+    "name": "New Major issues",
+    "description": "New Major issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_effort_to_grade_a",
+    "name": "Effort to rating A",
+    "description": "Remediation cost required to reach rating A.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "ncloc_language_distribution",
+    "name": "Lines of code per language",
+    "description": "Non Commenting Lines of Code Distributed By Language",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "package_edges_weight",
+    "name": "Package edges weight",
+    "description": "Package edges weight",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "package_feedback_edges",
+    "name": "Package dependencies to cut",
+    "description": "Package dependencies to cut",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "file_tangle_index",
+    "name": "File tangle index",
+    "description": "File tangle index",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "PERCENT",
+    "hidden": true
+  },
+  {
+    "key": "dit",
+    "name": "Depth in Tree",
+    "description": "Depth in Inheritance Tree",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "blocker_violations",
+    "name": "Blocker issues",
+    "description": "Blocker issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "projects",
+    "name": "Projects",
+    "description": "Number of projects",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "overall_coverage_line_hits_data",
+    "name": "Overall coverage hits by line",
+    "description": "Coverage hits by all tests and by line",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "revisions_by_line",
+    "name": "Revisions by line",
+    "description": "Revisions by line",
+    "domain": "SCM",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "open_issues",
+    "name": "Open issues",
+    "description": "Open issues",
+    "domain": "Issues",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "uncovered_conditions",
+    "name": "Uncovered conditions",
+    "description": "Uncovered conditions",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "noc",
+    "name": "Number of Children",
+    "description": "Number of Children",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "generated_ncloc",
+    "name": "Generated lines of code",
+    "description": "Generated non Commenting Lines of Code",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_conditions_to_cover",
+    "name": "Conditions to cover on new code",
+    "description": "Conditions to cover on new code",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_overall_coverage",
+    "name": "Overall coverage on new code",
+    "description": "Overall coverage of new/changed code",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "overall_coverage",
+    "name": "Overall coverage",
+    "description": "Overall test coverage",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "minor_violations",
+    "name": "Minor issues",
+    "description": "Minor issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "cpp-parse-errors",
+    "name": "C/C++ parse errors",
+    "description": "Parse errors",
+    "domain": "Size",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "package_tangle_index",
+    "name": "Package tangle index",
+    "description": "Package tangle index",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "violations",
+    "name": "Issues",
+    "description": "Issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "info_violations",
+    "name": "Info issues",
+    "description": "Info issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "lines_to_cover",
+    "name": "Lines to cover",
+    "description": "Lines to cover",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "overall_branch_coverage",
+    "name": "Overall condition coverage",
+    "description": "Condition coverage by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "info_remediation_cost",
+    "name": "Info and over Technical Debt",
+    "description": "",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "authors_by_line",
+    "name": "Authors by line",
+    "description": "Authors by line",
+    "domain": "SCM",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "suspect_lcom4_density",
+    "name": "Suspect LCOM4 density",
+    "description": "Density of classes having LCOM4>1",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "PERCENT",
+    "hidden": true
+  },
+  {
+    "key": "duplicated_blocks",
+    "name": "Duplicated blocks",
+    "description": "Duplicated blocks",
+    "domain": "Duplication",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "ncloc_data",
+    "name": "ncloc_data",
+    "description": "",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": true
+  },
+  {
+    "key": "temp-method-lines",
+    "name": "Temp info on method lines",
+    "description": "",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "lcom4",
+    "name": "LCOM4",
+    "description": "Lack of Cohesion of Functions",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "FLOAT",
+    "hidden": true
+  },
+  {
+    "key": "test_execution_time",
+    "name": "Unit tests duration",
+    "description": "Execution duration of unit tests",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "MILLISEC",
+    "hidden": false
+  },
+  {
+    "key": "new_it_lines_to_cover",
+    "name": "Lines to cover by IT on new code",
+    "description": "Lines to cover on new code by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "it_conditions_to_cover",
+    "name": "IT conditions to cover",
+    "description": "Conditions to cover by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_violations",
+    "name": "New issues",
+    "description": "New issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "statements",
+    "name": "Statements",
+    "description": "Number of statements",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "test_success_density",
+    "name": "Unit tests success (%)",
+    "description": "Density of successful unit tests",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_rating_file_distribution",
+    "name": "SQALE Rating File Distribution",
+    "description": "Number of elements for given SQALE ratings.",
+    "domain": "SQALE",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": false
+  },
+  {
+    "key": "overall_uncovered_conditions",
+    "name": "Overall uncovered conditions",
+    "description": "Uncovered conditions by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "public_api",
+    "name": "Public API",
+    "description": "Public API",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "issues",
+    "name": "JIRA Issues",
+    "description": "Number of JIRA Issues",
+    "domain": "Issues",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "test_errors",
+    "name": "Unit tests errors",
+    "description": "Number of unit test errors",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_it_conditions_to_cover",
+    "name": "Conditions to cover by IT on new code",
+    "description": "New conditions to cover by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "it_covered_conditions_by_line",
+    "name": "IT covered conditions by line",
+    "description": "IT covered conditions by line",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "confirmed_issues",
+    "name": "Confirmed issues",
+    "description": "Confirmed issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_effort_to_grade_b",
+    "name": "Effort to rating B",
+    "description": "Remediation cost required to reach rating B.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "uncovered_lines",
+    "name": "Uncovered lines",
+    "description": "Uncovered lines",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_overall_line_coverage",
+    "name": "Overall line coverage on new code",
+    "description": "Line coverage of added/changed code by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "it_branch_coverage",
+    "name": "IT condition coverage",
+    "description": "Condition coverage by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "it_uncovered_lines",
+    "name": "IT uncovered lines",
+    "description": "Uncovered lines by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_debt_ratio",
+    "name": "Technical Debt Ratio",
+    "description": "Ratio of the actual technical debt compared to the estimated cost to develop the whole source code from scratch.",
+    "domain": "Technical Debt",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "class_complexity_distribution",
+    "name": "Classes distribution /complexity",
+    "description": "Classes distribution /complexity",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": true
+  },
+  {
+    "key": "file_edges_weight",
+    "name": "File edges weight",
+    "description": "File edges weight",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_overall_uncovered_lines",
+    "name": "Overall uncovered lines on new code",
+    "description": "New lines that are not covered by any tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_effort_to_grade_d",
+    "name": "Effort to rating D",
+    "description": "Remediation cost required to reach rating D.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "coverage",
+    "name": "Coverage",
+    "description": "Coverage by unit tests",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "duplication_lines_data",
+    "name": "duplication_lines_data",
+    "description": "",
+    "domain": "Duplication",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": true
+  },
+  {
+    "key": "overall_lines_to_cover",
+    "name": "Overall lines to cover",
+    "description": "Lines to cover by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "minor_remediation_cost",
+    "name": "Minor and over Technical Debt",
+    "description": "Remediation cost required to remove all minor, major, critical and blocker issues.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "overall_conditions_to_cover",
+    "name": "Overall conditions to cover",
+    "description": "Conditions to cover by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "ncloc",
+    "name": "Lines of code",
+    "description": "Non Commenting Lines of Code",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_info_violations",
+    "name": "New Info issues",
+    "description": "New Info issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "comment_lines_data",
+    "name": "comment_lines_data",
+    "description": "",
+    "domain": "Documentation",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": true
+  },
+  {
+    "key": "new_technical_debt",
+    "name": "Added Technical Debt",
+    "description": "Added Technical Debt",
+    "domain": "Technical Debt",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "it_uncovered_conditions",
+    "name": "IT uncovered conditions",
+    "description": "Uncovered conditions by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_overall_branch_coverage",
+    "name": "Overall condition coverage on new code",
+    "description": "Condition coverage of new/changed code by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "accessors",
+    "name": "Accessors",
+    "description": "Accessors",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "major_violations",
+    "name": "Major issues",
+    "description": "Major issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "comment_lines_density",
+    "name": "Comments (%)",
+    "description": "Comments balanced by ncloc + comment lines",
+    "domain": "Documentation",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "new_overall_conditions_to_cover",
+    "name": "Overall conditions to cover on new code",
+    "description": "New conditions to cover by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "file_complexity",
+    "name": "Complexity /file",
+    "description": "Complexity average by file",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "FLOAT",
+    "hidden": false
+  },
+  {
+    "key": "classes",
+    "name": "Classes",
+    "description": "Classes",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_uncovered_conditions",
+    "name": "Uncovered conditions on new code",
+    "description": "Uncovered conditions on new code",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "overall_uncovered_lines",
+    "name": "Overall uncovered lines",
+    "description": "Uncovered lines by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "public_documented_api_density",
+    "name": "Public documented API (%)",
+    "description": "Public documented classes and functions balanced by ncloc",
+    "domain": "Documentation",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "major_remediation_cost",
+    "name": "Major and over Technical Debt",
+    "description": "Remediation cost required to remove all major, critical and blocker issues.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "file_cycles",
+    "name": "File cycles",
+    "description": "File cycles",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "clirr_new_api",
+    "name": "New API",
+    "description": "Number of new API",
+    "domain": "API compatibility",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "file_tangles",
+    "name": "File tangles",
+    "description": "Files tangles",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_blocker_violations",
+    "name": "New Blocker issues",
+    "description": "New Blocker issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "useless-duplicated-lines",
+    "name": "Useless Duplicated Lines",
+    "description": "Number of duplicated lines that could be reduced\"",
+    "domain": "Duplication",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "it_coverage",
+    "name": "IT coverage",
+    "description": "Integration tests coverage",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "clirr_api_behavior_changes",
+    "name": "API behavior changes",
+    "description": "Number of API changes which change the previous API behavior",
+    "domain": "API compatibility",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "critical_remediation_cost",
+    "name": "Critical and over Technical Debt",
+    "description": "Remediation cost required to remove all critical and blocker issues.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "new_line_coverage",
+    "name": "Line coverage on new code",
+    "description": "Line coverage of added/changed code",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "overall_conditions_by_line",
+    "name": "Overall conditions by line",
+    "description": "Overall conditions by all tests and by line",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "new_coverage",
+    "name": "Coverage on new code",
+    "description": "Coverage of new/changed code",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "development_cost",
+    "name": "SQALE Development Cost",
+    "description": "",
+    "domain": "Technical Debt",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "STRING",
+    "hidden": true
+  },
+  {
+    "key": "function_complexity",
+    "name": "Complexity /function",
+    "description": "Complexity average by function",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "FLOAT",
+    "hidden": false
+  },
+  {
+    "key": "new_lines_to_cover",
+    "name": "Lines to cover on new code",
+    "description": "Lines to cover on new code",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "rfc",
+    "name": "Response for Class",
+    "description": "Response for Class",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "critical_violations",
+    "name": "Critical issues",
+    "description": "Critical issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "conditions_to_cover",
+    "name": "Conditions to cover",
+    "description": "Conditions to cover",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "covered_conditions_by_line",
+    "name": "Covered conditions by line",
+    "description": "Covered conditions by line",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "new_it_coverage",
+    "name": "Coverage by IT on new code",
+    "description": "Integration tests coverage of new/changed code",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "profile_version",
+    "name": "Profile version",
+    "description": "Selected quality profile version",
+    "domain": "General",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_it_line_coverage",
+    "name": "Line coverage by IT on new code",
+    "description": "Integration tests line coverage of added/changed code",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "total-useless-lines",
+    "name": "Total Useless Code",
+    "description": "Number of lines that can be reduced",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "dsm",
+    "name": "Dependency Matrix",
+    "description": "Dependency Matrix",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "profile",
+    "name": "Profile",
+    "description": "Selected quality profile",
+    "domain": "General",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "reopened_issues",
+    "name": "Reopened issues",
+    "description": "Reopened issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_overall_lines_to_cover",
+    "name": "Overall lines to cover on new code",
+    "description": "New lines to cover by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_it_uncovered_lines",
+    "name": "Uncovered lines by IT on new code",
+    "description": "New lines that are not covered by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "lcom4_distribution",
+    "name": "Class distribution /LCOM4",
+    "description": "Class distribution /LCOM4",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": true
+  },
+  {
+    "key": "overall_line_coverage",
+    "name": "Overall line coverage",
+    "description": "Line coverage by all tests",
+    "domain": "Tests (Overall)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "sqale_effort_to_grade_c",
+    "name": "Effort to rating C",
+    "description": "Remediation cost required to reach rating C.",
+    "domain": "SQALE",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "sqale_rating",
+    "name": "SQALE Rating",
+    "description": "Rating of the technical debt ratio based on the SQALE Governance Model.",
+    "domain": "Technical Debt",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "RATING",
+    "hidden": false
+  },
+  {
+    "key": "line_coverage",
+    "name": "Line coverage",
+    "description": "Line coverage",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "commented_out_code_lines",
+    "name": "Commented-out LOC",
+    "description": "Commented lines of code",
+    "domain": "Documentation",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "class_complexity",
+    "name": "Complexity /class",
+    "description": "Complexity average by class",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "FLOAT",
+    "hidden": false
+  },
+  {
+    "key": "it_conditions_by_line",
+    "name": "IT conditions by line",
+    "description": "IT conditions by line",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "duplicated_lines_density",
+    "name": "Duplicated lines (%)",
+    "description": "Duplicated lines balanced by statements",
+    "domain": "Duplication",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "new_branch_coverage",
+    "name": "Condition coverage on new code",
+    "description": "Condition coverage of new/changed code",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "days_since_last_commit",
+    "name": "Days since last commit",
+    "description": "",
+    "domain": "SCM",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "duplicated_files",
+    "name": "Duplicated files",
+    "description": "Duplicated files",
+    "domain": "Duplication",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "clirr_api_breaks",
+    "name": "API breaks",
+    "description": "Number of API changes which break the backward compatibility",
+    "domain": "API compatibility",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "alert_status",
+    "name": "Quality Gate Status",
+    "description": "The project status with regard to its quality gate.",
+    "domain": "General",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "LEVEL",
+    "hidden": false
+  },
+  {
+    "key": "it_lines_to_cover",
+    "name": "IT lines to cover",
+    "description": "Lines to cover by integration tests",
+    "domain": "Tests (Integration)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "file_complexity_distribution",
+    "name": "Files distribution /complexity",
+    "description": "Files distribution /complexity",
+    "domain": "Complexity",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": false
+  },
+  {
+    "key": "last_commit_datetimes_by_line",
+    "name": "Last commit dates by line",
+    "description": "Last commit dates by line",
+    "domain": "SCM",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "rfc_distribution",
+    "name": "Class distribution /RFC",
+    "description": "Class distribution /RFC",
+    "domain": "Design",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DISTRIB",
+    "hidden": true
+  },
+  {
+    "key": "test_failures",
+    "name": "Unit tests failures",
+    "description": "Number of unit test failures",
+    "domain": "Tests",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "test_data",
+    "name": "Unit tests details",
+    "description": "Unit tests details",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "sqale_index",
+    "name": "Technical Debt",
+    "description": "Total effort (in days) to fix all the issues on the component and therefore to comply to all the requirements.",
+    "domain": "Technical Debt",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "WORK_DUR",
+    "hidden": false
+  },
+  {
+    "key": "file_feedback_edges",
+    "name": "Suspect file dependencies",
+    "description": "Suspect file dependencies",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_critical_violations",
+    "name": "New Critical issues",
+    "description": "New Critical issues",
+    "domain": "Issues",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "new_overall_uncovered_conditions",
+    "name": "Overall uncovered conditions on new code",
+    "description": "New conditions that are not covered by any test",
+    "domain": "Tests (Overall)",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "complexity_in_functions",
+    "name": "Complexity in functions",
+    "description": "Cyclomatic complexity in functions",
+    "domain": "Complexity",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": true
+  },
+  {
+    "key": "new_uncovered_lines",
+    "name": "Uncovered lines on new code",
+    "description": "Uncovered lines on new code",
+    "domain": "Tests",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "lcom4_blocks",
+    "name": "LCOM4 blocks",
+    "description": "LCOM4 blocks",
+    "domain": "Design",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": true
+  },
+  {
+    "key": "new_it_branch_coverage",
+    "name": "Condition coverage by IT on new code",
+    "description": "Integration tests condition coverage of new/changed code",
+    "domain": "Tests (Integration)",
+    "qualitative": true,
+    "user_managed": false,
+    "direction": 1,
+    "val_type": "PERCENT",
+    "hidden": false
+  },
+  {
+    "key": "generated_lines",
+    "name": "Generated Lines",
+    "description": "Number of generated lines",
+    "domain": "Size",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": -1,
+    "val_type": "INT",
+    "hidden": false
+  },
+  {
+    "key": "projects_in_error",
+    "name": "List of projects in error",
+    "description": "",
+    "domain": null,
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "STRING",
+    "hidden": true
+  },
+  {
+    "key": "duplications_data",
+    "name": "Duplications details",
+    "description": "Duplications details",
+    "domain": "Duplication",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": false
+  },
+  {
+    "key": "quality_profiles",
+    "name": "Profiles",
+    "description": "Details of quality profiles used during analysis",
+    "domain": "General",
+    "qualitative": false,
+    "user_managed": false,
+    "direction": 0,
+    "val_type": "DATA",
+    "hidden": true
+  }
+]
diff --git a/server/sonar-web/src/test/json/source-viewer-spec/tests.json b/server/sonar-web/src/test/json/source-viewer-spec/tests.json
new file mode 100644 (file)
index 0000000..70720d6
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "tests": [
+    {
+      "name": "test1",
+      "status": "OK",
+      "durationInMs": 15,
+      "coveredLines": 2
+    },
+    {
+      "name": "test2",
+      "status": "OK",
+      "durationInMs": 13,
+      "coveredLines": 3
+    },
+    {
+      "name": "test3",
+      "status": "FAILURE",
+      "durationInMs": 14,
+      "coveredLines": 1
+    },
+    {
+      "name": "test4",
+      "status": "ERROR",
+      "durationInMs": 0,
+      "coveredLines": 0
+    },
+    {
+      "name": "test5",
+      "status": "SKIPPED"
+    }
+  ]
+}