diff --git a/pom.xml b/pom.xml index c075e67..2ac35dd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - org.codehaus.sonar-plugins - parent - 19 - - sonar-elixir-plugin @@ -51,7 +45,7 @@ arthepsy Andris Raugulis moo@arthepsy.eu - 4.5 + 7.3 {0,date,yyyy-MM-dd HH:mm:ssa} UTF-8 @@ -59,20 +53,20 @@ - org.codehaus.sonar + org.sonarsource.sonarqube sonar-plugin-api ${sonar.version} provided - org.codehaus.sonar + org.sonarsource.sonarqube sonar-core ${sonar.version} provided - org.codehaus.sonar + org.sonarsource.sonarqube sonar-testing-harness ${sonar.version} test @@ -98,6 +92,8 @@ -Xlint:unchecked -Xlint:deprecation + 1.8 + 1.8 @@ -135,6 +131,18 @@ + + org.sonarsource.sonar-packaging-maven-plugin + sonar-packaging-maven-plugin + 1.17 + true + + eu.arthepsy.sonar.plugins.elixir.ElixirPlugin + https://github.com/arthepsy/sonar-elixir + https://github.com/arthepsy/sonar-elixir + https://github.com/arthepsy/sonar-elixir + + diff --git a/sonar-elixir-plugin/pom.xml b/sonar-elixir-plugin/pom.xml index caca627..372e8f9 100644 --- a/sonar-elixir-plugin/pom.xml +++ b/sonar-elixir-plugin/pom.xml @@ -24,16 +24,16 @@ - org.codehaus.sonar + org.sonarsource.sonarqube sonar-plugin-api - org.codehaus.sonar + org.sonarsource.sonarqube sonar-core - org.codehaus.sonar + org.sonarsource.sonarqube sonar-testing-harness test 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 083992a..e855e45 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 @@ -23,16 +23,6 @@ */ package eu.arthepsy.sonar.plugins.elixir; -import com.google.common.collect.ImmutableList; -import org.sonar.api.config.PropertyDefinition; - -import java.util.List; - public final class ElixirConfiguration { public static final String LOG_PREFIX = "[elixir] "; - - public static List getPropertyDefinitions() { - ImmutableList.Builder properties = ImmutableList.builder(); - return properties.build(); - } } diff --git a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirPlugin.java b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirPlugin.java index 0f6ff75..2ae1e08 100644 --- a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirPlugin.java +++ b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/ElixirPlugin.java @@ -23,24 +23,15 @@ */ package eu.arthepsy.sonar.plugins.elixir; -import com.google.common.collect.ImmutableList; import eu.arthepsy.sonar.plugins.elixir.language.Elixir; import eu.arthepsy.sonar.plugins.elixir.language.ElixirMeasureSensor; import eu.arthepsy.sonar.plugins.elixir.rule.ElixirQualityProfile; -import org.sonar.api.SonarPlugin; +import org.sonar.api.Plugin; -import java.util.List; - -public class ElixirPlugin extends SonarPlugin { +public class ElixirPlugin implements Plugin { @Override - public List getExtensions() { - ImmutableList.Builder builder = ImmutableList.builder(); - builder.addAll(ElixirConfiguration.getPropertyDefinitions()); - builder.add(Elixir.class); - builder.add(ElixirQualityProfile.class); - builder.add(ElixirMeasureSensor.class); - return builder.build(); + public void define(Context context) { + context.addExtensions(Elixir.class, ElixirQualityProfile.class, ElixirMeasureSensor.class); } - } 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 1d26d57..0dea79f 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 @@ -24,24 +24,22 @@ package eu.arthepsy.sonar.plugins.elixir.language; import eu.arthepsy.sonar.plugins.elixir.ElixirConfiguration; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.measure.MetricFinder; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.resources.Project; -import org.sonar.api.utils.ParsingUtils; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.Serializable; +import java.util.Arrays; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class ElixirMeasureSensor implements Sensor { @@ -50,32 +48,33 @@ public class ElixirMeasureSensor implements Sensor { private final FileSystem fileSystem; private final FilePredicate mainFilePredicate; + private final MetricFinder metricFinder; - public ElixirMeasureSensor(FileSystem fileSystem) { + public ElixirMeasureSensor(FileSystem fileSystem, MetricFinder metricFinder) { this.fileSystem = fileSystem; this.mainFilePredicate = fileSystem.predicates().and( fileSystem.predicates().hasType(InputFile.Type.MAIN), fileSystem.predicates().hasLanguage(Elixir.KEY)); + this.metricFinder = metricFinder; } @Override - public void analyse(Project project, SensorContext context) { + public void describe(SensorDescriptor sensorDescriptor) { + } + + public void execute(SensorContext context) { LOG.info("[elixir] analyse"); - for (InputFile file : fileSystem.inputFiles(mainFilePredicate )) { + for (InputFile file : fileSystem.inputFiles(mainFilePredicate)) { processMainFile(file, context); } } - @Override - public boolean shouldExecuteOnProject(Project project) { - return fileSystem.hasFiles(mainFilePredicate); - } - private void processMainFile(InputFile inputFile, SensorContext context) { List lines; try { - lines = Files.readAllLines(Paths.get(inputFile.absolutePath()), fileSystem.encoding()); + String contents = inputFile.contents(); + lines = Arrays.asList(contents.split("\\r?\\n")); } catch (IOException e) { LOG.warn(LOG_PREFIX + "could not process file: " + inputFile.toString()); return; @@ -84,21 +83,24 @@ private void processMainFile(InputFile inputFile, SensorContext context) { parser.parse(lines); LOG.debug(LOG_PREFIX + "processing file: " + inputFile.toString()); - double linesOfCode = parser.getLineCount() - parser.getEmptyLineCount() - parser.getCommentLineCount(); - context.saveMeasure(inputFile, CoreMetrics.LINES, (double)parser.getLineCount()); - context.saveMeasure(inputFile, CoreMetrics.NCLOC, (double)linesOfCode); - context.saveMeasure(inputFile, CoreMetrics.COMMENT_LINES, (double)parser.getCommentLineCount()); + int linesOfCode = parser.getLineCount() - parser.getEmptyLineCount() - parser.getCommentLineCount(); + saveMeasure(inputFile, context, CoreMetrics.LINES_KEY, parser.getLineCount()); + saveMeasure(inputFile, context, CoreMetrics.NCLOC_KEY, linesOfCode); + saveMeasure(inputFile, context, CoreMetrics.COMMENT_LINES_KEY, parser.getCommentLineCount()); + + int functionCount = parser.getPublicFunctionCount() + parser.getPrivateFunctionCount(); + saveMeasure(inputFile, context, CoreMetrics.FUNCTIONS_KEY, functionCount); + saveMeasure(inputFile, context, CoreMetrics.CLASSES_KEY, parser.getClassCount()); - double publicApi = parser.getPublicFunctionCount() + parser.getClassCount(); - double documentedApi = parser.getDocumentedPublicFunctionCount() + parser.getDocumentedClassCount(); - double undocumentedApi = publicApi - documentedApi; - double documentedApiDensity = (publicApi == 0 ? 100.0 : ParsingUtils.scaleValue(documentedApi / publicApi * 100, 2)); - context.saveMeasure(inputFile, CoreMetrics.PUBLIC_API, publicApi); - context.saveMeasure(inputFile, CoreMetrics.PUBLIC_UNDOCUMENTED_API, undocumentedApi); - context.saveMeasure(inputFile, CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, documentedApiDensity); + } - double functionCount = parser.getPublicFunctionCount() + parser.getPrivateFunctionCount(); - context.saveMeasure(inputFile, CoreMetrics.CLASSES, (double)parser.getClassCount()); - context.saveMeasure(inputFile, CoreMetrics.FUNCTIONS, (double)(functionCount)); + private void saveMeasure(InputFile inputFile, SensorContext context, String metricKey, Serializable value) { + org.sonar.api.batch.measure.Metric metric = metricFinder.findByKey(metricKey); + if (metric == null) { + throw new IllegalStateException("Unknown metric with key: " + metricKey); + } + NewMeasure measure = context.newMeasure().forMetric(metric).on(inputFile); + measure.withValue(value); + measure.save(); } } diff --git a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirParser.java b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirParser.java index cc1342b..1f09664 100644 --- a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirParser.java +++ b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/language/ElixirParser.java @@ -36,9 +36,6 @@ public class ElixirParser { private int classCount = 0; private int publicFunctionCount = 0; private int privateFunctionCount = 0; - private int documentedClassCount = 0; - private int documentedPrivateFunctionCount = 0; - private int documentedPublicFunctionCount = 0; private final Pattern defPattern = Pattern.compile("^\\s*def(|p|module|struct)\\s(.*)$"); private final Matcher defMatcher = defPattern.matcher(""); @@ -47,29 +44,20 @@ public class ElixirParser { private final Pattern docPattern = Pattern.compile("^\\s*@(doc|moduledoc|typedoc)([\"\\s].*)$"); private final Matcher docMatcher = docPattern.matcher(""); - private boolean hasDoc = false; - private boolean inClass = false; + ElixirParser() { } - public ElixirParser() { } + int getLineCount() { return lineCount; } + int getEmptyLineCount() { return emptyLineCount; } + int getCommentLineCount() { return commentLineCount; } + int getClassCount() { return classCount; } + int getPublicFunctionCount() { return publicFunctionCount; } + int getPrivateFunctionCount() { return privateFunctionCount; } - public int getLineCount() { return lineCount; } - public int getEmptyLineCount() { return emptyLineCount; } - public int getCommentLineCount() { return commentLineCount; } - public int getClassCount() { return classCount; } - public int getPublicFunctionCount() { return publicFunctionCount; } - public int getPrivateFunctionCount() { return privateFunctionCount; } - public int getDocumentedClassCount() { return documentedClassCount; } - public int getDocumentedPublicFunctionCount() { return documentedPublicFunctionCount; } - public int getDocumentedPrivateFunctionCount() { return documentedPrivateFunctionCount; } - - public void parse(List lines) { + void parse(List lines) { this.parseLines(lines); } private void parseLines(List lines) { - hasDoc = false; - inClass = false; - lineCount = lines.size(); for (int i = 0; i < lineCount; i++) { String line = lines.get(i); @@ -80,21 +68,6 @@ private void parseLines(List lines) { boolean inDoc = docMatcher.find(); if (inDoc) { commentLineCount++; - String docHead = docMatcher.group(2).trim(); - if (! (StringUtils.equalsIgnoreCase(docHead, "false") || StringUtils.equalsIgnoreCase(docHead, "nil"))) { - switch (docMatcher.group(1)) { - case "doc": - hasDoc = true; - break; - case "moduledoc": - if (inClass) { - documentedClassCount++; - } - break; - case "typedoc": - break; - } - } } heredocMatcher.reset(line); if (heredocMatcher.find()) { @@ -116,22 +89,14 @@ private void parseLines(List lines) { switch (defMatcher.group(1)) { case "module": classCount++; - inClass = true; break; case "": publicFunctionCount++; - if (hasDoc) { - documentedPublicFunctionCount++; - } break; case "p": privateFunctionCount++; - if (hasDoc) { - documentedPrivateFunctionCount++; - } break; } - hasDoc = false; } if (line.matches("^\\s*#.*$")) { commentLineCount++; diff --git a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfile.java b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfile.java index e969d21..face528 100644 --- a/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfile.java +++ b/sonar-elixir-plugin/src/main/java/eu/arthepsy/sonar/plugins/elixir/rule/ElixirQualityProfile.java @@ -24,18 +24,15 @@ package eu.arthepsy.sonar.plugins.elixir.rule; import eu.arthepsy.sonar.plugins.elixir.language.Elixir; -import org.sonar.api.profiles.ProfileDefinition; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.utils.ValidationMessages; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; -public class ElixirQualityProfile extends ProfileDefinition { +public class ElixirQualityProfile implements BuiltInQualityProfilesDefinition { private static final String DEFAULT_PROFILE = "Sonar way"; @Override - public RulesProfile createProfile(ValidationMessages validationMessages) { - final RulesProfile profile = RulesProfile.create(DEFAULT_PROFILE, Elixir.KEY); - //parser.parse(profile); - //parser.log(LoggerFactory.getLogger(ScapegoatQualityProfile.class), ScapegoatConfiguration.LOG_PREFIX); - return profile; + public void define(Context context) { + NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(DEFAULT_PROFILE, Elixir.KEY); + profile.setDefault(true); + profile.done(); } } 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 deleted file mode 100644 index 65b6a7a..0000000 --- a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/ElixirConfigurationTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 index a4ec728..fe82bdd 100644 --- 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 @@ -23,13 +23,26 @@ */ package eu.arthepsy.sonar.plugins.elixir; +import eu.arthepsy.sonar.plugins.elixir.language.Elixir; +import eu.arthepsy.sonar.plugins.elixir.language.ElixirMeasureSensor; +import eu.arthepsy.sonar.plugins.elixir.rule.ElixirQualityProfile; import org.junit.Test; +import org.sonar.api.Plugin.Context; -import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; public class ElixirPluginTest { + private final Context context; + + public ElixirPluginTest() { + this.context = mock(Context.class); + } + @Test - public void testExtensionCount() { - assertThat(new ElixirPlugin().getExtensions().size()).isEqualTo(3); + public void define() { + ElixirPlugin plugin = new ElixirPlugin(); + plugin.define(context); + verify(context).addExtensions(Elixir.class, ElixirQualityProfile.class, ElixirMeasureSensor.class); } } 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 1f95579..9388b4c 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 @@ -23,64 +23,100 @@ */ package eu.arthepsy.sonar.plugins.elixir.language; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.component.ResourcePerspectives; +import org.sonar.api.batch.measure.Metric; +import org.sonar.api.batch.measure.MetricFinder; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.resources.Project; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; -import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.*; public class ElixirMeasureSensorTest { - private final Project project = new Project("project"); - private SensorContext context = mock(SensorContext.class); + @Mock + private SensorContext context; + + @Mock private DefaultFileSystem fileSystem; - private ElixirMeasureSensor sensor; - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - private File baseDir; + @Mock + private MetricFinder metricFinder; + + @Mock + private DefaultIndexedFile indexedFile; + + @Mock + private Consumer metadataGenerator; + + @Mock + private FilePredicates filePredicates; + + @Mock + private Metric metric; + + @Mock + private NewMeasure newMeasure; + + private ElixirMeasureSensor sensor; @Before - public void prepare() throws IOException { - baseDir = temp.newFolder(); - fileSystem = new DefaultFileSystem(); - fileSystem.setBaseDir(baseDir); - sensor = new ElixirMeasureSensor(fileSystem); + public void prepare() { + MockitoAnnotations.initMocks(this); + + when(fileSystem.predicates()).thenReturn(filePredicates); + sensor = new ElixirMeasureSensor(fileSystem, metricFinder); } @Test public void testDocAnnotation() throws IOException { String fileName = "test_doc.ex"; - 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()); - fileSystem.add(inputFile); - - assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); - - sensor.analyse(project, context); - - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.LINES), eq(37.0)); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.NCLOC), eq(15.0)); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.COMMENT_LINES), eq(14.0)); - verify(context).saveMeasure(any(InputFile.class), eq(CoreMetrics.CLASSES), eq(1.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)); + InputStream testInputStream = getClass().getResourceAsStream("/" + fileName); + + String testFileContents = IOUtils.toString(testInputStream, Charset.defaultCharset()); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, metadataGenerator, testFileContents); + inputFile.setCharset(Charset.defaultCharset()); + when(indexedFile.language()).thenReturn(Elixir.KEY); + + List inputFiles = new ArrayList<>(); + inputFiles.add(inputFile); + when(fileSystem.inputFiles(any(FilePredicate.class))).thenReturn(inputFiles); + + when(metricFinder.findByKey(CoreMetrics.LINES_KEY)).thenReturn(metric); + when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(metric); + when(metricFinder.findByKey(CoreMetrics.COMMENT_LINES_KEY)).thenReturn(metric); + when(metricFinder.findByKey(CoreMetrics.FUNCTIONS_KEY)).thenReturn(metric); + when(metricFinder.findByKey(CoreMetrics.CLASSES_KEY)).thenReturn(metric); + when(context.newMeasure()).thenReturn(newMeasure); + when(newMeasure.forMetric(Matchers.any())).thenReturn(newMeasure); + when(newMeasure.on(any(InputFile.class))).thenReturn(newMeasure); + + sensor.execute(context); + + verify(newMeasure).withValue(eq(37)); + verify(newMeasure).withValue(eq(15)); + verify(newMeasure).withValue(eq(14)); + verify(newMeasure).withValue(eq(1)); + verify(newMeasure).withValue(eq(6)); } } \ No newline at end of file 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 index 8cfa2bb..4cb103b 100644 --- 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 @@ -23,16 +23,26 @@ */ package eu.arthepsy.sonar.plugins.elixir.language; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.junit.Test; -import static org.fest.assertions.Assertions.assertThat; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; 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"); + assertEquals("elixir", language.getKey()); + assertEquals("Elixir", language.getName()); + String[] suffixes = language.getFileSuffixes(); + assert(suffixes.length == 2); + final List expectedSuffixes = new ArrayList<>(); + expectedSuffixes.add("ex"); + expectedSuffixes.add("exs"); + assertTrue(Arrays.asList(suffixes).containsAll(expectedSuffixes)); } } 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 index 9b9a9db..ef2b7b9 100644 --- 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 @@ -23,27 +23,34 @@ */ package eu.arthepsy.sonar.plugins.elixir.rule; +import eu.arthepsy.sonar.plugins.elixir.language.Elixir; 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 org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; -import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; public class ElixirQualityProfileTest { private ElixirQualityProfile profile; - private ValidationMessages validationMessages; + + @Mock + BuiltInQualityProfilesDefinition.Context context; + + @Mock + BuiltInQualityProfilesDefinition.NewBuiltInQualityProfile newProfile; @Before public void prepare() { - profile = Mockito.spy(new ElixirQualityProfile()); - validationMessages = ValidationMessages.create(); + profile = new ElixirQualityProfile(); + MockitoAnnotations.initMocks(this); } @Test public void testRulesCount() { - RulesProfile rulesProfile = profile.createProfile(validationMessages); - assertThat(rulesProfile.getActiveRules().size()).isEqualTo(0); + when(context.createBuiltInQualityProfile(eq("Sonar way"), eq(Elixir.KEY))).thenReturn(newProfile); + profile.define(context); } } 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 deleted file mode 100644 index c87f811..0000000 --- a/sonar-elixir-plugin/src/test/java/eu/arthepsy/sonar/plugins/elixir/util/ClassDefinition.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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(); - } - } - } - -}