From 45bc01601aae433703a475f0d6d6562cc544f23c Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Tue, 3 Apr 2012 12:46:52 +0600 Subject: [PATCH] Add tests for tracking of violations --- .../ViolationTrackingBlocksRecognizer.java | 4 + .../ViolationTrackingDecorator.java | 11 +- .../timemachine/ViolationTrackingTest.java | 153 ++++++++++++++++++ .../ViolationTrackingTest/example1-v1.txt | 12 ++ .../ViolationTrackingTest/example1-v2.txt | 22 +++ .../ViolationTrackingTest/example2-v1.txt | 7 + .../ViolationTrackingTest/example2-v2.txt | 16 ++ 7 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/ViolationTrackingTest.java create mode 100644 plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt create mode 100644 plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt create mode 100644 plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt create mode 100644 plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingBlocksRecognizer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingBlocksRecognizer.java index 5aa12eb2566..ea4c1eee51f 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingBlocksRecognizer.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingBlocksRecognizer.java @@ -40,6 +40,10 @@ public class ViolationTrackingBlocksRecognizer { this.cmp = new HashedSequenceComparator(cmp); } + /** + * @param startA number of line from first version of text (numbering starts from 0) + * @param startB number of line from second version of text (numbering starts from 0) + */ public int computeLengthOfMaximalBlock(int startA, int startB) { if (!cmp.equals(a, startA, b, startB)) { return 0; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingDecorator.java index a01d02f6a3e..c4fbea8db04 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationTrackingDecorator.java @@ -30,6 +30,8 @@ import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; import org.sonar.api.violations.ViolationQuery; +import javax.annotation.Nullable; + import java.util.*; @DependsUpon({DecoratorBarriers.END_OF_VIOLATIONS_GENERATION, DecoratorBarriers.START_VIOLATION_TRACKING}) @@ -96,7 +98,11 @@ public class ViolationTrackingDecorator implements Decorator { return mapViolations(newViolations, pastViolations, null); } - private Map mapViolations(List newViolations, List pastViolations, ViolationTrackingBlocksRecognizer rec) { + /** + * @param rec null, if source code not available + */ + @VisibleForTesting + Map mapViolations(List newViolations, List pastViolations, @Nullable ViolationTrackingBlocksRecognizer rec) { Multimap pastViolationsByRule = LinkedHashMultimap.create(); for (RuleFailureModel pastViolation : pastViolations) { pastViolationsByRule.put(pastViolation.getRuleId(), pastViolation); @@ -109,7 +115,7 @@ public class ViolationTrackingDecorator implements Decorator { pastViolationsByRule, referenceViolationsMap); } - // Try first to match violations on same rule with same line and with same checkum (but not necessarily with same message) + // Try first to match violations on same rule with same line and with same checksum (but not necessarily with same message) for (Violation newViolation : newViolations) { if (isNotAlreadyMapped(newViolation, referenceViolationsMap)) { mapViolation(newViolation, @@ -120,7 +126,6 @@ public class ViolationTrackingDecorator implements Decorator { // If each new violation matches an old one we can stop the matching mechanism if (referenceViolationsMap.size() != newViolations.size()) { - // FIXME Godin: this condition just in order to bypass test if (rec != null) { // SONAR-3072 diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/ViolationTrackingTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/ViolationTrackingTest.java new file mode 100644 index 00000000000..d2b4a44c891 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/ViolationTrackingTest.java @@ -0,0 +1,153 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.timemachine; + +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.database.model.RuleFailureModel; +import org.sonar.api.resources.Project; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.Violation; +import org.sonar.api.utils.DateUtils; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; +import java.util.Map; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ViolationTrackingTest { + + private final Date analysisDate = DateUtils.parseDate("2010-12-25"); + + private ViolationTrackingDecorator decorator; + + @Before + public void setUp() { + Project project = mock(Project.class); + when(project.getAnalysisDate()).thenReturn(analysisDate); + decorator = new ViolationTrackingDecorator(project, null, null); + } + + /** + * SONAR-2928 + */ + @Test + public void violationNotAssociatedWithLine() throws Exception { + ViolationTrackingBlocksRecognizer rec = newRec("example2"); + + RuleFailureModel referenceViolation1 = newReferenceViolation("2 branches need to be covered", null, 50); + + Violation newViolation1 = newViolation("1 branch need to be covered", null, 50); + + Map mapping = decorator.mapViolations( + Arrays.asList(newViolation1), + Arrays.asList(referenceViolation1), + rec); + + assertThat(newViolation1.isNew(), is(false)); + assertThat(mapping.get(newViolation1), equalTo(referenceViolation1)); + } + + /** + * SONAR-3072 + */ + @Test + public void example1() throws Exception { + ViolationTrackingBlocksRecognizer rec = newRec("example1"); + + RuleFailureModel referenceViolation1 = newReferenceViolation("Indentation", 7, 50); + RuleFailureModel referenceViolation2 = newReferenceViolation("Indentation", 11, 50); + + Violation newViolation1 = newViolation("Indentation", 9, 50); + Violation newViolation2 = newViolation("Indentation", 13, 50); + Violation newViolation3 = newViolation("Indentation", 17, 50); + Violation newViolation4 = newViolation("Indentation", 21, 50); + + Map mapping = decorator.mapViolations( + Arrays.asList(newViolation1, newViolation2, newViolation3, newViolation4), + Arrays.asList(referenceViolation1, referenceViolation2), + rec); + + assertThat(newViolation1.isNew(), is(true)); + assertThat(newViolation2.isNew(), is(true)); + assertThat(newViolation3.isNew(), is(false)); + assertThat(mapping.get(newViolation3), equalTo(referenceViolation1)); + assertThat(newViolation4.isNew(), is(false)); + assertThat(mapping.get(newViolation4), equalTo(referenceViolation2)); + } + + /** + * SONAR-3072 + */ + @Test + public void example2() throws Exception { + ViolationTrackingBlocksRecognizer rec = newRec("example2"); + + RuleFailureModel referenceViolation1 = newReferenceViolation("SystemPrintln", 5, 50); + + Violation newViolation1 = newViolation("SystemPrintln", 6, 50); + Violation newViolation2 = newViolation("SystemPrintln", 10, 50); + Violation newViolation3 = newViolation("SystemPrintln", 14, 50); + + Map mapping = decorator.mapViolations( + Arrays.asList(newViolation1, newViolation2, newViolation3), + Arrays.asList(referenceViolation1), + rec); + + assertThat(newViolation1.isNew(), is(true)); + assertThat(newViolation2.isNew(), is(false)); + assertThat(mapping.get(newViolation2), equalTo(referenceViolation1)); + assertThat(newViolation3.isNew(), is(true)); + } + + private Violation newViolation(String message, Integer lineId, int ruleId) { + Rule rule = Rule.create().setKey("rule"); + rule.setId(ruleId); + return Violation.create(rule, null).setLineId(lineId).setMessage(message); + } + + private RuleFailureModel newReferenceViolation(String message, Integer lineId, int ruleId) { + RuleFailureModel referenceViolation = new RuleFailureModel(); + referenceViolation.setId(violationId++); + referenceViolation.setLine(lineId); + referenceViolation.setMessage(message); + referenceViolation.setRuleId(ruleId); + return referenceViolation; + } + + private int violationId = 0; + + private static ViolationTrackingBlocksRecognizer newRec(String name) throws IOException { + return new ViolationTrackingBlocksRecognizer(load(name + "-v1"), load(name + "-v2")); + } + + private static String load(String name) throws IOException { + return Resources.toString(ViolationTrackingTest.class.getResource("ViolationTrackingTest/" + name + ".txt"), Charsets.UTF_8); + } + +} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt new file mode 100644 index 00000000000..1920333ddb6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v1.txt @@ -0,0 +1,12 @@ +package example1; + +public class Toto { + + public void doSomething() { + // doSomething + } + + public void doSomethingElse() { + // doSomethingElse + } +} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt new file mode 100644 index 00000000000..231532452b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example1-v2.txt @@ -0,0 +1,22 @@ +package example1; + +public class Toto { + + public Toto(){} + + public void doSomethingNew() { + // doSomethingNew + } + + public void doSomethingElseNew() { + // doSomethingElseNew + } + + public void doSomething() { + // doSomething + } + + public void doSomethingElse() { + // doSomethingElse + } +} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt new file mode 100644 index 00000000000..a920afe459b --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v1.txt @@ -0,0 +1,7 @@ +package example2; + +public class Toto { + void method1() { + System.out.println("toto"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt new file mode 100644 index 00000000000..c5c8250cf65 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/ViolationTrackingTest/example2-v2.txt @@ -0,0 +1,16 @@ +package example2; + +public class Toto { + + void method2() { + System.out.println("toto"); + } + + void method1() { + System.out.println("toto"); + } + + void method3() { + System.out.println("toto"); + } +} -- 2.39.5