]> source.dussan.org Git - sonarqube.git/commitdiff
7035 Use coverage measures instead of overall coverage ones on the project overview...
authorStas Vilchik <vilchiks@gmail.com>
Tue, 24 Nov 2015 10:20:54 +0000 (11:20 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Tue, 24 Nov 2015 10:21:08 +0000 (11:21 +0100)
14 files changed:
it/it-tests/src/test/java/it/Category1Suite.java
it/it-tests/src/test/java/it/projectOverview/ProjectOverviewTest.java
it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html [new file with mode: 0644]
it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html [new file with mode: 0644]
it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_project_overview_after_first_analysis.html
it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/coverage-measures-list.js
server/sonar-web/src/main/js/apps/overview/components/coverage-selection-mixin.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/detailed-measure.js
server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js
server/sonar-web/src/main/js/apps/overview/domains/coverage-domain.js
server/sonar-web/src/main/js/apps/overview/main/coverage.js
server/sonar-web/src/main/js/apps/overview/main/main.js
server/sonar-web/tests/apps/overview/main/coverage-test.js

index 69598fb08997e1375b29ea265054b4ebc4a07bf0..6896d5b070d48c6dba9908d69f8e7dc098bf25af 100644 (file)
@@ -51,6 +51,7 @@ import it.measureHistory.TimeMachineTest;
 import it.measureHistory.TimeMachineUiTest;
 import it.projectAdministration.BulkDeletionTest;
 import it.projectAdministration.ProjectAdministrationTest;
+import it.projectOverview.ProjectOverviewTest;
 import it.qualityGate.QualityGateNotificationTest;
 import it.qualityGate.QualityGateTest;
 import it.qualityGate.QualityGateUiTest;
@@ -70,6 +71,8 @@ import static util.ItUtils.xooPlugin;
   // project administration
   BulkDeletionTest.class,
   ProjectAdministrationTest.class,
+  // project pages
+  ProjectOverviewTest.class,
   // settings
   PropertySetsTest.class,
   SubCategoriesTest.class,
index 145d926f5f5fa507b33a8b282a00a7146e36df52..9e3ac118f5bbb3074bae86b7cb11fe892bd73bb9 100644 (file)
@@ -36,7 +36,7 @@ public class ProjectOverviewTest {
 
   @Test
   public void test_project_overview_after_first_analysis() throws Exception {
-    executeBuild("project-for-overview", "Project For Overview");
+    executeBuild("shared/xoo-sample", "project-for-overview", "Project For Overview");
 
     Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("test_project_overview_after_first_analysis",
       "/projectOverview/ProjectOverviewTest/test_project_overview_after_first_analysis.html"
@@ -44,9 +44,39 @@ public class ProjectOverviewTest {
     new SeleneseTest(selenese).runOn(orchestrator);
   }
 
-  private void executeBuild(String projectKey, String projectName) {
+  @Test
+  public void test_ut_coverage_on_project_overview() throws Exception {
+    executeBuild("testing/xoo-sample-ut-coverage", "project-for-overview-ut-coverage", "Project For Overview UT");
+
+    Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("test_ut_coverage_on_project_overview",
+      "/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html"
+    ).build();
+    new SeleneseTest(selenese).runOn(orchestrator);
+  }
+
+  @Test
+  public void test_it_coverage_on_project_overview() throws Exception {
+    executeBuild("testing/xoo-sample-it-coverage", "project-for-overview-it-coverage", "Project For Overview IT");
+
+    Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("test_it_coverage_onfi_project_overview",
+      "/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html"
+    ).build();
+    new SeleneseTest(selenese).runOn(orchestrator);
+  }
+
+  @Test
+  public void test_overall_coverage_on_project_overview() throws Exception {
+    executeBuild("testing/xoo-sample-overall-coverage", "project-for-overview-overall-coverage", "Project For Overview Overall");
+
+    Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("test_overall_coverage_on_project_overview",
+      "/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html"
+    ).build();
+    new SeleneseTest(selenese).runOn(orchestrator);
+  }
+
+  private void executeBuild(String projectLocation, String projectKey, String projectName) {
     orchestrator.executeBuild(
-      SonarRunner.create(projectDir("shared/xoo-sample"))
+      SonarRunner.create(projectDir(projectLocation))
         .setProjectKey(projectKey)
         .setProjectName(projectName)
     );
diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html
new file mode 100644 (file)
index 0000000..896815c
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <link rel="selenium.base" href="http://localhost:49506"/>
+  <title>test_project_overview_after_first_analysis</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+  <thead>
+  <tr>
+    <td rowspan="1" colspan="3">test_project_overview_after_first_analysis</td>
+  </tr>
+  </thead>
+  <tbody>
+  <tr>
+       <td>open</td>
+       <td>/sonar/overview?id=project-for-overview-it-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Coverage*</td>
+</tr>
+<tr>
+       <td>open</td>
+       <td>/sonar/overview/tests?id=project-for-overview-it-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*IT coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*IT line coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*IT condition coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*IT uncovered conditions*1*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*IT uncovered lines*2*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*X*Complexity*Y*IT coverage*Size*IT uncovered lines*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Size*Lines of code*Color*IT coverage*</td>
+</tr>
+</tbody>
+</table>
+</body>
+</html>
diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html
new file mode 100644 (file)
index 0000000..02eea80
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <link rel="selenium.base" href="http://localhost:49506"/>
+  <title>test_project_overview_after_first_analysis</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+  <thead>
+  <tr>
+    <td rowspan="1" colspan="3">test_project_overview_after_first_analysis</td>
+  </tr>
+  </thead>
+  <tbody>
+  <tr>
+       <td>open</td>
+       <td>/sonar/overview?id=project-for-overview-overall-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*62.5%*Coverage*</td>
+</tr>
+<tr>
+       <td>open</td>
+       <td>/sonar/overview/tests?id=project-for-overview-overall-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*62.5%*Overall coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*75.0%*Overall line coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Overall condition coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Uncovered conditions*3*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*IT uncovered conditions*3*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Overall uncovered conditions*2*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Uncovered lines*2*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*IT uncovered lines*2*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Overall uncovered lines*1*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*X*Complexity*Y*Overall coverage*Size*Overall uncovered lines*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Size*Lines of code*Color*Overall coverage*</td>
+</tr>
+</tbody>
+</table>
+</body>
+</html>
index ddbe51f8e0b159b83d96b7c95b0f038d6470fb1d..d62a279456d6c71652b2959f9bc0d36332492182 100644 (file)
     <td>id=content</td>
     <td>*A*0*Issues*0*Debt*</td>
   </tr>
-  <tr>
-    <td>waitForText</td>
-    <td>id=content</td>
-    <td>*Blocker*0*Critical*0*Major*0*Minor*0*Info*0*</td>
-  </tr>
   <tr>
     <td>waitForText</td>
     <td>id=content</td>
@@ -42,7 +37,7 @@
   <tr>
     <td>waitForText</td>
     <td>id=content</td>
-    <td>*13*Lines of Code*1*Files*</td>
+    <td>*13*Lines of Code*</td>
   </tr>
   <tr>
     <td>assertNotText</td>
diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html
new file mode 100644 (file)
index 0000000..69bc51e
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <link rel="selenium.base" href="http://localhost:49506"/>
+  <title>test_project_overview_after_first_analysis</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+  <thead>
+  <tr>
+    <td rowspan="1" colspan="3">test_project_overview_after_first_analysis</td>
+  </tr>
+  </thead>
+  <tbody>
+  <tr>
+       <td>open</td>
+       <td>/sonar/overview?id=project-for-overview-ut-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Coverage*</td>
+</tr>
+<tr>
+       <td>open</td>
+       <td>/sonar/overview/tests?id=project-for-overview-ut-coverage</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Line coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*50.0%*Condition coverage*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Lines to cover*4*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Uncovered conditions*1*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Uncovered lines*2*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*X*Complexity*Y*Coverage*Size*Uncovered lines*</td>
+</tr>
+<tr>
+       <td>waitForText</td>
+       <td>id=content</td>
+       <td>*Size*Lines of code*Color*Coverage*</td>
+</tr>
+</tbody>
+</table>
+</body>
+</html>
index 898da4b1cd0b3d426e4e4458b21bcf38f4286655..c9c376957b9c043d532b49b8ab698d2461bfdb15 100644 (file)
@@ -7,32 +7,35 @@ import { CoverageMeasure } from '../components/coverage-measure';
 
 
 const TEST_DOMAINS = ['Tests', 'Tests (Integration)', 'Tests (Overall)'];
-
-const UT_COVERAGE_METRICS = ['coverage', 'line_coverage', 'branch_coverage'];
-const UT_NEW_COVERAGE_METRICS = ['new_coverage', 'new_line_coverage', 'new_branch_coverage'];
-
-const IT_COVERAGE_METRICS = ['it_coverage', 'it_line_coverage', 'it_branch_coverage'];
-const IT_NEW_COVERAGE_METRICS = ['new_it_coverage', 'new_it_line_coverage', 'new_it_branch_coverage'];
-
-const OVERALL_COVERAGE_METRICS = ['overall_coverage', 'overall_line_coverage', 'overall_branch_coverage'];
-const OVERALL_NEW_COVERAGE_METRICS = ['new_overall_coverage', 'new_overall_line_coverage',
-  'new_overall_branch_coverage'];
-
 const TEST_METRICS = ['tests', 'test_execution_time', 'test_errors', 'test_failures', 'skipped_tests',
   'test_success_density'];
 
-const KNOWN_METRICS = [].concat(TEST_METRICS, OVERALL_COVERAGE_METRICS, UT_COVERAGE_METRICS, IT_COVERAGE_METRICS);
-
 
 export const CoverageMeasuresList = React.createClass({
   renderOtherMeasures() {
+    let knownMetrics = [].concat(TEST_METRICS, [
+      this.props.coverageMetricPrefix + 'coverage',
+      this.props.coverageMetricPrefix + 'line_coverage',
+      this.props.coverageMetricPrefix + 'branch_coverage'
+    ]);
     let metrics = filterMetricsForDomains(this.props.metrics, TEST_DOMAINS)
-        .filter(metric => KNOWN_METRICS.indexOf(metric.key) === -1)
+        .filter(metric => knownMetrics.indexOf(metric.key) === -1)
         .map(metric => metric.key);
     return this.renderListOfMeasures(metrics);
   },
 
-  renderCoverage (metrics) {
+  renderCoverage () {
+    let metrics = [
+      this.props.coverageMetricPrefix + 'coverage',
+      this.props.coverageMetricPrefix + 'line_coverage',
+      this.props.coverageMetricPrefix + 'branch_coverage'
+    ];
+
+    if (_.every(metrics, metric => this.props.measures[metric] == null)) {
+      // if no measures exist
+      return null;
+    }
+
     let measures = metrics.map(metric => {
       return <CoverageMeasure key={metric}
                               metric={metric}
@@ -45,15 +48,18 @@ export const CoverageMeasuresList = React.createClass({
     </div>;
   },
 
-  shouldRenderTypedCoverage () {
-    return this.props.measures['coverage'] != null && this.props.measures['it_coverage'] != null;
-  },
+  renderNewCoverage () {
+    let metrics = [
+      'new_' + this.props.coverageMetricPrefix + 'coverage',
+      'new_' + this.props.coverageMetricPrefix + 'line_coverage',
+      'new_' + this.props.coverageMetricPrefix + 'branch_coverage'
+    ];
 
-  renderTypedCoverage (metrics) {
-    return this.shouldRenderTypedCoverage() ? this.renderCoverage(metrics) : null;
-  },
+    if (_.every(metrics, metric => this.props.leak[metric] == null)) {
+      // if no measures exist
+      return null;
+    }
 
-  renderNewCoverage (metrics) {
     let measures = metrics.map(metric => {
       return <CoverageMeasure key={metric}
                               metric={metric}
@@ -66,54 +72,25 @@ export const CoverageMeasuresList = React.createClass({
     </div>;
   },
 
-  renderTypedNewCoverage (metrics) {
-    return this.shouldRenderTypedCoverage() ? this.renderNewCoverage(metrics) : null;
-  },
-
-  renderUTCoverage () {
-    return this.renderTypedCoverage(UT_COVERAGE_METRICS);
-  },
-
-  renderUTNewCoverage () {
-    return this.renderTypedNewCoverage(UT_NEW_COVERAGE_METRICS);
-  },
-
-  renderITCoverage () {
-    return this.renderTypedCoverage(IT_COVERAGE_METRICS);
-  },
-
-  renderITNewCoverage () {
-    return this.renderTypedNewCoverage(IT_NEW_COVERAGE_METRICS);
-  },
-
-  renderOverallCoverage () {
-    return this.renderCoverage(OVERALL_COVERAGE_METRICS);
-  },
+  renderListOfMeasures(list) {
+    let metrics = list.map(key => _.findWhere(this.props.metrics, { key }));
 
-  renderOverallNewCoverage () {
-    return this.renderNewCoverage(OVERALL_NEW_COVERAGE_METRICS);
-  },
+    if (_.every(metrics, metric => this.props.measures[metric.key] == null)) {
+      // if no measures exist
+      return null;
+    }
 
-  renderListOfMeasures(list) {
-    let metrics = list
-        .map(key => _.findWhere(this.props.metrics, { key }))
-        .map(metric => {
-          return <DetailedMeasure key={metric.key} {...this.props} {...this.props} metric={metric.key}
-                                  type={metric.type}/>;
-        });
+    metrics = metrics.map(metric => {
+      return <DetailedMeasure key={metric.key} {...this.props} {...this.props} metric={metric.key}
+                              type={metric.type}/>;
+    });
     return <div className="overview-detailed-measures-list">{metrics}</div>;
   },
 
   render () {
     return <div>
-      {this.renderOverallCoverage()}
-      {this.renderOverallNewCoverage()}
-
-      {this.renderUTCoverage()}
-      {this.renderUTNewCoverage()}
-
-      {this.renderITCoverage()}
-      {this.renderITNewCoverage()}
+      {this.renderCoverage()}
+      {this.renderNewCoverage()}
 
       {this.renderListOfMeasures(TEST_METRICS)}
 
diff --git a/server/sonar-web/src/main/js/apps/overview/components/coverage-selection-mixin.js b/server/sonar-web/src/main/js/apps/overview/components/coverage-selection-mixin.js
new file mode 100644 (file)
index 0000000..630c6b8
--- /dev/null
@@ -0,0 +1,11 @@
+export const CoverageSelectionMixin = {
+  getCoverageMetricPrefix (measures) {
+    if (measures['coverage'] != null && measures['it_coverage'] != null && measures['overall_coverage'] != null) {
+      return 'overall_';
+    } else if (measures['coverage'] != null) {
+      return '';
+    } else {
+      return 'it_';
+    }
+  }
+};
index df0b8e2630c39bc2ddbfb1f331244326ad95b48d..dda17a4814aefe2a0fb2f14b6b6d89268008710e 100644 (file)
@@ -11,10 +11,9 @@ export const DetailedMeasure = React.createClass({
       return null;
     }
     let leak = this.props.leak[this.props.metric];
+    let formatted = leak != null ? formatMeasureVariation(leak, getShortType(this.props.type)) : '—';
     return <div className="overview-detailed-measure-leak">
-      <span className="overview-detailed-measure-value">
-        {formatMeasureVariation(leak, getShortType(this.props.type))}
-      </span>
+      <span className="overview-detailed-measure-value">{formatted}</span>
     </div>;
   },
 
index 056863ecdb4e78a67927e032a3a36852b58688f2..7dee684daaa65cd5e4299a5f3249aba967d6cb29 100644 (file)
@@ -96,7 +96,7 @@ export class DomainBubbleChart extends React.Component {
     let formatYTick = (tick) => formatMeasure(tick, this.state.yMetric.type);
     return <BubbleChart items={items}
                         height={HEIGHT}
-                        padding={[25, 30, 50, 60]}
+                        padding={[25, 60, 50, 60]}
                         formatXTick={formatXTick}
                         formatYTick={formatYTick}/>;
   }
index 6df04be61bbf355a96013db949fb0f36fb69ba16..7d2ab65d8b749bc249b1dc8d992933357f88afec 100644 (file)
@@ -5,6 +5,7 @@ import { getMeasuresAndVariations } from '../../../api/measures';
 import { DomainTimeline } from '../components/domain-timeline';
 import { DomainTreemap } from '../components/domain-treemap';
 import { DomainBubbleChart } from '../components/domain-bubble-chart';
+import { CoverageSelectionMixin } from '../components/coverage-selection-mixin';
 import { getPeriodLabel, getPeriodDate } from './../helpers/periods';
 import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin';
 import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics';
@@ -17,7 +18,7 @@ const TEST_DOMAINS = ['Tests', 'Tests (Integration)', 'Tests (Overall)'];
 
 
 export const CoverageMain = React.createClass({
-  mixins: [TooltipsMixin],
+  mixins: [TooltipsMixin, CoverageSelectionMixin],
 
   getInitialState() {
     return {
@@ -31,7 +32,12 @@ export const CoverageMain = React.createClass({
     this.requestMeasures().then(r => {
       let measures = this.getMeasuresValues(r, 'value');
       let leak = this.getMeasuresValues(r, 'var' + this.props.leakPeriodIndex);
-      this.setState({ ready: true, measures, leak });
+      this.setState({
+        ready: true,
+        measures,
+        leak,
+        coverageMetricPrefix: this.getCoverageMetricPrefix(measures),
+      });
     });
   },
 
@@ -80,6 +86,9 @@ export const CoverageMain = React.createClass({
         .domain([0, 100])
         .range(CHART_COLORS_RANGE_PERCENT);
 
+    let coverageMetric = this.state.coverageMetricPrefix + 'coverage',
+        uncoveredLinesMetric = this.state.coverageMetricPrefix + 'uncovered_lines';
+
     return <div className="overview-detailed-page">
       <div className="overview-cards-list">
         <div className="overview-card overview-card-fixed-width">
@@ -93,15 +102,15 @@ export const CoverageMain = React.createClass({
         <div className="overview-card">
           <DomainBubbleChart {...this.props}
               xMetric="complexity"
-              yMetric="overall_coverage"
-              sizeMetrics={['overall_uncovered_lines']}/>
+              yMetric={coverageMetric}
+              sizeMetrics={[uncoveredLinesMetric]}/>
         </div>
       </div>
 
       <div className="overview-cards-list">
         <div className="overview-card">
           <DomainTimeline {...this.props} {...this.state}
-              initialMetric="overall_coverage"
+              initialMetric={coverageMetric}
               metrics={this.getMetricsForTimeline()}
               allMetrics={this.getAllMetricsForTimeline()}/>
         </div>
@@ -109,7 +118,7 @@ export const CoverageMain = React.createClass({
         <div className="overview-card">
           <DomainTreemap {...this.props}
               sizeMetric="ncloc"
-              colorMetric="overall_coverage"
+              colorMetric={coverageMetric}
               scale={treemapScale}/>
         </div>
       </div>
index 0c964a6c63c268a57430806313156f422a125484..7a80f024bffcf68400db6005a6404ad2e554c41c 100644 (file)
@@ -13,27 +13,16 @@ export const GeneralCoverage = React.createClass({
   propTypes: {
     measures: React.PropTypes.object.isRequired,
     leakPeriodLabel: React.PropTypes.string,
-    leakPeriodDate: React.PropTypes.object
+    leakPeriodDate: React.PropTypes.object,
+    coverageMetricPrefix: React.PropTypes.string.isRequired
   },
 
   getCoverageMetric () {
-    if (this.props.measures['overall_coverage'] != null) {
-      return 'overall_coverage';
-    } else if (this.props.measures['coverage'] != null) {
-      return 'coverage';
-    } else {
-      return 'it_coverage';
-    }
+    return this.props.coverageMetricPrefix + 'coverage';
   },
 
   getNewCoverageMetric () {
-    if (this.props.leak['new_overall_coverage'] != null) {
-      return 'new_overall_coverage';
-    } else if (this.props.leak['new_coverage'] != null) {
-      return 'new_coverage';
-    } else {
-      return 'new_it_coverage';
-    }
+    return 'new_' + this.props.coverageMetricPrefix + 'coverage';
   },
 
   renderNewCoverage () {
index 8e9b17a21c3d3df0f1c56f8ceb8ae0337c9a02a3..470b92f49d10ee96dd336e99d11933d48fdbe04f 100644 (file)
@@ -6,6 +6,7 @@ import { GeneralIssues } from './issues';
 import { GeneralCoverage } from './coverage';
 import { GeneralDuplications } from './duplications';
 import { GeneralSize } from './size';
+import { CoverageSelectionMixin } from '../components/coverage-selection-mixin';
 import { getPeriodLabel, getPeriodDate } from './../helpers/periods';
 import { getMeasuresAndVariations } from '../../../api/measures';
 import { getFacet, getIssuesCount } from '../../../api/issues';
@@ -30,7 +31,6 @@ const METRICS_LIST = [
 
 const HISTORY_METRICS_LIST = [
   'sqale_index',
-  'overall_coverage',
   'duplicated_lines_density',
   'ncloc'
 ];
@@ -42,6 +42,8 @@ function getFacetValue (facet, key) {
 
 
 export default React.createClass({
+  mixins: [CoverageSelectionMixin],
+
   propTypes: {
     leakPeriodIndex: React.PropTypes.string.isRequired
   },
@@ -77,7 +79,8 @@ export default React.createClass({
       this.setState({
         ready: true,
         measures: measures,
-        leak: leak
+        leak: leak,
+        coverageMetricPrefix: this.getCoverageMetricPrefix(measures)
       }, this.requestHistory);
     });
   },
@@ -134,7 +137,8 @@ export default React.createClass({
   },
 
   requestHistory () {
-    let metrics = HISTORY_METRICS_LIST.join(',');
+    let coverageMetric = this.state.coverageMetricPrefix + 'coverage';
+    let metrics = [].concat(HISTORY_METRICS_LIST, coverageMetric).join(',');
     return getTimeMachineData(this.props.component.key, metrics).then(r => {
       let history = {};
       r[0].cols.forEach((col, index) => {
@@ -159,11 +163,13 @@ export default React.createClass({
       return this.renderLoading();
     }
 
+    let coverageMetric = this.state.coverageMetricPrefix + 'coverage';
     let props = _.extend({}, this.props, this.state);
 
     return <div className="overview-domains-list">
       <GeneralIssues {...props} history={this.state.history['sqale_index']}/>
-      <GeneralCoverage {...props} history={this.state.history['overall_coverage']}/>
+      <GeneralCoverage {...props} coverageMetricPrefix={this.state.coverageMetricPrefix}
+                                  history={this.state.history[coverageMetric]}/>
       <GeneralDuplications {...props} history={this.state.history['duplicated_lines_density']}/>
       <GeneralSize {...props} history={this.state.history['ncloc']}/>
     </div>;
index 616016322dd6facd1af093cc771ece15b856f8af..631179a344de32592acaf095d1a79e563bd791c1 100644 (file)
@@ -28,20 +28,8 @@ const LEAK_FOR_IT = _.omit(LEAK_FOR_UT, 'new_coverage');
 
 
 describe('Overview :: GeneralCoverage', function () {
-  it('should display overall coverage', function () {
-    let component = <GeneralCoverage measures={MEASURES} leak={LEAK} component={COMPONENT}
-                                     leakPeriodDate={DATE}/>;
-    let output = TestUtils.renderIntoDocument(component);
-
-    let coverageElement = TestUtils.findRenderedDOMComponentWithClass(output, 'js-overview-main-coverage');
-    expect(coverageElement.textContent).to.equal('73.5%');
-
-    let newCoverageElement = TestUtils.findRenderedDOMComponentWithClass(output, 'js-overview-main-new-coverage');
-    expect(newCoverageElement.textContent).to.equal('72.5%');
-  });
-
   it('should display tests', function () {
-    let component = <GeneralCoverage measures={MEASURES} component={COMPONENT}/>;
+    let component = <GeneralCoverage measures={MEASURES} component={COMPONENT} coverageMetricPrefix=""/>;
     let output = TestUtils.renderIntoDocument(component);
     let coverageElement = TestUtils.findRenderedDOMComponentWithClass(output, 'js-overview-main-tests');
     expect(coverageElement.textContent).to.equal('137');
@@ -49,7 +37,7 @@ describe('Overview :: GeneralCoverage', function () {
 
   it('should not display tests', function () {
     let measuresWithoutTests = _.omit(MEASURES, 'tests');
-    let component = <GeneralCoverage measures={measuresWithoutTests} component={COMPONENT}/>;
+    let component = <GeneralCoverage measures={measuresWithoutTests} component={COMPONENT} coverageMetricPrefix=""/>;
     let output = TestUtils.renderIntoDocument(component);
     let coverageElements = TestUtils.scryRenderedDOMComponentsWithClass(output, 'js-overview-main-tests');
     expect(coverageElements).to.be.empty;
@@ -57,7 +45,7 @@ describe('Overview :: GeneralCoverage', function () {
 
   it('should fall back to UT coverage', function () {
     let component = <GeneralCoverage measures={MEASURES_FOR_UT} leak={LEAK_FOR_UT} component={COMPONENT}
-                                     leakPeriodDate={DATE}/>;
+                                     leakPeriodDate={DATE} coverageMetricPrefix=""/>;
     let output = TestUtils.renderIntoDocument(component);
 
     let coverageElement = TestUtils.findRenderedDOMComponentWithClass(output, 'js-overview-main-coverage');
@@ -69,7 +57,7 @@ describe('Overview :: GeneralCoverage', function () {
 
   it('should fall back to IT coverage', function () {
     let component = <GeneralCoverage measures={MEASURES_FOR_IT} leak={LEAK_FOR_IT} component={COMPONENT}
-                                     leakPeriodDate={DATE}/>;
+                                     leakPeriodDate={DATE} coverageMetricPrefix="it_"/>;
     let output = TestUtils.renderIntoDocument(component);
 
     let coverageElement = TestUtils.findRenderedDOMComponentWithClass(output, 'js-overview-main-coverage');