From: Jean-Baptiste Vilain Date: Mon, 5 Aug 2013 07:11:53 +0000 (+0200) Subject: SONAR-3858 Store NULL as measure value for metrics on new code when code has not... X-Git-Tag: 3.7.1-RC1-~168 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6a7e25cbfc3abbbcd3f70c26862d48ef47cdaf79;p=sonarqube.git SONAR-3858 Store NULL as measure value for metrics on new code when code has not changed --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java index ea51e3ee3e8..126ba4e0098 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java @@ -147,10 +147,17 @@ public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { Measure newUncoveredConditions = new Measure(getNewUncoveredConditionsMetric()); for (PeriodStruct struct : structs) { - newLines.setVariation(struct.index, (double) struct.newLines); - newUncoveredLines.setVariation(struct.index, (double) (struct.newLines - struct.newCoveredLines)); - newConditions.setVariation(struct.index, (double) struct.newConditions); - newUncoveredConditions.setVariation(struct.index, (double) struct.newConditions - struct.newCoveredConditions); + if(struct.hasNewCode()) { + newLines.setVariation(struct.index, (double) struct.getNewLines()); + newUncoveredLines.setVariation(struct.index, (double) (struct.getNewLines() - struct.getNewCoveredLines())); + newConditions.setVariation(struct.index, (double) struct.getNewConditions()); + newUncoveredConditions.setVariation(struct.index, (double) struct.getNewConditions() - struct.getNewCoveredConditions()); + } else { + newLines.setVariation(struct.index, null); + newUncoveredLines.setVariation(struct.index, null); + newConditions.setVariation(struct.index, null); + newUncoveredConditions.setVariation(struct.index, null); + } } context.saveMeasure(newLines); @@ -169,7 +176,10 @@ public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { public static final class PeriodStruct { int index; Date date; - int newLines = 0, newCoveredLines = 0, newConditions = 0, newCoveredConditions = 0; + Integer newLines; + Integer newCoveredLines; + Integer newConditions; + Integer newCoveredConditions; PeriodStruct(PastSnapshot pastSnapshot) { this.index = pastSnapshot.getIndex(); @@ -182,10 +192,10 @@ public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { } void reset() { - newLines = 0; - newCoveredLines = 0; - newConditions = 0; - newCoveredConditions = 0; + newLines = null; + newCoveredLines = null; + newConditions = null; + newCoveredConditions = null; } void analyze(Date lineDate, int hits, int conditions, int coveredConditions) { @@ -200,17 +210,49 @@ public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { } void addLine(boolean covered) { + if(newLines == null) { + newLines = 0; + } newLines += 1; if (covered) { + if(newCoveredLines == null) { + newCoveredLines = 0; + } newCoveredLines += 1; } } void addConditions(int count, int countCovered) { + if(newConditions == null) { + newConditions = 0; + } newConditions += count; if (count > 0) { + if(newCoveredConditions == null) { + newCoveredConditions = 0; + } newCoveredConditions += countCovered; } } + + boolean hasNewCode() { + return newLines != null; + } + + public int getNewLines() { + return newLines != null ? newLines : 0; + } + + public int getNewCoveredLines() { + return newCoveredLines != null ? newCoveredLines : 0; + } + + public int getNewConditions() { + return newConditions != null ? newConditions : 0; + } + + public int getNewCoveredConditions() { + return newCoveredConditions != null ? newCoveredConditions : 0; + } } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java index 665da7d17e5..e49d9525a5a 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java @@ -35,10 +35,7 @@ import java.util.List; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class NewCoverageFileAnalyzerTest { @@ -46,9 +43,9 @@ public class NewCoverageFileAnalyzerTest { public void shouldDoNothingIfNoScmData() throws ParseException { DecoratorContext context = mock(DecoratorContext.class); when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)) - .thenReturn(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=10")); + .thenReturn(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=10")); - AbstractNewCoverageFileAnalyzer decorator = newDecorator(); + NewCoverageFileAnalyzer decorator = newDecorator(); decorator.doDecorate(context); verify(context, never()).saveMeasure(any(Measure.class)); } @@ -57,9 +54,9 @@ public class NewCoverageFileAnalyzerTest { public void shouldDoNothingIfNoCoverageData() throws ParseException { DecoratorContext context = mock(DecoratorContext.class); when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)) - .thenReturn(new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2008-05-18T00:00:00+0000")); + .thenReturn(new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2008-05-18T00:00:00+0000")); - AbstractNewCoverageFileAnalyzer decorator = newDecorator(); + NewCoverageFileAnalyzer decorator = newDecorator(); decorator.doDecorate(context); verify(context, never()).saveMeasure(any(Measure.class)); @@ -69,11 +66,11 @@ public class NewCoverageFileAnalyzerTest { public void shouldGetNewLines() throws ParseException { DecoratorContext context = mock(DecoratorContext.class); when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn( - new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); + new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn( - new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); + new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); - AbstractNewCoverageFileAnalyzer decorator = newDecorator(); + NewCoverageFileAnalyzer decorator = newDecorator(); decorator.doDecorate(context); // line 11 has been updated after date1 (2009-12-25). This line is covered. @@ -81,8 +78,8 @@ public class NewCoverageFileAnalyzerTest { verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, 0.0))); // no line have been updated after date3 (2011-02-18) - verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, 0.0))); - verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, 0.0))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null))); // no data on other periods verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 2, null))); @@ -97,15 +94,15 @@ public class NewCoverageFileAnalyzerTest { public void shouldGetNewConditions() throws ParseException { DecoratorContext context = mock(DecoratorContext.class); when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn( - new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); + new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn( - new Measure(CoreMetrics.CONDITIONS_BY_LINE, "11=4")); + new Measure(CoreMetrics.CONDITIONS_BY_LINE, "11=4")); when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn( - new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "11=1")); + new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "11=1")); when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn( - new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); + new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); - AbstractNewCoverageFileAnalyzer decorator = newDecorator(); + NewCoverageFileAnalyzer decorator = newDecorator(); decorator.doDecorate(context); // line 11 has been updated after date1 (2009-12-25). This line has 1 covered condition amongst 4 @@ -113,8 +110,8 @@ public class NewCoverageFileAnalyzerTest { verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 3.0))); // no line have been updated after date3 (2011-02-18) - verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, 0.0))); - verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, 0.0))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null))); // no data on other periods verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 2, null))); @@ -129,15 +126,15 @@ public class NewCoverageFileAnalyzerTest { public void shouldNotGetNewConditionsWhenNewLineHasNoConditions() throws ParseException { DecoratorContext context = mock(DecoratorContext.class); when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn( - new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); + new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "10=2;11=3")); when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn( - new Measure(CoreMetrics.CONDITIONS_BY_LINE, "10=1")); + new Measure(CoreMetrics.CONDITIONS_BY_LINE, "10=1")); when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn( - new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "10=1")); + new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "10=1")); when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn( - new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); + new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000")); - AbstractNewCoverageFileAnalyzer decorator = newDecorator(); + NewCoverageFileAnalyzer decorator = newDecorator(); decorator.doDecorate(context); // line 11 has been updated after date1 (2009-12-25) but it has no conditions @@ -145,6 +142,36 @@ public class NewCoverageFileAnalyzerTest { verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, 0.0))); } + @Test + public void shouldSetNullValueWhenNothingHasChanged() throws Exception { + String lastCommitDatesByLine = "1=2008-08-02T13:56:37+0200;" + + "2=2008-08-02T13:56:37+0200;" + + "3=2008-08-02T13:56:37+0200;" + + "4=2008-08-02T13:56:37+0200"; + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA)).thenReturn( + new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "2=1;3=1")); + when(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE)).thenReturn( + new Measure(CoreMetrics.CONDITIONS_BY_LINE, "2=1")); + when(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)).thenReturn( + new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "2=1")); + when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn( + new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, lastCommitDatesByLine)); + + NewCoverageFileAnalyzer decorator = newDecorator(); + decorator.doDecorate(context); + + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 1, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 1, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 1, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 1, null))); + + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_LINES_TO_COVER, 3, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_LINES, 3, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_CONDITIONS_TO_COVER, 3, null))); + verify(context).saveMeasure(argThat(new VariationMatcher(CoreMetrics.NEW_UNCOVERED_CONDITIONS, 3, null))); + } static class VariationMatcher extends ArgumentMatcher { Metric metric; @@ -159,10 +186,10 @@ public class NewCoverageFileAnalyzerTest { @Override public boolean matches(Object o) { - Measure m = (Measure)o; + Measure m = (Measure) o; if (m.getMetric().equals(metric)) { - if ((variation==null && m.getVariation(index)==null) || - (variation!=null && variation.equals(m.getVariation(index)))) { + if ((variation == null && m.getVariation(index) == null) || + (variation != null && variation.equals(m.getVariation(index)))) { return true; } } @@ -170,10 +197,10 @@ public class NewCoverageFileAnalyzerTest { } } - private AbstractNewCoverageFileAnalyzer newDecorator() throws ParseException { + private NewCoverageFileAnalyzer newDecorator() throws ParseException { List structs = Arrays.asList( - new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")), - new AbstractNewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18"))); + new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")), + new AbstractNewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18"))); return new NewCoverageFileAnalyzer(structs); } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/drilldown.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/drilldown.rb index 33f74db2482..aed6f4fb4b4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/drilldown.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/drilldown.rb @@ -105,7 +105,7 @@ class DrilldownColumn condition_values[:best_value]=@drilldown.metric.best_value end - if options[:exclude_zero_value] || options[:period] + if options[:exclude_zero_value] || (options[:period] && !@drilldown.metric.on_new_code?) conditions += " AND project_measures.#{value_column}<>0" end