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;
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);
}
}
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++;
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));
}
@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)));
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;
}
}