diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-07-01 18:33:52 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-07-02 13:46:26 +0200 |
commit | 00bd0332e9346fc49d9cd5205deb34929be2b22f (patch) | |
tree | c35d2ac1de1c33aa5b6ae6b4745f85ef57861801 | |
parent | 4a199cc79ff17dfc24f8de685760bcbda0e48d09 (diff) | |
download | sonarqube-00bd0332e9346fc49d9cd5205deb34929be2b22f.tar.gz sonarqube-00bd0332e9346fc49d9cd5205deb34929be2b22f.zip |
SONAR-6605 Create average formula
3 files changed, 553 insertions, 0 deletions
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 new file mode 100644 index 00000000000..8d9c3cb996c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/AverageFormula.java @@ -0,0 +1,178 @@ +/* + * 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.server.computation.formula; + +import com.google.common.base.Optional; +import java.util.Objects; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.measure.Measure; + +public class AverageFormula implements Formula<AverageFormula.AverageCounter> { + + private final String outputMetricKey; + + private final String mainMetric; + private final String byMetric; + @CheckForNull + private final String fallbackMetric; + + private AverageFormula(Builder builder) { + this.outputMetricKey = builder.outputMetricKey; + this.mainMetric = builder.mainMetric; + this.byMetric = builder.byMetric; + this.fallbackMetric = builder.fallbackMetric; + } + + @Override + public AverageCounter createNewCounter() { + return new AverageCounter(); + } + + @Override + public Optional<Measure> createMeasure(AverageCounter counter, Component.Type componentType) { + Optional<Double> mainValueOptional = counter.getMainValue(); + Optional<Double> byValueOptional = counter.getByValue(); + if (mainValueOptional.isPresent() && byValueOptional.isPresent()) { + double mainValue = mainValueOptional.get(); + double byValue = byValueOptional.get(); + if (byValue > 0d) { + return Optional.of(Measure.newMeasureBuilder().create(mainValue / byValue)); + } + } + return Optional.absent(); + } + + @Override + public String getOutputMetricKey() { + return outputMetricKey; + } + + public static class Builder { + private String outputMetricKey; + private String mainMetric; + private String byMetric; + @CheckForNull + private String fallbackMetric; + + private Builder() { + // prevents instantiation outside static method + } + + public static Builder newBuilder(){ + return new Builder(); + } + + public Builder setOutputMetricKey(String m) { + this.outputMetricKey = m; + return this; + } + + public Builder setMainMetricKey(String m) { + this.mainMetric = m; + return this; + } + + public Builder setByMetricKey(String m) { + this.byMetric = m; + return this; + } + + public Builder setFallbackMetricKey(@Nullable String m) { + this.fallbackMetric = m; + return this; + } + + public AverageFormula build() { + Objects.requireNonNull(outputMetricKey, "Output metric key cannot be null"); + Objects.requireNonNull(mainMetric, "Main metric Key cannot be null"); + Objects.requireNonNull(byMetric, "By metric Key cannot be null"); + return new AverageFormula(this); + } + } + + class AverageCounter implements Counter<AverageCounter> { + + private boolean initialized = false; + + private double mainValue = 0d; + private double byValue = 0d; + + @Override + public void aggregate(AverageCounter counter) { + addValuesIfPresent(counter.getMainValue(), counter.getByValue()); + } + + @Override + public void aggregate(CounterContext counterContext) { + Optional<Double> mainValueOptional = getDoubleValue(counterContext.getMeasure(mainMetric)); + if (!mainValueOptional.isPresent() && fallbackMetric != null) { + mainValueOptional = getDoubleValue(counterContext.getMeasure(fallbackMetric)); + } + Optional<Double> byValueOptional = getDoubleValue(counterContext.getMeasure(byMetric)); + addValuesIfPresent(mainValueOptional, byValueOptional); + } + + private void addValuesIfPresent(Optional<Double> counterMainValue, Optional<Double> counterByValue) { + if (counterMainValue.isPresent() && counterByValue.isPresent()) { + initialized = true; + mainValue += counterMainValue.get(); + byValue += counterByValue.get(); + } + } + + public Optional<Double> getMainValue() { + return getValue(mainValue); + } + + public Optional<Double> getByValue() { + return getValue(byValue); + } + + private Optional<Double> getValue(double value) { + if (initialized) { + return Optional.of(value); + } + return Optional.absent(); + } + } + + private static Optional<Double> getDoubleValue(Optional<Measure> measureOptional) { + if (!measureOptional.isPresent()) { + return Optional.absent(); + } + Measure measure = measureOptional.get(); + switch (measure.getValueType()) { + case DOUBLE: + return Optional.of(measure.getDoubleValue()); + case LONG: + return Optional.of((double) measure.getLongValue()); + case INT: + return Optional.of((double) measure.getIntValue()); + case NO_VALUE: + return Optional.absent(); + default: + throw new IllegalArgumentException(String.format("Measure of type '%s' are not supported", measure.getValueType().name())); + } + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaStepTest.java new file mode 100644 index 00000000000..683052e194e --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaStepTest.java @@ -0,0 +1,121 @@ +/* + * 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.server.computation.formula; + +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.computation.batch.TreeRootHolderRule; +import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.component.DumbComponent; +import org.sonar.server.computation.measure.MeasureRepositoryRule; +import org.sonar.server.computation.metric.MetricRepositoryRule; +import org.sonar.server.computation.step.ComputeFormulaMeasuresStep; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_KEY; +import static org.sonar.server.computation.component.Component.Type.DIRECTORY; +import static org.sonar.server.computation.component.Component.Type.MODULE; +import static org.sonar.server.computation.component.Component.Type.PROJECT; +import static org.sonar.server.computation.component.DumbComponent.builder; +import static org.sonar.server.computation.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf; +import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries; + +public class AverageFormulaStepTest { + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(CoreMetrics.FUNCTION_COMPLEXITY) + .add(CoreMetrics.COMPLEXITY_IN_FUNCTIONS) + .add(CoreMetrics.FUNCTIONS); + + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + ComputeFormulaMeasuresStep sut; + + @Before + public void setUp() throws Exception { + FormulaRepository formulaRepository = mock(FormulaRepository.class); + when(formulaRepository.getFormulas()).thenReturn(Lists.<Formula>newArrayList( + AverageFormula.Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .build())); + sut = new ComputeFormulaMeasuresStep(treeRootHolder, measureRepository, metricRepository, formulaRepository); + } + + @Test + public void add_measures() throws Exception { + DumbComponent project = builder(PROJECT, 1) + .addChildren( + builder(MODULE, 11) + .addChildren( + builder(DIRECTORY, 111) + .addChildren( + builder(Component.Type.FILE, 1111).build(), + builder(Component.Type.FILE, 1112).build() + ).build() + ).build(), + builder(MODULE, 12) + .addChildren( + builder(DIRECTORY, 121) + .addChildren( + builder(Component.Type.FILE, 1211).build() + ).build() + ).build() + ).build(); + + treeRootHolder.setRoot(project); + + measureRepository.addRawMeasure(1111, COMPLEXITY_IN_FUNCTIONS_KEY, newMeasureBuilder().create(5)); + measureRepository.addRawMeasure(1111, FUNCTIONS_KEY, newMeasureBuilder().create(2)); + + measureRepository.addRawMeasure(1112, COMPLEXITY_IN_FUNCTIONS_KEY, newMeasureBuilder().create(1)); + measureRepository.addRawMeasure(1112, FUNCTIONS_KEY, newMeasureBuilder().create(1)); + + measureRepository.addRawMeasure(1211, COMPLEXITY_IN_FUNCTIONS_KEY, newMeasureBuilder().create(9)); + measureRepository.addRawMeasure(1211, FUNCTIONS_KEY, newMeasureBuilder().create(2)); + + sut.execute(); + + assertThat(toEntries(measureRepository.getNewRawMeasures(1))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(3d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(11))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(1111))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(2.5d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(1112))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(1d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(12))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(121))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d))); + assertThat(toEntries(measureRepository.getNewRawMeasures(1211))).containsOnly(entryOf(FUNCTION_COMPLEXITY_KEY, newMeasureBuilder().create(4.5d))); + } + +} 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 new file mode 100644 index 00000000000..2a3c0d88a3d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/formula/AverageFormulaTest.java @@ -0,0 +1,254 @@ +/* + * 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.server.computation.formula; + +import com.google.common.base.Optional; +import org.assertj.guava.api.Assertions; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.computation.component.Component; +import org.sonar.server.computation.measure.Measure; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_KEY; +import static org.sonar.server.computation.formula.AverageFormula.Builder; + +public class AverageFormulaTest { + + private static final AverageFormula BASIC_AVERAGE_FORMULA = Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .build(); + + CounterContext counterContext = mock(CounterContext.class); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void fail_with_NPE_when_building_formula_without_output_metric() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("Output metric key cannot be null"); + + Builder.newBuilder() + .setOutputMetricKey(null) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .build(); + } + + @Test + public void fail_with_NPE_when_building_formula_without_main_metric() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("Main metric Key cannot be null"); + + Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(null) + .setByMetricKey(FUNCTIONS_KEY) + .build(); + } + + @Test + public void fail_with_NPE_when_building_formula_without_by_metric() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("By metric Key cannot be null"); + + Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(null) + .build(); + } + + @Test + public void check_new_counter_class() throws Exception { + assertThat(BASIC_AVERAGE_FORMULA.createNewCounter().getClass()).isEqualTo(AverageFormula.AverageCounter.class); + } + + @Test + public void check_output_metric_key_is_function_complexity_key() throws Exception { + assertThat(BASIC_AVERAGE_FORMULA.getOutputMetricKey()).isEqualTo(FUNCTION_COMPLEXITY_KEY); + } + + @Test + public void create_measure_when_counter_is_aggregated_from_context() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10d); + addMeasure(FUNCTIONS_KEY, 2d); + counter.aggregate(counterContext); + + assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5d); + } + + @Test + public void create_measure_when_counter_is_aggregated_from_another_counter() throws Exception { + AverageFormula.AverageCounter anotherCounter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10d); + addMeasure(FUNCTIONS_KEY, 2d); + anotherCounter.aggregate(counterContext); + + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + counter.aggregate(anotherCounter); + + assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5d); + } + + @Test + public void create_double_measure() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10d); + addMeasure(FUNCTIONS_KEY, 2d); + counter.aggregate(counterContext); + + assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5d); + } + + @Test + public void create_integer_measure() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10); + addMeasure(FUNCTIONS_KEY, 2); + counter.aggregate(counterContext); + + assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5); + } + + @Test + public void create_long_measure() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10L); + addMeasure(FUNCTIONS_KEY, 2L); + counter.aggregate(counterContext); + + assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5L); + } + + @Test + public void not_create_measure_when_aggregated_measure_has_no_value() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10L); + when(counterContext.getMeasure(FUNCTIONS_KEY)).thenReturn(Optional.of(Measure.newMeasureBuilder().createNoValue())); + counter.aggregate(counterContext); + + Assertions.assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT)).isAbsent(); + } + + @Test + public void fail_with_IAE_when_aggregate_from_component_and_context_with_not_numeric_measures() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Measure of type 'STRING' are not supported"); + + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10L); + when(counterContext.getMeasure(FUNCTIONS_KEY)).thenReturn(Optional.of(Measure.newMeasureBuilder().create("data"))); + counter.aggregate(counterContext); + + BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT); + } + + @Test + public void no_measure_created_when_counter_has_no_value() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + when(counterContext.getMeasure(anyString())).thenReturn(Optional.<Measure>absent()); + counter.aggregate(counterContext); + + Assertions.assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT)).isAbsent(); + } + + @Test + public void not_create_measure_when_only_one_measure() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10L); + when(counterContext.getMeasure(FUNCTIONS_KEY)).thenReturn(Optional.<Measure>absent()); + counter.aggregate(counterContext); + + Assertions.assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT)).isAbsent(); + } + + @Test + public void not_create_measure_when_by_value_is_zero() throws Exception { + AverageFormula.AverageCounter counter = BASIC_AVERAGE_FORMULA.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10d); + addMeasure(FUNCTIONS_KEY, 0d); + counter.aggregate(counterContext); + + Assertions.assertThat(BASIC_AVERAGE_FORMULA.createMeasure(counter, Component.Type.PROJECT)).isAbsent(); + } + + @Test + public void create_measure_from_fall_back_measure() throws Exception { + AverageFormula sut = Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .setFallbackMetricKey(CoreMetrics.COMPLEXITY_KEY) + .build(); + + AverageFormula.AverageCounter counter = sut.createNewCounter(); + when(counterContext.getMeasure(COMPLEXITY_IN_FUNCTIONS_KEY)).thenReturn(Optional.<Measure>absent()); + addMeasure(COMPLEXITY_KEY, 10d); + addMeasure(FUNCTIONS_KEY, 2d); + counter.aggregate(counterContext); + + assertThat(sut.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5d); + } + + @Test + public void not_use_fallback_measure_if_main_measure_exists() throws Exception { + AverageFormula sut = Builder.newBuilder() + .setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .setFallbackMetricKey(CoreMetrics.COMPLEXITY_KEY) + .build(); + + AverageFormula.AverageCounter counter = sut.createNewCounter(); + addMeasure(COMPLEXITY_IN_FUNCTIONS_KEY, 10d); + addMeasure(COMPLEXITY_KEY, 12d); + addMeasure(FUNCTIONS_KEY, 2d); + counter.aggregate(counterContext); + + assertThat(sut.createMeasure(counter, Component.Type.PROJECT).get().getDoubleValue()).isEqualTo(5d); + } + + private void addMeasure(String metricKey, double value) { + when(counterContext.getMeasure(metricKey)).thenReturn(Optional.of(Measure.newMeasureBuilder().create(value))); + } + + private void addMeasure(String metricKey, int value) { + when(counterContext.getMeasure(metricKey)).thenReturn(Optional.of(Measure.newMeasureBuilder().create(value))); + } + + private void addMeasure(String metricKey, long value) { + when(counterContext.getMeasure(metricKey)).thenReturn(Optional.of(Measure.newMeasureBuilder().create(value))); + } + +} |