From: Julien HENRY Date: Fri, 20 Feb 2015 13:57:39 +0000 (+0100) Subject: SONAR-5931 Add a tester class for SensorContext X-Git-Tag: 5.1-RC1~140 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ee09741a99176e635b310ab295dd898533828d69;p=sonarqube.git SONAR-5931 Add a tester class for SensorContext --- diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java index 92169bdf42b..de18a8b9264 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java @@ -19,37 +19,30 @@ */ package org.sonar.xoo.lang; -import org.sonar.api.batch.sensor.internal.SensorStorage; - import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; +import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import java.io.File; import java.io.IOException; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class MeasureSensorTest { private MeasureSensor sensor; - private SensorContext context = mock(SensorContext.class); - private DefaultFileSystem fileSystem; + private SensorContextTester context; @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -59,22 +52,13 @@ public class MeasureSensorTest { private File baseDir; private MetricFinder metricFinder; - private SensorStorage storage; @Before public void prepare() throws IOException { baseDir = temp.newFolder(); metricFinder = mock(MetricFinder.class); sensor = new MeasureSensor(metricFinder); - fileSystem = new DefaultFileSystem(baseDir.toPath()); - when(context.fileSystem()).thenReturn(fileSystem); - storage = mock(SensorStorage.class); - when(context.newMeasure()).then(new Answer() { - @Override - public DefaultMeasure answer(InvocationOnMock invocation) throws Throwable { - return new DefaultMeasure(storage); - } - }); + context = SensorContextTester.create(baseDir); } @Test @@ -85,7 +69,7 @@ public class MeasureSensorTest { @Test public void testNoExecutionIfNoMeasureFile() { DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); - fileSystem.add(inputFile); + context.fileSystem().add(inputFile); sensor.execute(context); } @@ -94,7 +78,7 @@ public class MeasureSensorTest { File measures = new File(baseDir, "src/foo.xoo.measures"); FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\n\n#comment"); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); - fileSystem.add(inputFile); + context.fileSystem().add(inputFile); Metric booleanMetric = new Metric.Builder("bool", "Bool", Metric.ValueType.BOOL) .create(); @@ -106,10 +90,10 @@ public class MeasureSensorTest { sensor.execute(context); - verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.NCLOC).onFile(inputFile).withValue(12)); - verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.BRANCH_COVERAGE).onFile(inputFile).withValue(5.3)); - verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.TECHNICAL_DEBT).onFile(inputFile).withValue(300L)); - verify(storage).store(new DefaultMeasure().forMetric(booleanMetric).onFile(inputFile).withValue(true)); + assertThat(context.measure("foo:src/foo.xoo", CoreMetrics.NCLOC).value()).isEqualTo(12); + assertThat(context.measure("foo:src/foo.xoo", CoreMetrics.BRANCH_COVERAGE).value()).isEqualTo(5.3); + assertThat(context.measure("foo:src/foo.xoo", CoreMetrics.TECHNICAL_DEBT).value()).isEqualTo(300L); + assertThat(context.measure("foo:src/foo.xoo", booleanMetric).value()).isTrue(); } @Test @@ -117,7 +101,7 @@ public class MeasureSensorTest { File measures = new File(baseDir, "src/foo.xoo.measures"); FileUtils.write(measures, "unknow:12\n\n#comment"); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); - fileSystem.add(inputFile); + context.fileSystem().add(inputFile); thrown.expect(IllegalStateException.class); diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java index 4bd8aa2da61..9b9a7baca05 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java @@ -24,27 +24,20 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.internal.SensorContextTester; import java.io.File; import java.io.IOException; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; public class SyntaxHighlightingSensorTest { private SyntaxHighlightingSensor sensor; - private SensorContext context = mock(SensorContext.class); - private DefaultFileSystem fileSystem; + private SensorContextTester context; @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -54,8 +47,7 @@ public class SyntaxHighlightingSensorTest { public void prepare() throws IOException { baseDir = temp.newFolder(); sensor = new SyntaxHighlightingSensor(); - fileSystem = new DefaultFileSystem(baseDir.toPath()); - when(context.fileSystem()).thenReturn(fileSystem); + context = SensorContextTester.create(baseDir); } @Test @@ -66,7 +58,7 @@ public class SyntaxHighlightingSensorTest { @Test public void testNoExecutionIfNoSyntaxFile() { DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); - fileSystem.add(inputFile); + context.fileSystem().add(inputFile); sensor.execute(context); } @@ -75,15 +67,11 @@ public class SyntaxHighlightingSensorTest { File symbol = new File(baseDir, "src/foo.xoo.highlighting"); FileUtils.write(symbol, "1:4:k\n12:15:cppd\n\n#comment"); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); - fileSystem.add(inputFile); - NewHighlighting builder = mock(NewHighlighting.class); - when(context.newHighlighting()).thenReturn(builder); - when(builder.onFile(any(InputFile.class))).thenReturn(builder); + context.fileSystem().add(inputFile); sensor.execute(context); - verify(builder).highlight(1, 4, TypeOfText.KEYWORD); - verify(builder).highlight(12, 15, TypeOfText.CPP_DOC); - verify(builder).save(); + assertThat(context.highlightingTypeFor("foo:src/foo.xoo", 2)).containsOnly(TypeOfText.KEYWORD); + assertThat(context.highlightingTypeFor("foo:src/foo.xoo", 13)).containsOnly(TypeOfText.CPP_DOC); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java new file mode 100644 index 00000000000..1a41ccefe44 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -0,0 +1,303 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.sensor.internal; + +import com.google.common.annotations.Beta; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.fs.InputDir; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultInputDir; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.NewDependency; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; +import org.sonar.api.batch.sensor.duplication.Duplication; +import org.sonar.api.batch.sensor.duplication.NewDuplication; +import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication; +import org.sonar.api.batch.sensor.highlighting.NewHighlighting; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; +import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule; +import org.sonar.api.batch.sensor.issue.Issue; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; +import org.sonar.api.batch.sensor.measure.Measure; +import org.sonar.api.batch.sensor.measure.NewMeasure; +import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; +import org.sonar.api.config.Settings; +import org.sonar.api.measures.Metric; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Utility class to help testing {@link Sensor} + * @since 5.1 + */ +@Beta +public class SensorContextTester implements SensorContext { + + private Settings settings; + private DefaultFileSystem fs; + private ActiveRules activeRules; + private MockAnalysisMode analysisMode; + private InMemorySensorStorage sensorStorage; + + private SensorContextTester(File moduleBaseDir) { + this.settings = new Settings(); + this.fs = new DefaultFileSystem(moduleBaseDir); + this.activeRules = new ActiveRulesBuilder().build(); + this.analysisMode = new MockAnalysisMode(); + this.sensorStorage = new InMemorySensorStorage(); + } + + public static SensorContextTester create(File moduleBaseDir) { + return new SensorContextTester(moduleBaseDir); + } + + @Override + public Settings settings() { + return settings; + } + + public void setSettings(Settings settings) { + this.settings = settings; + } + + @Override + public DefaultFileSystem fileSystem() { + return fs; + } + + public void setFileSystem(DefaultFileSystem fs) { + this.fs = fs; + } + + @Override + public ActiveRules activeRules() { + return activeRules; + } + + public void setActiveRules(ActiveRules activeRules) { + this.activeRules = activeRules; + } + + @Override + public MockAnalysisMode analysisMode() { + return analysisMode; + } + + @Override + public NewMeasure newMeasure() { + return new DefaultMeasure<>(sensorStorage); + } + + public Collection measures(@Nullable String componetKey) { + if (componetKey == null) { + return sensorStorage.projectMeasuresByMetric.values(); + } + Map measures = sensorStorage.measuresByComponentAndMetric.get(componetKey); + return measures != null ? measures.values() : Collections.emptyList(); + } + + public Measure measure(String componetKey, Metric metric) { + return measure(componetKey, metric.key()); + } + + public Measure measure(String componetKey, String metricKey) { + if (componetKey == null) { + return sensorStorage.projectMeasuresByMetric.get(metricKey); + } + Map measures = sensorStorage.measuresByComponentAndMetric.get(componetKey); + return measures != null ? measures.get(metricKey) : null; + } + + @Override + public NewIssue newIssue() { + return new DefaultIssue(sensorStorage); + } + + public Collection allIssues() { + List result = new ArrayList<>(); + result.addAll(sensorStorage.projectIssues); + for (String key : sensorStorage.issuesByComponent.keySet()) { + result.addAll(sensorStorage.issuesByComponent.get(key)); + } + return result; + } + + /** + * @param componentKey null for project issues + */ + public Collection issues(@Nullable String componentKey) { + if (componentKey != null) { + List list = sensorStorage.issuesByComponent.get(componentKey); + return list != null ? list : Collections.emptyList(); + } else { + return sensorStorage.projectIssues; + } + } + + @Override + public NewHighlighting newHighlighting() { + return new DefaultHighlighting(sensorStorage); + } + + public List highlightingTypeFor(String componentKey, int charIndex) { + DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey); + if (syntaxHighlightingData == null) { + return Collections.emptyList(); + } + List result = new ArrayList(); + for (SyntaxHighlightingRule sortedRule : syntaxHighlightingData.getSyntaxHighlightingRuleSet()) { + if (sortedRule.getStartPosition() <= charIndex && sortedRule.getEndPosition() > charIndex) { + result.add(sortedRule.getTextType()); + } + } + return result; + } + + @Override + public NewDuplication newDuplication() { + return new DefaultDuplication(sensorStorage); + } + + public Collection duplications() { + return sensorStorage.duplications; + } + + @Override + public NewDependency newDependency() { + return new DefaultDependency(sensorStorage); + } + + public Collection dependencies() { + return sensorStorage.dependencies; + } + + public static class MockAnalysisMode implements AnalysisMode { + private boolean isIncremental = false; + private boolean isPreview = false; + + @Override + public boolean isIncremental() { + return isIncremental; + } + + public void setIncremental(boolean value) { + this.isIncremental = value; + } + + @Override + public boolean isPreview() { + return isPreview; + } + + public void setPreview(boolean value) { + this.isPreview = value; + } + } + + private static class InMemorySensorStorage implements SensorStorage { + + private Map projectMeasuresByMetric = new HashMap<>(); + private Map> measuresByComponentAndMetric = new HashMap<>(); + + private Collection projectIssues = new ArrayList<>(); + private Map> issuesByComponent = new HashMap<>(); + + private Map highlightingByComponent = new HashMap<>(); + + private List duplications = new ArrayList<>(); + private List dependencies = new ArrayList<>(); + + @Override + public void store(Measure measure) { + String key = getKey(measure.inputFile()); + if (key == null) { + projectMeasuresByMetric.put(measure.metric().key(), measure); + } else { + if (!measuresByComponentAndMetric.containsKey(key)) { + measuresByComponentAndMetric.put(key, new HashMap()); + } + measuresByComponentAndMetric.get(key).put(measure.metric().key(), measure); + } + } + + @Override + public void store(Issue issue) { + String key = getKey(issue.inputPath()); + if (key == null) { + projectIssues.add(issue); + } else { + if (!issuesByComponent.containsKey(key)) { + issuesByComponent.put(key, new ArrayList()); + } + issuesByComponent.get(key).add(issue); + } + } + + @Override + public void store(Duplication duplication) { + duplications.add(duplication); + } + + @Override + public void store(Dependency dependency) { + dependencies.add(dependency); + } + + @Override + public void store(DefaultHighlighting highlighting) { + highlightingByComponent.put(getKey(highlighting.inputFile()), highlighting); + } + + @CheckForNull + private String getKey(@Nullable InputPath inputPath) { + if (inputPath == null) { + return null; + } + if (inputPath instanceof InputFile) { + return ((DefaultInputFile) inputPath).key(); + } + if (inputPath instanceof InputDir) { + return ((DefaultInputDir) inputPath).key(); + } + throw new IllegalStateException("Unknow component " + inputPath); + } + + } + +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java new file mode 100644 index 00000000000..090e487ddfe --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java @@ -0,0 +1,158 @@ +package org.sonar.api.batch.sensor.internal; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultInputDir; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.api.config.Settings; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.rule.RuleKey; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SensorContextTesterTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + private SensorContextTester tester; + private File baseDir; + + @Before + public void prepare() throws Exception { + baseDir = temp.newFolder(); + tester = SensorContextTester.create(baseDir); + } + + @Test + public void testSettings() { + Settings settings = new Settings(); + settings.setProperty("foo", "bar"); + tester.setSettings(settings); + assertThat(tester.settings().getString("foo")).isEqualTo("bar"); + } + + @Test + public void testActiveRules() { + ActiveRules activeRules = new ActiveRulesBuilder().create(RuleKey.of("repo", "rule")).activate().build(); + tester.setActiveRules(activeRules); + assertThat(tester.activeRules().findAll()).hasSize(1); + } + + @Test + public void testFs() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); + tester.setFileSystem(fs); + assertThat(tester.fileSystem().baseDir()).isNotEqualTo(baseDir); + } + + @Test + public void testAnalysisMode() { + assertThat(tester.analysisMode().isIncremental()).isFalse(); + assertThat(tester.analysisMode().isPreview()).isFalse(); + tester.analysisMode().setIncremental(true); + assertThat(tester.analysisMode().isIncremental()).isTrue(); + tester.analysisMode().setPreview(true); + assertThat(tester.analysisMode().isPreview()).isTrue(); + } + + @Test + public void testIssues() { + assertThat(tester.issues("foo:src/Foo.java")).isEmpty(); + assertThat(tester.allIssues()).isEmpty(); + tester.newIssue() + .onFile(new DefaultInputFile("foo", "src/Foo.java")) + .forRule(RuleKey.of("repo", "rule")) + .atLine(1) + .save(); + tester.newIssue() + .onFile(new DefaultInputFile("foo", "src/Foo.java")) + .forRule(RuleKey.of("repo", "rule")) + .atLine(3) + .save(); + assertThat(tester.issues("foo:src/Foo.java")).hasSize(2); + assertThat(tester.allIssues()).hasSize(2); + tester.newIssue() + .onDir(new DefaultInputDir("foo", "src")) + .forRule(RuleKey.of("repo", "rule")) + .save(); + assertThat(tester.issues("foo:src")).hasSize(1); + assertThat(tester.allIssues()).hasSize(3); + tester.newIssue() + .onProject() + .forRule(RuleKey.of("repo", "rule")) + .save(); + assertThat(tester.issues(null)).hasSize(1); + assertThat(tester.allIssues()).hasSize(4); + } + + @Test + public void testMeasures() { + assertThat(tester.measures("foo:src/Foo.java")).isEmpty(); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull(); + tester.newMeasure() + .onFile(new DefaultInputFile("foo", "src/Foo.java")) + .forMetric(CoreMetrics.NCLOC) + .withValue(2) + .save(); + assertThat(tester.measures("foo:src/Foo.java")).hasSize(1); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); + tester.newMeasure() + .onFile(new DefaultInputFile("foo", "src/Foo.java")) + .forMetric(CoreMetrics.LINES) + .withValue(4) + .save(); + assertThat(tester.measures("foo:src/Foo.java")).hasSize(2); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); + assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull(); + tester.newMeasure() + .onProject() + .forMetric(CoreMetrics.DIRECTORIES) + .withValue(4) + .save(); + assertThat(tester.measures(null)).hasSize(1); + assertThat(tester.measure(null, "directories")).isNotNull(); + } + + @Test + public void testHighlighting() { + assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 3)).isEmpty(); + tester.newHighlighting() + .onFile(new DefaultInputFile("foo", "src/Foo.java")) + .highlight(0, 4, TypeOfText.ANNOTATION) + .highlight(8, 10, TypeOfText.CONSTANT) + .highlight(9, 10, TypeOfText.COMMENT) + .save(); + assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 3)).containsExactly(TypeOfText.ANNOTATION); + assertThat(tester.highlightingTypeFor("foo:src/Foo.java", 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT); + } + + @Test + public void testDuplication() { + assertThat(tester.duplications()).isEmpty(); + tester.newDuplication() + .originBlock(new DefaultInputFile("foo", "src/Foo.java").setLines(40), 1, 30) + .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo2.java").setLines(40), 3, 33) + .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo3.java").setLines(40), 4, 34) + .save(); + assertThat(tester.duplications()).hasSize(1); + } + + @Test + public void testDependencies() { + assertThat(tester.dependencies()).isEmpty(); + tester.newDependency() + .from(new DefaultInputFile("foo", "src/Foo.java")) + .to(new DefaultInputFile("foo", "src/Foo2.java")) + .weight(3) + .save(); + assertThat(tester.dependencies()).hasSize(1); + } +}