Skip to content

Commit

Permalink
#58 Do not report duplication on test files
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed May 4, 2017
1 parent 86f8885 commit 34d64a4
Show file tree
Hide file tree
Showing 27 changed files with 223 additions and 139 deletions.
28 changes: 6 additions & 22 deletions sonar-groovy-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,6 @@
</dependency>

<!-- unit tests -->
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-testing-harness</artifactId>
<version>${sonar.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
<version>${sonar.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
Expand All @@ -146,19 +133,16 @@
<version>1.6</version>
<scope>test</scope>
</dependency>
<!-- TODO http://jira.codehaus.org/browse/SONAR-2011 We need following
dependency, otherwise we will receive java.lang.NoClassDefFoundError: org/apache/maven/project/MavenProject
during call mock(org.sonar.api.resources.Project.class) -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0.7</version>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>1.4</version>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.7.22</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,30 @@
*/
package org.sonar.plugins.groovy.foundation;

import groovyjarjarantlr.Token;
import groovyjarjarantlr.TokenStream;
import groovyjarjarantlr.TokenStreamException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import org.codehaus.groovy.antlr.GroovySourceToken;
import org.codehaus.groovy.antlr.parser.GroovyLexer;
import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.internal.apachecommons.lang.StringUtils;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import javax.annotation.Nullable;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import groovyjarjarantlr.Token;
import groovyjarjarantlr.TokenStream;
import groovyjarjarantlr.TokenStreamException;

public class GroovyHighlighterAndTokenizer {

private static final Logger LOG = Loggers.get(GroovyHighlighterAndTokenizer.class);
Expand Down Expand Up @@ -104,24 +103,24 @@ public class GroovyHighlighterAndTokenizer {
};

private static final int[] STRINGS = {
GroovyLexer.STRING_CH,
GroovyLexer.STRING_CONSTRUCTOR,
GroovyLexer.STRING_CTOR_END,
GroovyLexer.STRING_CTOR_MIDDLE,
GroovyLexer.STRING_CTOR_START,
GroovyLexer.STRING_LITERAL,
GroovyLexer.STRING_NL,
GroovyLexer.REGEX_MATCH,
GroovyLexer.REGEX_FIND,
GroovyLexer.REGEXP_LITERAL,
GroovyLexer.REGEXP_CTOR_END,
GroovyLexer.REGEXP_SYMBOL,
GroovyLexer.DOLLAR_REGEXP_LITERAL,
GroovyLexer.DOLLAR_REGEXP_CTOR_END,
GroovyLexer.DOLLAR_REGEXP_SYMBOL,
GroovyLexer.DOLLAR,
GroovyLexer.ESCAPED_DOLLAR,
GroovyLexer.ESCAPED_SLASH
GroovyLexer.STRING_CH,
GroovyLexer.STRING_CONSTRUCTOR,
GroovyLexer.STRING_CTOR_END,
GroovyLexer.STRING_CTOR_MIDDLE,
GroovyLexer.STRING_CTOR_START,
GroovyLexer.STRING_LITERAL,
GroovyLexer.STRING_NL,
GroovyLexer.REGEX_MATCH,
GroovyLexer.REGEX_FIND,
GroovyLexer.REGEXP_LITERAL,
GroovyLexer.REGEXP_CTOR_END,
GroovyLexer.REGEXP_SYMBOL,
GroovyLexer.DOLLAR_REGEXP_LITERAL,
GroovyLexer.DOLLAR_REGEXP_CTOR_END,
GroovyLexer.DOLLAR_REGEXP_SYMBOL,
GroovyLexer.DOLLAR,
GroovyLexer.ESCAPED_DOLLAR,
GroovyLexer.ESCAPED_SLASH
};

private static final int[] CONSTANTS = {
Expand Down Expand Up @@ -173,7 +172,9 @@ public void processFile(SensorContext context) {
String text = token.getText();
TypeOfText typeOfText = typeOfText(type, text).orElse(null);
GroovySourceToken gst = (GroovySourceToken) token;
tokens.add(new GroovyToken(token.getLine(), token.getColumn(), gst.getLineLast(), gst.getColumnLast(), text, typeOfText));
if (StringUtils.isNotBlank(text)) {
tokens.add(new GroovyToken(token.getLine(), token.getColumn(), gst.getLineLast(), gst.getColumnLast(), getImage(token, text), typeOfText));
}
token = tokenStream.nextToken();
type = token.getType();
}
Expand All @@ -184,17 +185,32 @@ public void processFile(SensorContext context) {
}

if (!tokens.isEmpty()) {
NewCpdTokens cpdTokens = context.newCpdTokens().onFile(inputFile);
boolean isNotTest = inputFile.type() != InputFile.Type.TEST;
NewCpdTokens cpdTokens = isNotTest ? context.newCpdTokens().onFile(inputFile) : null;
NewHighlighting highlighting = context.newHighlighting().onFile(inputFile);
for (GroovyToken groovyToken : tokens) {
cpdTokens = cpdTokens.addToken(groovyToken.startLine, groovyToken.startColumn, groovyToken.endLine, groovyToken.endColumn, groovyToken.value);
if (isNotTest) {
cpdTokens = cpdTokens.addToken(groovyToken.startLine, groovyToken.startColumn, groovyToken.endLine, groovyToken.endColumn, groovyToken.value);
}
if (groovyToken.typeOfText != null) {
highlighting = highlighting.highlight(groovyToken.startLine, groovyToken.startColumn, groovyToken.endLine, groovyToken.endColumn, groovyToken.typeOfText);
}
}
highlighting.save();
cpdTokens.save();
if (isNotTest) {
cpdTokens.save();
}
}
}

private String getImage(Token token, String text) {
if (token.getType() == GroovyTokenTypes.STRING_LITERAL
|| token.getType() == GroovyTokenTypes.STRING_CTOR_START
|| token.getType() == GroovyTokenTypes.STRING_CTOR_MIDDLE
|| token.getType() == GroovyTokenTypes.STRING_CTOR_END) {
return "LITERAL";
}
return text;
}

private Optional<TypeOfText> typeOfText(int type, String text) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import org.junit.Test;

import static org.fest.assertions.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public class GroovyMetricsTest {
@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.sonar.api.Plugin;
import org.sonar.api.SonarQubeVersion;

import static org.fest.assertions.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public class GroovyPluginTest {

Expand All @@ -32,7 +32,7 @@ public void testExtensions() {
GroovyPlugin plugin = new GroovyPlugin();
Plugin.Context context = new Plugin.Context(SonarQubeVersion.V5_6);
plugin.define(context);
assertThat(context.getExtensions()).hasSize(16);
assertThat(context.getExtensions()).hasSize(17);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import java.io.IOException;
import java.nio.file.Files;

import static org.fest.assertions.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Sonar Groovy Plugin
* Copyright (C) 2010-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.plugins.groovy;

import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

public final class TestUtils {

private TestUtils() {
}

/**
* Search for a test resource in the classpath. For example getResource("org/sonar/MyClass/foo.txt");
*
* @param path the starting slash is optional
* @return the resource. Null if resource not found
*/
public static File getResource(String path) {
String resourcePath = path;
if (!resourcePath.startsWith("/")) {
resourcePath = "/" + resourcePath;
}
URL url = TestUtils.class.getResource(resourcePath);
if (url != null) {
return FileUtils.toFile(url);
}
return null;
}

/**
* Search for a resource in the classpath. For example calling the method getResource(getClass(), "myTestName/foo.txt") from
* the class org.sonar.Foo loads the file $basedir/src/test/resources/org/sonar/Foo/myTestName/foo.txt
*
* @return the resource. Null if resource not found
*/
public static File getResource(Class baseClass, String path) {
String resourcePath = StringUtils.replaceChars(baseClass.getCanonicalName(), '.', '/');
if (!path.startsWith("/")) {
resourcePath += "/";
}
resourcePath += path;
return getResource(resourcePath);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
package org.sonar.plugins.groovy.cobertura;

import com.google.common.collect.ImmutableMap;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
Expand All @@ -42,12 +44,8 @@
import org.sonar.plugins.groovy.GroovyPlugin;
import org.sonar.plugins.groovy.foundation.Groovy;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand All @@ -72,7 +70,6 @@ public void test_description() {
assertThat(defaultSensorDescriptor.languages()).containsOnly(Groovy.KEY);
}


/**
* See SONARPLUGINS-696
*/
Expand All @@ -94,29 +91,30 @@ public boolean apply(InputFile inputFile) {
}
}

when(fp.hasAbsolutePath(Matchers.anyString())).thenAnswer(new Answer<FilePredicate>() {
when(fp.hasAbsolutePath(ArgumentMatchers.anyString())).thenAnswer(new Answer<FilePredicate>() {
@Override
public FilePredicate answer(InvocationOnMock invocation) throws Throwable {
return new CustomFilePredicate(invocation.getArgumentAt(0, String.class));
return new CustomFilePredicate(invocation.<String>getArgument(0));
}
});

FileSystem mockfileSystem = mock(FileSystem.class);
when(mockfileSystem.predicates()).thenReturn(fp);
when(mockfileSystem.hasFiles(Matchers.any(FilePredicate.class))).thenReturn(true);
when(mockfileSystem.hasFiles(ArgumentMatchers.nullable(FilePredicate.class))).thenReturn(true);

Map<String, DefaultInputFile> groovyFilesByName = new HashMap<>();

when(mockfileSystem.inputFile(any(FilePredicate.class))).thenAnswer(new Answer<InputFile>() {
boolean firstCall = true;

@Override
public InputFile answer(InvocationOnMock invocation) throws Throwable {
if (firstCall) {
// The first class in the test coverage.xml is a java class and the rest are groovy
firstCall = false;
return new DefaultInputFile("", "fake.java").setLanguage("java");
}
String fileName = invocation.getArgumentAt(0, CustomFilePredicate.class).fileName;
String fileName = invocation.<CustomFilePredicate>getArgument(0).fileName;
DefaultInputFile groovyFile;
if (!groovyFilesByName.containsKey(fileName)) {
// store groovy file as default input files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import org.apache.commons.lang.CharUtils;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.fest.assertions.Fail;
import org.assertj.core.api.Fail;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -32,7 +32,7 @@
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.plugins.groovy.foundation.Groovy;
import org.sonar.test.TestUtils;
import org.sonar.plugins.groovy.TestUtils;

import java.io.File;
import java.io.FileReader;
Expand All @@ -41,7 +41,7 @@
import java.io.StringWriter;
import java.io.Writer;

import static org.fest.assertions.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public class CodeNarcProfileExporterTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

import java.util.List;

import static org.fest.assertions.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public class CodeNarcRulesDefinitionTest {

Expand Down
Loading

0 comments on commit 34d64a4

Please sign in to comment.