/* * qualinsight-plugins-sonarqube-smell * Copyright (c) 2015, QualInsight * http://www.qualinsight.com/ * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, you can retrieve a copy * from <http://www.gnu.org/licenses/>. */ package com.qualinsight.plugins.sonarqube.smell.plugin.extension; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.Serializable; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.measures.Metric; import com.qualinsight.plugins.sonarqube.smell.api.model.SmellType; @RunWith(MockitoJUnitRunner.class) public class SmellMeasurerTest { private static final Integer EXPECTED_SMELL_TYPE_COUNT = SmellType.values().length; private static final Integer EXPECTED_DEBT_PER_SMELL_TYPE = 10; private static final Integer EXPECTED_SMELL_TYPE_DEBT = EXPECTED_SMELL_TYPE_COUNT * EXPECTED_DEBT_PER_SMELL_TYPE; @Mock InputFile inputFile; @Mock SensorContext sensorContext; @Mock NewMeasure<Serializable> measure; @Test public void measure_with_annotatedFile_should_saveExpectedMeasures() { Mockito.when(this.inputFile.file()) .thenReturn(new File("src/test/resources/SmellMeasurerTest_1.java")); Mockito.when(this.sensorContext.newMeasure()) .thenReturn(this.measure); Mockito.when(this.measure.forMetric(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.withValue(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.on(Mockito.any())) .thenReturn(this.measure); final SmellMeasurer sut = new SmellMeasurer(this.sensorContext); sut.measure(this.inputFile); final ArgumentCaptor<Metric> metricCaptor = ArgumentCaptor.forClass(Metric.class); final ArgumentCaptor<Serializable> valueCaptor = ArgumentCaptor.forClass(Serializable.class); // 2 because of : SMELL_COUNT, SMELL_DEBT Mockito.verify(this.sensorContext, Mockito.times(2 + SmellType.values().length)) .newMeasure(); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .save(); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .forMetric(metricCaptor.capture()); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .withValue(valueCaptor.capture()); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .on(Mockito.any()); final List<Metric> capturedMetrics = metricCaptor.getAllValues(); final List<Serializable> capturedValues = valueCaptor.getAllValues(); int i = 0; while (i < EXPECTED_SMELL_TYPE_COUNT) { assertEquals(Integer.valueOf(1), capturedValues.get(i++)); } assertEquals(SmellMetrics.SMELL_COUNT, capturedMetrics.get(i)); assertEquals(Integer.valueOf(EXPECTED_SMELL_TYPE_COUNT), capturedValues.get(i++)); assertEquals(SmellMetrics.SMELL_DEBT, capturedMetrics.get(i)); assertEquals(Long.valueOf(EXPECTED_SMELL_TYPE_DEBT), capturedValues.get(i++)); Mockito.verifyNoMoreInteractions(this.sensorContext); } @Test public void measure_with_nonAnnotatedFile_should_not_saveAnyMeasure() { Mockito.when(this.inputFile.file()) .thenReturn(new File("src/test/resources/SmellMeasurerTest_2.java")); Mockito.when(this.sensorContext.newMeasure()) .thenReturn(this.measure); Mockito.when(this.measure.forMetric(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.withValue(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.on(Mockito.any())) .thenReturn(this.measure); final SmellMeasurer sut = new SmellMeasurer(this.sensorContext); sut.measure(this.inputFile); final ArgumentCaptor<Serializable> valueCaptor = ArgumentCaptor.forClass(Serializable.class); // 2 because of : SMELL_COUNT, SMELL_DEBT Mockito.verify(this.sensorContext, Mockito.times(2)) .newMeasure(); Mockito.verify(this.measure, Mockito.times(2)) .save(); Mockito.verify(this.measure, Mockito.times(2)) .forMetric(Mockito.any()); Mockito.verify(this.measure, Mockito.times(2)) .withValue(valueCaptor.capture()); Mockito.verify(this.measure, Mockito.times(2)) .on(Mockito.any()); final List<Serializable> capturedValues = valueCaptor.getAllValues(); int i = 0; assertEquals(Integer.valueOf(0), capturedValues.get(i++)); assertEquals(Long.valueOf(0), capturedValues.get(i++)); Mockito.verifyNoMoreInteractions(this.sensorContext); } @Test public void measure_with_annotatedFile_should_saveExpectedMeasuresAfterHavingRegroupedThemBySmellType() { Mockito.when(this.inputFile.file()) .thenReturn(new File("src/test/resources/SmellMeasurerTest_3.java")); Mockito.when(this.sensorContext.newMeasure()) .thenReturn(this.measure); Mockito.when(this.measure.forMetric(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.withValue(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.on(Mockito.any())) .thenReturn(this.measure); final SmellMeasurer sut = new SmellMeasurer(this.sensorContext); sut.measure(this.inputFile); final ArgumentCaptor<Serializable> valueCaptor = ArgumentCaptor.forClass(Serializable.class); Mockito.verify(this.sensorContext, Mockito.times(3)) .newMeasure(); Mockito.verify(this.measure, Mockito.times(3)) .save(); Mockito.verify(this.measure, Mockito.times(3)) .forMetric(Mockito.any()); Mockito.verify(this.measure, Mockito.times(3)) .withValue(valueCaptor.capture()); Mockito.verify(this.measure, Mockito.times(3)) .on(Mockito.any()); final List<Serializable> capturedValues = valueCaptor.getAllValues(); int i = 0; assertEquals(Integer.valueOf(3), capturedValues.get(i++)); assertEquals(Integer.valueOf(3), capturedValues.get(i++)); assertEquals(Long.valueOf(30), capturedValues.get(i++)); Mockito.verifyNoMoreInteractions(this.sensorContext); } @Test public void measure_with_annotatedFile_should_saveExpectedMeasuresAfterHavingDetectedAllPossibleAnnotations() { Mockito.when(this.inputFile.file()) .thenReturn(new File("src/test/resources/SmellMeasurerTest_4.java")); Mockito.when(this.sensorContext.newMeasure()) .thenReturn(this.measure); Mockito.when(this.measure.forMetric(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.withValue(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.on(Mockito.any())) .thenReturn(this.measure); final SmellMeasurer sut = new SmellMeasurer(this.sensorContext); sut.measure(this.inputFile); // 1 different metric should be saved 1 time but counted as 8 final ArgumentCaptor<Serializable> valueCaptor = ArgumentCaptor.forClass(Serializable.class); // 2 because of : SMELL_COUNT, SMELL_DEBT Mockito.verify(this.sensorContext, Mockito.times(3)) .newMeasure(); Mockito.verify(this.measure, Mockito.times(3)) .save(); Mockito.verify(this.measure, Mockito.times(3)) .forMetric(Mockito.any()); Mockito.verify(this.measure, Mockito.times(3)) .withValue(valueCaptor.capture()); Mockito.verify(this.measure, Mockito.times(3)) .on(Mockito.any()); final List<Serializable> capturedValues = valueCaptor.getAllValues(); int i = 0; assertEquals(Integer.valueOf(8), capturedValues.get(i++)); assertEquals(Integer.valueOf(8), capturedValues.get(i++)); assertEquals(Long.valueOf(80), capturedValues.get(i++)); Mockito.verifyNoMoreInteractions(this.sensorContext); } @Test public void measure_with_annotatedFile_should_saveExpectedMeasuresThatHaveLineBreaksInAnnotations() { Mockito.when(this.inputFile.file()) .thenReturn(new File("src/test/resources/SmellMeasurerTest_5.java")); Mockito.when(this.sensorContext.newMeasure()) .thenReturn(this.measure); Mockito.when(this.measure.forMetric(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.withValue(Mockito.any())) .thenReturn(this.measure); Mockito.when(this.measure.on(Mockito.any())) .thenReturn(this.measure); final SmellMeasurer sut = new SmellMeasurer(this.sensorContext); sut.measure(this.inputFile); // different metrics should be saved, one for each SmellType final ArgumentCaptor<Metric> metricCaptor = ArgumentCaptor.forClass(Metric.class); final ArgumentCaptor<Serializable> valueCaptor = ArgumentCaptor.forClass(Serializable.class); // 2 because of : SMELL_COUNT, SMELL_DEBT Mockito.verify(this.sensorContext, Mockito.times(2 + SmellType.values().length)) .newMeasure(); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .save(); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .forMetric(metricCaptor.capture()); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .withValue(valueCaptor.capture()); Mockito.verify(this.measure, Mockito.times(2 + SmellType.values().length)) .on(Mockito.any()); final List<Metric> capturedMetrics = metricCaptor.getAllValues(); final List<Serializable> capturedValues = valueCaptor.getAllValues(); int i = 0; while (i < EXPECTED_SMELL_TYPE_COUNT) { assertEquals(Integer.valueOf(1), capturedValues.get(i++)); } assertEquals(SmellMetrics.SMELL_COUNT, capturedMetrics.get(i)); assertEquals(Integer.valueOf(EXPECTED_SMELL_TYPE_COUNT), capturedValues.get(i++)); assertEquals(SmellMetrics.SMELL_DEBT, capturedMetrics.get(i)); assertEquals(Long.valueOf(EXPECTED_SMELL_TYPE_DEBT), capturedValues.get(i++)); Mockito.verifyNoMoreInteractions(this.sensorContext); } }