]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2171 Do not compute LCOM4/RFC measures when bytecode is not available
authorsimonbrandhof <simon.brandhof@gmail.com>
Fri, 4 Feb 2011 17:39:49 +0000 (18:39 +0100)
committersimonbrandhof <simon.brandhof@gmail.com>
Fri, 4 Feb 2011 18:08:27 +0000 (19:08 +0100)
plugins/sonar-design-plugin/src/main/java/org/sonar/plugins/design/batch/SuspectLcom4DensityDecorator.java
plugins/sonar-design-plugin/src/test/java/org/sonar/plugins/design/batch/SuspectLcom4DensityDecoratorTest.java

index b627753b364caeb9e0a7039dc3eac95d70ac0bf9..f5f6ccaaa2581c7be1f8d67b8ee7feef8f64f469 100644 (file)
@@ -29,6 +29,7 @@ import org.sonar.api.measures.Metric;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.resources.Scopes;
 
 import java.util.Collection;
 import java.util.List;
@@ -47,10 +48,10 @@ public class SuspectLcom4DensityDecorator implements Decorator {
   public void decorate(Resource resource, DecoratorContext context) {
     if (ResourceUtils.isFile(resource)) {
       // do nothing
-    } else if (ResourceUtils.isDirectory(resource)) {
+    } else if (Scopes.isDirectory(resource)) {
       decorateDirectory(context);
 
-    } else {
+    } else if (Scopes.isProject(resource)) {
       decorateProject(context);
     }
   }
@@ -60,24 +61,29 @@ public class SuspectLcom4DensityDecorator implements Decorator {
     int totalFiles = 0;
 
     List<DecoratorContext> children = context.getChildren();
+    boolean hasLcom4=false;
     for (DecoratorContext child : children) {
       int files = MeasureUtils.getValue(child.getMeasure(CoreMetrics.FILES), 0.0).intValue();
       totalFiles += files;
-      total += MeasureUtils.getValue(child.getMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY), 0.0) * files;
+      Measure childSuspectDensity = child.getMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY);
+      if (childSuspectDensity!=null && childSuspectDensity.getValue()!=null) {
+        hasLcom4=true;
+        total += childSuspectDensity.getValue() * files;
+      }
     }
 
-    if (totalFiles > 0) {
+    if (hasLcom4 && totalFiles > 0) {
       context.saveMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY, (total / totalFiles));
     }
   }
 
   private void decorateDirectory(DecoratorContext context) {
+    Collection<Measure> fileLcoms = context.getChildrenMeasures(CoreMetrics.LCOM4);
     double files = MeasureUtils.getValue(context.getMeasure(CoreMetrics.FILES), 0.0);
-    if (files > 0.0) {
+    if (!fileLcoms.isEmpty() && files>0.0) {
       double suspectFiles = 0.0;
 
       // directory children are files
-      Collection<Measure> fileLcoms = context.getChildrenMeasures(CoreMetrics.LCOM4);
       for (Measure fileLcom : fileLcoms) {
         if (MeasureUtils.getValue(fileLcom, 0.0) > 1.0) {
           suspectFiles++;
index ab60ee41dd95eaf80d96d75a327b67ba418132b0..a668b60746479a2bbdf3678d5389460f51029ce3 100644 (file)
@@ -25,15 +25,18 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.resources.JavaFile;
 import org.sonar.api.resources.JavaPackage;
+import org.sonar.api.resources.Project;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import static org.mockito.Mockito.*;
 
 public class SuspectLcom4DensityDecoratorTest {
 
   @Test
-  public void doNotDecorateFiles() {
+  public void shouldNotDecorateFiles() {
     DecoratorContext context = mock(DecoratorContext.class);
     when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 1.0));
     when(context.getMeasure(CoreMetrics.LCOM4)).thenReturn(newLcom4(3));
@@ -45,7 +48,7 @@ public class SuspectLcom4DensityDecoratorTest {
   }
 
   @Test
-  public void decoratePackages() {
+  public void shouldComputeDensityOnPackages() {
     DecoratorContext context = mock(DecoratorContext.class);
     when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 4.0));
     when(context.getChildrenMeasures(CoreMetrics.LCOM4)).thenReturn(Arrays.asList(newLcom4(1), newLcom4(3), newLcom4(5), newLcom4(1)));
@@ -56,7 +59,42 @@ public class SuspectLcom4DensityDecoratorTest {
     verify(context).saveMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY, 50.0);
   }
 
+  @Test
+  public void shouldConsolidateDensityOnProjects() {
+    List<DecoratorContext> children = Arrays.asList(
+        newContext(3, 20.0),
+        newContext(0, 0.0),
+        newContext(5, 50.0));
+
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getChildren()).thenReturn(children);
+
+    SuspectLcom4DensityDecorator decorator = new SuspectLcom4DensityDecorator();
+    decorator.decorate(new Project("Foo"), context);
+
+    verify(context).saveMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY, (20.0*3 + 50.0*5) / (3.0+5.0));
+  }
+
+  @Test
+  public void doNotComputeDensityWhenLcom4IsMissing() {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 4.0));
+    when(context.getChildrenMeasures(CoreMetrics.LCOM4)).thenReturn(Collections.<Measure>emptyList());
+
+    SuspectLcom4DensityDecorator decorator = new SuspectLcom4DensityDecorator();
+    decorator.decorate(new JavaPackage("org.foo"), context);
+
+    verify(context, never()).saveMeasure(eq(CoreMetrics.SUSPECT_LCOM4_DENSITY), anyDouble());
+  }
+
   private Measure newLcom4(int lcom4) {
-    return new Measure(CoreMetrics.LCOM4, (double)lcom4);
+    return new Measure(CoreMetrics.LCOM4, (double) lcom4);
+  }
+
+  private DecoratorContext newContext(int files, double density) {
+    DecoratorContext context = mock(DecoratorContext.class);
+    when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, (double) files));
+    when(context.getMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY)).thenReturn(new Measure(CoreMetrics.SUSPECT_LCOM4_DENSITY, density));
+    return context;
   }
 }