Skip to content

Commit

Permalink
fixed bug with duplicated resources for package objects on first leve…
Browse files Browse the repository at this point in the history
…l of hierarchy
  • Loading branch information
fmueller committed Apr 26, 2014
1 parent a4bc085 commit a3f8ffd
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 69 deletions.
41 changes: 29 additions & 12 deletions src/main/java/org/sonar/plugins/scala/language/ScalaFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public static ScalaFile fromInputFile(InputFile inputFile) {
/**
* Creates a {@link ScalaFile} from a file in the source directories.
*
* @param inputFile the file object with relative path
* @param inputFile the file object with relative path
* @param isUnitTest whether it is a unit test file or a source file
* @return the {@link ScalaFile} created if exists, null otherwise
*/
Expand All @@ -125,12 +125,27 @@ public static ScalaFile fromInputFile(InputFile inputFile, boolean isUnitTest) {
return null;
}

final String packageName = PackageResolver.resolvePackageNameOfFile(
inputFile.getFile().getAbsolutePath());
final String className = resolveClassName(inputFile);
String packageName = PackageResolver.resolvePackageNameOfFile(inputFile.getFile().getAbsolutePath());
String className = resolveClassName(inputFile);

if (isPackageObjectInFirstLevelPackage(packageName, className)) {
String lastFolderName = extractLastFolderName(inputFile);
return new ScalaFile(StringUtils.EMPTY, lastFolderName + "." + className, isUnitTest);
}

return new ScalaFile(packageName, className, isUnitTest);
}

private static boolean isPackageObjectInFirstLevelPackage(String packageName, String className) {
return "<empty>".equalsIgnoreCase(packageName) && "package".equalsIgnoreCase(className);
}

private static String extractLastFolderName(InputFile inputFile) {
String absolutePath = inputFile.getFile().getAbsolutePath();
int lastPathSeparator = absolutePath.lastIndexOf("/");
return absolutePath.substring(absolutePath.lastIndexOf("/", lastPathSeparator - 1) + 1, lastPathSeparator);
}

private static String resolveClassName(InputFile inputFile) {
String classname = inputFile.getRelativePath();
if (inputFile.getRelativePath().indexOf('/') >= 0) {
Expand All @@ -139,12 +154,14 @@ private static String resolveClassName(InputFile inputFile) {
return StringUtils.substringBeforeLast(classname, ".");
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("key", getKey())
.append("fileName", filename)
.append("isUnitTest", isUnitTest)
.toString();
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("key", getKey())
.append("fileName", filename)
.append("isUnitTest", isUnitTest)
.append("longName", longName)
.append("parent", parent)
.toString();
}
}
14 changes: 9 additions & 5 deletions src/main/java/org/sonar/plugins/scala/language/ScalaPackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.sonar.plugins.scala.language;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
Expand All @@ -37,10 +38,6 @@ public class ScalaPackage extends Resource {

public static final String DEFAULT_PACKAGE_NAME = "[default]";

public ScalaPackage() {
this(null);
}

public ScalaPackage(String key) {
super();
setKey(StringUtils.defaultIfEmpty(StringUtils.trim(key), DEFAULT_PACKAGE_NAME));
Expand Down Expand Up @@ -87,4 +84,11 @@ public boolean matchFilePattern(String antPattern) {
WildcardPattern matcher = WildcardPattern.create(patternWithoutFileSuffix, ".");
return matcher.match(getKey());
}
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("key", getKey())
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
*/
package org.sonar.plugins.scala.sensor;

import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -33,6 +31,8 @@
import org.sonar.plugins.scala.language.Scala;
import org.sonar.plugins.scala.language.ScalaFile;

import java.io.IOException;

/**
* This Sensor imports all Scala files into Sonar.
*
Expand Down Expand Up @@ -61,20 +61,19 @@ public void analyse(Project project, SensorContext sensorContext) {
}
}

private void addFileToSonar(SensorContext sensorContext, InputFile inputFile,
boolean isUnitTest, String charset) {
private void addFileToSonar(SensorContext sensorContext, InputFile inputFile, boolean isUnitTest, String charset) {
try {
String source = FileUtils.readFileToString(inputFile.getFile(), charset);
ScalaFile resource = ScalaFile.fromInputFile(inputFile, isUnitTest);
ScalaFile file = ScalaFile.fromInputFile(inputFile, isUnitTest);

sensorContext.index(resource);
sensorContext.saveSource(resource, source);
sensorContext.index(file);
sensorContext.saveSource(file, source);

if (LOGGER.isDebugEnabled()) {
if (isUnitTest) {
LOGGER.debug("Added Scala test file to Sonar: " + inputFile.getFile().getAbsolutePath());
LOGGER.debug("Added Scala test file to Sonar: {}", file);
} else {
LOGGER.debug("Added Scala source file to Sonar: " + inputFile.getFile().getAbsolutePath());
LOGGER.debug("Added Scala source file to Sonar: {}", file);
}
}
} catch (IOException ioe) {
Expand All @@ -86,4 +85,4 @@ private void addFileToSonar(SensorContext sensorContext, InputFile inputFile,
public String toString() {
return getClass().getSimpleName();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ object Compiler extends Global(new Settings() {

}) {

private val LOGGER = LoggerFactory.getLogger(classOf[Compiler])
private val logger = LoggerFactory.getLogger(classOf[Compiler])

try {
new Run()
} catch {
case ex: Throwable => LOGGER.error("Could not initiate Scala compiler, probably due classpath issues!", ex)
case ex: Throwable => logger.error("Could not initiate Scala compiler, probably due classpath issues!", ex)
}

override def forScaladoc = true
Expand Down
27 changes: 19 additions & 8 deletions src/test/java/org/sonar/plugins/scala/language/ScalaFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@
*/
package org.sonar.plugins.scala.language;

import org.junit.Test;
import org.sonar.api.resources.InputFile;
import org.sonar.api.resources.InputFileUtils;
import org.sonar.api.resources.Qualifiers;
import org.sonar.plugins.scala.util.FileTestUtils;

import java.io.File;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;

import org.junit.Test;
import org.sonar.api.resources.InputFile;
import org.sonar.api.resources.Qualifiers;
import org.sonar.plugins.scala.util.FileTestUtils;

public class ScalaFileTest {

@Test
Expand Down Expand Up @@ -71,6 +72,16 @@ public void shouldCreateScalaTestFileWithCorrectAttributes() {
assertThat(scalaFile.isUnitTest(), is(true));
}

@Test
public void shouldHandlePackeObjectsInFirstLevelProperly() {
InputFile inputFile = InputFileUtils.create(new File("src/test/resources/"), "scalaSourceImporter/package.scala");
ScalaFile scalaFile = ScalaFile.fromInputFile(inputFile, false);

assertThat(scalaFile.getName(), is("scalaSourceImporter.package"));
assertThat(scalaFile.getLongName(), is(scalaFile.getName()));
assertThat(scalaFile.getKey(), is("[default].scalaSourceImporter.package"));
}

@Test
public void shouldNotCreateScalaFileIfInputFileIsNull() {
assertNull(ScalaFile.fromInputFile(null));
Expand All @@ -90,4 +101,4 @@ public void shouldNotCreateScalaFileIfRelativePathIsNull() {
when(inputFile.getRelativePath()).thenReturn(null);
assertNull(ScalaFile.fromInputFile(inputFile));
}
}
}
160 changes: 160 additions & 0 deletions src/test/java/org/sonar/plugins/scala/sensor/FakeSensorContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* 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 02
*/
package org.sonar.plugins.scala.sensor;

import com.google.common.collect.Sets;
import org.sonar.api.batch.Event;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.ProjectLink;
import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Violation;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
* This fake helps to detect duplicate resources in tests.
*/
class FakeSensorContext implements SensorContext {

private final Set<Resource> resources = Sets.newHashSet();

public void saveSource(Resource reference, String source) {
if (resources.contains(reference)) {
throw new RuntimeException("Duplicate resources in sensor context are not allowed!");
}
resources.add(reference);
}

public boolean index(Resource resource) {
return false;
}

public boolean index(Resource resource, Resource parentReference) {
return false;
}

public boolean isExcluded(Resource reference) {
return false;
}

public boolean isIndexed(Resource reference, boolean acceptExcluded) {
return false;
}

public <R extends Resource> R getResource(R reference) {
return null;
}

public Resource getParent(Resource reference) {
return null;
}

public Collection<Resource> getChildren(Resource reference) {
return null;
}

public Measure getMeasure(Metric metric) {
return null;
}

public <M> M getMeasures(MeasuresFilter<M> filter) {
return null;
}

public Measure saveMeasure(Measure measure) {
return null;
}

public Measure saveMeasure(Metric metric, Double value) {
return null;
}

public Measure getMeasure(Resource resource, Metric metric) {
return null;
}

public String saveResource(Resource resource) {
return null;
}

public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
return null;
}

public Measure saveMeasure(Resource resource, Metric metric, Double value) {
return null;
}

public Measure saveMeasure(Resource resource, Measure measure) {
return null;
}

public void saveViolation(Violation violation, boolean force) {

}

public void saveViolation(Violation violation) {

}

public void saveViolations(Collection<Violation> violations) {

}

public Dependency saveDependency(Dependency dependency) {
return null;
}

public Set<Dependency> getDependencies() {
return null;
}

public Collection<Dependency> getIncomingDependencies(Resource to) {
return null;
}

public Collection<Dependency> getOutgoingDependencies(Resource from) {
return null;
}

public void saveLink(ProjectLink link) {
}

public void deleteLink(String key) {
}

public List<Event> getEvents(Resource resource) {
return null;
}

public Event createEvent(Resource resource, String name, String description, String category, Date date) {
return null;
}

public void deleteEvent(Event event) {
}
}
Loading

0 comments on commit a3f8ffd

Please sign in to comment.