/*
* SonarQube Java
* Copyright (C) 2012-2016 SonarSource SA
* mailto:contact AT sonarsource DOT 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, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.plugins.surefire;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.api.test.TestCase;
import org.sonar.plugins.java.api.JavaResourceLocator;
import java.io.File;
import java.net.URISyntaxException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class SurefireJavaParserTest {
private ResourcePerspectives perspectives;
private JavaResourceLocator javaResourceLocator;
private SurefireJavaParser parser;
@Before
public void before() {
perspectives = mock(ResourcePerspectives.class);
javaResourceLocator = mock(JavaResourceLocator.class);
when(javaResourceLocator.findResourceByClassName(anyString())).thenAnswer(invocation -> new DefaultInputFile("", (String) invocation.getArguments()[0]));
parser = new SurefireJavaParser(perspectives, javaResourceLocator);
}
@Test
public void should_register_tests() throws URISyntaxException {
SensorContextTester context = SensorContextTester.create(new File(""));
MutableTestCase testCase = mock(MutableTestCase.class);
when(testCase.setDurationInMs(anyLong())).thenReturn(testCase);
when(testCase.setStatus(any(TestCase.Status.class))).thenReturn(testCase);
when(testCase.setMessage(anyString())).thenReturn(testCase);
when(testCase.setStackTrace(anyString())).thenReturn(testCase);
when(testCase.setType(anyString())).thenReturn(testCase);
MutableTestPlan testPlan = mock(MutableTestPlan.class);
when(testPlan.addTestCase(anyString())).thenReturn(testCase);
when(perspectives.as(eq(MutableTestPlan.class), argThat(new ArgumentMatcher<InputFile>() {
@Override
public boolean matches(Object o) {
if(o instanceof InputFile) {
return ":ch.hortis.sonar.mvn.mc.MetricsCollectorRegistryTest".equals(((InputFile) o).key());
}
return false;
}
}))).thenReturn(testPlan);
parser.collect(context, getDir("multipleReports"), true);
verify(testPlan).addTestCase("testGetUnKnownCollector");
verify(testPlan).addTestCase("testGetJDependsCollector");
}
@Test
public void should_store_zero_tests_when_directory_is_null_or_non_existing_or_a_file() throws Exception {
SensorContext context = mock(SensorContext.class);
parser.collect(context, null, false);
verify(context, never()).newMeasure();
context = mock(SensorContext.class);
parser.collect(context, getDir("nonExistingReportsDirectory"), false);
verify(context, never()).newMeasure();
context = mock(SensorContext.class);
parser.collect(context, getDir("file.txt"), true);
verify(context, never()).newMeasure();
}
@Test
public void shouldAggregateReports() throws URISyntaxException {
SensorContextTester context = mockContext();
parser.collect(context, getDir("multipleReports"), true);
assertThat(context.measures(":ch.hortis.sonar.mvn.mc.MetricsCollectorRegistryTest")).hasSize(5);
assertThat(context.measures(":ch.hortis.sonar.mvn.mc.CloverCollectorTest")).hasSize(5);
assertThat(context.measures(":ch.hortis.sonar.mvn.mc.CheckstyleCollectorTest")).hasSize(5);
assertThat(context.measures(":ch.hortis.sonar.mvn.SonarMojoTest")).hasSize(5);
assertThat(context.measures(":ch.hortis.sonar.mvn.mc.JDependsCollectorTest")).hasSize(5);
assertThat(context.measures(":ch.hortis.sonar.mvn.mc.JavaNCSSCollectorTest")).hasSize(5);
}
// SONAR-2841: if there's only a test suite report, then it should be read.
@Test
public void shouldUseTestSuiteReportIfAlone() throws URISyntaxException {
SensorContextTester context = mockContext();
parser.collect(context, getDir("onlyTestSuiteReport"), true);
assertThat(context.measures(":org.sonar.SecondTest")).hasSize(5);
assertThat(context.measures(":org.sonar.JavaNCSSCollectorTest")).hasSize(5);
}
/**
* See http://jira.codehaus.org/browse/SONAR-2371
*/
@Test
public void shouldInsertZeroWhenNoReports() throws URISyntaxException {
SensorContext context = mock(SensorContext.class);
parser.collect(context, getDir("noReports"), true);
verify(context, never()).newMeasure();
}
@Test
public void shouldNotInsertZeroOnFiles() throws URISyntaxException {
SensorContext context = mock(SensorContext.class);
parser.collect(context, getDir("noTests"), true);
verify(context, never()).newMeasure();
}
@Test
public void shouldMergeInnerClasses() throws URISyntaxException {
SensorContextTester context = mockContext();
parser.collect(context, getDir("innerClasses"), true);
assertThat(context.measure(":org.apache.commons.collections.bidimap.AbstractTestBidiMap", CoreMetrics.TESTS).value()).isEqualTo(7);
assertThat(context.measure(":org.apache.commons.collections.bidimap.AbstractTestBidiMap", CoreMetrics.TEST_ERRORS).value()).isEqualTo(1);
assertThat(context.measures(":org.apache.commons.collections.bidimap.AbstractTestBidiMap$TestBidiMapEntrySet")).isEmpty();
}
@Test
public void shouldMergeNestedInnerClasses() throws URISyntaxException {
SensorContextTester context = mockContext();
parser.collect(context, getDir("nestedInnerClasses"), true);
assertThat(context.measure(":org.sonar.plugins.surefire.NestedInnerTest", CoreMetrics.TESTS).value()).isEqualTo(3);
}
@Test
public void should_not_count_negative_tests() throws URISyntaxException {
SensorContextTester context = mockContext();
parser.collect(context, getDir("negativeTestTime"), true);
//Test times : -1.120, 0.644, 0.015 -> computed time : 0.659, ignore negative time.
assertThat(context.measure(":java.Foo", CoreMetrics.SKIPPED_TESTS).value()).isEqualTo(0);
assertThat(context.measure(":java.Foo", CoreMetrics.TESTS).value()).isEqualTo(6);
assertThat(context.measure(":java.Foo", CoreMetrics.TEST_ERRORS).value()).isEqualTo(0);
assertThat(context.measure(":java.Foo", CoreMetrics.TEST_FAILURES).value()).isEqualTo(0);
assertThat(context.measure(":java.Foo", CoreMetrics.TEST_EXECUTION_TIME).value()).isEqualTo(659);
}
private java.io.File getDir(String dirname) throws URISyntaxException {
return new java.io.File("src/test/resources/org/sonar/plugins/surefire/api/SurefireParserTest/" + dirname);
}
private SensorContextTester mockContext() {
return SensorContextTester.create(new File(""));
}
}