Skip to content

Commit

Permalink
Adding checks and tests to avoid NaN double metrics.
Browse files Browse the repository at this point in the history
  • Loading branch information
ericlemes committed Feb 1, 2018
1 parent 1d61c38 commit be40c96
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ public void publishMeasureForFile(InputFile inputFile, SourceFile squidFile, Sen

private void publishComplexFunctionMetricsForFile(InputFile inputFile, SourceFile squidFile, SensorContext context){
FunctionCount c = complexFunctionsPerFile.get(squidFile);
if (c == null)
return;
if (c == null){
c = new FunctionCount();
c.countBelowThreshold = 0;
c.countOverThreshold = 0;
}

context.<Integer>newMeasure()
.forMetric(FunctionComplexityMetrics.COMPLEX_FUNCTIONS)
Expand All @@ -143,15 +146,18 @@ private void publishComplexFunctionMetricsForFile(InputFile inputFile, SourceFil
context.<Double>newMeasure()
.forMetric(FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)
.on(inputFile)
.withValue(calculatePercentage((int)c.countOverThreshold, (int)c.countBelowThreshold))
.withValue(calculatePercentual((int)c.countOverThreshold, (int)c.countBelowThreshold))
.save();
}

private void publishLocInComplexFunctionMetricsForFile(InputFile inputFile, SourceFile squidFile, SensorContext context){
FunctionCount locCount = locInComplexFunctionsPerFile.get(squidFile);

if (locCount == null)
return;
if (locCount == null){
locCount = new FunctionCount();
locCount.countBelowThreshold = 0;
locCount.countOverThreshold = 0;
}

context.<Integer>newMeasure()
.forMetric(FunctionComplexityMetrics.LOC_IN_COMPLEX_FUNCTIONS)
Expand All @@ -162,7 +168,7 @@ private void publishLocInComplexFunctionMetricsForFile(InputFile inputFile, Sour
context.<Double>newMeasure()
.forMetric(FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)
.on(inputFile)
.withValue(calculatePercentage((int)locCount.countOverThreshold, (int)locCount.countBelowThreshold))
.withValue(calculatePercentual((int)locCount.countOverThreshold, (int)locCount.countBelowThreshold))
.save();
}

Expand All @@ -182,7 +188,7 @@ private void publishComplexFunctionMetrics(InputModule module, SensorContext con
context.<Double>newMeasure()
.forMetric(FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)
.on(module)
.withValue(calculatePercentage(functionsOverThreshold, functionsBelowThreshold))
.withValue(calculatePercentual(functionsOverThreshold, functionsBelowThreshold))
.save();
}

Expand All @@ -196,12 +202,16 @@ private void publishLinesOfCodeInComplexFunctionMetrics(InputModule module, Sens
context.<Double>newMeasure()
.forMetric(FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)
.on(module)
.withValue(calculatePercentage(linesOfCodeOverThreshold, linesOfCodeBelowThreshold))
.withValue(calculatePercentual(linesOfCodeOverThreshold, linesOfCodeBelowThreshold))
.save();
}

private double calculatePercentage(int overThreshold, int belowThreshold){
return ((float)overThreshold * 100.0) / ((float)overThreshold + (float)belowThreshold);
private double calculatePercentual(int overThreshold, int belowThreshold){
double total = (double)overThreshold + (double)belowThreshold;
if (total > 0)
return ((float)overThreshold * 100.0) / ((float)overThreshold + (float)belowThreshold);
else
return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ public class CxxFunctionSizeSquidSensor extends SquidAstVisitor<Grammar> impleme

public static final String FUNCTION_SIZE_THRESHOLD_KEY = "funcsize.threshold";

private int functionsBelowThreshold;
private int functionsBelowThreshold = 0;

private int sizeThreshold;
private int sizeThreshold = 0;

private int functionsOverThreshold;
private int functionsOverThreshold = 0;

private int locBelowThreshold;
private int locBelowThreshold = 0;

private int locOverThreshold;
private int locOverThreshold = 0;

private Hashtable<SourceFile, FunctionCount> bigFunctionsPerFile = new Hashtable<>();

Expand Down Expand Up @@ -167,13 +167,20 @@ private void publishLocInBigFunctionForProject(InputModule module, SensorContext
}

private double calculatePercentual(int overThreshold, int belowThreshold){
return ((float)overThreshold * 100.0) / ((float)overThreshold + (float)belowThreshold);
double total = (double)overThreshold + (double)belowThreshold;
if (total > 0)
return ((float)overThreshold * 100.0) / ((float)overThreshold + (float)belowThreshold);
else
return 0;
}

private void publishBigFunctionMetrics(InputFile inputFile, SourceFile squidFile, SensorContext context) {
FunctionCount c = bigFunctionsPerFile.get(squidFile);
if (c == null)
return;
if (c == null){
c = new FunctionCount();
c.countBelowThreshold = 0;
c.countOverThreshold = 0;
}

context.<Integer>newMeasure()
.forMetric(FunctionSizeMetrics.BIG_FUNCTIONS)
Expand All @@ -190,8 +197,11 @@ private void publishBigFunctionMetrics(InputFile inputFile, SourceFile squidFile

private void publishLocInBigFunctionMetrics(InputFile inputFile, SourceFile squidFile, SensorContext context) {
FunctionCount c = locInBigFunctionsPerFile.get(squidFile);
if (c == null)
return;
if (c == null) {
c = new FunctionCount();
c.countBelowThreshold = 0;
c.countOverThreshold = 0;
}

context.<Integer>newMeasure()
.forMetric(FunctionSizeMetrics.LOC_IN_FUNCTIONS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ private DefaultInputFile getInputFile() throws IOException{
return inputFile;
}

private DefaultInputFile getEmptyInputFile() throws IOException{
File baseDir = TestUtils.loadResource("/org/sonar/cxx/sensors");
File target = new File(baseDir, "EmptyFile.cc");

String content = new String(Files.readAllBytes(target.toPath()), "UTF-8");
DefaultInputFile inputFile = TestInputFileBuilder.create("ProjectKey", baseDir, target).setContents(content)
.setCharset(Charset.forName("UTF-8")).setLanguage(language.getKey())
.setType(InputFile.Type.MAIN).build();

sensorContext = SensorContextTester.create(baseDir);
sensorContext.fileSystem().add(inputFile);

when(fileLinesContextFactory.createFor(inputFile)).thenReturn(fileLinesContext);

return inputFile;
}

public <T> boolean containsAll(Collection<T> c){
return false;
}
Expand All @@ -109,7 +126,20 @@ public void testPublishMeasuresForProject() throws IOException {
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(44);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)).isEqualTo(40.0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(80);
}
}

@Test
public void testPublishMeasuresForEmptyProject() throws IOException {
DefaultInputFile inputFile = getEmptyInputFile();

CxxAstScanner.scanSingleFile(inputFile, sensorContext, TestUtils.mockCxxLanguage(), sensor.getVisitor());
sensor.publishMeasureForProject(sensorContext.module(), sensorContext);

assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(0);
}

@Test
public void testPublishMeasuresForFile() throws IOException {
Expand All @@ -123,4 +153,17 @@ public void testPublishMeasuresForFile() throws IOException {
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)).isEqualTo(40.0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(80);
}

@Test
public void testPublishMeasuresForEmptyFile() throws IOException {
DefaultInputFile inputFile = getEmptyInputFile();

SourceFile squidFile = CxxAstScanner.scanSingleFile(inputFile, sensorContext, TestUtils.mockCxxLanguage(), sensor.getVisitor());
sensor.publishMeasureForFile(inputFile, squidFile, sensorContext);

assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.PERC_COMPLEX_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionComplexityMetrics.PERC_LOC_IN_COMPLEX_FUNCTIONS)).isEqualTo(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ private DefaultInputFile getInputFile() throws IOException{
return inputFile;
}

private DefaultInputFile getEmptyInputFile() throws IOException{
File baseDir = TestUtils.loadResource("/org/sonar/cxx/sensors");
File target = new File(baseDir, "EmptyFile.cc");

String content = new String(Files.readAllBytes(target.toPath()), "UTF-8");
DefaultInputFile inputFile = TestInputFileBuilder.create("ProjectKey", baseDir, target).setContents(content)
.setCharset(Charset.forName("UTF-8")).setLanguage(language.getKey())
.setType(InputFile.Type.MAIN).build();

sensorContext = SensorContextTester.create(baseDir);
sensorContext.fileSystem().add(inputFile);

when(fileLinesContextFactory.createFor(inputFile)).thenReturn(fileLinesContext);

return inputFile;
}

private <T extends Serializable> T getMeasureValue(SensorContextTester sensorContext, String componentKey, Metric<T> metric){
Collection<Measure> measures = sensorContext.measures(componentKey);
T value = null;
Expand All @@ -106,6 +123,20 @@ public void testPublishMeasuresForProject() throws IOException {
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.PERC_LOC_IN_BIG_FUNCTIONS)).isEqualTo(80);
}

@Test
public void testPublishMeasuresForEmptyProject() throws IOException {
DefaultInputFile inputFile = getEmptyInputFile();

CxxAstScanner.scanSingleFile(inputFile, sensorContext, TestUtils.mockCxxLanguage(), sensor.getVisitor());
sensor.publishMeasureForProject(sensorContext.module(), sensorContext);

assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.LOC_IN_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.LOC_IN_BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.PERC_BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, sensorContext.module().key(), FunctionSizeMetrics.PERC_LOC_IN_BIG_FUNCTIONS)).isEqualTo(0);
}

@Test
public void testPublishMeasuresForFile() throws IOException {
DefaultInputFile inputFile = getInputFile();
Expand All @@ -119,4 +150,18 @@ public void testPublishMeasuresForFile() throws IOException {
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.PERC_BIG_FUNCTIONS)).isEqualTo(40.0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.PERC_LOC_IN_BIG_FUNCTIONS)).isEqualTo(80);
}

@Test
public void testPublishMeasuresForEmptyFile() throws IOException {
DefaultInputFile inputFile = getEmptyInputFile();

SourceFile squidFile = CxxAstScanner.scanSingleFile(inputFile, sensorContext, TestUtils.mockCxxLanguage(), sensor.getVisitor());
sensor.publishMeasureForFile(inputFile, squidFile, sensorContext);

assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.LOC_IN_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.LOC_IN_BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.PERC_BIG_FUNCTIONS)).isEqualTo(0);
assertThat(getMeasureValue(sensorContext, inputFile.key(), FunctionSizeMetrics.PERC_LOC_IN_BIG_FUNCTIONS)).isEqualTo(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit be40c96

Please sign in to comment.