2 * Sonar, open source software quality management tool.
3 * Copyright (C) 2008-2012 SonarSource
4 * mailto:contact AT sonarsource DOT com
6 * Sonar is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * Sonar is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Sonar; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
20 package org.sonar.plugins.core.timemachine;
22 import org.junit.Test;
23 import org.mockito.Matchers;
24 import org.sonar.api.CoreProperties;
25 import org.sonar.api.batch.DecoratorContext;
26 import org.sonar.api.database.model.MeasureModel;
27 import org.sonar.api.measures.*;
28 import org.sonar.api.resources.*;
29 import org.sonar.api.rules.Rule;
30 import org.sonar.api.rules.RulePriority;
31 import org.sonar.batch.components.PastMeasuresLoader;
32 import org.sonar.batch.components.PastSnapshot;
33 import org.sonar.batch.components.TimeMachineConfiguration;
34 import org.sonar.jpa.test.AbstractDbUnitTestCase;
36 import java.util.Arrays;
37 import java.util.Date;
39 import static org.hamcrest.CoreMatchers.is;
40 import static org.hamcrest.MatcherAssert.assertThat;
41 import static org.hamcrest.core.IsNull.nullValue;
42 import static org.mockito.Mockito.*;
44 public class VariationDecoratorTest extends AbstractDbUnitTestCase {
46 public static final int NCLOC_ID = 12;
47 public static final Metric NCLOC = new Metric("ncloc").setId(NCLOC_ID);
49 public static final int COVERAGE_ID = 16;
50 public static final Metric COVERAGE = new Metric("coverage").setId(COVERAGE_ID);
52 public static final int VIOLATIONS_ID = 17;
53 public static final Metric VIOLATIONS = new Metric("violations").setId(VIOLATIONS_ID);
56 public void shouldComputeVariations() {
57 TimeMachineConfiguration conf = mock(TimeMachineConfiguration.class);
58 when(conf.isFileVariationEnabled()).thenReturn(false);
59 VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), conf);
61 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Project("foo")), is(true));
62 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_DATE, new Project("foo")), is(true));
66 public void shouldNotComputeFileVariations() {
67 TimeMachineConfiguration conf = mock(TimeMachineConfiguration.class);
68 when(conf.isFileVariationEnabled()).thenReturn(false);
69 VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), conf);
71 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new JavaFile("org.foo.Bar")), is(false));
72 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_DATE, new JavaFile("org.foo.Bar")), is(false));
73 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new File("org/foo/Bar.php")), is(false));
74 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_DATE, new File("org/foo/Bar.php")), is(false));
78 public void shouldComputeFileVariationsIfExplictlyEnabled() {
79 TimeMachineConfiguration conf = mock(TimeMachineConfiguration.class);
80 when(conf.isFileVariationEnabled()).thenReturn(true);
81 VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), conf);
83 // only for variation with reference analysis
84 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new JavaFile("org.foo.Bar")), is(true));
85 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_DATE, new JavaFile("org.foo.Bar")), is(false));
86 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new File("org/foo/Bar.php")), is(true));
87 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_DATE, new File("org/foo/Bar.php")), is(false));
89 // no side-effect on other resources
90 assertThat(decorator.shouldComputeVariation(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Project("foo")), is(true));
94 public void shouldCompareAndSaveVariation() {
95 Resource javaPackage = new JavaPackage("org.foo");
97 PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
98 PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
99 PastSnapshot pastSnapshot3 = new PastSnapshot("days", new Date()).setIndex(3);
101 // first past analysis
102 when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList(
103 new Object[]{NCLOC_ID, null, null, 180.0},
104 new Object[]{COVERAGE_ID, null, null, 75.0}));
106 // second past analysis
107 when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot3)).thenReturn(Arrays.<Object[]>asList(
108 new Object[]{NCLOC_ID, null, null, 240.0}));
111 DecoratorContext context = mock(DecoratorContext.class);
112 Measure currentNcloc = newMeasure(NCLOC, 200.0);
113 Measure currentCoverage = newMeasure(COVERAGE, 80.0);
114 when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage));
116 VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3), false);
117 decorator.decorate(javaPackage, context);
119 // context updated for each variation : 2 times for ncloc and 1 time for coverage
120 verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
122 assertThat(currentNcloc.getVariation1(), is(20.0));
123 assertThat(currentNcloc.getVariation2(), nullValue());
124 assertThat(currentNcloc.getVariation3(), is(-40.0));
126 assertThat(currentCoverage.getVariation1(), is(5.0));
127 assertThat(currentCoverage.getVariation2(), nullValue());
128 assertThat(currentCoverage.getVariation3(), nullValue());
132 public void shouldComputeVariationOfRuleMeasures() {
133 Rule rule1 = Rule.create();
135 Rule rule2 = Rule.create();
138 Resource javaPackage = new JavaPackage("org.foo");
140 PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class);
141 PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1);
143 // first past analysis
144 when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList(
145 new Object[]{VIOLATIONS_ID, null, null, 180.0},//total
146 new Object[]{VIOLATIONS_ID, null, rule1.getId(), 100.0},// rule 1
147 new Object[]{VIOLATIONS_ID, null, rule2.getId(), 80.0})); // rule 2
150 DecoratorContext context = mock(DecoratorContext.class);
151 Measure violations = newMeasure(VIOLATIONS, 200.0);
152 Measure violationsRule1 = RuleMeasure.createForRule(VIOLATIONS, rule1, 130.0);
153 Measure violationsRule2 = RuleMeasure.createForRule(VIOLATIONS, rule2, 70.0);
154 when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2));
156 VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), false);
157 decorator.decorate(javaPackage, context);
159 // context updated for each variation
160 verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject());
162 assertThat(violations.getVariation1(), is(20.0));
165 private Measure newMeasure(Metric metric, double value) {
166 return new Measure(metric, value);