From 183dce664cb2584e602bb9bd6cc236d579af263b Mon Sep 17 00:00:00 2001 From: Andris Raugulis Date: Tue, 7 Jul 2015 17:12:00 +0300 Subject: [PATCH] Fix sensor and update tests. Add coverage report. --- .travis.yml | 3 + README.md | 1 + pom.xml | 18 +++++ .../plugins/elixir/ElixirConfiguration.java | 2 +- .../elixir/language/ElixirMeasureSensor.java | 7 +- .../elixir/ElixirConfigurationTest.java | 42 +++++++++++ .../plugins/elixir/ElixirPluginTest.java | 35 +++++++++ .../language/ElixirMeasureSensorTest.java | 13 ++-- .../plugins/elixir/language/ElixirTest.java | 38 ++++++++++ .../elixir/rule/ElixirQualityProfileTest.java | 49 ++++++++++++ .../plugins/elixir/util/ClassDefinition.java | 74 +++++++++++++++++++ .../src/test/resources/test_doc.ex | 14 +++- 12 files changed, 282 insertions(+), 14 deletions(-) create mode 100644 sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfigurationTest.java create mode 100644 sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirPluginTest.java create mode 100644 sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirTest.java create mode 100644 sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfileTest.java create mode 100644 sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/util/ClassDefinition.java diff --git a/.travis.yml b/.travis.yml index 3711103..0c311af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,6 @@ jdk: - oraclejdk7 - oraclejdk8 +after_success: + - mvn clean test jacoco:report coveralls:report + diff --git a/README.md b/README.md index 0df4dda..b759c74 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ SonarQube Elixir Plugin =========== [![build status](https://travis-ci.org/arthepsy/sonar-elixir.svg?branch=master)](https://travis-ci.org/arthepsy/sonar-elixir/) +[![Coverage Status](https://coveralls.io/repos/arthepsy/sonar-elixir/badge.svg?branch=master)](https://coveralls.io/r/arthepsy/sonar-elixir?branch=master) diff --git a/pom.xml b/pom.xml index 5ac7920..f315ea5 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,24 @@ + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + prepare-agent + + prepare-agent + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 3.1.0 + com.mycila.maven-license-plugin diff --git a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfiguration.java b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfiguration.java index 46f5ac6..083992a 100644 --- a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfiguration.java +++ b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfiguration.java @@ -28,7 +28,7 @@ import java.util.List; -public class ElixirConfiguration { +public final class ElixirConfiguration { public static final String LOG_PREFIX = "[elixir] "; public static List getPropertyDefinitions() { diff --git a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensor.java b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensor.java index 9d30ade..2c5bf6f 100644 --- a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensor.java +++ b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensor.java @@ -103,6 +103,7 @@ private void processMainFile(InputFile inputFile, SensorContext context) { docMatcher.reset(line); boolean inDoc = docMatcher.find(); if (inDoc) { + commentLineCount++; String docText = docMatcher.group(2).trim(); if (! (StringUtils.equalsIgnoreCase(docText, "false") || StringUtils.equalsIgnoreCase(docText, "nil"))) { switch (docMatcher.group(1)) { @@ -119,18 +120,12 @@ private void processMainFile(InputFile inputFile, SensorContext context) { } heredocMatcher.reset(line); if (heredocMatcher.find()) { - if (inDoc) { - commentLineCount++; - } while (i < lineCount - 1) { if (inDoc) { commentLineCount++; } i++; line = lines.get(i); - if (StringUtils.isBlank(line)) { - emptyLineCount++; - } if (line.matches("^\\s*\"\"\"\\s*$")) { break; } diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfigurationTest.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfigurationTest.java new file mode 100644 index 0000000..65b6a7a --- /dev/null +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfigurationTest.java @@ -0,0 +1,42 @@ +/* + * SonarQube Elixir plugin + * Copyright (C) 2015 Andris Raugulis + * moo@arthepsy.eu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package eu.arthepsy.sonar.plugins.elixir; + +import eu.arthepsy.sonar.plugins.elixir.util.ClassDefinition; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class ElixirConfigurationTest { + @Test + public void testClassDefinition() { + ClassDefinition.testFinalClassDefinition(ElixirConfiguration.class); + } + + @Test + public void testPropertyCount() { + assertThat(ElixirConfiguration.getPropertyDefinitions().size()).isEqualTo(0); + } +} diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirPluginTest.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirPluginTest.java new file mode 100644 index 0000000..a4ec728 --- /dev/null +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirPluginTest.java @@ -0,0 +1,35 @@ +/* + * SonarQube Elixir plugin + * Copyright (C) 2015 Andris Raugulis + * moo@arthepsy.eu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package eu.arthepsy.sonar.plugins.elixir; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class ElixirPluginTest { + @Test + public void testExtensionCount() { + assertThat(new ElixirPlugin().getExtensions().size()).isEqualTo(3); + } +} diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensorTest.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensorTest.java index 9949495..f54ccc2 100644 --- a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensorTest.java +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirMeasureSensorTest.java @@ -40,6 +40,7 @@ import java.io.File; import java.io.IOException; +import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.*; public class ElixirMeasureSensorTest { @@ -52,12 +53,10 @@ public class ElixirMeasureSensorTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); private File baseDir; - private ResourcePerspectives perspectives; @Before public void prepare() throws IOException { baseDir = temp.newFolder(); - perspectives = mock(ResourcePerspectives.class); fileSystem = new DefaultFileSystem(); fileSystem.setBaseDir(baseDir); sensor = new ElixirMeasureSensor(fileSystem); @@ -69,16 +68,18 @@ public void testDocAnnotation() throws IOException { File source = new File(baseDir, fileName); FileUtils.write(source, IOUtils.toString(getClass().getResourceAsStream("/" + fileName))); DefaultInputFile inputFile = new DefaultInputFile(fileName).setLanguage(Elixir.KEY); - inputFile.setAbsolutePath(new File(baseDir,inputFile.relativePath()).getAbsolutePath()); + inputFile.setAbsolutePath(new File(baseDir, inputFile.relativePath()).getAbsolutePath()); fileSystem.add(inputFile); + assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); + sensor.analyse(project, context); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.LINES), eq(21.0)); + verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.LINES), eq(33.0)); verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.NCLOC), eq(14.0)); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.COMMENT_LINES), eq(3.0)); + verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.COMMENT_LINES), eq(13.0)); verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.CLASSES), eq(1.0)); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.FUNCTIONS), eq(4.0)); + verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.FUNCTIONS), eq(6.0)); verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.PUBLIC_API), eq(5.0)); verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.PUBLIC_UNDOCUMENTED_API), eq(2.0)); } diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirTest.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirTest.java new file mode 100644 index 0000000..8cfa2bb --- /dev/null +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirTest.java @@ -0,0 +1,38 @@ +/* + * SonarQube Elixir plugin + * Copyright (C) 2015 Andris Raugulis + * moo@arthepsy.eu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package eu.arthepsy.sonar.plugins.elixir.language; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class ElixirTest { + @Test + public void test() { + Elixir language = new Elixir(); + assertThat(language.getKey()).isEqualTo("elixir"); + assertThat(language.getName()).isEqualTo("Elixir"); + assertThat(language.getFileSuffixes()).containsOnly("ex", "exs"); + } +} diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfileTest.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfileTest.java new file mode 100644 index 0000000..9b9a9db --- /dev/null +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfileTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube Elixir plugin + * Copyright (C) 2015 Andris Raugulis + * moo@arthepsy.eu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package eu.arthepsy.sonar.plugins.elixir.rule; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.utils.ValidationMessages; + +import static org.fest.assertions.Assertions.assertThat; + +public class ElixirQualityProfileTest { + private ElixirQualityProfile profile; + private ValidationMessages validationMessages; + + @Before + public void prepare() { + profile = Mockito.spy(new ElixirQualityProfile()); + validationMessages = ValidationMessages.create(); + } + + @Test + public void testRulesCount() { + RulesProfile rulesProfile = profile.createProfile(validationMessages); + assertThat(rulesProfile.getActiveRules().size()).isEqualTo(0); + } +} diff --git a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/util/ClassDefinition.java b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/util/ClassDefinition.java new file mode 100644 index 0000000..c87f811 --- /dev/null +++ b/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/util/ClassDefinition.java @@ -0,0 +1,74 @@ +/* + * SonarQube Elixir plugin + * Copyright (C) 2015 Andris Raugulis + * moo@arthepsy.eu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package eu.arthepsy.sonar.plugins.elixir.util; + +import static org.junit.Assert.fail; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import static org.fest.assertions.Assertions.assertThat; + +public final class ClassDefinition { + + public static void testFinalClassDefinition(Class clazz) { + testFinalClassDefinition(clazz, false); + } + + public static void testFinalClassDefinition(Class clazz, Boolean privateConstructor) { + assertThat(Modifier.isFinal(clazz.getModifiers())).isTrue(); + final Constructor constructor; + try { + constructor = clazz.getDeclaredConstructor(); + } catch (NoSuchMethodException e) { + fail(e.getMessage()); + return; + } + if (privateConstructor) { + assertThat(Modifier.isPrivate(constructor.getModifiers())).isTrue(); + } + constructor.setAccessible(true); + try { + constructor.newInstance(); + } catch (InstantiationException e) { + fail(e.getMessage()); + return; + } catch (IllegalAccessException e) { + fail(e.getMessage()); + return; + } catch (InvocationTargetException e) { + fail(e.getMessage()); + return; + } + constructor.setAccessible(false); + for (final Method method: clazz.getMethods()) { + if (method.getDeclaringClass().equals(clazz)) { + assertThat(Modifier.isStatic(method.getModifiers())).isTrue(); + } + } + } + +} diff --git a/sonar-elixir-plugin/src/test/resources/test_doc.ex b/sonar-elixir-plugin/src/test/resources/test_doc.ex index 5e3a8a1..9a40d97 100644 --- a/sonar-elixir-plugin/src/test/resources/test_doc.ex +++ b/sonar-elixir-plugin/src/test/resources/test_doc.ex @@ -3,6 +3,8 @@ defmodule Docs do @doc """ function doc1 + + documentation """ def doc1() do end @@ -15,7 +17,17 @@ defmodule Docs do def doc3() do end + @doc "private function doc4" + defp doc4() do + end + @doc nil - def doc4() do + def doc5() do + end + + # very + # very + # private function doc6 + defp doc6() do end end