From 5e35883be216144c2ec992b8e9daa60283c66f81 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 1 Feb 2013 11:12:40 +0100 Subject: [PATCH] SONAR-4094 On each source file, provide the ability to list all unit tests covering at least one line of code in this source file --- .../resources/org/sonar/l10n/core.properties | 4 ++- .../org/sonar/core/test/DefaultTestCase.java | 1 - .../org/sonar/core/test/DefaultTestable.java | 10 +++++++ .../sonar/core/test/DefaultTestableTest.java | 25 ++++++++++++++++++ .../java/org/sonar/api/test/Testable.java | 2 ++ .../app/controllers/resource_controller.rb | 26 ++++++++++++------- .../app/views/resource/_options.html.erb | 9 +++++-- .../app/views/test/_testcase_working_view.erb | 2 +- 8 files changed, 64 insertions(+), 15 deletions(-) diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index d92f8379b28..42370f16277 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -1131,7 +1131,9 @@ overall_coverage_viewer.by=by all tests coverage_viewer.unit_tests=Unit Tests coverage_viewer.integration_tests=Integration Tests coverage_viewer.overall_tests=All Tests -lines_covered_per_test=Lines covered per test +coverage_viewer.per_test=Per test +coverage_viewer.lines_covered_per_test=Lines covered +coverage_viewer.select_test=Select a test #------------------------------------------------------------------------------ diff --git a/sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java b/sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java index 1856135585a..5bd1948f3f4 100644 --- a/sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java +++ b/sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java @@ -132,5 +132,4 @@ public class DefaultTestCase extends BeanVertex implements MutableTestCase { }, null); } - } diff --git a/sonar-core/src/main/java/org/sonar/core/test/DefaultTestable.java b/sonar-core/src/main/java/org/sonar/core/test/DefaultTestable.java index c1cd1ee24e3..bf9163710ff 100644 --- a/sonar-core/src/main/java/org/sonar/core/test/DefaultTestable.java +++ b/sonar-core/src/main/java/org/sonar/core/test/DefaultTestable.java @@ -27,6 +27,7 @@ import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Vertex; import org.sonar.api.component.Component; +import org.sonar.api.test.Cover; import org.sonar.api.test.MutableTestable; import org.sonar.api.test.TestCase; import org.sonar.core.component.ComponentVertex; @@ -62,6 +63,7 @@ public class DefaultTestable extends BeanVertex implements MutableTestable { public int countTestCasesOfLine(int line) { int number = 0; +// element().query() // TODO filter on edge for (Edge edge : covers()) { if (Iterables.contains(lines(edge), line)) { @@ -91,6 +93,14 @@ public class DefaultTestable extends BeanVertex implements MutableTestable { return coveredLines.build(); } + public Cover coverOfTestCase(final TestCase testCase) { + return Iterables.find(getEdges(DefaultCover.class, Direction.IN, "covers"), new Predicate() { + public boolean apply(Cover input) { + return input.testCase().key().equals(testCase.key()); + } + }, null); + } + private Iterable covers() { return element().getEdges(Direction.IN, "covers"); } diff --git a/sonar-core/src/test/java/org/sonar/core/test/DefaultTestableTest.java b/sonar-core/src/test/java/org/sonar/core/test/DefaultTestableTest.java index 1d020084041..3a921a2508d 100644 --- a/sonar-core/src/test/java/org/sonar/core/test/DefaultTestableTest.java +++ b/sonar-core/src/test/java/org/sonar/core/test/DefaultTestableTest.java @@ -21,7 +21,10 @@ package org.sonar.core.test; import com.google.common.collect.Iterables; import org.junit.Test; +import org.sonar.api.component.mock.MockSourceFile; import org.sonar.api.test.MutableTestCase; +import org.sonar.core.component.ComponentVertex; +import org.sonar.core.component.ScanGraph; import org.sonar.core.graph.BeanGraph; import java.util.Arrays; @@ -87,4 +90,26 @@ public class DefaultTestableTest { assertThat(testable.testCaseByKey("T2")).isEqualTo(testCase2); assertThat(testable.testCaseByKey("Unknown")).isNull(); } + + @Test + public void should_return_cover_of_testCase(){ + BeanGraph beanGraph = BeanGraph.createInMemory(); + + ScanGraph graph = ScanGraph.create(); + ComponentVertex file1 = graph.addComponent(MockSourceFile.createMain("org.foo.Bar")); + DefaultTestable testable1 = beanGraph.createAdjacentVertex(file1, DefaultTestable.class, "testable"); + + ComponentVertex file2 = graph.addComponent(MockSourceFile.createMain("org.foo.File")); + DefaultTestable testable2 = beanGraph.createAdjacentVertex(file2, DefaultTestable.class, "testable"); + + DefaultTestPlan plan = beanGraph.createVertex(DefaultTestPlan.class); + plan.addTestCase("T1"); + + MutableTestCase testCase = Iterables.get(plan.testCases(), 0); + testCase.setCover(testable1, Arrays.asList(10, 11, 12)); + + assertThat(testable1.coverOfTestCase(testCase).testCase()).isEqualTo(testCase); + assertThat(testable1.coverOfTestCase(testCase).testable()).isEqualTo(testable1); + assertThat(testable2.coverOfTestCase(testCase)).isNull(); + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java b/sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java index 3c33dafec8e..70185cd819d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java @@ -36,4 +36,6 @@ public interface Testable extends Perspective { SortedSet testedLines(); + Cover coverOfTestCase(TestCase testCase); + } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb index 8899163c3b6..76fdd09c203 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb @@ -181,7 +181,9 @@ class ResourceController < ApplicationController @expandable = (@lines!=nil) if @lines metric = Metric.by_key(params[:coverage_filter]||params[:metric]) - @coverage_filter = (metric ? metric.key : 'coverage') + @coverage_filter = params[:coverage_filter] if params[:coverage_filter] == 'lines_covered_per_test' + @coverage_filter = (metric ? metric.key : 'coverage') unless @coverage_filter + @test_case_filter = params[:test_case_filter] if !params[:test_case_filter].blank? it_prefix = '' it_prefix = 'it_' if (@coverage_filter.start_with?('it_') || @coverage_filter.start_with?('new_it_')) @@ -195,8 +197,8 @@ class ResourceController < ApplicationController @hits_by_line.each_pair do |line_id, hits| line = @lines[line_id-1] if line - line.covered_lines = 0 - line.covered_lines = @testable.countTestCasesOfLine(line_id) if @testable + line.index = line_id + line.covered_lines = @testable ? @testable.countTestCasesOfLine(line_id) : 0 line.hits = hits.to_i line.conditions = @conditions_by_line[line_id].to_i line.covered_conditions = @covered_conditions_by_line[line_id].to_i @@ -216,6 +218,7 @@ class ResourceController < ApplicationController to = (@period && @snapshot.period_datetime(@period) ? Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000) : nil) @filtered = true + if ('lines_to_cover'==@coverage_filter || 'coverage'==@coverage_filter || 'line_coverage'==@coverage_filter || 'new_lines_to_cover'==@coverage_filter || 'new_coverage'==@coverage_filter || 'new_line_coverage'==@coverage_filter || 'it_lines_to_cover'==@coverage_filter || 'it_coverage'==@coverage_filter || 'it_line_coverage'==@coverage_filter || @@ -245,13 +248,16 @@ class ResourceController < ApplicationController 'overall_uncovered_conditions'==@coverage_filter || 'new_overall_uncovered_conditions' == @coverage_filter) @coverage_filter="#{it_prefix}uncovered_conditions" filter_lines { |line| line.conditions && line.covered_conditions && line.covered_conditions 'index', :layout => !request.xhr? @@ -440,7 +446,7 @@ class ResourceController < ApplicationController end class Line - attr_accessor :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label, :covered_lines + attr_accessor :index, :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label, :covered_lines def initialize(source) @source=source diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb index ffef6a7b759..f96ca310f91 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb @@ -89,13 +89,18 @@ <% end %> + <% if @testable && !@testable.testCases.empty? %> + + + + <% end %> - <% if @testable && !@testable.testCases.empty? %> + <% if @coverage_filter=='lines_covered_per_test' %>