From: Evgeny Mandrikov Date: Tue, 20 Mar 2012 06:40:13 +0000 (+0400) Subject: SONAR-3289 On java projects compute complexity distribution by file X-Git-Tag: 3.0~170 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=380241e75968446018fba19e65df8ffe549bf1da;p=sonarqube.git SONAR-3289 On java projects compute complexity distribution by file And do not compute complexity distribution by class. --- diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java index 7932d233545..789c0c0d1cf 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java @@ -20,7 +20,6 @@ package org.sonar.plugins.squid; import org.sonar.api.*; -import org.sonar.api.PropertyType; import org.sonar.plugins.squid.decorators.*; import java.util.Arrays; @@ -58,9 +57,15 @@ import java.util.List; public final class SquidPlugin extends SonarPlugin { public List getExtensions() { - return Arrays.asList(SquidSensor.class, SquidRuleRepository.class, JavaSourceImporter.class, - ClassComplexityDistributionBuilder.class, FunctionComplexityDistributionBuilder.class, ClassesDecorator.class, - ChidamberKemererDistributionBuilder.class, FunctionsDecorator.class); + return Arrays.asList( + SquidSensor.class, + SquidRuleRepository.class, + JavaSourceImporter.class, + FileComplexityDistributionDecorator.class, + FunctionComplexityDistributionBuilder.class, + ClassesDecorator.class, + ChidamberKemererDistributionBuilder.class, + FunctionsDecorator.class); } } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilder.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilder.java deleted file mode 100644 index efc4049fbf2..00000000000 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.squid.decorators; - -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependedUpon; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.measures.*; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Resource; -import org.sonar.api.resources.Scopes; - -/** - * @since 2.6 - */ -public final class ClassComplexityDistributionBuilder implements Decorator { - - private static final Number[] LIMITS = { 0, 5, 10, 20, 30, 60, 90 }; - - @DependsUpon - public Metric dependOnComplexity() { - return CoreMetrics.COMPLEXITY; - } - - @DependedUpon - public Metric generatesFunctionComplexityDistribution() { - return CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION; - } - - public void decorate(Resource resource, DecoratorContext context) { - if (shouldExecuteOn(resource, context)) { - RangeDistributionBuilder builder = new RangeDistributionBuilder(CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION, LIMITS); - for (DecoratorContext childContext : context.getChildren()) { - if (Scopes.isProgramUnit(childContext.getResource())) { - Measure complexity = childContext.getMeasure(CoreMetrics.COMPLEXITY); - if (complexity != null) { - builder.add(complexity.getValue()); - } - } - } - Measure measure = builder.build(true); - measure.setPersistenceMode(PersistenceMode.MEMORY); - context.saveMeasure(measure); - } - } - - boolean shouldExecuteOn(Resource resource, DecoratorContext context) { - return Scopes.isFile(resource) && context.getMeasure(CoreMetrics.COMPLEXITY) != null; - } - - public boolean shouldExecuteOnProject(Project project) { - return Java.KEY.equals(project.getLanguageKey()); - } -} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecorator.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecorator.java new file mode 100644 index 00000000000..2ac235dcd69 --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecorator.java @@ -0,0 +1,69 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.squid.decorators; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.Scopes; + +/** + * @since 2.15 + */ +public class FileComplexityDistributionDecorator implements Decorator { + + private static final Number[] LIMITS = {0, 5, 10, 20, 30, 60, 90}; + + @DependsUpon + public Metric dependOnComplexity() { + return CoreMetrics.COMPLEXITY; + } + + @DependedUpon + public Metric generatesComplexityDistribution() { + return CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION; + } + + public boolean shouldExecuteOnProject(Project project) { + return Java.KEY.equals(project.getLanguageKey()); + } + + private static boolean shouldExecuteOn(Resource resource, DecoratorContext context) { + return Scopes.isFile(resource) && context.getMeasure(CoreMetrics.COMPLEXITY) != null; + } + + @Override + public void decorate(Resource resource, DecoratorContext context) { + if (shouldExecuteOn(resource, context)) { + RangeDistributionBuilder builder = new RangeDistributionBuilder(CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION, LIMITS); + Measure complexity = context.getMeasure(CoreMetrics.COMPLEXITY); + builder.add(complexity.getValue()); + Measure measure = builder.build(true); + measure.setPersistenceMode(PersistenceMode.MEMORY); + context.saveMeasure(measure); + } + } + +} diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidPluginTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidPluginTest.java index 42d793b2f87..c42ac5ecb76 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidPluginTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidPluginTest.java @@ -19,11 +19,11 @@ */ package org.sonar.plugins.squid; +import org.junit.Test; + import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; -import org.junit.Test; - public class SquidPluginTest { @Test diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilderTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilderTest.java deleted file mode 100644 index 6af44b077f0..00000000000 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/ClassComplexityDistributionBuilderTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.squid.decorators; - -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.Test; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Measure; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.JavaFile; -import org.sonar.api.resources.JavaPackage; -import org.sonar.api.resources.Project; -import org.sonar.java.api.JavaClass; - -import java.util.Arrays; -import java.util.List; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ClassComplexityDistributionBuilderTest { - - @Test - public void shouldExecuteOnJavaProjectsOnly() throws Exception { - ClassComplexityDistributionBuilder builder = new ClassComplexityDistributionBuilder(); - assertThat(builder.shouldExecuteOnProject(new Project("java").setLanguageKey(Java.KEY)), is(true)); - assertThat(builder.shouldExecuteOnProject(new Project("php").setLanguageKey("php")), is(false)); - } - - @Test - public void shouldExecuteOnFilesOnly() throws Exception { - ClassComplexityDistributionBuilder builder = new ClassComplexityDistributionBuilder(); - DecoratorContext context = mock(DecoratorContext.class); - when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 20.0)); - - assertThat(builder.shouldExecuteOn(new JavaPackage("org.foo"), context), is(false)); - assertThat(builder.shouldExecuteOn(new JavaFile("org.foo.Bar"), context), is(true)); - assertThat(builder.shouldExecuteOn(JavaClass.create("org.foo.Bar"), context), is(false)); - } - - @Test - public void shouldCalculateDistributionOnFile() throws Exception { - - List children = Arrays.asList( - // first range - newClassChild("One", 2.0), newClassChild("Two", 1.0), newClassChild("Zero complexity", 0.0), - - // second range - newClassChild("Three", 8.0), - - // out of range - newClassChild("No complexity", null)); - - DecoratorContext context = mock(DecoratorContext.class); - when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 20.0)); - when(context.getChildren()).thenReturn(children); - - ClassComplexityDistributionBuilder builder = new ClassComplexityDistributionBuilder(); - builder.decorate(JavaFile.fromRelativePath("org/foo/MyFile.java", false), context); - - verify(context).saveMeasure(argThat(new BaseMatcher() { - public boolean matches(Object o) { - Measure measure = (Measure) o; - return measure.getMetric().equals(CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION) && - measure.getData().equals("0=3;5=1;10=0;20=0;30=0;60=0;90=0"); - } - - public void describeTo(Description description) { - - } - })); - } - - private DecoratorContext newClassChild(String classname, Double complexity) { - DecoratorContext context = mock(DecoratorContext.class); - when(context.getResource()).thenReturn(JavaClass.create(classname)); - when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, complexity)); - return context; - } -} diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecoratorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecoratorTest.java new file mode 100644 index 00000000000..f0adaa85f9c --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/decorators/FileComplexityDistributionDecoratorTest.java @@ -0,0 +1,87 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.squid.decorators; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.PersistenceMode; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Project; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + +public class FileComplexityDistributionDecoratorTest { + + private FileComplexityDistributionDecorator decorator; + + @Before + public void setUp() { + decorator = new FileComplexityDistributionDecorator(); + } + + @Test + public void shouldExecuteOnJavaProjectsOnly() throws Exception { + assertThat(decorator.shouldExecuteOnProject(new Project("java").setLanguageKey(Java.KEY)), is(true)); + assertThat(decorator.shouldExecuteOnProject(new Project("php").setLanguageKey("php")), is(false)); + } + + @Test + public void shouldExecuteOnFilesOnly() throws Exception { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 20.0)); + + decorator.decorate(new JavaPackage("org.foo"), context); + verify(context, never()).saveMeasure(any(Measure.class)); + } + + @Test + public void shouldDependOnComplexity() { + DecoratorContext context = mock(DecoratorContext.class); + assertThat(decorator.dependOnComplexity(), is(CoreMetrics.COMPLEXITY)); + assertThat(decorator.generatesComplexityDistribution(), is(CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION)); + + decorator.decorate(new JavaFile("org.foo.Bar"), context); + verify(context, never()).saveMeasure(any(Measure.class)); + } + + @Test + public void shouldCalculateDistributionOnFile() throws Exception { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 20.0)); + + decorator.decorate(JavaFile.fromRelativePath("org/foo/MyFile.java", false), context); + ArgumentCaptor measureCaptor = ArgumentCaptor.forClass(Measure.class); + verify(context).saveMeasure(measureCaptor.capture()); + Measure measure = measureCaptor.getValue(); + assertThat(measure.getMetric(), is(CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION)); + assertThat(measure.getData(), is("0=0;5=0;10=0;20=1;30=0;60=0;90=0")); + assertThat(measure.getPersistenceMode(), is(PersistenceMode.MEMORY)); + } + +}