]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4093 Display number of tests covering a line
authorJulien Lancelot <julien.lancelot@gmail.com>
Tue, 29 Jan 2013 14:56:43 +0000 (15:56 +0100)
committerJulien Lancelot <julien.lancelot@gmail.com>
Tue, 29 Jan 2013 14:56:43 +0000 (15:56 +0100)
sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java
sonar-core/src/main/java/org/sonar/core/test/DefaultTestable.java
sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java
sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb

index 23e2789d4ffc08ec44ecfa87c47b91085114a82b..07590798d3a82cd64def787a0cfaf674162aa28c 100644 (file)
@@ -24,8 +24,6 @@ import com.google.common.collect.Iterables;
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Vertex;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.sonar.api.test.CoveredTestable;
 import org.sonar.api.test.MutableTestCase;
 import org.sonar.api.test.TestPlan;
@@ -40,8 +38,6 @@ import java.util.List;
 
 public class DefaultTestCase extends BeanVertex implements MutableTestCase {
 
-  private static final Logger LOG = LoggerFactory.getLogger(DefaultTestCase.class);
-
   public String type() {
     return (String) getProperty("type");
   }
@@ -105,8 +101,6 @@ public class DefaultTestCase extends BeanVertex implements MutableTestCase {
   }
 
   public void covers(Testable testable, List<Integer> lines) {
-    LOG.info("Covers : " + testable.component().key(), " on "+ lines);
-
     Vertex componentVertex = GraphUtil.single(beanGraph().getUnderlyingGraph().getVertices("key", testable.component().key()));
     beanGraph().getUnderlyingGraph().addEdge(null, element(), componentVertex, "covers").setProperty("lines", lines);
   }
@@ -132,4 +126,27 @@ public class DefaultTestCase extends BeanVertex implements MutableTestCase {
   public Collection<CoveredTestable> coveredTestable() {
     return null;
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    DefaultTestCase that = (DefaultTestCase) o;
+
+    if (key() != null ? !key().equals(that.key()) : that.key() != null) {
+      return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return key() != null ? key().hashCode() : 0;
+  }
 }
index d2e72ae271cc42d425cec7d7961600e6bd59f781..debd0d4aa543aa580b85ec0d04bdd12877a78115 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.core.test;
 
+import com.google.common.collect.Iterables;
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Vertex;
@@ -29,9 +30,13 @@ import org.sonar.core.component.ComponentVertex;
 import org.sonar.core.graph.BeanVertex;
 import org.sonar.core.graph.GraphUtil;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.SortedSet;
 
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Sets.newHashSet;
 import static com.google.common.collect.Sets.newTreeSet;
 
 public class DefaultTestable extends BeanVertex implements MutableTestable {
@@ -41,12 +46,24 @@ public class DefaultTestable extends BeanVertex implements MutableTestable {
     return beanGraph().wrap(component, ComponentVertex.class);
   }
 
-  public List<TestCase> coveringTestCases() {
-    return null;
+  public Collection<TestCase> coveringTestCases() {
+    List<TestCase> testCases = newArrayList();
+    for (Edge edge : element().getEdges(Direction.IN, "covers")){
+      Vertex testable = edge.getVertex(Direction.OUT);
+      testCases.add(beanGraph().wrap(testable, DefaultTestCase.class));
+    }
+    return testCases;
   }
 
-  public List<TestCase> testCasesCoveringLine(int line) {
-    return null;
+  public Collection<TestCase> testCasesCoveringLine(int line) {
+    Set<TestCase> testCases = newHashSet();
+    for (Edge edge : element().getEdges(Direction.IN, "covers")){
+      if (Iterables.contains( (List<Integer>) edge.getProperty("lines"), line)){
+        Vertex testable = edge.getVertex(Direction.OUT);
+        testCases.add(beanGraph().wrap(testable, DefaultTestCase.class));
+      }
+    }
+    return testCases;
   }
 
   public SortedSet<Integer> coveredLines() {
index 83907024e1e8e36936af048f6917b9cba0b9c525..f2c46189a1590db05efce116cef8192ce7906359 100644 (file)
@@ -21,14 +21,14 @@ package org.sonar.api.test;
 
 import org.sonar.api.component.Perspective;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.SortedSet;
 
 public interface Testable extends Perspective {
 
-  List<TestCase> coveringTestCases();
+  Collection<TestCase> coveringTestCases();
 
-  List<TestCase> testCasesCoveringLine(int line);
+  Collection<TestCase> testCasesCoveringLine(int line);
 
   SortedSet<Integer> coveredLines();
 
index 99edfc505a1da7b5611260846001cda0f2cd07ed..5127fe218a8df25aa3e7ca35871d74a98fffe535 100644 (file)
@@ -37,7 +37,9 @@ import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.api.rules.RuleRepository;
 import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.MutableTestable;
 import org.sonar.api.test.TestPlan;
+import org.sonar.api.test.Testable;
 import org.sonar.api.utils.ValidationMessages;
 import org.sonar.api.web.Footer;
 import org.sonar.api.web.NavigationSection;
@@ -546,4 +548,8 @@ public final class JRubyFacade {
     return get(SnapshotPerspectives.class).as(MutableTestPlan.class, snapshotId);
   }
 
+  public Testable getTestable(long snapshotId) {
+    return get(SnapshotPerspectives.class).as(MutableTestable.class, snapshotId);
+  }
+
 }
index 6a78bb2c82857acafec1fe98ccbbe5c07aa462c2..3d5b5e2ee1f89c6d3741a0f368641bddafbb850d 100644 (file)
@@ -191,9 +191,11 @@ class ResourceController < ApplicationController
       @conditions_by_line = load_distribution("#{it_prefix}conditions_by_line")
       @covered_conditions_by_line = load_distribution("#{it_prefix}covered_conditions_by_line")
 
+      testable = java_facade.getTestable(@snapshot.id)
       @hits_by_line.each_pair do |line_id, hits|
         line = @lines[line_id-1]
         if line
+          line.covered_lines = testable.testCasesCoveringLine(line_id).size if testable && testable.testCasesCoveringLine(line_id).size > 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
@@ -431,7 +433,7 @@ class ResourceController < ApplicationController
   end
 
   class Line
-    attr_accessor :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label
+    attr_accessor :source, :revision, :author, :datetime, :violations, :hits, :conditions, :covered_conditions, :hidden, :highlighted, :deprecated_conditions_label, :covered_lines
 
     def initialize(source)
       @source=source
index 1f452a265e91bb9f210d1a1a5e74bb27a0860a83..c4366994cb4996e38dd94b2a81f78b6e5dbd4761 100644 (file)
@@ -99,7 +99,7 @@
 
         <% if @display_coverage %>
           <% if line.highlighted? %>
-            <td class="ind <%= hits_status -%>"><%= line.hits -%></td>
+            <td class="ind <%= hits_status -%>"><%= line.covered_lines if line.covered_lines -%></td>
             <td class="ind <%= conditions_status -%>">
               <% if line.deprecated_conditions_label -%>
                 <%= line.deprecated_conditions_label -%>