aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-12-04 11:41:15 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-12-07 17:26:43 +0100
commit6cf62f0adc9677404df3ff457135591c17ad89a5 (patch)
tree08b31db10e52e92575a6343768f93e46b13266b7
parent541c15654fc024534c45710b30b9cfc8ec551d96 (diff)
downloadsonarqube-6cf62f0adc9677404df3ff457135591c17ad89a5.tar.gz
sonarqube-6cf62f0adc9677404df3ff457135591c17ad89a5.zip
SONAR-6939 ability for plugins to override the decimal scale of float
measures
-rw-r--r--it/it-plugins/batch-plugin/src/main/java/com/sonarsource/BatchPlugin.java10
-rw-r--r--it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMeasureComputer.java34
-rw-r--r--it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMetric.java25
-rw-r--r--it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleProperty.java13
-rw-r--r--it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleSensor.java36
-rw-r--r--it/it-tests/src/test/java/it/Category3Suite.java7
-rw-r--r--it/it-tests/src/test/java/it/measure/DecimalScaleMetricTest.java39
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java6
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/ConstantFloatMeasureSensor.java74
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/XooMetrics.java43
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageFormula.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/BatchMeasureToMeasure.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/Measure.java32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureDtoToMeasure.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerContextImpl.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/metric/Metric.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java14
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricImpl.java30
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/CommentMeasuresStep.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/DuplicationMeasuresStep.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/UnitTestMeasuresStep.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/metric/ws/MetricJsonWriter.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/metric/ws/SearchAction.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaExecutionTest.java16
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/formula/coverage/CoverageUtilsTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CommentDensityRuleTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CoverageRuleTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/BatchMeasureToMeasureTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/BestValueOptimizationTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MapBasedRawMeasureRepositoryTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureDtoToMeasureTest.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryImplTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureTest.java22
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureImplTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricImplTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryRule.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionEvaluatorTest.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/CustomMeasuresCopyStepTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComplexityMeasuresStepTest.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportCoverageMeasuresStepTest.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportUnitTestMeasuresStepTest.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComplexityMeasuresStepTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsCoverageMeasuresStepTest.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsUnitTestMeasuresStepTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java1
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric-result.xml2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric.xml2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml4
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml4
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/models/project_measure.rb8
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1005_add_decimal_scale_to_metrics.rb33
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java68
-rw-r--r--sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java11
-rw-r--r--sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java2
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/metric/MetricMapper.xml11
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql1
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl3
-rw-r--r--sonar-db/src/test/java/org/sonar/db/metric/MetricDaoTest.java1
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/metric/MetricDaoTest/shared.xml6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaContext.java21
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java33
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/AverageFormula.java82
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaContext.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaData.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/MeanAggregationFormula.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java19
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java68
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java34
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildValuesFormula.java22
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/WeightedMeanAggregationFormula.java39
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/DefaultFormulaDataTest.java42
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/AverageFormulaTest.java170
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/MeanAggregationFormulaTest.java52
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java15
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java98
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java119
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildValuesFormulaTest.java74
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/measures/WeightedMeanAggregationFormulaTest.java (renamed from plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/package-info.java)17
92 files changed, 685 insertions, 1034 deletions
diff --git a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/BatchPlugin.java b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/BatchPlugin.java
index 7c4c479c64b..f26975594f9 100644
--- a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/BatchPlugin.java
+++ b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/BatchPlugin.java
@@ -1,5 +1,9 @@
package com.sonarsource;
+import com.sonarsource.decimal_scale_of_measures.DecimalScaleMeasureComputer;
+import com.sonarsource.decimal_scale_of_measures.DecimalScaleMetric;
+import com.sonarsource.decimal_scale_of_measures.DecimalScaleProperty;
+import com.sonarsource.decimal_scale_of_measures.DecimalScaleSensor;
import java.util.Arrays;
import java.util.List;
import org.sonar.api.SonarPlugin;
@@ -8,6 +12,12 @@ public class BatchPlugin extends SonarPlugin {
public List getExtensions() {
return Arrays.asList(
+ // SONAR-6939 decimal_scale_of_measures
+ DecimalScaleMeasureComputer.class,
+ DecimalScaleMetric.class,
+ DecimalScaleSensor.class,
+ DecimalScaleProperty.definition(),
+
DumpSettingsInitializer.class,
RaiseMessageException.class,
TempFolderExtension.class,
diff --git a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMeasureComputer.java b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMeasureComputer.java
new file mode 100644
index 00000000000..f3dc985c7e8
--- /dev/null
+++ b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMeasureComputer.java
@@ -0,0 +1,34 @@
+package com.sonarsource.decimal_scale_of_measures;
+
+import org.sonar.api.ce.measure.Measure;
+import org.sonar.api.ce.measure.MeasureComputer;
+
+public class DecimalScaleMeasureComputer implements MeasureComputer {
+
+ @Override
+ public MeasureComputerDefinition define(MeasureComputerDefinitionContext defContext) {
+ return defContext.newDefinitionBuilder()
+ // Output metrics must contains at least one metric
+ .setOutputMetrics(DecimalScaleMetric.KEY)
+
+ .build();
+ }
+
+ @Override
+ public void compute(MeasureComputerContext context) {
+ if (context.getMeasure(DecimalScaleMetric.KEY) == null) {
+ Iterable<Measure> childMeasures = context.getChildrenMeasures(DecimalScaleMetric.KEY);
+ int count = 0;
+ double total = 0.0;
+ for (Measure childMeasure : childMeasures) {
+ count++;
+ total += childMeasure.getDoubleValue();
+ }
+ double value = 0.0;
+ if (count > 0) {
+ value = total / count;
+ }
+ context.addMeasure(DecimalScaleMetric.KEY, value);
+ }
+ }
+}
diff --git a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMetric.java b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMetric.java
new file mode 100644
index 00000000000..ef12e051fb1
--- /dev/null
+++ b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleMetric.java
@@ -0,0 +1,25 @@
+package com.sonarsource.decimal_scale_of_measures;
+
+import java.util.Collections;
+import java.util.List;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.Metrics;
+
+public class DecimalScaleMetric implements Metrics {
+
+ public static final String KEY = "decimal_scale";
+
+ private static final Metric METRIC = new Metric.Builder(KEY, "Decimal Scale", Metric.ValueType.FLOAT)
+ .setDescription("Numeric metric with overridden decimal scale")
+ .setDecimalScale(4)
+ .create();
+
+ @Override
+ public List getMetrics() {
+ return Collections.singletonList(definition());
+ }
+
+ public static Metric definition() {
+ return METRIC;
+ }
+}
diff --git a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleProperty.java b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleProperty.java
new file mode 100644
index 00000000000..5fa85e71e59
--- /dev/null
+++ b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleProperty.java
@@ -0,0 +1,13 @@
+package com.sonarsource.decimal_scale_of_measures;
+
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+
+public class DecimalScaleProperty {
+
+ public static final String KEY = "sonar.scanner.feedDecimalScaleMetric";
+
+ public static PropertyDefinition definition() {
+ return PropertyDefinition.builder(KEY).name("Enable test decimal_scale_of_measures").type(PropertyType.BOOLEAN).defaultValue(String.valueOf(false)).build();
+ }
+}
diff --git a/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleSensor.java b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleSensor.java
new file mode 100644
index 00000000000..c6fe8c6ea03
--- /dev/null
+++ b/it/it-plugins/batch-plugin/src/main/java/com/sonarsource/decimal_scale_of_measures/DecimalScaleSensor.java
@@ -0,0 +1,36 @@
+package com.sonarsource.decimal_scale_of_measures;
+
+import org.sonar.api.batch.Sensor;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+public class DecimalScaleSensor implements Sensor {
+ private static final Logger LOG = Loggers.get(DecimalScaleSensor.class);
+
+ @Override
+ public boolean shouldExecuteOnProject(Project project) {
+ return true;
+ }
+
+ @Override
+ public void analyse(Project module, SensorContext context) {
+ if (context.settings().getBoolean(DecimalScaleProperty.KEY)) {
+ FilePredicate all = context.fileSystem().predicates().all();
+ Iterable<InputFile> files = context.fileSystem().inputFiles(all);
+ double value = 0.0001;
+ for (InputFile file : files) {
+ LOG.info("Value for {}: {}", file.relativePath(), value);
+ context.newMeasure()
+ .on(file)
+ .forMetric(DecimalScaleMetric.definition())
+ .withValue(value)
+ .save();
+ value += 0.0001;
+ }
+ }
+ }
+}
diff --git a/it/it-tests/src/test/java/it/Category3Suite.java b/it/it-tests/src/test/java/it/Category3Suite.java
index 61bfc18575a..cd1f4974f5c 100644
--- a/it/it-tests/src/test/java/it/Category3Suite.java
+++ b/it/it-tests/src/test/java/it/Category3Suite.java
@@ -7,6 +7,7 @@ package it;
import com.sonar.orchestrator.Orchestrator;
import it.analysis.*;
+import it.measure.DecimalScaleMetricTest;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -29,7 +30,9 @@ import static util.ItUtils.xooPlugin;
BatchTest.class,
IssuesModeTest.class,
SettingsEncryptionTest.class,
- ReportDumpTest.class
+ ReportDumpTest.class,
+ // measures
+ DecimalScaleMetricTest.class
})
public class Category3Suite {
@@ -45,7 +48,7 @@ public class Category3Suite {
// Used by IssuesModeTest
.addPlugin(pluginArtifact("access-secured-props-plugin"))
- // used by TempFolderTest
+ // used by TempFolderTest and DecimalScaleMetricTest
.addPlugin(pluginArtifact("batch-plugin"))
// used by ExtensionLifecycleTest
diff --git a/it/it-tests/src/test/java/it/measure/DecimalScaleMetricTest.java b/it/it-tests/src/test/java/it/measure/DecimalScaleMetricTest.java
new file mode 100644
index 00000000000..63c716051cf
--- /dev/null
+++ b/it/it-tests/src/test/java/it/measure/DecimalScaleMetricTest.java
@@ -0,0 +1,39 @@
+package it.measure;
+
+import com.sonar.orchestrator.Orchestrator;
+import it.Category3Suite;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.wsclient.services.Resource;
+import org.sonar.wsclient.services.ResourceQuery;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * SONAR-6939
+ */
+public class DecimalScaleMetricTest {
+
+ /**
+ * Requires the plugin "batch-plugin"
+ */
+ @ClassRule
+ public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
+
+ @Test
+ public void override_decimal_scale_of_numeric_metric() {
+ String projectKey = "DecimalScaleMetricTest.override_decimal_scale_of_numeric_metric";
+ // see DecimalScaleMetric
+ String metricKey = "decimal_scale";
+ ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
+ "sonar.projectKey", projectKey,
+ "sonar.scanner.feedDecimalScaleMetric", String.valueOf(true));
+
+ Resource resource = orchestrator.getServer().getWsClient()
+ .find(ResourceQuery.createForMetrics(projectKey, metricKey));
+ // Ability to define decimal scale of metrics was introduced in v5.3. By default it is 1.
+ assertThat(resource.getMeasureValue(metricKey)).isEqualTo(0.0001);
+ assertThat(resource.getMeasureFormattedValue(metricKey, null)).isEqualTo("0.0001");
+ }
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
index a2cb7066e0a..598be59d3dc 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
@@ -32,8 +32,6 @@ import org.sonar.xoo.lang.SymbolReferencesSensor;
import org.sonar.xoo.lang.SyntaxHighlightingSensor;
import org.sonar.xoo.lang.XooCpdMapping;
import org.sonar.xoo.lang.XooTokenizer;
-import org.sonar.xoo.measures.ConstantFloatMeasureSensor;
-import org.sonar.xoo.measures.XooMetrics;
import org.sonar.xoo.rule.ChecksSensor;
import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
import org.sonar.xoo.rule.DeprecatedResourceApiSensor;
@@ -115,10 +113,6 @@ public class XooPlugin extends SonarPlugin {
TestExecutionSensor.class,
CoveragePerTestSensor.class,
- // Measures
- XooMetrics.class,
- ConstantFloatMeasureSensor.class,
-
// Other
XooProjectBuilder.class,
XooPostJob.class);
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/ConstantFloatMeasureSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/ConstantFloatMeasureSensor.java
deleted file mode 100644
index 416efe2bc39..00000000000
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/ConstantFloatMeasureSensor.java
+++ /dev/null
@@ -1,74 +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.
- */
-
-package org.sonar.xoo.measures;
-
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.config.Settings;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.xoo.Xoo;
-
-/**
- * Save a constant float measure on each XOO source file
- */
-public class ConstantFloatMeasureSensor implements Sensor {
-
- public static final String SONAR_XOO_ENABLE_FLOAT_SENSOR = "sonar.xoo.enableFloatSensor";
- public static final String SONAR_XOO_FLOAT_PRECISION = "sonar.xoo.floatPrecision";
-
- public static final double CONSTANT_VALUE = 1.2345678910111213d;
-
- private final FileSystem fs;
- private final Settings settings;
-
- public ConstantFloatMeasureSensor(FileSystem fs, Settings settings) {
- this.fs = fs;
- this.settings = settings;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return fs.hasFiles(fs.predicates().hasLanguage(Xoo.KEY)) && settings.getBoolean(
- SONAR_XOO_ENABLE_FLOAT_SENSOR);
- }
-
- @Override
- public void analyse(Project project, SensorContext context) {
- Measure<?> floatMeasure = settings.hasKey(SONAR_XOO_FLOAT_PRECISION)
- ? new Measure<>(XooMetrics.CONSTANT_FLOAT_MEASURE, CONSTANT_VALUE, settings.getInt(SONAR_XOO_FLOAT_PRECISION))
- : new Measure<>(XooMetrics.CONSTANT_FLOAT_MEASURE, CONSTANT_VALUE);
- for (InputFile inputFile : getSourceFiles()) {
- context.saveMeasure(inputFile, floatMeasure);
- }
- }
-
- private Iterable<InputFile> getSourceFiles() {
- return fs.inputFiles(fs.predicates().and(fs.predicates().hasLanguage(Xoo.KEY), fs.predicates().hasType(InputFile.Type.MAIN)));
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
-}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/XooMetrics.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/XooMetrics.java
deleted file mode 100644
index 511baf2761c..00000000000
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/XooMetrics.java
+++ /dev/null
@@ -1,43 +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.
- */
-
-package org.sonar.xoo.measures;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.Metrics;
-
-public final class XooMetrics implements Metrics {
-
- public static final String CONSTANT_FLOAT_MEASURE_KEY = "xoo_constant_float_measure";
-
- public static final Metric<Float> CONSTANT_FLOAT_MEASURE = new Metric.Builder(CONSTANT_FLOAT_MEASURE_KEY, "Constant float measure", Metric.ValueType.FLOAT)
- .setDescription("Return always the same float measure for every components")
- .setDirection(Metric.DIRECTION_WORST)
- .setDomain(CoreMetrics.DOMAIN_GENERAL)
- .create();
-
- @Override
- public List<Metric> getMetrics() {
- return Lists.<Metric>newArrayList(CONSTANT_FLOAT_MEASURE);
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java
index 1506751c82e..f2456fb68a3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java
@@ -56,7 +56,7 @@ public class AverageFormula implements Formula<AverageFormula.AverageCounter> {
double mainValue = mainValueOptional.get();
double byValue = byValueOptional.get();
if (byValue > 0d) {
- return Optional.of(Measure.newMeasureBuilder().create(mainValue / byValue));
+ return Optional.of(Measure.newMeasureBuilder().create(mainValue / byValue, context.getMetric().getDecimalScale()));
}
}
return Optional.absent();
@@ -78,7 +78,7 @@ public class AverageFormula implements Formula<AverageFormula.AverageCounter> {
// prevents instantiation outside static method
}
- public static Builder newBuilder(){
+ public static Builder newBuilder() {
return new Builder();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageFormula.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageFormula.java
index 1521df8f9d0..6f44d2fbc2f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageFormula.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/coverage/CoverageFormula.java
@@ -39,7 +39,7 @@ public abstract class CoverageFormula<T extends ElementsAndCoveredElementsCounte
long elements = counter.elements;
long coveredElements = counter.coveredElements;
if (elements > 0L) {
- return Optional.of(newMeasureBuilder().create(calculateCoverage(coveredElements, elements)));
+ return Optional.of(newMeasureBuilder().create(calculateCoverage(coveredElements, elements), context.getMetric().getDecimalScale()));
}
return Optional.absent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/BatchMeasureToMeasure.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/BatchMeasureToMeasure.java
index a7931c61116..9c10dfde023 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/BatchMeasureToMeasure.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/BatchMeasureToMeasure.java
@@ -75,7 +75,10 @@ public class BatchMeasureToMeasure {
if (!batchMeasure.hasDoubleValue()) {
return toNoValueMeasure(builder, batchMeasure);
}
- return of(builder.create(batchMeasure.getDoubleValue(), data));
+ return of(builder.create(batchMeasure.getDoubleValue(),
+ // Decimals are not truncated in scanner report, so an arbitrary decimal scale is applied when reading values from report
+ org.sonar.api.measures.Metric.MAX_DECIMAL_SCALE,
+ data));
}
private static Optional<Measure> toBooleanMeasure(Measure.NewMeasureBuilder builder, BatchReport.Measure batchMeasure, @Nullable String data) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/Measure.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/Measure.java
index 0891ca0e137..ffb4ead0809 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/Measure.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/Measure.java
@@ -34,11 +34,6 @@ import static java.util.Objects.requireNonNull;
public final class Measure {
- /**
- * Default precision when saving a double value type
- */
- private static final int DEFAULT_PRECISION = 1;
-
public enum ValueType {
NO_VALUE, BOOLEAN, INT, LONG, DOUBLE, STRING, LEVEL
}
@@ -94,12 +89,11 @@ public final class Measure {
private Measure(ValueType valueType, @Nullable Integer ruleId, @Nullable Integer characteristicId, @Nullable Developer developer,
@Nullable Double value, @Nullable String data, @Nullable Level dataLevel,
@Nullable String description, @Nullable QualityGateStatus qualityGateStatus, @Nullable MeasureVariations variations) {
- checkArgument(value == null || !Double.isNaN(value), "Nan is not allowed as a Measure value");
this.valueType = valueType;
this.ruleId = ruleId;
this.characteristicId = characteristicId;
this.developer = developer;
- this.value = scale(value);
+ this.value = value;
this.data = data;
this.dataLevel = dataLevel;
this.description = description;
@@ -107,15 +101,6 @@ public final class Measure {
this.variations = variations;
}
- @CheckForNull
- private static Double scale(@Nullable Double value) {
- if (value == null) {
- return null;
- }
- BigDecimal bd = BigDecimal.valueOf(value);
- return bd.setScale(DEFAULT_PRECISION, RoundingMode.HALF_UP).doubleValue();
- }
-
public static NewMeasureBuilder newMeasureBuilder() {
return new NewMeasureBuilder();
}
@@ -217,12 +202,14 @@ public final class Measure {
return create(value, null);
}
- public Measure create(double value, @Nullable String data) {
- return new Measure(ValueType.DOUBLE, ruleId, characteristicId, developer, value, data, null, description, qualityGateStatus, variations);
+ public Measure create(double value, int decimalScale, @Nullable String data) {
+ checkArgument(!Double.isNaN(value), "NaN is not allowed as a Measure value");
+ double scaledValue = scale(value, decimalScale);
+ return new Measure(ValueType.DOUBLE, ruleId, characteristicId, developer, scaledValue, data, null, description, qualityGateStatus, variations);
}
- public Measure create(double value) {
- return create(value, null);
+ public Measure create(double value, int decimalScale) {
+ return create(value, decimalScale, null);
}
public Measure create(String value) {
@@ -468,4 +455,9 @@ public final class Measure {
.add("description", description)
.toString();
}
+
+ private static double scale(double value, int decimalScale) {
+ BigDecimal bd = BigDecimal.valueOf(value);
+ return bd.setScale(decimalScale, RoundingMode.HALF_UP).doubleValue();
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureDtoToMeasure.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureDtoToMeasure.java
index 68a598d4d2a..b029e98ba53 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureDtoToMeasure.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureDtoToMeasure.java
@@ -75,7 +75,9 @@ public class MeasureDtoToMeasure {
if (value == null) {
return toNoValueMeasure(measureDto);
}
- return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto).create(value.doubleValue(), data));
+
+ return of(setCommonProperties(Measure.newMeasureBuilder(), measureDto)
+ .create(value.doubleValue(), org.sonar.api.measures.Metric.MAX_DECIMAL_SCALE, data));
}
private static Optional<Measure> toBooleanMeasure(MeasureDto measureDto, @Nullable Double value, String data) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerContextImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerContextImpl.java
index 13d3a9a4578..3449aad39ff 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerContextImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerContextImpl.java
@@ -151,7 +151,7 @@ public class MeasureComputerContextImpl implements MeasureComputerContext {
public void addMeasure(String metricKey, double value) {
Metric metric = metricRepository.getByKey(metricKey);
validateAddMeasure(metric);
- measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value));
+ measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value, metric.getDecimalScale()));
}
@Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/Metric.java b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/Metric.java
index ee6771b6cfe..3c096d69609 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/Metric.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/Metric.java
@@ -49,6 +49,12 @@ public interface Metric {
@CheckForNull
Double getBestValue();
+ /**
+ * The decimal scale of float measures. Returned value is greater than or equal zero.
+ * @throws IllegalStateException if the value type is not decimal (see {@link org.sonar.server.computation.measure.Measure.ValueType}
+ */
+ int getDecimalScale();
+
enum MetricType {
INT(Measure.ValueType.INT),
MILLISEC(Measure.ValueType.LONG),
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java
index cfce85a4047..eed9a958399 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java
@@ -22,15 +22,27 @@ package org.sonar.server.computation.metric;
import com.google.common.base.Function;
import javax.annotation.Nonnull;
import org.sonar.db.metric.MetricDto;
+import org.sonar.server.computation.measure.Measure;
+
+import static com.google.common.base.Objects.firstNonNull;
enum MetricDtoToMetric implements Function<MetricDto, Metric> {
INSTANCE;
+ private static final int DEFAULT_DECIMAL_SCALE = 1;
+
@Override
@Nonnull
public Metric apply(@Nonnull MetricDto metricDto) {
+ Metric.MetricType metricType = Metric.MetricType.valueOf(metricDto.getValueType());
+ Integer decimalScale = null;
+ if (metricType.getValueType() == Measure.ValueType.DOUBLE) {
+ decimalScale = firstNonNull(metricDto.getDecimalScale(), DEFAULT_DECIMAL_SCALE);
+ }
+
return new MetricImpl(
- metricDto.getId(), metricDto.getKey(), metricDto.getShortName(), Metric.MetricType.valueOf(metricDto.getValueType()),
+ metricDto.getId(), metricDto.getKey(), metricDto.getShortName(), metricType,
+ decimalScale,
metricDto.getBestValue(), metricDto.isOptimizedBestValue());
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricImpl.java
index 0e8980d53ea..df411912075 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricImpl.java
@@ -19,13 +19,15 @@
*/
package org.sonar.server.computation.metric;
-import java.util.Objects;
+import com.google.common.base.Objects;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
+import org.sonar.server.computation.measure.Measure;
import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
@Immutable
public final class MetricImpl implements Metric {
@@ -34,20 +36,26 @@ public final class MetricImpl implements Metric {
private final String key;
private final String name;
private final MetricType type;
+ private final Integer decimalScale;
private final Double bestValue;
private final boolean bestValueOptimized;
public MetricImpl(int id, String key, String name, MetricType type) {
- this(id, key, name, type, null, false);
+ this(id, key, name, type, null, null, false);
}
- public MetricImpl(int id, String key, String name, MetricType type,
+ public MetricImpl(int id, String key, String name, MetricType type, @Nullable Integer decimalScale,
@Nullable Double bestValue, boolean bestValueOptimized) {
checkArgument(!bestValueOptimized || bestValue != null, "A BestValue must be specified if Metric is bestValueOptimized");
this.id = id;
- this.key = requireNonNull(key);
- this.name = requireNonNull(name);
- this.type = requireNonNull(type);
+ this.key = checkNotNull(key);
+ this.name = checkNotNull(name);
+ this.type = checkNotNull(type);
+ if (type.getValueType() == Measure.ValueType.DOUBLE) {
+ this.decimalScale = Objects.firstNonNull(decimalScale, org.sonar.api.measures.Metric.DEFAULT_DECIMAL_SCALE);
+ } else {
+ this.decimalScale = decimalScale;
+ }
this.bestValueOptimized = bestValueOptimized;
this.bestValue = bestValue;
}
@@ -73,6 +81,12 @@ public final class MetricImpl implements Metric {
}
@Override
+ public int getDecimalScale() {
+ checkState(decimalScale != null, "Decimal scale is not defined on metric %s", key);
+ return decimalScale;
+ }
+
+ @Override
@CheckForNull
public Double getBestValue() {
return bestValue;
@@ -92,7 +106,7 @@ public final class MetricImpl implements Metric {
return false;
}
MetricImpl metric = (MetricImpl) o;
- return Objects.equals(key, metric.key);
+ return Objects.equal(key, metric.key);
}
@Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java
index 7ebcf4ea813..cc2cb24ad3f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java
@@ -129,7 +129,7 @@ public class SqaleMeasuresVisitor extends PathAwareVisitorAdapter<SqaleMeasuresV
}
private void saveDebtRatioMeasure(Component component, double density) {
- measureRepository.add(component, debtRatioMetric, newMeasureBuilder().create(100.0 * density));
+ measureRepository.add(component, debtRatioMetric, newMeasureBuilder().create(100.0 * density, debtRatioMetric.getDecimalScale()));
}
private void saveSqaleRatingMeasure(Component component, double density) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/CommentMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/CommentMeasuresStep.java
index 883960d4aa9..1ca58fd3a1f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/CommentMeasuresStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/CommentMeasuresStep.java
@@ -112,7 +112,7 @@ public class CommentMeasuresStep implements ComputationStep {
double divisor = nclocs + comments;
if (divisor > 0d) {
double value = 100d * (comments / divisor);
- return Optional.of(Measure.newMeasureBuilder().create(value));
+ return Optional.of(Measure.newMeasureBuilder().create(value, context.getMetric().getDecimalScale()));
}
}
}
@@ -155,7 +155,7 @@ public class CommentMeasuresStep implements ComputationStep {
if (publicApis > 0d) {
double documentedAPI = publicApis - publicUndocumentedApis;
double value = 100d * (documentedAPI / publicApis);
- return Optional.of(Measure.newMeasureBuilder().create(value));
+ return Optional.of(Measure.newMeasureBuilder().create(value, context.getMetric().getDecimalScale()));
}
}
return Optional.absent();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java
index 2cf7e865d0f..60eff65c489 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java
@@ -92,7 +92,7 @@ public class CustomMeasuresCopyStep implements ComputationStep {
return Measure.newMeasureBuilder().create((long) dto.getValue());
case FLOAT:
case PERCENT:
- return Measure.newMeasureBuilder().create(dto.getValue());
+ return Measure.newMeasureBuilder().create(dto.getValue(), metric.getDecimalScale());
case BOOL:
return Measure.newMeasureBuilder().create(NumberUtils.compare(dto.getValue(), 1.0) == 0);
case LEVEL:
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/DuplicationMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/DuplicationMeasuresStep.java
index 2d60d64a37b..897d7f231b7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/DuplicationMeasuresStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/DuplicationMeasuresStep.java
@@ -209,7 +209,7 @@ public class DuplicationMeasuresStep implements ComputationStep {
Optional<Integer> nbLines = getNbLinesFromLocOrNcloc(context);
if (nbLines.isPresent() && nbLines.get() > 0) {
double density = Math.min(100d, 100d * duplicatedLines / nbLines.get());
- return Optional.of(Measure.newMeasureBuilder().create(density));
+ return Optional.of(Measure.newMeasureBuilder().create(density, context.getMetric().getDecimalScale()));
}
return Optional.absent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/UnitTestMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/UnitTestMeasuresStep.java
index 61a87ac1283..47d67790df3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/UnitTestMeasuresStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/UnitTestMeasuresStep.java
@@ -92,7 +92,7 @@ public class UnitTestMeasuresStep implements ComputationStep {
case TEST_FAILURES_KEY:
return createMeasure(context.getComponent().getType(), counter.testsFailuresCounter.getValue());
case TEST_SUCCESS_DENSITY_KEY:
- return createDensityMeasure(counter);
+ return createDensityMeasure(counter, context.getMetric().getDecimalScale());
default:
throw new IllegalStateException(String.format("Metric '%s' is not supported", metricKey));
}
@@ -105,7 +105,7 @@ public class UnitTestMeasuresStep implements ComputationStep {
return Optional.absent();
}
- private static Optional<Measure> createDensityMeasure(UnitTestsCounter counter) {
+ private static Optional<Measure> createDensityMeasure(UnitTestsCounter counter, int decimalScale) {
if (isPositive(counter.testsCounter.getValue(), true)
&& isPositive(counter.testsErrorsCounter.getValue(), false)
&& isPositive(counter.testsFailuresCounter.getValue(), false)) {
@@ -113,7 +113,7 @@ public class UnitTestMeasuresStep implements ComputationStep {
int errors = counter.testsErrorsCounter.getValue().get();
int failures = counter.testsFailuresCounter.getValue().get();
double density = (errors + failures) * 100d / tests;
- return Optional.of(Measure.newMeasureBuilder().create(100d - density));
+ return Optional.of(Measure.newMeasureBuilder().create(100d - density, decimalScale));
}
return Optional.absent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/MetricJsonWriter.java b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/MetricJsonWriter.java
index fc9ad5b2596..ceb6b9357bc 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/MetricJsonWriter.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/MetricJsonWriter.java
@@ -40,7 +40,9 @@ public class MetricJsonWriter {
public static final String FIELD_QUALITATIVE = "qualitative";
public static final String FIELD_HIDDEN = "hidden";
public static final String FIELD_CUSTOM = "custom";
- public static final Set<String> OPTIONAL_FIELDS = ImmutableSet.of(FIELD_NAME, FIELD_DESCRIPTION, FIELD_DOMAIN, FIELD_DIRECTION, FIELD_QUALITATIVE, FIELD_HIDDEN, FIELD_CUSTOM);
+ public static final String FIELD_DECIMAL_SCALE = "decimalScale";
+ public static final Set<String> OPTIONAL_FIELDS = ImmutableSet.of(FIELD_NAME, FIELD_DESCRIPTION, FIELD_DOMAIN,
+ FIELD_DIRECTION, FIELD_QUALITATIVE, FIELD_HIDDEN, FIELD_CUSTOM, FIELD_DECIMAL_SCALE);
public static final Set<String> MANDATORY_FIELDS = ImmutableSet.of(FIELD_ID, FIELD_KEY, FIELD_NAME, FIELD_DOMAIN, FIELD_TYPE);
public static final Set<String> ALL_FIELDS = ImmutableSet.copyOf(Sets.union(MANDATORY_FIELDS, OPTIONAL_FIELDS));
@@ -69,6 +71,7 @@ public class MetricJsonWriter {
writeIfNeeded(json, metric.isQualitative(), FIELD_QUALITATIVE, fieldsToReturn);
writeIfNeeded(json, metric.isHidden(), FIELD_HIDDEN, fieldsToReturn);
writeIfNeeded(json, metric.isUserManaged(), FIELD_CUSTOM, fieldsToReturn);
+ writeIfNeeded(json, metric.getDecimalScale(), FIELD_DECIMAL_SCALE, fieldsToReturn);
json.endObject();
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/SearchAction.java
index 118230d5fa1..03aa5e668b7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/SearchAction.java
@@ -52,8 +52,6 @@ public class SearchAction implements MetricsWsAction {
public static final String PARAM_IS_CUSTOM = "isCustom";
- private static final Set<String> OPTIONAL_FIELDS = newHashSet(FIELD_NAME, FIELD_DESCRIPTION, FIELD_DOMAIN, FIELD_TYPE, FIELD_DIRECTION, FIELD_QUALITATIVE, FIELD_HIDDEN,
- FIELD_CUSTOM);
private final Set<String> allPossibleFields;
private final DbClient dbClient;
@@ -61,7 +59,7 @@ public class SearchAction implements MetricsWsAction {
public SearchAction(DbClient dbClient) {
this.dbClient = dbClient;
Set<String> possibleFields = newHashSet(FIELD_ID, FIELD_KEY);
- possibleFields.addAll(OPTIONAL_FIELDS);
+ possibleFields.addAll(MetricJsonWriter.OPTIONAL_FIELDS);
allPossibleFields = possibleFields;
}
@@ -72,7 +70,7 @@ public class SearchAction implements MetricsWsAction {
.setDescription("Search for metrics")
.setResponseExample(getClass().getResource("example-search.json"))
.addPagingParams(100)
- .addFieldsParam(OPTIONAL_FIELDS)
+ .addFieldsParam(MetricJsonWriter.OPTIONAL_FIELDS)
.setHandler(this);
action.createParam(PARAM_IS_CUSTOM)
diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java b/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java
index 9f3746bf464..34a7138a473 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java
@@ -156,6 +156,7 @@ public class RegisterMetrics {
dto.setUserManaged(metric.getUserManaged());
dto.setWorstValue(metric.getWorstValue());
dto.setDeleteHistoricalData(metric.getDeleteHistoricalData());
+ dto.setDecimalScale(metric.getDecimalScale());
return dto;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaExecutionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaExecutionTest.java
index abf260cde66..f34cca2d52d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaExecutionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaExecutionTest.java
@@ -107,14 +107,14 @@ public class AverageFormulaExecutionTest {
new PathAwareCrawler<>(underTest).visit(project);
- assertThat(toEntries(measureRepository.getAddedRawMeasures(1))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(3d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(11))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(1111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2.5d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(1112))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(1d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(12))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(121))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(1211))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(1))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(3d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(11))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(1111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2.5d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(1112))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(1d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(12))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(121))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(1211))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d, 1)));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java
index 32ad48aac48..5e34ba93146 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java
@@ -245,7 +245,7 @@ public class AverageFormulaTest {
}
private void addMeasure(String metricKey, double value) {
- when(counterInitializationContext.getMeasure(metricKey)).thenReturn(Optional.of(Measure.newMeasureBuilder().create(value)));
+ when(counterInitializationContext.getMeasure(metricKey)).thenReturn(Optional.of(Measure.newMeasureBuilder().create(value, 1)));
}
private void addMeasure(String metricKey, int value) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/coverage/CoverageUtilsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/coverage/CoverageUtilsTest.java
index 9be8edbbae1..6269d2af2ff 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/coverage/CoverageUtilsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/coverage/CoverageUtilsTest.java
@@ -87,7 +87,7 @@ public class CoverageUtilsTest {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("value can not be converted to long because current value type is a DOUBLE");
- fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().create(152d));
+ fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().create(152d, 1));
getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CommentDensityRuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CommentDensityRuleTest.java
index ac9c83e0451..6ec84888939 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CommentDensityRuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CommentDensityRuleTest.java
@@ -72,7 +72,7 @@ public class CommentDensityRuleTest {
@Test
public void no_issues_if_enough_comments() {
activeRuleHolder.put(new ActiveRule(RULE_KEY, Severity.CRITICAL, ImmutableMap.of(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY, "25")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(90.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(90.0, 1));
DefaultIssue issue = underTest.processFile(FILE, "java");
@@ -82,7 +82,7 @@ public class CommentDensityRuleTest {
@Test
public void issue_if_not_enough_comments() {
activeRuleHolder.put(new ActiveRule(RULE_KEY, Severity.CRITICAL, ImmutableMap.of(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY, "25")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(10.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(10.0, 1));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_KEY, Measure.newMeasureBuilder().create(40));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.NCLOC_KEY, Measure.newMeasureBuilder().create(360));
@@ -99,7 +99,7 @@ public class CommentDensityRuleTest {
@Test
public void issue_if_not_enough_comments__test_ceil() {
activeRuleHolder.put(new ActiveRule(RULE_KEY, Severity.CRITICAL, ImmutableMap.of(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY, "25")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(0.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(0.0, 1));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_KEY, Measure.newMeasureBuilder().create(0));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.NCLOC_KEY, Measure.newMeasureBuilder().create(1));
@@ -121,7 +121,7 @@ public class CommentDensityRuleTest {
thrown.expectMessage("Minimum density of rule [common-java:InsufficientCommentDensity] is incorrect. Got [100] but must be strictly less than 100.");
activeRuleHolder.put(new ActiveRule(RULE_KEY, Severity.CRITICAL, ImmutableMap.of(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY, "100")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(0.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_DENSITY_KEY, Measure.newMeasureBuilder().create(0.0, 1));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.COMMENT_LINES_KEY, Measure.newMeasureBuilder().create(0));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), CoreMetrics.NCLOC_KEY, Measure.newMeasureBuilder().create(1));
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CoverageRuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CoverageRuleTest.java
index 68d6c59e9db..be3e3850d18 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CoverageRuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/commonrule/CoverageRuleTest.java
@@ -86,7 +86,7 @@ public abstract class CoverageRuleTest {
@Test
public void no_issue_if_enough_coverage() {
activeRuleHolder.put(new ActiveRule(getRuleKey(), Severity.CRITICAL, ImmutableMap.of(getMinPropertyKey(), "65")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(90.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(90.0, 1));
DefaultIssue issue = underTest.processFile(FILE, "java");
@@ -96,7 +96,7 @@ public abstract class CoverageRuleTest {
@Test
public void issue_if_coverage_is_too_low() {
activeRuleHolder.put(new ActiveRule(getRuleKey(), Severity.CRITICAL, ImmutableMap.of(getMinPropertyKey(), "65")));
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(20.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(20.0, 1));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getUncoveredMetricKey(), Measure.newMeasureBuilder().create(40));
measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getToCoverMetricKey(), Measure.newMeasureBuilder().create(50));
@@ -123,7 +123,7 @@ public abstract class CoverageRuleTest {
@Test
public void ignored_if_rule_is_deactivated() {
// coverage is too low, but rule is not activated
- measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(20.0));
+ measureRepository.addRawMeasure(FILE.getReportAttributes().getRef(), getCoverageMetricKey(), Measure.newMeasureBuilder().create(20.0, 1));
DefaultIssue issue = underTest.processFile(FILE, "java");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BatchMeasureToMeasureTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BatchMeasureToMeasureTest.java
index ff5b90b606d..08cc3c6b9cf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BatchMeasureToMeasureTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BatchMeasureToMeasureTest.java
@@ -203,7 +203,7 @@ public class BatchMeasureToMeasureTest {
assertThat(measure.isPresent()).isTrue();
assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.DOUBLE);
- assertThat(measure.get().getDoubleValue()).isEqualTo(10.6d);
+ assertThat(measure.get().getDoubleValue()).isEqualTo(10.6395d);
assertThat(measure.get().getData()).isEqualTo(SOME_DATA);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BestValueOptimizationTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BestValueOptimizationTest.java
index 90491dd2cc0..9e3e2117e57 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BestValueOptimizationTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/BestValueOptimizationTest.java
@@ -145,9 +145,9 @@ public class BestValueOptimizationTest {
public void verify_value_comparison_for_double_metric() {
Predicate<Measure> underTest = BestValueOptimization.from(createMetric(Metric.MetricType.FLOAT, 36.5d), FILE_COMPONENT);
- assertThat(underTest.apply(newMeasureBuilder().create(36.5d))).isTrue();
- assertThat(underTest.apply(newMeasureBuilder().setVariations(SOME_EMPTY_VARIATIONS).create(36.5d))).isTrue();
- assertThat(underTest.apply(newMeasureBuilder().create(36.6d))).isFalse();
+ assertThat(underTest.apply(newMeasureBuilder().create(36.5d, 1))).isTrue();
+ assertThat(underTest.apply(newMeasureBuilder().setVariations(SOME_EMPTY_VARIATIONS).create(36.5d, 1))).isTrue();
+ assertThat(underTest.apply(newMeasureBuilder().create(36.6d, 1))).isFalse();
}
@Test
@@ -165,6 +165,6 @@ public class BestValueOptimizationTest {
}
private static MetricImpl createMetric(Metric.MetricType metricType, double bestValue) {
- return new MetricImpl(metricType.hashCode() + (int) bestValue, "key" + metricType + bestValue, "name" + metricType + bestValue, metricType, bestValue, true);
+ return new MetricImpl(metricType.hashCode() + (int) bestValue, "key" + metricType + bestValue, "name" + metricType + bestValue, metricType, null, bestValue, true);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MapBasedRawMeasureRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MapBasedRawMeasureRepositoryTest.java
index f30cc3a0e6e..5354fc51f66 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MapBasedRawMeasureRepositoryTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MapBasedRawMeasureRepositoryTest.java
@@ -156,7 +156,7 @@ public class MapBasedRawMeasureRepositoryTest {
private static final List<Measure> MEASURES = ImmutableList.of(
Measure.newMeasureBuilder().create(1),
Measure.newMeasureBuilder().create(1l),
- Measure.newMeasureBuilder().create(1d),
+ Measure.newMeasureBuilder().create(1d, 1),
Measure.newMeasureBuilder().create(true),
Measure.newMeasureBuilder().create(false),
Measure.newMeasureBuilder().create("sds"),
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureDtoToMeasureTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureDtoToMeasureTest.java
index f5acb7726de..dbd60e52b24 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureDtoToMeasureTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureDtoToMeasureTest.java
@@ -23,6 +23,7 @@ import com.google.common.base.Optional;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import org.assertj.core.data.Offset;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -239,7 +240,7 @@ public class MeasureDtoToMeasureTest {
assertThat(measure.isPresent()).isTrue();
assertThat(measure.get().getValueType()).isEqualTo(Measure.ValueType.DOUBLE);
- assertThat(measure.get().getDoubleValue()).isEqualTo(10.6d);
+ assertThat(measure.get().getDoubleValue()).isEqualTo(10.6395d);
assertThat(measure.get().getData()).isEqualTo(SOME_DATA);
assertThat(measure.get().getQualityGateStatus().getStatus()).isEqualTo(Level.OK);
assertThat(measure.get().getQualityGateStatus().getText()).isEqualTo(SOME_ALERT_TEXT);
@@ -340,4 +341,15 @@ public class MeasureDtoToMeasureTest {
assertThat(measure.get().getVariations().hasVariation4()).isFalse();
assertThat(measure.get().getVariations().getVariation5()).isEqualTo(5);
}
+
+ @Test
+ public void toMeasure_should_not_loose_decimals_of_float_values() {
+ MetricImpl metric = new MetricImpl(42, "double", "name", Metric.MetricType.FLOAT, 5, null, false);
+ MeasureDto measureDto = new MeasureDto()
+ .setValue(0.12345);
+
+ Optional<Measure> measure = underTest.toMeasure(measureDto, metric);
+
+ assertThat(measure.get().getDoubleValue()).isEqualTo(0.12345, Offset.offset(0.000001));
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryImplTest.java
index d75b8a93496..456e79ef79d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryImplTest.java
@@ -233,7 +233,7 @@ public class MeasureRepositoryImplTest {
private static final List<Measure> MEASURES = ImmutableList.of(
Measure.newMeasureBuilder().create(1),
Measure.newMeasureBuilder().create(1l),
- Measure.newMeasureBuilder().create(1d),
+ Measure.newMeasureBuilder().create(1d, 1),
Measure.newMeasureBuilder().create(true),
Measure.newMeasureBuilder().create(false),
Measure.newMeasureBuilder().create("sds"),
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureTest.java
index f95d131e427..4c93db5619d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureTest.java
@@ -44,7 +44,7 @@ public class MeasureTest {
private static final Measure INT_MEASURE = newMeasureBuilder().create((int) 1);
private static final Measure LONG_MEASURE = newMeasureBuilder().create(1l);
- private static final Measure DOUBLE_MEASURE = newMeasureBuilder().create(1d);
+ private static final Measure DOUBLE_MEASURE = newMeasureBuilder().create(1d, 1);
private static final Measure STRING_MEASURE = newMeasureBuilder().create("some_sT ring");
private static final Measure TRUE_MEASURE = newMeasureBuilder().create(true);
private static final Measure FALSE_MEASURE = newMeasureBuilder().create(false);
@@ -296,7 +296,7 @@ public class MeasureTest {
assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create(false, null).getQualityGateStatus()).isEqualTo(someStatus);
assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create((int) 1, null).getQualityGateStatus()).isEqualTo(someStatus);
assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create((long) 1, null).getQualityGateStatus()).isEqualTo(someStatus);
- assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create((double) 1, null).getQualityGateStatus()).isEqualTo(someStatus);
+ assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create((double) 1, 1, null).getQualityGateStatus()).isEqualTo(someStatus);
assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create("str").getQualityGateStatus()).isEqualTo(someStatus);
assertThat(newMeasureBuilder().setQualityGateStatus(someStatus).create(Measure.Level.OK).getQualityGateStatus()).isEqualTo(someStatus);
}
@@ -361,7 +361,7 @@ public class MeasureTest {
assertThat(newMeasureBuilder().create(false, someData).getData()).isEqualTo(someData);
assertThat(newMeasureBuilder().create((int) 1, someData).getData()).isEqualTo(someData);
assertThat(newMeasureBuilder().create((long) 1, someData).getData()).isEqualTo(someData);
- assertThat(newMeasureBuilder().create((double) 1, someData).getData()).isEqualTo(someData);
+ assertThat(newMeasureBuilder().create((double) 1, 1, someData).getData()).isEqualTo(someData);
}
@Test
@@ -371,26 +371,26 @@ public class MeasureTest {
@Test
public void double_values_are_scaled_to_1_digit_and_round() {
- assertThat(newMeasureBuilder().create(30.27777d).getDoubleValue()).isEqualTo(30.3d);
- assertThat(newMeasureBuilder().create(30d).getDoubleValue()).isEqualTo(30d);
- assertThat(newMeasureBuilder().create(30.01d).getDoubleValue()).isEqualTo(30d);
- assertThat(newMeasureBuilder().create(30.1d).getDoubleValue()).isEqualTo(30.1d);
+ assertThat(newMeasureBuilder().create(30.27777d, 1).getDoubleValue()).isEqualTo(30.3d);
+ assertThat(newMeasureBuilder().create(30d, 1).getDoubleValue()).isEqualTo(30d);
+ assertThat(newMeasureBuilder().create(30.01d, 1).getDoubleValue()).isEqualTo(30d);
+ assertThat(newMeasureBuilder().create(30.1d, 1).getDoubleValue()).isEqualTo(30.1d);
}
@Test
public void create_with_double_value_throws_IAE_if_value_is_NaN() {
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Nan is not allowed as a Measure value");
+ expectedException.expectMessage("NaN is not allowed as a Measure value");
- newMeasureBuilder().create(Double.NaN);
+ newMeasureBuilder().create(Double.NaN, 1);
}
@Test
public void create_with_double_value_data_throws_IAE_if_value_is_NaN() {
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Nan is not allowed as a Measure value");
+ expectedException.expectMessage("NaN is not allowed as a Measure value");
- newMeasureBuilder().create(Double.NaN, "some data");
+ newMeasureBuilder().create(Double.NaN, 1, "some data");
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java
index 409673b7a05..7245fce8da6 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java
@@ -81,7 +81,7 @@ public class MeasureToMeasureDtoTest {
{ Measure.newMeasureBuilder().create(true, SOME_DATA), SOME_BOOLEAN_METRIC},
{ Measure.newMeasureBuilder().create(1, SOME_DATA), SOME_INT_METRIC},
{ Measure.newMeasureBuilder().create((long) 1, SOME_DATA), SOME_LONG_METRIC},
- { Measure.newMeasureBuilder().create((double) 2, SOME_DATA), SOME_DOUBLE_METRIC},
+ { Measure.newMeasureBuilder().create((double) 2, 1, SOME_DATA), SOME_DOUBLE_METRIC},
{ Measure.newMeasureBuilder().create(SOME_STRING), SOME_STRING_METRIC},
{ Measure.newMeasureBuilder().create(Measure.Level.OK), SOME_LEVEL_METRIC}
};
@@ -210,7 +210,7 @@ public class MeasureToMeasureDtoTest {
@Test
public void toMeasureDto_maps_value_and_data_from_data_field_for_DOUBLE_metric() {
- MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create((double) 789, SOME_DATA), SOME_DOUBLE_METRIC, SOME_COMPONENT);
+ MeasureDto trueMeasureDto = underTest.toMeasureDto(Measure.newMeasureBuilder().create((double) 789, 1, SOME_DATA), SOME_DOUBLE_METRIC, SOME_COMPONENT);
assertThat(trueMeasureDto.getValue()).isEqualTo(789);
assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureImplTest.java
index c6b11e3fdbd..2f9714ce981 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureImplTest.java
@@ -43,13 +43,13 @@ public class MeasureImplTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Value can not be converted to int because current value type is a DOUBLE");
- MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d));
+ MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d, 1));
measure.getIntValue();
}
@Test
public void get_double_value() throws Exception {
- MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d));
+ MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d, 1));
assertThat(measure.getDoubleValue()).isEqualTo(1d);
}
@@ -103,7 +103,7 @@ public class MeasureImplTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Value can not be converted to boolean because current value type is a DOUBLE");
- MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d));
+ MeasureImpl measure = new MeasureImpl(Measure.newMeasureBuilder().create(1d, 1));
measure.getBooleanValue();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricImplTest.java
index 3b6cac89f36..839f6692f3a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricImplTest.java
@@ -53,7 +53,7 @@ public class MetricImplTest {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("A BestValue must be specified if Metric is bestValueOptimized");
- new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.INT, null, true);
+ new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.INT, 1, null, true);
}
@Test
@@ -72,8 +72,8 @@ public class MetricImplTest {
assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.FLOAT)).isEqualTo(expected);
assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.STRING)).isEqualTo(expected);
- assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.STRING, 0d, true)).isEqualTo(expected);
- assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.STRING, null, false)).isEqualTo(expected);
+ assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.STRING, null, 0d, true)).isEqualTo(expected);
+ assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.STRING, null, null, false)).isEqualTo(expected);
assertThat(new MetricImpl(SOME_ID, "some other key", SOME_NAME, Metric.MetricType.FLOAT)).isNotEqualTo(expected);
}
@@ -87,7 +87,7 @@ public class MetricImplTest {
@Test
public void all_fields_are_displayed_in_toString() {
- assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.FLOAT, 951d, true).toString())
+ assertThat(new MetricImpl(SOME_ID, SOME_KEY, SOME_NAME, Metric.MetricType.FLOAT, 1, 951d, true).toString())
.isEqualTo("MetricImpl{id=42, key=key, name=name, type=FLOAT, bestValue=951.0, bestValueOptimized=true}");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryRule.java
index 8d77c4c7eb5..2b51faf2c01 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryRule.java
@@ -62,6 +62,7 @@ public class MetricRepositoryRule extends ExternalResource implements MetricRepo
return new MetricImpl(
id, coreMetric.getKey(), coreMetric.getName(),
convert(coreMetric.getType()),
+ coreMetric.getDecimalScale(),
coreMetric.getBestValue(), coreMetric.isOptimizedBestValue());
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionEvaluatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionEvaluatorTest.java
index 246aa59975e..03fc4c87bd3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionEvaluatorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/ConditionEvaluatorTest.java
@@ -54,7 +54,7 @@ public class ConditionEvaluatorTest {
public void testInputNumbers() {
try {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
underTest.evaluate(createErrorCondition(metric, LESS_THAN, "20"), measure);
} catch (NumberFormatException ex) {
fail();
@@ -70,7 +70,7 @@ public class ConditionEvaluatorTest {
try {
Metric metric = createMetric(MetricType.PERCENT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
underTest.evaluate(createErrorCondition(metric, LESS_THAN, "20.1"), measure);
} catch (NumberFormatException ex) {
fail();
@@ -88,7 +88,7 @@ public class ConditionEvaluatorTest {
@Test
public void testEquals_for_double() {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR).hasValue(10.2d);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.1"), measure)).hasLevel(OK).hasValue(10.2d);
@@ -106,7 +106,7 @@ public class ConditionEvaluatorTest {
@Test
public void testNotEquals_for_double() {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "10.2"), measure)).hasLevel(OK).hasValue(10.2d);
assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "10.1"), measure)).hasLevel(ERROR).hasValue(10.2d);
@@ -124,7 +124,7 @@ public class ConditionEvaluatorTest {
@Test
public void testGreater() {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, GREATER_THAN, "10.1"), measure)).hasLevel(ERROR).hasValue(10.2d);
assertThat(underTest.evaluate(createErrorCondition(metric, GREATER_THAN, "10.2"), measure)).hasLevel(OK).hasValue(10.2d);
@@ -134,7 +134,7 @@ public class ConditionEvaluatorTest {
@Test
public void testSmaller() {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, LESS_THAN, "10.1"), measure)).hasLevel(OK).hasValue(10.2d);
assertThat(underTest.evaluate(createErrorCondition(metric, LESS_THAN, "10.2"), measure)).hasLevel(OK).hasValue(10.2d);
@@ -144,7 +144,7 @@ public class ConditionEvaluatorTest {
@Test
public void testEquals_Percent() {
Metric metric = createMetric(MetricType.PERCENT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR).hasValue(10.2d);
}
@@ -152,7 +152,7 @@ public class ConditionEvaluatorTest {
@Test
public void testEquals_Float() {
Metric metric = createMetric(MetricType.PERCENT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR).hasValue(10.2d);
}
@@ -235,7 +235,7 @@ public class ConditionEvaluatorTest {
@Test
public void testErrorAndWarningLevel() {
Metric metric = createMetric(MetricType.FLOAT);
- Measure measure = newMeasureBuilder().create(10.2d, null);
+ Measure measure = newMeasureBuilder().create(10.2d, 1, null);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR);
assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.1"), measure)).hasLevel(OK);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java
index b06cbc2f621..777658b202a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java
@@ -95,7 +95,7 @@ public class ReportSqaleMeasuresVisitorTest {
assertThat(toEntries(measureRepository.getRawMeasures(root)))
.containsOnly(
entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")),
- entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d)),
+ entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d, 1)),
entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(A)));
}
@@ -238,7 +238,7 @@ public class ReportSqaleMeasuresVisitorTest {
private void verifyComponentMeasures(int componentRef, long expectedDevCost, double expectedDebtRatio, SqaleRatingGrid.SqaleRating expectedRating) {
assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(
entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(Long.toString(expectedDevCost))),
- entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(expectedDebtRatio * 100.0)),
+ entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(expectedDebtRatio * 100.0, 1)),
entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(expectedRating)));
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java
index cdb5ed97f59..ed74622a39c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java
@@ -111,7 +111,7 @@ public class ViewsSqaleMeasuresVisitorTest {
assertThat(toEntries(measureRepository.getRawMeasures(root)))
.containsOnly(
entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")),
- entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d)),
+ entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d, 1)),
entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(A)));
}
@@ -152,7 +152,7 @@ public class ViewsSqaleMeasuresVisitorTest {
private void assertNewRawMeasures(int componentRef, long debt, long devCost, SqaleRatingGrid.SqaleRating sqaleRating) {
assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(
entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(String.valueOf(devCost))),
- entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(debt / (double) devCost * 100.0)),
+ entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(debt / (double) devCost * 100.0, 1)),
entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(sqaleRating)));
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/CustomMeasuresCopyStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/CustomMeasuresCopyStepTest.java
index e37f49682d5..741d477ca20 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/CustomMeasuresCopyStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/CustomMeasuresCopyStepTest.java
@@ -220,7 +220,7 @@ public class CustomMeasuresCopyStepTest {
}
private void assertRawMeasureValue(int componentRef, String metricKey, double value) {
- assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(entryOf(metricKey, newMeasureBuilder().create(value)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(entryOf(metricKey, newMeasureBuilder().create(value, 1)));
}
private void assertRawMeasureValue(int componentRef, String metricKey, String value) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
index cd2a159dce9..55c27353139 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
@@ -190,7 +190,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
measureRepository.addRawMeasure(ROOT_REF, STRING_METRIC_KEY, newMeasureBuilder().create("measure-data"));
measureRepository.addRawMeasure(INTERMEDIATE_1_REF, INT_METRIC_KEY, newMeasureBuilder().create(12));
measureRepository.addRawMeasure(INTERMEDIATE_2_REF, LONG_METRIC_KEY, newMeasureBuilder().create(9635L));
- measureRepository.addRawMeasure(LEAF_REF, DOUBLE_METRIC_KEY, newMeasureBuilder().create(123.123d));
+ measureRepository.addRawMeasure(LEAF_REF, DOUBLE_METRIC_KEY, newMeasureBuilder().create(123.123d, 1));
underTest.execute();
@@ -271,7 +271,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
.setVariation(createPeriod(4), 4.4d)
.setVariation(createPeriod(5), 5.5d)
.build())
- .create(10d));
+ .create(10d, 1));
underTest.execute();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComplexityMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComplexityMeasuresStepTest.java
index 7f6b0921a69..878e4f521ff 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComplexityMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComplexityMeasuresStepTest.java
@@ -204,14 +204,14 @@ public class ReportComplexityMeasuresStepTest {
underTest.execute();
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(2.5)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(1d)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(2.5, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(1d, 1)));
double expectedNonFileValue = 2d;
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue, 1)));
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java
index 07f848adc1f..784a6103501 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportComputeMeasureVariationsStepTest.java
@@ -211,7 +211,7 @@ public class ReportComputeMeasureVariationsStepTest {
addRawMeasure(PROJECT, ISSUES_METRIC, newMeasureBuilder().create(80, null));
addRawMeasure(PROJECT, DEBT_METRIC, newMeasureBuilder().create(5L, null));
- addRawMeasure(PROJECT, FILE_COMPLEXITY_METRIC, newMeasureBuilder().create(3d, null));
+ addRawMeasure(PROJECT, FILE_COMPLEXITY_METRIC, newMeasureBuilder().create(3d, 1, null));
addRawMeasure(PROJECT, BUILD_BREAKER_METRIC, newMeasureBuilder().create(false, null));
underTest.execute();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportCoverageMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportCoverageMeasuresStepTest.java
index 220773de571..736c808e9fc 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportCoverageMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportCoverageMeasuresStepTest.java
@@ -204,19 +204,19 @@ public class ReportCoverageMeasuresStepTest {
underTest.execute();
assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(
- entryOf(codeCoverageKey, newMeasureBuilder().create(98.8d)),
- entryOf(lineCoverageKey, newMeasureBuilder().create(99d)),
- entryOf(branchCoverageKey, newMeasureBuilder().create(97d)));
+ entryOf(codeCoverageKey, newMeasureBuilder().create(98.8d, 1)),
+ entryOf(lineCoverageKey, newMeasureBuilder().create(99d, 1)),
+ entryOf(branchCoverageKey, newMeasureBuilder().create(97d, 1)));
assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(
- entryOf(codeCoverageKey, newMeasureBuilder().create(91d)),
- entryOf(lineCoverageKey, newMeasureBuilder().create(90d)),
- entryOf(branchCoverageKey, newMeasureBuilder().create(96d)));
+ entryOf(codeCoverageKey, newMeasureBuilder().create(91d, 1)),
+ entryOf(lineCoverageKey, newMeasureBuilder().create(90d, 1)),
+ entryOf(branchCoverageKey, newMeasureBuilder().create(96d, 1)));
assertThat(toEntries(measureRepository.getAddedRawMeasures(UNIT_TEST_FILE_REF))).isEmpty();
MeasureRepoEntry[] nonFileRepoEntries = {
- entryOf(codeCoverageKey, newMeasureBuilder().create(95.5d)),
- entryOf(lineCoverageKey, newMeasureBuilder().create(95.4d)),
- entryOf(branchCoverageKey, newMeasureBuilder().create(96.4d))
+ entryOf(codeCoverageKey, newMeasureBuilder().create(95.5d, 1)),
+ entryOf(lineCoverageKey, newMeasureBuilder().create(95.4d, 1)),
+ entryOf(branchCoverageKey, newMeasureBuilder().create(96.4d, 1))
};
assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(nonFileRepoEntries);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportUnitTestMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportUnitTestMeasuresStepTest.java
index 9da9e10ec1e..ba9c3ab4d7a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportUnitTestMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ReportUnitTestMeasuresStepTest.java
@@ -130,12 +130,12 @@ public class ReportUnitTestMeasuresStepTest {
underTest.execute();
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(40d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(70d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d)));
- assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(40d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(70d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d, 1)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(TEST_SUCCESS_DENSITY_KEY, newMeasureBuilder().create(60d, 1)));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComplexityMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComplexityMeasuresStepTest.java
index dcad4dca23b..726f12a1c77 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComplexityMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComplexityMeasuresStepTest.java
@@ -232,7 +232,7 @@ public class ViewsComplexityMeasuresStepTest {
}
private void assertAddedRawMeasures(int componentRef, String metricKey, double expected) {
- assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(expected)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).contains(entryOf(metricKey, newMeasureBuilder().create(expected, 1)));
}
private void addRawMeasureValue(int componentRef, String metricKey, int value) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java
index f498a21c092..e005dceee43 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsComputeMeasureVariationsStepTest.java
@@ -214,7 +214,7 @@ public class ViewsComputeMeasureVariationsStepTest {
addRawMeasure(VIEW, ISSUES_METRIC, Measure.newMeasureBuilder().create(80, null));
addRawMeasure(VIEW, DEBT_METRIC, Measure.newMeasureBuilder().create(5L, null));
- addRawMeasure(VIEW, FILE_COMPLEXITY_METRIC, Measure.newMeasureBuilder().create(3d, null));
+ addRawMeasure(VIEW, FILE_COMPLEXITY_METRIC, Measure.newMeasureBuilder().create(3d, 1));
addRawMeasure(VIEW, BUILD_BREAKER_METRIC, Measure.newMeasureBuilder().create(false, null));
underTest.execute();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsCoverageMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsCoverageMeasuresStepTest.java
index 9d454dec179..27f6b72affa 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsCoverageMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsCoverageMeasuresStepTest.java
@@ -215,17 +215,17 @@ public class ViewsCoverageMeasuresStepTest {
assertThat(toEntries(measureRepository.getAddedRawMeasures(PROJECTVIEW_3_REF))).isEmpty();
MeasureRepoEntry[] subViewRepoEntries = {
- entryOf(codeCoverageKey, newMeasureBuilder().create(95.5d)),
- entryOf(lineCoverageKey, newMeasureBuilder().create(95.4d)),
- entryOf(branchCoverageKey, newMeasureBuilder().create(96.4d))
+ entryOf(codeCoverageKey, newMeasureBuilder().create(95.5d, 1)),
+ entryOf(lineCoverageKey, newMeasureBuilder().create(95.4d, 1)),
+ entryOf(branchCoverageKey, newMeasureBuilder().create(96.4d, 1))
};
assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_SUBVIEW_REF))).contains(subViewRepoEntries);
assertThat(toEntries(measureRepository.getAddedRawMeasures(SUBVIEW_REF))).contains(subViewRepoEntries);
assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(
- entryOf(codeCoverageKey, newMeasureBuilder().create(92d)),
- entryOf(lineCoverageKey, newMeasureBuilder().create(91.2d)),
- entryOf(branchCoverageKey, newMeasureBuilder().create(96.3d)));
+ entryOf(codeCoverageKey, newMeasureBuilder().create(92d, 1)),
+ entryOf(lineCoverageKey, newMeasureBuilder().create(91.2d, 1)),
+ entryOf(branchCoverageKey, newMeasureBuilder().create(96.3d, 1)));
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsUnitTestMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsUnitTestMeasuresStepTest.java
index 0035d6a9ece..522d835dc29 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsUnitTestMeasuresStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ViewsUnitTestMeasuresStepTest.java
@@ -276,7 +276,7 @@ public class ViewsUnitTestMeasuresStepTest {
private void assertAddedRawMeasureValue(int componentRef, String metricKey, double value) {
assertThat(entryOf(metricKey, measureRepository.getAddedRawMeasure(componentRef, metricKey).get()))
- .isEqualTo(entryOf(metricKey, newMeasureBuilder().create(value)));
+ .isEqualTo(entryOf(metricKey, newMeasureBuilder().create(value, 1)));
}
private void assertAddedRawMeasureValue(int componentRef, String metricKey, long value) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java
index 6f6a63bfa85..f0d8dee6316 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java
@@ -81,6 +81,7 @@ public class RegisterMetricsTest {
.setQualitative(true)
.setDomain("new domain")
.setUserManaged(false)
+ .setDecimalScale(3)
.setHidden(true)
.create();
Metric custom = new Metric.Builder("custom", "New custom", Metric.ValueType.FLOAT)
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml
index dbedde99411..fef184f9319 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml
@@ -3,6 +3,6 @@
<!-- disabled -->
<metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="desc1" domain="domain1"
short_name="One" qualitative="[true]" user_managed="[false]" enabled="[false]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]" decimal_scale="[null]"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml
index b48ad61cd33..4ebaa508ddb 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml
@@ -4,6 +4,6 @@
short_name="One" qualitative="[true]" user_managed="[false]"
enabled="[true]"
worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]" decimal_scale="[null]"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric-result.xml
index 1f4be94dde4..91722603b13 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric-result.xml
@@ -4,6 +4,6 @@
short_name="New name" qualitative="[true]" user_managed="[false]"
enabled="[true]"
worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="-1" hidden="[true]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="-1" hidden="[true]" decimal_scale="1"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric.xml
index ad7f1e33933..3935b7ab168 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/enable_disabled_metric.xml
@@ -4,6 +4,6 @@
short_name="One" qualitative="[true]" user_managed="[false]"
enabled="[false]"
worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]" decimal_scale="[null]"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml
index 1bb5088d8e0..a525424ca47 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml
@@ -2,10 +2,10 @@
<metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="desc1" domain="domain1"
short_name="One" qualitative="[true]" user_managed="[false]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]" decimal_scale="1"/>
<metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
domain="[null]"
short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]" decimal_scale="1"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml
index 886e1d2d8f4..0cb384843c2 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml
@@ -4,12 +4,12 @@
<metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="new description"
domain="new domain"
short_name="New name" qualitative="[true]" user_managed="[false]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="-1" hidden="[true]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="-1" hidden="[true]" decimal_scale="3"/>
<!-- custom metric is unchanged -->
<metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
domain="[null]"
short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]" decimal_scale="1"/>
</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml
index 483a9cb43c6..8f52db2d6f5 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml
+++ b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml
@@ -3,10 +3,10 @@
<metrics delete_historical_data="[false]" id="1" name="m1" val_type="INT" description="old description"
domain="old domain"
short_name="old short name" qualitative="[false]" user_managed="[false]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]" decimal_scale="[null]"/>
<metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
domain="[null]"
short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
- optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+ optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]" decimal_scale="1"/>
</dataset>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/project_measure.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/project_measure.rb
index e3195f67456..4b42ca50ded 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/project_measure.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/project_measure.rb
@@ -79,7 +79,7 @@ class ProjectMeasure < ActiveRecord::Base
when Metric::VALUE_TYPE_INT
number_with_precision(value(), :precision => 0)
when Metric::VALUE_TYPE_FLOAT
- number_with_precision(value(), :precision => 1)
+ number_with_precision(value(), :precision => (metric().decimal_scale||1))
when Metric::VALUE_TYPE_PERCENT
number_to_percentage(value(), {:precision => 1})
when Metric::VALUE_TYPE_MILLISEC
@@ -108,12 +108,12 @@ class ProjectMeasure < ActiveRecord::Base
when Metric::VALUE_TYPE_INT
number_with_precision(val, :precision => 0)
when Metric::VALUE_TYPE_FLOAT
- number_with_precision(val, :precision => 1)
+ number_with_precision(val, :precision => (metric().decimal_scale||1))
when Metric::VALUE_TYPE_PERCENT
if (options[:variation]==true)
- number_with_precision(val, :precision => 1)
+ number_with_precision(val, :precision => (metric().decimal_scale||1))
else
- number_to_percentage(val, {:precision => 1})
+ number_to_percentage(val, {:precision => (metric().decimal_scale||1)})
end
when Metric::VALUE_TYPE_MILLISEC
millisecs_formatted_value(val)
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1005_add_decimal_scale_to_metrics.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1005_add_decimal_scale_to_metrics.rb
new file mode 100644
index 00000000000..48d0bd5a1e2
--- /dev/null
+++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1005_add_decimal_scale_to_metrics.rb
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+#
+# SonarQube 5.3
+# SONAR-6939
+#
+class AddDecimalScaleToMetrics < ActiveRecord::Migration
+
+ def self.up
+ add_column 'metrics', 'decimal_scale', :integer, :null => true
+ end
+
+end
+
+
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
index b78239bac82..9212cc46512 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
@@ -35,8 +35,6 @@ import org.sonar.batch.mediumtest.BatchMediumTester;
import org.sonar.batch.mediumtest.TaskResult;
import org.sonar.batch.protocol.output.BatchReport.Measure;
import org.sonar.xoo.XooPlugin;
-import org.sonar.xoo.measures.ConstantFloatMeasureSensor;
-import org.sonar.xoo.measures.XooMetrics;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
@@ -52,7 +50,6 @@ public class MeasuresMediumTest {
public BatchMediumTester tester = BatchMediumTester.builder()
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
- .registerMetric(XooMetrics.CONSTANT_FLOAT_MEASURE)
.build();
@Before
@@ -103,71 +100,6 @@ public class MeasuresMediumTest {
}
@Test
- public void floatMeasuresTruncatedTo1ByDefault() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- File xooMeasureFile = new File(srcDir, "sample.xoo.measures");
- FileUtils.write(xooFile, "Sample xoo\ncontent");
- FileUtils.write(xooMeasureFile, "lines:20");
-
- TaskResult result = tester.newTask()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project")
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.skip", "true")
- .put(ConstantFloatMeasureSensor.SONAR_XOO_ENABLE_FLOAT_SENSOR, "true")
- .build())
- .start();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project")).extracting("metricKey", "intValue", "doubleValue", "stringValue").containsOnly(
- Tuple.tuple(CoreMetrics.QUALITY_PROFILES_KEY, 0, 0.0,
- "[{\"key\":\"Sonar Way\",\"language\":\"xoo\",\"name\":\"Sonar Way\",\"rulesUpdatedAt\":\"2009-02-13T23:31:31+0000\"}]"));
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue", "doubleValue").containsOnly(
- Tuple.tuple(CoreMetrics.LINES_KEY, 2, 0.0),
- Tuple.tuple(XooMetrics.CONSTANT_FLOAT_MEASURE_KEY, 0, 1.2));
- }
-
- @Test
- public void floatMeasuresCustomPrecision() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- File xooMeasureFile = new File(srcDir, "sample.xoo.measures");
- FileUtils.write(xooFile, "Sample xoo\ncontent");
- FileUtils.write(xooMeasureFile, "lines:20");
-
- TaskResult result = tester.newTask()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project")
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.skip", "true")
- .put(ConstantFloatMeasureSensor.SONAR_XOO_ENABLE_FLOAT_SENSOR, "true")
- .put(ConstantFloatMeasureSensor.SONAR_XOO_FLOAT_PRECISION, "5")
- .build())
- .start();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project")).extracting("metricKey", "intValue", "doubleValue", "stringValue").containsOnly(
- Tuple.tuple(CoreMetrics.QUALITY_PROFILES_KEY, 0, 0.0,
- "[{\"key\":\"Sonar Way\",\"language\":\"xoo\",\"name\":\"Sonar Way\",\"rulesUpdatedAt\":\"2009-02-13T23:31:31+0000\"}]"));
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue", "doubleValue").containsOnly(
- Tuple.tuple(CoreMetrics.LINES_KEY, 2, 0.0),
- Tuple.tuple(XooMetrics.CONSTANT_FLOAT_MEASURE_KEY, 0, 1.23457));
- }
-
- @Test
public void computeLinesOnAllFiles() throws IOException {
File xooFile = new File(srcDir, "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\n\ncontent");
diff --git a/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java b/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java
index 9822dabaa84..c5bace1c447 100644
--- a/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java
+++ b/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java
@@ -55,6 +55,8 @@ public class MetricDto {
private boolean enabled;
+ private Integer decimalScale;
+
public Integer getId() {
return id;
}
@@ -196,4 +198,13 @@ public class MetricDto {
return this;
}
+ @CheckForNull
+ public Integer getDecimalScale() {
+ return decimalScale;
+ }
+
+ public MetricDto setDecimalScale(@Nullable Integer i) {
+ this.decimalScale = i;
+ return this;
+ }
}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java
index a9180d4e9c8..7bc2b344ce2 100644
--- a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java
+++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java
@@ -29,7 +29,7 @@ import org.sonar.db.MyBatis;
public class DatabaseVersion {
- public static final int LAST_VERSION = 1003;
+ public static final int LAST_VERSION = 1005;
/**
* The minimum supported version which can be upgraded. Lower
diff --git a/sonar-db/src/main/resources/org/sonar/db/metric/MetricMapper.xml b/sonar-db/src/main/resources/org/sonar/db/metric/MetricMapper.xml
index adf0d7544cb..58518e16eb7 100644
--- a/sonar-db/src/main/resources/org/sonar/db/metric/MetricMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/metric/MetricMapper.xml
@@ -18,7 +18,8 @@
m.best_value as bestValue,
m.optimized_best_value as optimizedBestValue,
m.hidden,
- m.delete_historical_data as deleteHistoricalData
+ m.delete_historical_data as deleteHistoricalData,
+ m.decimal_scale as decimalScale
</sql>
<select id="selectByKey" parameterType="map" resultType="org.sonar.db.metric.MetricDto">
@@ -86,13 +87,14 @@
keyProperty="id">
INSERT INTO metrics (
name, description, direction, domain, short_name, qualitative, val_type, user_managed, enabled, worst_value,
- best_value, optimized_best_value, hidden, delete_historical_data)
+ best_value, optimized_best_value, hidden, delete_historical_data, decimal_scale)
VALUES (
#{kee, jdbcType=VARCHAR}, #{description, jdbcType=VARCHAR}, #{direction, jdbcType=INTEGER},
#{domain, jdbcType=VARCHAR}, #{shortName, jdbcType=VARCHAR}, #{qualitative, jdbcType=BOOLEAN},
#{valueType, jdbcType=VARCHAR}, #{userManaged, jdbcType=BOOLEAN}, #{enabled, jdbcType=BOOLEAN},
#{worstValue, jdbcType=DOUBLE}, #{bestValue, jdbcType=DOUBLE},
- #{optimizedBestValue, jdbcType=BOOLEAN}, #{hidden, jdbcType=BOOLEAN}, #{deleteHistoricalData, jdbcType=BOOLEAN}
+ #{optimizedBestValue, jdbcType=BOOLEAN}, #{hidden, jdbcType=BOOLEAN}, #{deleteHistoricalData, jdbcType=BOOLEAN},
+ #{decimalScale, jdbcType=INTEGER}
)
</insert>
@@ -107,7 +109,8 @@
description=#{description, jdbcType=VARCHAR},
direction=#{direction, jdbcType=INTEGER},
hidden=#{hidden, jdbcType=BOOLEAN},
- qualitative=#{qualitative, jdbcType=BOOLEAN}
+ qualitative=#{qualitative, jdbcType=BOOLEAN},
+ decimal_scale=#{decimalScale, jdbcType=INTEGER}
where id=#{id}
</update>
diff --git a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql
index 0b770f42727..1e3e3a14b43 100644
--- a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql
+++ b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql
@@ -364,6 +364,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1000');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1001');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1002');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1003');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1005');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
diff --git a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
index d71d0d7399d..bda06b21a81 100644
--- a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
+++ b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
@@ -351,7 +351,8 @@ CREATE TABLE "METRICS" (
"BEST_VALUE" DOUBLE,
"OPTIMIZED_BEST_VALUE" BOOLEAN,
"HIDDEN" BOOLEAN,
- "DELETE_HISTORICAL_DATA" BOOLEAN
+ "DELETE_HISTORICAL_DATA" BOOLEAN,
+ "DECIMAL_SCALE" INTEGER
);
CREATE TABLE "LOADED_TEMPLATES" (
diff --git a/sonar-db/src/test/java/org/sonar/db/metric/MetricDaoTest.java b/sonar-db/src/test/java/org/sonar/db/metric/MetricDaoTest.java
index eb3940fa9ae..473e83889b5 100644
--- a/sonar-db/src/test/java/org/sonar/db/metric/MetricDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/metric/MetricDaoTest.java
@@ -82,6 +82,7 @@ public class MetricDaoTest {
assertThat(result.isDeleteHistoricalData()).isFalse();
assertThat(result.isHidden()).isFalse();
assertThat(result.isEnabled()).isTrue();
+ assertThat(result.getDecimalScale()).isEqualTo(3);
// Disabled metrics are returned
result = underTest.selectByKey(session, "disabled");
diff --git a/sonar-db/src/test/resources/org/sonar/db/metric/MetricDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/metric/MetricDaoTest/shared.xml
index dda5d3bbb88..1a43f8ed39e 100644
--- a/sonar-db/src/test/resources/org/sonar/db/metric/MetricDaoTest/shared.xml
+++ b/sonar-db/src/test/resources/org/sonar/db/metric/MetricDaoTest/shared.xml
@@ -2,14 +2,14 @@
<metrics id="1" name="ncloc" val_type="INT" description="Non Commenting Lines of Code" domain="Size" short_name="Lines of code"
qualitative="[false]" enabled="[true]" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="-1" hidden="[false]"
- delete_historical_data="[false]" user_managed="[false]"/>
+ delete_historical_data="[false]" user_managed="[false]" decimal_scale="[null]"/>
<metrics id="2" name="coverage" val_type="PERCENT" description="Coverage by unit tests" domain="Tests" short_name="Coverage"
qualitative="[true]" enabled="[true]" worst_value="0" optimized_best_value="[false]" best_value="100" direction="1" hidden="[false]"
- delete_historical_data="[false]" user_managed="[false]"/>
+ delete_historical_data="[false]" user_managed="[false]" decimal_scale="3"/>
<metrics id="3" name="disabled" val_type="INT" description="[null]" domain="[null]" short_name="disabled"
qualitative="[false]" enabled="[false]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1" hidden="[false]"
- delete_historical_data="[false]" user_managed="[false]"/>
+ delete_historical_data="[false]" user_managed="[false]" decimal_scale="[null]"/>
</dataset>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaContext.java
index 766652028ed..50b1f151b7d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaContext.java
@@ -19,37 +19,42 @@
*/
package org.sonar.api.batch;
+import org.sonar.api.measures.Formula;
import org.sonar.api.measures.FormulaContext;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Resource;
/**
* @since 1.11
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
+@Deprecated
public class DefaultFormulaContext implements FormulaContext {
- private Metric metric;
- private DecoratorContext decoratorContext;
-
public DefaultFormulaContext(Metric metric) {
- this.metric = metric;
}
@Override
public Metric getTargetMetric() {
- return metric;
+ throw fail();
}
@Override
public Resource getResource() {
- return decoratorContext.getResource();
+ throw fail();
}
public void setMetric(Metric metric) {
- this.metric = metric;
+ throw fail();
}
public void setDecoratorContext(DecoratorContext decoratorContext) {
- this.decoratorContext = decoratorContext;
+ throw fail();
+ }
+
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java
index 1aa4bc24193..8e218a00c9c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java
@@ -19,52 +19,51 @@
*/
package org.sonar.api.batch;
+import java.util.Collection;
+import org.sonar.api.measures.Formula;
import org.sonar.api.measures.FormulaData;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
/**
* @since 1.11
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
+@Deprecated
public class DefaultFormulaData implements FormulaData {
- private DecoratorContext decoratorContext;
-
- public DefaultFormulaData(DecoratorContext decoratorContext) {
- this.decoratorContext = decoratorContext;
+ public DefaultFormulaData(DecoratorContext unused) {
}
@Override
public Measure getMeasure(Metric metric) {
- return decoratorContext.getMeasure(metric);
+ throw fail();
}
@Override
public <M> M getMeasures(MeasuresFilter<M> filter) {
- return decoratorContext.getMeasures(filter);
+ throw fail();
}
@Override
public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {
- return decoratorContext.getChildrenMeasures(filter);
+ throw fail();
}
@Override
public Collection<Measure> getChildrenMeasures(Metric metric) {
- return decoratorContext.getChildrenMeasures(metric);
+ throw fail();
}
@Override
public Collection<FormulaData> getChildren() {
- List<FormulaData> result = new ArrayList<>();
- for (DecoratorContext childContext : decoratorContext.getChildren()) {
- result.add(new DefaultFormulaData(childContext));
- }
- return result;
+ throw fail();
+ }
+
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/AverageFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/AverageFormula.java
index f029f438918..2c3af7f5b95 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/AverageFormula.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/AverageFormula.java
@@ -21,33 +21,15 @@
package org.sonar.api.measures;
import java.util.List;
-import org.sonar.api.resources.ResourceUtils;
-
-import static com.google.common.collect.Lists.newArrayList;
/**
- * Formula used to compute an average for a given metric A, which is the result of the sum of measures of this metric (A) divided by another metric (B).
- * <p/>
- * For example: to compute the metric "complexity by file", the main metric (A) is "complexity" and the other metric (B) is "file".
- *
* @since 3.0
- * @deprecated since 5.2 decorators are no more executed on batch side
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
@Deprecated
public class AverageFormula implements Formula {
- private Metric mainMetric;
- private Metric byMetric;
- private Metric fallbackMetric;
-
- /**
- * This method should be private but it kep package-protected because of AverageComplexityFormula.
- */
- AverageFormula(Metric mainMetric, Metric byMetric) {
- this.mainMetric = mainMetric;
- this.byMetric = byMetric;
- }
-
/**
* Creates a new {@link AverageFormula} class.
*
@@ -55,7 +37,7 @@ public class AverageFormula implements Formula {
* @param by The metric used to divide the main metric to compute average (ex.: "file" for "complexity by file")
*/
public static AverageFormula create(Metric main, Metric by) {
- return new AverageFormula(main, by);
+ return new AverageFormula();
}
/**
@@ -65,8 +47,7 @@ public class AverageFormula implements Formula {
* @since 3.6
*/
public AverageFormula setFallbackForMainMetric(Metric fallbackMetric) {
- this.fallbackMetric = fallbackMetric;
- return this;
+ throw fail();
}
/**
@@ -74,7 +55,7 @@ public class AverageFormula implements Formula {
*/
@Override
public List<Metric> dependsUponMetrics() {
- return fallbackMetric != null ? newArrayList(mainMetric, fallbackMetric, byMetric) : newArrayList(mainMetric, byMetric);
+ throw fail();
}
/**
@@ -82,56 +63,11 @@ public class AverageFormula implements Formula {
*/
@Override
public Measure calculate(FormulaData data, FormulaContext context) {
- if (!shouldDecorateResource(data, context)) {
- return null;
- }
-
- Measure result;
- if (ResourceUtils.isFile(context.getResource())) {
- result = calculateForFile(data, context);
- } else {
- result = calculateOnChildren(data, context);
- }
- return result;
- }
-
- private Measure calculateOnChildren(FormulaData data, FormulaContext context) {
- Measure result = null;
-
- double totalByMeasure = 0;
- double totalMainMeasure = 0;
- boolean hasApplicableChildren = false;
-
- for (FormulaData childrenData : data.getChildren()) {
- Double fallbackMeasure = fallbackMetric != null ? MeasureUtils.getValue(childrenData.getMeasure(fallbackMetric), null) : null;
- Double childrenByMeasure = MeasureUtils.getValue(childrenData.getMeasure(byMetric), null);
- Double childrenMainMeasure = MeasureUtils.getValue(childrenData.getMeasure(mainMetric), fallbackMeasure);
- if (childrenMainMeasure != null && childrenByMeasure != null && childrenByMeasure > 0.0) {
- totalByMeasure += childrenByMeasure;
- totalMainMeasure += childrenMainMeasure;
- hasApplicableChildren = true;
- }
- }
- if (hasApplicableChildren) {
- result = new Measure(context.getTargetMetric(), totalMainMeasure / totalByMeasure);
- }
- return result;
- }
-
- private Measure calculateForFile(FormulaData data, FormulaContext context) {
- Measure result = null;
-
- Double fallbackMeasure = fallbackMetric != null ? MeasureUtils.getValue(data.getMeasure(fallbackMetric), null) : null;
- Double byMeasure = MeasureUtils.getValue(data.getMeasure(byMetric), null);
- Double mainMeasure = MeasureUtils.getValue(data.getMeasure(mainMetric), fallbackMeasure);
- if (mainMeasure != null && byMeasure != null && byMeasure > 0.0) {
- result = new Measure(context.getTargetMetric(), mainMeasure / byMeasure);
- }
-
- return result;
+ throw fail();
}
- private static boolean shouldDecorateResource(FormulaData data, FormulaContext context) {
- return !MeasureUtils.hasValue(data.getMeasure(context.getTargetMetric()));
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException("Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. " +
+ "Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaContext.java
index b3c2fcb524b..2011af669f9 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaContext.java
@@ -23,7 +23,10 @@ import org.sonar.api.resources.Resource;
/**
* @since 1.11
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
+@Deprecated
public interface FormulaContext {
Metric getTargetMetric();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaData.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaData.java
index 8cf5bb54307..459aec61695 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaData.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/FormulaData.java
@@ -23,7 +23,10 @@ import java.util.Collection;
/**
* @since 1.11
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
+@Deprecated
public interface FormulaData {
Measure getMeasure(Metric metric);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeanAggregationFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeanAggregationFormula.java
index f66bf51009d..22647cca1d5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeanAggregationFormula.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeanAggregationFormula.java
@@ -19,21 +19,17 @@
*/
package org.sonar.api.measures;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
/**
* @since 2.0
- * @deprecated since 5.2 decorators are no more executed on batch side
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
@Deprecated
public class MeanAggregationFormula implements Formula {
- private boolean forceZeroIfMissingData=false;
-
- public MeanAggregationFormula(boolean forceZeroIfMissingData) {
- this.forceZeroIfMissingData = forceZeroIfMissingData;
+ public MeanAggregationFormula(boolean unused) {
}
public MeanAggregationFormula() {
@@ -42,26 +38,16 @@ public class MeanAggregationFormula implements Formula {
@Override
public List<Metric> dependsUponMetrics() {
- return Collections.emptyList();
+ throw fail();
}
@Override
public Measure calculate(FormulaData data, FormulaContext context) {
- double sum=0.0;
- int count=0;
- boolean hasValue=false;
- Collection<Measure> measures = data.getChildrenMeasures(context.getTargetMetric());
- for (Measure measure : measures) {
- if (MeasureUtils.hasValue(measure)) {
- sum+=measure.getValue();
- count++;
- hasValue=true;
- }
- }
+ throw fail();
+ }
- if (!hasValue && !forceZeroIfMissingData) {
- return null;
- }
- return new Measure(context.getTargetMetric(), (count==0) ? 0.0 : (sum/count));
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java
index 4f2bef50a9f..adeae251213 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java
@@ -21,8 +21,6 @@ package org.sonar.api.measures;
import com.google.common.annotations.Beta;
import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
import java.util.Date;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -43,7 +41,9 @@ public class Measure<G extends Serializable> implements Serializable {
/**
* Default precision when saving a float type metric
+ * @deprecated in 5.3. Decimal scale is provided by metric, not by measure.
*/
+ @Deprecated
public static final int DEFAULT_PRECISION = 1;
protected String metricKey;
@@ -322,27 +322,22 @@ public class Measure<G extends Serializable> implements Serializable {
/**
* Sets the measure value with a given precision
*
- * @param v the measure value
- * @param precision the measure value precision
- * @return the measure object instance
+ * @return {@code this}
+ * @deprecated in 5.3. The decimal scale is given by the metric, not by the measure. Anyway this parameter was enforced to 1 before version 5.3.
*/
- public Measure<G> setValue(@Nullable Double v, int precision) {
+ @Deprecated
+ public Measure<G> setValue(@Nullable Double v, int decimalScale) {
if (v != null) {
if (Double.isNaN(v)) {
throw new IllegalArgumentException("Measure value can not be NaN");
}
- this.value = scaleValue(v, precision);
+ this.value = v;
} else {
this.value = null;
}
return this;
}
- private static double scaleValue(double value, int scale) {
- BigDecimal bd = BigDecimal.valueOf(value);
- return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue();
- }
-
/**
* @return the data field of the measure
*/
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
index 949e0ab603c..8fdb94f44a6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
@@ -27,19 +27,33 @@ import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.server.ServerSide;
+import static com.google.common.base.Objects.firstNonNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
@BatchSide
@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
@ServerSide
public class Metric<G extends Serializable> implements Serializable, org.sonar.api.batch.measure.Metric<G> {
/**
+ * @since 5.3
+ */
+ public static final int DEFAULT_DECIMAL_SCALE = 1;
+
+ /**
+ * The maximum supported value of scale for decimal metrics
+ * @since 5.3
+ */
+ public static final int MAX_DECIMAL_SCALE = 20;
+
+ /**
* A metric bigger value means a degradation
*/
public static final int DIRECTION_WORST = -1;
@@ -126,6 +140,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
private Boolean optimizedBestValue;
private Boolean hidden = Boolean.FALSE;
private Boolean deleteHistoricalData;
+ private Integer decimalScale;
private Metric(Builder builder) {
this.key = builder.key;
@@ -143,6 +158,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
this.formula = builder.formula;
this.userManaged = builder.userManaged;
this.deleteHistoricalData = builder.deleteHistoricalData;
+ this.decimalScale = builder.decimalScale;
}
/**
@@ -208,9 +224,12 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
this.name = name;
this.qualitative = qualitative;
this.userManaged = userManaged;
- if (ValueType.PERCENT.equals(this.type)) {
+ if (ValueType.PERCENT == this.type) {
this.bestValue = (direction == DIRECTION_BETTER) ? 100.0 : 0.0;
this.worstValue = (direction == DIRECTION_BETTER) ? 0.0 : 100.0;
+ this.decimalScale = DEFAULT_DECIMAL_SCALE;
+ } else if (ValueType.FLOAT == this.type) {
+ this.decimalScale = DEFAULT_DECIMAL_SCALE;
}
}
@@ -492,6 +511,15 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
return deleteHistoricalData;
}
+ /**
+ * Return the number scale if metric type is {@link ValueType#FLOAT}, else {@code null}
+ * @since 5.3
+ */
+ @CheckForNull
+ public Integer getDecimalScale() {
+ return decimalScale;
+ }
+
@Override
public int hashCode() {
return key.hashCode();
@@ -557,6 +585,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
private boolean hidden = false;
private boolean userManaged = false;
private boolean deleteHistoricalData = false;
+ private Integer decimalScale = null;
/**
* Creates a new {@link Builder} object.
@@ -566,15 +595,9 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
* @param type the metric type
*/
public Builder(String key, String name, ValueType type) {
- if (StringUtils.isBlank(key)) {
- throw new IllegalArgumentException("Metric key can not be blank");
- }
- if (StringUtils.isBlank(name)) {
- throw new IllegalArgumentException("Metric name can not be blank");
- }
- if (type == null) {
- throw new IllegalArgumentException("Metric type can not be null");
- }
+ checkArgument(isNotBlank(key), "Metric key can not be blank");
+ checkArgument(isNotBlank(name), "Name of metric %s must be set", key);
+ checkArgument(type != null, "Type of metric %s must be set", key);
this.key = key;
this.name = name;
this.type = type;
@@ -647,11 +670,6 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
* When a formula is set, sensors/decorators just need to store measures at a specific level and let Sonar run the formula to store
* measures on the remaining levels.
*
- * @see SumChildDistributionFormula
- * @see SumChildValuesFormula
- * @see MeanAggregationFormula
- * @see WeightedMeanAggregationFormula
- *
* @param f the formula
* @return the builder
*
@@ -741,14 +759,30 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
}
/**
+ * Scale to be used if the metric has decimal type ({@link ValueType#FLOAT} or {@link ValueType#PERCENT}).
+ * Default is 1. It is not set (({@code null}) on non-decimal metrics.
+ * @since 5.3
+ */
+ public Builder setDecimalScale(int scale) {
+ checkArgument(scale >= 0, "Scale of decimal metric %s must be positive: %d", key, scale);
+ checkArgument(scale <= MAX_DECIMAL_SCALE, "Scale of decimal metric [%s] must be less than or equal %s: %s", key, MAX_DECIMAL_SCALE, scale);
+ this.decimalScale = scale;
+ return this;
+ }
+
+ /**
* Creates a new metric definition based on the properties set on this metric builder.
*
* @return a new {@link Metric} object
*/
public <G extends Serializable> Metric<G> create() {
- if (ValueType.PERCENT.equals(this.type)) {
+ if (ValueType.PERCENT == this.type) {
this.bestValue = (direction == DIRECTION_BETTER) ? 100.0 : 0.0;
this.worstValue = (direction == DIRECTION_BETTER) ? 0.0 : 100.0;
+ this.decimalScale = firstNonNull(decimalScale, DEFAULT_DECIMAL_SCALE);
+
+ } else if (ValueType.FLOAT == this.type) {
+ this.decimalScale = firstNonNull(decimalScale, DEFAULT_DECIMAL_SCALE);
}
return new Metric<>(this);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java
index e75a2f3c119..616eb2cbff7 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java
@@ -19,50 +19,38 @@
*/
package org.sonar.api.measures;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
-import org.sonar.api.resources.Scopes;
/**
* @since 2.0
*
* Used to consolidate a distribution measure throughout the resource tree
- * @deprecated since 5.2 decorators are no more executed on batch side
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
@Deprecated
public class SumChildDistributionFormula implements Formula {
- private String minimumScopeToPersist= Scopes.FILE;
-
@Override
public List<Metric> dependsUponMetrics() {
- return Collections.emptyList();
+ throw fail();
}
public String getMinimumScopeToPersist() {
- return minimumScopeToPersist;
+ throw fail();
}
public SumChildDistributionFormula setMinimumScopeToPersist(String s) {
- this.minimumScopeToPersist = s;
- return this;
+ throw fail();
}
@Override
public Measure calculate(FormulaData data, FormulaContext context) {
- Collection<Measure> measures = data.getChildrenMeasures(context.getTargetMetric());
- if (measures == null || measures.isEmpty()) {
- return null;
- }
- RangeDistributionBuilder distribution = new RangeDistributionBuilder(context.getTargetMetric());
- for (Measure measure : measures) {
- distribution.add(measure);
- }
- Measure measure = distribution.build();
- if (!Scopes.isHigherThanOrEquals(context.getResource().getScope(), minimumScopeToPersist)) {
- measure.setPersistenceMode(PersistenceMode.MEMORY);
- }
- return measure;
+ throw fail();
+ }
+
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildValuesFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildValuesFormula.java
index 37e7abf6a25..450befdee5a 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildValuesFormula.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildValuesFormula.java
@@ -19,33 +19,31 @@
*/
package org.sonar.api.measures;
-import java.util.Collections;
import java.util.List;
/**
* @since 1.11
- * @deprecated since 5.2 decorators are no more executed on batch side
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
@Deprecated
public class SumChildValuesFormula implements Formula {
- private boolean saveZeroIfNoChildValues;
-
- public SumChildValuesFormula(boolean saveZeroIfNoChildValues) {
- this.saveZeroIfNoChildValues = saveZeroIfNoChildValues;
+ public SumChildValuesFormula(boolean unused) {
}
@Override
public List<Metric> dependsUponMetrics() {
- return Collections.emptyList();
+ throw fail();
}
@Override
public Measure calculate(FormulaData data, FormulaContext context) {
- Double sum = MeasureUtils.sum(saveZeroIfNoChildValues, data.getChildrenMeasures(context.getTargetMetric()));
- if (sum != null) {
- return new Measure(context.getTargetMetric(), sum);
- }
- return null;
+ throw fail();
+ }
+
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/WeightedMeanAggregationFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/WeightedMeanAggregationFormula.java
index 7be604edaf6..360eb01ea9e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/WeightedMeanAggregationFormula.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/WeightedMeanAggregationFormula.java
@@ -19,54 +19,31 @@
*/
package org.sonar.api.measures;
-import java.util.Collections;
import java.util.List;
/**
* @since 2.0
- * @deprecated since 5.2 decorators are no more executed on batch side
+ * @deprecated since 5.2. Aggregation of measures is provided by {@link org.sonar.api.ce.measure.MeasureComputer}. {@link org.sonar.api.batch.Decorator}
+ * and {@link Formula} are no more supported.
*/
@Deprecated
public class WeightedMeanAggregationFormula implements Formula {
- private Metric weightingMetric;
- private boolean zeroIfNoValues=false;
-
public WeightedMeanAggregationFormula(Metric weightingMetric, boolean zeroIfNoValues) {
- this.weightingMetric = weightingMetric;
- if (weightingMetric==null) {
- throw new IllegalArgumentException("Metric can not be null");
- }
- this.zeroIfNoValues = zeroIfNoValues;
}
@Override
public List<Metric> dependsUponMetrics() {
- return Collections.emptyList();
+ throw fail();
}
@Override
public Measure calculate(FormulaData data, FormulaContext context) {
- double sum=0.0;
- double count=0.0;
- boolean hasValue=false;
-
- for (FormulaData child : data.getChildren()) {
- Measure measure = child.getMeasure(context.getTargetMetric());
- Measure weightingMeasure = child.getMeasure(weightingMetric);
- if (MeasureUtils.haveValues(measure, weightingMeasure)) {
- sum += measure.getValue() * weightingMeasure.getValue();
- count += weightingMeasure.getValue();
- hasValue=true;
- }
- }
-
- if (!hasValue && !zeroIfNoValues) {
- return null;
- }
+ throw fail();
+ }
- double result = (Double.doubleToRawLongBits(count)==0L) ? 0.0 : (sum/count);
- return new Measure(context.getTargetMetric(), result);
+ private static RuntimeException fail() {
+ throw new UnsupportedOperationException(
+ "Unsupported since version 5.2. Decorators and formulas are not used anymore for aggregation measures. Please use org.sonar.api.ce.measure.MeasureComputer.");
}
}
-
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/DefaultFormulaDataTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/DefaultFormulaDataTest.java
index 5139aa75edb..03f6188eea6 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/DefaultFormulaDataTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/DefaultFormulaDataTest.java
@@ -23,42 +23,22 @@ import org.junit.Test;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
public class DefaultFormulaDataTest {
- @Test
- public void isDecoratorContextProxy() {
- DecoratorContext context = mock(DecoratorContext.class);
- DefaultFormulaData data = new DefaultFormulaData(context);
-
- data.getChildrenMeasures(any(MeasuresFilter.class));
- verify(context).getChildrenMeasures(any(MeasuresFilter.class));
+ DefaultFormulaData underTest = new DefaultFormulaData(null);
- data.getChildrenMeasures(any(Metric.class));
- verify(context).getChildrenMeasures(any(Metric.class));
-
- data.getMeasures(any(MeasuresFilter.class));
- verify(context).getMeasures(any(MeasuresFilter.class));
-
- data.getMeasure(any(Metric.class));
- verify(context).getMeasure(any(Metric.class));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_1() {
+ underTest.getChildren();
}
- @Test
- public void getChildren() {
- DecoratorContext context = mock(DecoratorContext.class);
- DecoratorContext child1 = mock(DecoratorContext.class);
- DecoratorContext child2 = mock(DecoratorContext.class);
- when(context.getChildren()).thenReturn(Arrays.asList(child1, child2));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_2() {
+ underTest.getChildrenMeasures((MeasuresFilter) null);
+ }
- DefaultFormulaData data = new DefaultFormulaData(context);
- assertThat(data.getChildren()).hasSize(2);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_3() {
+ underTest.getChildrenMeasures((Metric) null);
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/AverageFormulaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/AverageFormulaTest.java
index e4a9c96f57c..cc05ee44bbf 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/AverageFormulaTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/AverageFormulaTest.java
@@ -19,174 +19,24 @@
*/
package org.sonar.api.measures;
-import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.resources.File;
-
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class AverageFormulaTest {
- private FormulaContext context;
- private FormulaData data;
+ AverageFormula underTest = new AverageFormula();
- @Before
- public void before() {
- context = mock(FormulaContext.class);
- when(context.getTargetMetric()).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY);
- data = mock(FormulaData.class);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_1() {
+ underTest.calculate(null, null);
}
- @Test
- public void test_depends_upon_metrics() throws Exception {
- AverageFormula formula = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS);
- assertThat(formula.dependsUponMetrics()).containsOnly(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_2() {
+ underTest.dependsUponMetrics();
}
- @Test
- public void test_depends_upon_fallback_metric() throws Exception {
- AverageFormula formula = AverageFormula.create(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, CoreMetrics.FUNCTIONS).setFallbackForMainMetric(CoreMetrics.COMPLEXITY);
- assertThat(formula.dependsUponMetrics()).containsOnly(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_3() {
+ underTest.setFallbackForMainMetric(null);
}
-
- @Test
- public void test_average_calculation() {
- List<FormulaData> childrenData = newArrayList();
- FormulaData data1 = mock(FormulaData.class);
- childrenData.add(data1);
- when(data1.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 43.0));
- when(data1.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 107.0));
-
- FormulaData data2 = mock(FormulaData.class);
- childrenData.add(data2);
- when(data2.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 127.0));
- when(data2.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 233.0));
-
- when(data.getChildren()).thenReturn(childrenData);
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
-
- assertThat(measure.getValue()).isEqualTo(2.0);
- }
-
- @Test
- public void should_not_compute_if_not_target_metric() {
- when(data.getMeasure(CoreMetrics.FUNCTION_COMPLEXITY)).thenReturn(new Measure(CoreMetrics.FUNCTION_COMPLEXITY, 2.0));
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
- assertThat(measure).isNull();
- }
-
- @Test
- public void test_when_no_children_measures() {
- List<FormulaData> childrenData = newArrayList();
- when(data.getChildren()).thenReturn(childrenData);
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
- assertThat(measure).isNull();
- }
-
- @Test
- public void test_when_no_complexity_measures() {
- List<FormulaData> childrenData = newArrayList();
- FormulaData data1 = mock(FormulaData.class);
- childrenData.add(data1);
- when(data1.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 43.0));
-
- when(data.getChildren()).thenReturn(childrenData);
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
-
- assertThat(measure).isNull();
- }
-
- @Test
- public void test_when_no_by_metric_measures() {
- List<FormulaData> childrenData = newArrayList();
- FormulaData data1 = mock(FormulaData.class);
- childrenData.add(data1);
- when(data1.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 43.0));
-
- when(data.getChildren()).thenReturn(childrenData);
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
-
- assertThat(measure).isNull();
- }
-
- @Test
- public void test_when_mixed_metrics() {
- List<FormulaData> childrenData = newArrayList();
- FormulaData data1 = mock(FormulaData.class);
- childrenData.add(data1);
- when(data1.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 43.0));
- when(data1.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 107.0));
-
- FormulaData data2 = mock(FormulaData.class);
- childrenData.add(data2);
- when(data2.getMeasure(CoreMetrics.STATEMENTS)).thenReturn(new Measure(CoreMetrics.STATEMENTS, 127.0));
- when(data2.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 233.0));
-
- when(data.getChildren()).thenReturn(childrenData);
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
-
- assertThat(measure.getValue()).isEqualTo(2.5);
- }
-
- @Test
- public void test_calculation_for_file() {
- when(data.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 60.0));
- when(data.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 20.0));
- when(context.getResource()).thenReturn(File.create("foo"));
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS).calculate(data, context);
- assertThat(measure.getValue()).isEqualTo(3.0);
- }
-
- @Test
- public void should_use_fallback_metric_when_no_data_on_main_metric_for_file() {
- when(data.getMeasure(CoreMetrics.COMPLEXITY_IN_FUNCTIONS)).thenReturn(null);
- when(data.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 60.0));
- when(data.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 20.0));
- when(context.getResource()).thenReturn(File.create("foo"));
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, CoreMetrics.FUNCTIONS)
- .setFallbackForMainMetric(CoreMetrics.COMPLEXITY)
- .calculate(data, context);
- assertThat(measure.getValue()).isEqualTo(3.0);
- }
-
- @Test
- public void should_use_main_metric_even_if_fallback_metric_provided() {
- when(data.getMeasure(CoreMetrics.COMPLEXITY_IN_FUNCTIONS)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 60.0));
- when(data.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 42.0));
- when(data.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 20.0));
- when(context.getResource()).thenReturn(File.create("foo"));
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, CoreMetrics.FUNCTIONS)
- .setFallbackForMainMetric(CoreMetrics.COMPLEXITY)
- .calculate(data, context);
- assertThat(measure.getValue()).isEqualTo(3.0);
- }
-
- @Test
- public void should_use_fallback_metric_when_no_data_on_main_metric_for_children() {
- List<FormulaData> childrenData = newArrayList();
- FormulaData data1 = mock(FormulaData.class);
- childrenData.add(data1);
- when(data1.getMeasure(CoreMetrics.COMPLEXITY_IN_FUNCTIONS)).thenReturn(null);
- when(data1.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 107.0));
- when(data1.getMeasure(CoreMetrics.FUNCTIONS)).thenReturn(new Measure(CoreMetrics.FUNCTIONS, 43.0));
-
- when(data.getChildren()).thenReturn(childrenData);
-
- Measure measure = AverageFormula.create(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, CoreMetrics.FUNCTIONS)
- .setFallbackForMainMetric(CoreMetrics.COMPLEXITY)
- .calculate(data, context);
-
- assertThat(measure.getValue()).isEqualTo(2.5);
- }
-
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeanAggregationFormulaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeanAggregationFormulaTest.java
index c1443832c7b..2beec78cdd1 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeanAggregationFormulaTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeanAggregationFormulaTest.java
@@ -19,57 +19,19 @@
*/
package org.sonar.api.measures;
-import org.junit.Before;
import org.junit.Test;
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
public class MeanAggregationFormulaTest {
- private FormulaContext context;
- private FormulaData data;
-
- @Before
- public void before() {
- context = mock(FormulaContext.class);
- data = mock(FormulaData.class);
- }
-
- @Test
- public void calculateChildrenMean() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.COVERAGE);
- when(data.getChildrenMeasures(CoreMetrics.COVERAGE)).thenReturn(Arrays.<Measure>asList(newCoverage(100.0), newCoverage(50.0), newCoverage(30.0)));
-
- Measure measure = new MeanAggregationFormula().calculate(data, context);
- assertThat(measure.getValue(), is(60.0));
- }
-
- @Test
- public void doNotForceZero() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.COVERAGE);
- when(data.getChildrenMeasures(CoreMetrics.COVERAGE)).thenReturn(Collections.<Measure>emptyList());
-
- Measure measure = new MeanAggregationFormula(false).calculate(data, context);
- assertNull(measure);
- }
-
- @Test
- public void forceZero() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.COVERAGE);
- when(data.getChildrenMeasures(CoreMetrics.COVERAGE)).thenReturn(Collections.<Measure>emptyList());
+ MeanAggregationFormula underTest = new MeanAggregationFormula();
- Measure measure = new MeanAggregationFormula(true).calculate(data, context);
- assertThat(measure.getValue(), is(0.0));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_1() {
+ underTest.calculate(null, null);
}
- private Measure newCoverage(double val) {
- return new Measure(CoreMetrics.COVERAGE, val);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_2() {
+ underTest.dependsUponMetrics();
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java
index 9a33b01caab..b671a63e9c7 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java
@@ -46,12 +46,6 @@ public class MeasureTest {
}
@Test
- public void scaleValue() {
- assertThat(new Measure(CoreMetrics.COVERAGE, 80.666666).getValue()).isEqualTo(80.7);
- assertThat(new Measure(CoreMetrics.COVERAGE, 80.666666, 2).getValue()).isEqualTo(80.67);
- }
-
- @Test
public void defaultPersistenceModeIsFull() {
assertThat(new Measure(CoreMetrics.LINES, 32.0).getPersistenceMode()).isEqualTo(PersistenceMode.FULL);
}
@@ -81,15 +75,6 @@ public class MeasureTest {
assertThat(new Measure(CoreMetrics.LINES).setValue(3.6).getIntValue()).isEqualTo(3);
}
- @Test
- public void valuesAreRoundUp() {
- assertThat(new Measure(CoreMetrics.COVERAGE, 5.22222222).getValue()).isEqualTo(5.2);
- assertThat(new Measure(CoreMetrics.COVERAGE, 5.7777777).getValue()).isEqualTo(5.8);
-
- assertThat(new Measure(CoreMetrics.COVERAGE, 5.22222222, 3).getValue()).isEqualTo(5.222);
- assertThat(new Measure(CoreMetrics.COVERAGE, 5.7777777, 3).getValue()).isEqualTo(5.778);
- }
-
/**
* Proper definition of equality for measures is important, because used to store them.
*/
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java
index 24ae4b69be7..0a088f53d3a 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java
@@ -19,55 +19,97 @@
*/
package org.sonar.api.measures;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
public class MetricTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
@Test
public void shouldCreateMetric() {
Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.INT)
- .setDomain("my domain")
- .create();
+ .setDomain("my domain")
+ .create();
- assertThat(metric.getKey(), is("foo"));
- assertThat(metric.getName(), is("Foo"));
- assertThat(metric.getDomain(), is("my domain"));
+ assertThat(metric.getKey()).isEqualTo("foo");
+ assertThat(metric.getName()).isEqualTo("Foo");
+ assertThat(metric.getDomain()).isEqualTo("my domain");
}
@Test
public void shouldCreateMetricWithDefaultValues() {
Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.INT)
- .create();
-
- assertThat(metric.getBestValue(), nullValue());
- assertThat(metric.getDescription(), nullValue());
- assertThat(metric.getWorstValue(), nullValue());
- assertThat(metric.getDirection(), is(Metric.DIRECTION_NONE));
- assertThat(metric.getEnabled(), is(true));
- assertThat(metric.getFormula(), nullValue());
- assertThat(metric.getId(), nullValue());
- assertThat(metric.getUserManaged(), is(false));
- assertThat(metric.isHidden(), is(false));
- assertThat(metric.isOptimizedBestValue(), is(false));
+ .create();
+
+ assertThat(metric.getBestValue()).isNull();
+ assertThat(metric.getDescription()).isNull();
+ assertThat(metric.getWorstValue()).isNull();
+ assertThat(metric.getDirection()).isEqualTo(Metric.DIRECTION_NONE);
+ assertThat(metric.getEnabled()).isTrue();
+ assertThat(metric.getFormula()).isNull();
+ assertThat(metric.getId()).isNull();
+ assertThat(metric.getUserManaged()).isFalse();
+ assertThat(metric.isHidden()).isFalse();
+ assertThat(metric.isOptimizedBestValue()).isFalse();
}
@Test
public void shouldCreatePercentMetricWithDefaultValues() {
Metric better = new Metric.Builder("foo", "Foo", Metric.ValueType.PERCENT)
- .setDirection(Metric.DIRECTION_BETTER)
- .create();
+ .setDirection(Metric.DIRECTION_BETTER)
+ .create();
Metric worst = new Metric.Builder("foo", "Foo", Metric.ValueType.PERCENT)
- .setDirection(Metric.DIRECTION_WORST)
- .create();
+ .setDirection(Metric.DIRECTION_WORST)
+ .create();
+
+ assertThat(better.getBestValue()).isEqualTo(100.0);
+ assertThat(better.getWorstValue()).isEqualTo(0.0);
+ assertThat(worst.getBestValue()).isEqualTo(0.0);
+ assertThat(worst.getWorstValue()).isEqualTo(100.0);
+ }
+
+ @Test
+ public void override_decimal_scale_of_float_metric() {
+ Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.FLOAT)
+ .setDecimalScale(3)
+ .create();
+ assertThat(metric.getDecimalScale()).isEqualTo(3);
+ }
+
+ @Test
+ public void fail_if_decimal_scale_is_greater_than_max_supported_value() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Scale of decimal metric [foo] must be less than or equal 20: 21");
- assertThat(better.getBestValue(), is(100.0));
- assertThat(better.getWorstValue(), is(0.0));
- assertThat(worst.getBestValue(), is(0.0));
- assertThat(worst.getWorstValue(), is(100.0));
+ new Metric.Builder("foo", "Foo", Metric.ValueType.FLOAT)
+ .setDecimalScale(Metric.MAX_DECIMAL_SCALE + 1)
+ .create();
}
+ @Test
+ public void override_decimal_scale_of_percent_metric() {
+ Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.PERCENT)
+ .setDecimalScale(3)
+ .create();
+ assertThat(metric.getDecimalScale()).isEqualTo(3);
+ }
+
+ @Test
+ public void default_decimal_scale_is_1() {
+ Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.FLOAT)
+ .create();
+ assertThat(metric.getDecimalScale()).isEqualTo(1);
+ }
+
+ @Test
+ public void non_decimal_metric_has_no_scale() {
+ Metric metric = new Metric.Builder("foo", "Foo", Metric.ValueType.INT)
+ .create();
+ assertThat(metric.getDecimalScale()).isNull();
+ }
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java
index b4d64fd8551..e712da3f312 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java
@@ -19,122 +19,29 @@
*/
package org.sonar.api.measures;
-import com.google.common.collect.Lists;
-import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Scopes;
-
-import java.util.Collections;
-import java.util.List;
-
-import static junit.framework.Assert.assertNull;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class SumChildDistributionFormulaTest {
- SumChildDistributionFormula formula;
- FormulaContext context;
- FormulaData data;
-
- @Before
- public void init() {
- formula = new SumChildDistributionFormula();
- context = mock(FormulaContext.class);
- when(context.getResource()).thenReturn(File.create("foo"));
- data = mock(FormulaData.class);
- }
-
- @Test
- public void testWhenGetChildrenReturnsNull() {
- when(context.getTargetMetric()).thenReturn(new Metric("foo"));
- when(data.getChildrenMeasures(new Metric("foo"))).thenReturn(null);
- assertNull(formula.calculate(data, context));
- }
-
- @Test
- public void testWhenGetChildrenReturnsEmpty() {
- when(context.getTargetMetric()).thenReturn(new Metric("foo"));
- when(data.getChildrenMeasures(new Metric("foo"))).thenReturn(Collections.<Measure>emptyList());
- assertNull(formula.calculate(data, context));
- }
-
- @Test
- public void shouldNotSumDifferentRanges() {
- Metric m = new Metric("foo", Metric.ValueType.DATA);
- when(context.getTargetMetric()).thenReturn(m);
-
- List<Measure> list = Lists.newArrayList(
- new Measure(m, "1=0;2=2;5=0;10=10;20=2"),
- new Measure(m, "1=0;2=2;5=0;10=10;30=3")
- );
- when(data.getChildrenMeasures(new Metric("foo"))).thenReturn(list);
- assertThat(formula.calculate(data, context), nullValue());
- }
- @Test
- public void shouldSumSameIntRanges() {
- Metric m = new Metric("foo", Metric.ValueType.DATA);
- when(context.getTargetMetric()).thenReturn(m);
+ SumChildDistributionFormula underTest = new SumChildDistributionFormula();
- List<Measure> list = Lists.newArrayList(
- new Measure(m, "1=0;2=2;5=0;10=10;20=2"),
- new Measure(m, "1=3;2=2;5=3;10=12;20=0")
- );
- when(data.getChildrenMeasures(new Metric("foo"))).thenReturn(list);
- assertThat(formula.calculate(data, context).getData(), is("1=3;2=4;5=3;10=22;20=2"));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_1() {
+ underTest.calculate(null, null);
}
- @Test
- public void shouldSumSameDoubleRanges() {
- initContextWithChildren();
- assertThat(formula.calculate(data, context).getData(), is("0.5=3;2.5=6"));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_2() {
+ underTest.dependsUponMetrics();
}
- @Test
- public void shouldNotPersistWhenScopeLowerThanMinimun() {
- when(context.getResource()).thenReturn(File.create("org/Foo.java"));
-
- initContextWithChildren();
- formula.setMinimumScopeToPersist(Scopes.DIRECTORY);
-
- Measure distribution = formula.calculate(data, context);
- assertThat(distribution.getPersistenceMode().useDatabase(), is(false));
- }
-
- @Test
- public void shouldPersistWhenScopeEqualsMinimun() {
- when(context.getResource()).thenReturn(File.create("org/Foo.java"));
-
- initContextWithChildren();
- formula.setMinimumScopeToPersist(Scopes.FILE);
-
- Measure distribution = formula.calculate(data, context);
- assertThat(distribution.getPersistenceMode().useDatabase(), is(true));
- }
-
- @Test
- public void shouldPersistWhenScopeHigherThanMinimun() {
- when(context.getResource()).thenReturn(Directory.create("org/foo"));
-
- initContextWithChildren();
- formula.setMinimumScopeToPersist(Scopes.FILE);
-
- Measure distribution = formula.calculate(data, context);
- assertThat(distribution.getPersistenceMode().useDatabase(), is(true));
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_3() {
+ underTest.getMinimumScopeToPersist();
}
- private void initContextWithChildren() {
- Metric m = new Metric("foo", Metric.ValueType.DATA);
- when(context.getTargetMetric()).thenReturn(m);
- List<Measure> list = Lists.newArrayList(
- new Measure(m, "0.5=0;2.5=2"),
- new Measure(m, "0.5=3;2.5=4")
- );
- when(data.getChildrenMeasures(new Metric("foo"))).thenReturn(list);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_4() {
+ underTest.setMinimumScopeToPersist(null);
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildValuesFormulaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildValuesFormulaTest.java
deleted file mode 100644
index 5bc69ab6684..00000000000
--- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildValuesFormulaTest.java
+++ /dev/null
@@ -1,74 +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.
- */
-package org.sonar.api.measures;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SumChildValuesFormulaTest {
- private FormulaContext context;
- private FormulaData data;
-
- @Before
- public void before() {
- context = mock(FormulaContext.class);
- data = mock(FormulaData.class);
- }
-
- @Test
- public void sumChildValues() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.NCLOC);
- when(data.getChildrenMeasures(CoreMetrics.NCLOC)).thenReturn(
- Arrays.<Measure>asList(new Measure(CoreMetrics.NCLOC, 100.0), new Measure(CoreMetrics.NCLOC, 50.0)));
-
- Measure measure = new SumChildValuesFormula(true).calculate(data, context);
-
- assertThat(measure.getMetric()).isEqualTo(CoreMetrics.NCLOC);
- assertThat(measure.getValue()).isEqualTo(150.0);
- }
-
- @Test
- public void doNotInsertZero() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.NCLOC);
- when(data.getChildrenMeasures(CoreMetrics.NCLOC)).thenReturn(Collections.<Measure>emptyList());
-
- Measure measure = new SumChildValuesFormula(false).calculate(data, context);
-
- assertThat(measure).isNull();
- }
-
- @Test
- public void doInsertZero() {
- when(context.getTargetMetric()).thenReturn(CoreMetrics.NCLOC);
- when(data.getChildrenMeasures(CoreMetrics.NCLOC)).thenReturn(Collections.<Measure>emptyList());
-
- Measure measure = new SumChildValuesFormula(true).calculate(data, context);
-
- assertThat(measure.getMetric()).isEqualTo(CoreMetrics.NCLOC);
- assertThat(measure.getValue()).isEqualTo(0.0);
- }
-}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/package-info.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/WeightedMeanAggregationFormulaTest.java
index 53dbecc35dc..3aa8d6d50af 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/measures/package-info.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/WeightedMeanAggregationFormulaTest.java
@@ -17,9 +17,20 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+package org.sonar.api.measures;
-@ParametersAreNonnullByDefault
-package org.sonar.xoo.measures;
+import org.junit.Test;
-import javax.annotation.ParametersAreNonnullByDefault;
+public class WeightedMeanAggregationFormulaTest {
+ WeightedMeanAggregationFormula underTest = new WeightedMeanAggregationFormula(null, false);
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_1() {
+ underTest.calculate(null, null);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void fail_if_used_2() {
+ underTest.dependsUponMetrics();
+ }
+}