aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch/src/test/java/org/sonar/batch
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2014-07-09 18:36:52 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2014-07-09 18:36:52 +0200
commit4d5d1f5be3d1ace0199d39a086165e1086600a26 (patch)
treef44cfe310ddf3cd277fce68fbec36e90fdb255c8 /sonar-batch/src/test/java/org/sonar/batch
parent6a7de91d1fb7b3197da780079607a2489064d67b (diff)
downloadsonarqube-4d5d1f5be3d1ace0199d39a086165e1086600a26.tar.gz
sonarqube-4d5d1f5be3d1ace0199d39a086165e1086600a26.zip
SONAR-5388 Introduce the SQALE Rating metric in SonarQube Core
Diffstat (limited to 'sonar-batch/src/test/java/org/sonar/batch')
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java189
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingGridTest.java72
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingSettingsTest.java143
3 files changed, 404 insertions, 0 deletions
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java
new file mode 100644
index 00000000000..1fe1574bffe
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.batch.debt;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.test.IsMeasure;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SqaleRatingDecoratorTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ static final Long ONE_DAY_IN_MINUTES = 8L * 60;
+
+ Settings settings;
+ Metric[] metrics = {CoreMetrics.NCLOC, CoreMetrics.ABSTRACTNESS, CoreMetrics.COMPLEXITY};
+
+ @Mock
+ DecoratorContext context;
+
+ DefaultFileSystem fs;
+
+ File file = File.create("src/main/java/Foo.java");
+
+ SqaleRatingDecorator decorator;
+
+ @Before
+ public void setUp() throws Exception {
+ settings = new Settings();
+
+ fs = new DefaultFileSystem();
+ fs.add(new DefaultInputFile(file.getPath())
+ .setLanguage("java")
+ .setFile(temp.newFile("Foo.java")));
+
+ decorator = new SqaleRatingDecorator(new SqaleRatingSettings(settings), metrics, fs);
+ }
+
+ @Test
+ public void generates_metrics() throws Exception {
+ SqaleRatingDecorator decorator = new SqaleRatingDecorator();
+ assertThat(decorator.generatesMetrics()).hasSize(2);
+ }
+
+ @Test
+ public void depends_on_metrics() {
+ SqaleRatingDecorator decorator = new SqaleRatingDecorator();
+ assertThat(decorator.dependsOnMetrics()).containsOnly(CoreMetrics.TECHNICAL_DEBT, CoreMetrics.NCLOC, CoreMetrics.COMPLEXITY);
+ }
+
+ @Test
+ public void execute_on_project() throws Exception {
+ SqaleRatingDecorator decorator = new SqaleRatingDecorator();
+ assertThat(decorator.shouldExecuteOnProject(null)).isTrue();
+ }
+
+ @Test
+ public void not_execute_on_unit_test() throws Exception {
+ File resource = mock(File.class);
+ when(resource.getQualifier()).thenReturn(Qualifiers.UNIT_TEST_FILE);
+ DecoratorContext context = mock(DecoratorContext.class);
+
+ SqaleRatingDecorator decorator = new SqaleRatingDecorator();
+ decorator.decorate(resource, context);
+
+ verify(context, never()).saveMeasure(any(Measure.class));
+ }
+
+ @Test
+ public void save_total_rating_c() {
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, 2 * ONE_DAY_IN_MINUTES);
+ settings.setProperty(CoreProperties.SIZE_METRIC, "ncloc");
+ settings.setProperty(CoreProperties.RATING_GRID, "1, 10,20,50");
+
+ when(context.getResource()).thenReturn(file);
+ when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 10.0));
+ when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 300.0 * ONE_DAY_IN_MINUTES));
+
+ decorator.decorate(file, context);
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 3.0)));
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600")));
+
+ verify(context).getMeasure(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void save_total_rating_a() {
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, 2 * ONE_DAY_IN_MINUTES);
+ settings.setProperty(CoreProperties.SIZE_METRIC, "ncloc");
+ settings.setProperty(CoreProperties.RATING_GRID, "1, 10,20,50");
+
+ when(context.getResource()).thenReturn(file);
+ when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 10.0));
+ when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 0.0));
+
+ decorator.decorate(file, context);
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 1.0)));
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600")));
+
+ verify(context).getMeasure(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void save_total_rating_e() {
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, 2 * ONE_DAY_IN_MINUTES);
+ settings.setProperty(CoreProperties.SIZE_METRIC, "ncloc");
+ settings.setProperty(CoreProperties.RATING_GRID, "1, 10,20,50");
+
+ when(context.getResource()).thenReturn(file);
+ when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 10.0));
+ when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 100000000000.0));
+
+ decorator.decorate(file, context);
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 5.0)));
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600")));
+
+ verify(context).getMeasure(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void save_total_rating_on_project() {
+ settings.setProperty(CoreProperties.RATING_GRID, "1, 10,20,50");
+
+ when(context.getResource()).thenReturn(new Project("Sample"));
+ when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 300.0 * ONE_DAY_IN_MINUTES));
+ when(context.getChildrenMeasures(CoreMetrics.DEVELOPMENT_COST)).thenReturn(newArrayList(new Measure(CoreMetrics.DEVELOPMENT_COST, Double.toString(20.0 * ONE_DAY_IN_MINUTES))));
+
+ decorator.decorate(mock(File.class), context);
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 3.0)));
+ verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600")));
+
+ verify(context, never()).getMeasure(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void translate_rating_to_letter() {
+ assertThat(SqaleRatingDecorator.toRatingLetter(null)).isNull();
+ assertThat(SqaleRatingDecorator.toRatingLetter(1)).isEqualTo("A");
+ assertThat(SqaleRatingDecorator.toRatingLetter(4)).isEqualTo("D");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void test_rating_out_of_range() {
+ SqaleRatingDecorator.toRatingLetter(89);
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingGridTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingGridTest.java
new file mode 100644
index 00000000000..cabf747826a
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingGridTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.batch.debt;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class SqaleRatingGridTest {
+
+ private SqaleRatingGrid ratingGrid;
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ double[] gridValues = new double[] {0.1, 0.2, 0.5, 1};
+ ratingGrid = new SqaleRatingGrid(gridValues);
+ }
+
+ @Test
+ public void return_grade_lower_bound() throws Exception {
+ assertThat(ratingGrid.getGradeLowerBound(SqaleRatingGrid.SqaleRating.A)).isEqualTo(0);
+ assertThat(ratingGrid.getGradeLowerBound(SqaleRatingGrid.SqaleRating.B)).isEqualTo(0.1);
+ assertThat(ratingGrid.getGradeLowerBound(SqaleRatingGrid.SqaleRating.C)).isEqualTo(0.2);
+ assertThat(ratingGrid.getGradeLowerBound(SqaleRatingGrid.SqaleRating.D)).isEqualTo(0.5);
+ assertThat(ratingGrid.getGradeLowerBound(SqaleRatingGrid.SqaleRating.E)).isEqualTo(1);
+ }
+
+ @Test
+ public void return_rating_matching_density() throws Exception {
+ assertThat(ratingGrid.getRatingForDensity(0)).isEqualTo(1);
+ assertThat(ratingGrid.getRatingForDensity(0.05)).isEqualTo(1);
+ assertThat(ratingGrid.getRatingForDensity(0.1)).isEqualTo(2);
+ assertThat(ratingGrid.getRatingForDensity(0.15)).isEqualTo(2);
+ assertThat(ratingGrid.getRatingForDensity(0.2)).isEqualTo(3);
+ assertThat(ratingGrid.getRatingForDensity(0.25)).isEqualTo(3);
+ assertThat(ratingGrid.getRatingForDensity(0.5)).isEqualTo(4);
+ assertThat(ratingGrid.getRatingForDensity(0.65)).isEqualTo(4);
+ assertThat(ratingGrid.getRatingForDensity(1)).isEqualTo(5);
+ assertThat(ratingGrid.getRatingForDensity(1.01)).isEqualTo(5);
+ }
+
+ @Test
+ public void fail_on_invalid_density() throws Exception {
+ throwable.expect(RuntimeException.class);
+
+ ratingGrid.getRatingForDensity(-1);
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingSettingsTest.java
new file mode 100644
index 00000000000..cd784f135fc
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingSettingsTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.batch.debt;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+
+public class SqaleRatingSettingsTest {
+
+ private static final Metric[] metrics = {CoreMetrics.NCLOC, CoreMetrics.ABSTRACTNESS, CoreMetrics.COMPLEXITY};
+
+ private Settings settings;
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ settings = new Settings();
+ }
+
+ @Test
+ public void load_rating_grid() throws Exception {
+ settings.setProperty(CoreProperties.RATING_GRID, "1,3.4,8,50");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ double[] grid = configurationLoader.getRatingGrid();
+ assertThat(grid).hasSize(4);
+ assertThat(grid[0]).isEqualTo(1.0);
+ assertThat(grid[1]).isEqualTo(3.4);
+ assertThat(grid[2]).isEqualTo(8.0);
+ assertThat(grid[3]).isEqualTo(50.0);
+ }
+
+ @Test
+ public void load_work_units_for_language() throws Exception {
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, "50");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ assertThat(configurationLoader.getWorkUnitsBySizePoint("defaultLanguage")).isEqualTo(50L);
+ }
+
+ @Test
+ public void load_size_metric_for_language() throws Exception {
+ settings.setProperty(CoreProperties.SIZE_METRIC, "complexity");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ assertThat(configurationLoader.getSizeMetric("defaultLanguage", metrics)).isEqualTo(CoreMetrics.COMPLEXITY);
+ }
+
+ @Test
+ public void load_overridden_values_for_language() throws Exception {
+
+ String aLanguage = "aLanguage";
+ String anotherLanguage = "anotherLanguage";
+
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS, "0,1");
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, aLanguage);
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "30");
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.NCLOC_KEY);
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, anotherLanguage);
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "1" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_SIZE_METRIC_KEY, CoreMetrics.COMPLEXITY_KEY);
+
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ assertThat(configurationLoader.getSizeMetric(aLanguage, metrics)).isEqualTo(CoreMetrics.NCLOC);
+ assertThat(configurationLoader.getSizeMetric(anotherLanguage, metrics)).isEqualTo(CoreMetrics.COMPLEXITY);
+ assertThat(configurationLoader.getWorkUnitsBySizePoint(aLanguage)).isEqualTo(30L);
+ assertThat(configurationLoader.getWorkUnitsBySizePoint(anotherLanguage)).isEqualTo(40L);
+ }
+
+ @Test
+ public void fail_on_invalid_rating_grid_configuration() throws Exception {
+
+ throwable.expect(IllegalArgumentException.class);
+ settings.setProperty(CoreProperties.RATING_GRID, "a b c");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ configurationLoader.getRatingGrid();
+ }
+
+ @Test
+ public void fail_on_invalid_work_unit_value() throws Exception {
+ throwable.expect(IllegalArgumentException.class);
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, "a");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ configurationLoader.getSizeMetric("aLanguage", metrics);
+ }
+
+ @Test
+ public void fail_on_unknown_metric_key() throws Exception {
+ throwable.expect(IllegalArgumentException.class);
+ settings.setProperty(CoreProperties.SIZE_METRIC, "unknown");
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ configurationLoader.getSizeMetric("aLanguage", metrics);
+ }
+
+ @Test
+ public void use_generic_value_when_specific_setting_is_missing() throws Exception {
+ String aLanguage = "aLanguage";
+
+ settings.setProperty(CoreProperties.SIZE_METRIC, "complexity");
+ settings.setProperty(CoreProperties.MAN_DAYS_BY_SIZE_POINT, "30");
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS, "0");
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_LANGUAGE_KEY, aLanguage);
+ settings.setProperty(CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS + "." + "0" + "." + CoreProperties.LANGUAGE_SPECIFIC_PARAMETERS_MAN_DAYS_KEY, "40");
+
+ SqaleRatingSettings configurationLoader = new SqaleRatingSettings(settings);
+
+ assertThat(configurationLoader.getSizeMetric(aLanguage, metrics)).isEqualTo(CoreMetrics.COMPLEXITY);
+ assertThat(configurationLoader.getWorkUnitsBySizePoint(aLanguage)).isEqualTo(40L);
+ }
+}