diff --git a/pom.xml b/pom.xml
index 920a44b0eb..1dd6905195 100644
--- a/pom.xml
+++ b/pom.xml
@@ -185,7 +185,12 @@
sslr-squid-bridge
2.4
-
+
+ org.codehaus.sonar.dotnet.tests
+ sonar-dotnet-tests-library
+ 1.1.2
+
+
junit
junit
diff --git a/sonar-cxx-plugin/pom.xml b/sonar-cxx-plugin/pom.xml
index d5dd97c07f..33231b924e 100644
--- a/sonar-cxx-plugin/pom.xml
+++ b/sonar-cxx-plugin/pom.xml
@@ -27,6 +27,11 @@
sonar-plugin-api
provided
+
+ org.codehaus.sonar.dotnet.tests
+ sonar-dotnet-tests-library
+
+
${project.groupId}
cxx-squid
diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java
index 3432dbe55c..cc3d45f4d7 100644
--- a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java
+++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java
@@ -46,6 +46,9 @@
import org.sonar.plugins.cxx.veraxx.CxxVeraxxRuleRepository;
import org.sonar.plugins.cxx.veraxx.CxxVeraxxSensor;
import org.sonar.plugins.cxx.xunit.CxxXunitSensor;
+import org.sonar.plugins.cxx.xunit.MSTestResultsProvider;
+import org.sonar.plugins.cxx.xunit.MSTestResultsProvider.MSTestResultsAggregator;
+import org.sonar.plugins.cxx.xunit.MSTestResultsProvider.MSTestResultsImportSensor;
import org.sonar.plugins.cxx.utils.CxxMetrics;
import com.google.common.collect.ImmutableList;
@@ -377,6 +380,14 @@ private static List testingAndCoverageProperties() {
.onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE)
.type(PropertyType.BOOLEAN)
.index(7)
+ .build(),
+
+ PropertyDefinition.builder(MSTestResultsProvider.VISUAL_STUDIO_TEST_RESULTS_PROPERTY_KEY)
+ .name("Visual Studio Test Reports Paths")
+ .description("Example: \"report.trx\", \"report1.trx,report2.trx\" or \"C:/report.trx\"")
+ .subCategory(subcateg)
+ .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE)
+ .index(8)
.build()
);
}
@@ -412,6 +423,8 @@ public List getExtensions() {
l.add(CxxExternalRulesSensor.class);
l.add(CxxExternalRuleRepository.class);
l.add(CxxRuleRepository.class);
+ l.add(MSTestResultsAggregator.class);
+ l.add(MSTestResultsImportSensor.class);
l.addAll(generalProperties());
l.addAll(codeAnalysisProperties());
diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/xunit/MSTestResultsProvider.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/xunit/MSTestResultsProvider.java
new file mode 100644
index 0000000000..da8e372a3f
--- /dev/null
+++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/xunit/MSTestResultsProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Sonar C++ Plugin (Community)
+ * Copyright (C) 2010 Neticoa SAS France
+ * dev@sonar.codehaus.org
+ *
+ * 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 02
+ */
+package org.sonar.plugins.cxx.xunit;
+
+import org.sonar.api.config.Settings;
+import org.sonar.plugins.dotnet.tests.UnitTestConfiguration;
+import org.sonar.plugins.dotnet.tests.UnitTestResultsAggregator;
+import org.sonar.plugins.dotnet.tests.UnitTestResultsImportSensor;
+
+public class MSTestResultsProvider {
+
+ public static final String VISUAL_STUDIO_TEST_RESULTS_PROPERTY_KEY = "sonar.cxx.vstest.reportsPaths";
+ private static final UnitTestConfiguration UNIT_TEST_CONF = new UnitTestConfiguration(VISUAL_STUDIO_TEST_RESULTS_PROPERTY_KEY);
+
+ private MSTestResultsProvider() {
+ }
+
+ public static class MSTestResultsAggregator extends UnitTestResultsAggregator {
+
+ public MSTestResultsAggregator(Settings settings) {
+ super(UNIT_TEST_CONF, settings);
+ }
+
+ }
+
+ public static class MSTestResultsImportSensor extends UnitTestResultsImportSensor {
+
+ public MSTestResultsImportSensor(MSTestResultsAggregator unitTestResultsAggregator) {
+ super(unitTestResultsAggregator);
+ }
+
+ }
+}
diff --git a/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/CxxPluginTest.java b/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/CxxPluginTest.java
index 84a7463f7b..575791299c 100644
--- a/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/CxxPluginTest.java
+++ b/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/CxxPluginTest.java
@@ -27,6 +27,6 @@ public class CxxPluginTest {
@Test
public void testGetExtensions() throws Exception {
CxxPlugin plugin = new CxxPlugin();
- assertEquals(58, plugin.getExtensions().size());
+ assertEquals(61, plugin.getExtensions().size());
}
}
diff --git a/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/xunit/MSTestResultsProviderTest.java b/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/xunit/MSTestResultsProviderTest.java
new file mode 100644
index 0000000000..6658066acc
--- /dev/null
+++ b/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/xunit/MSTestResultsProviderTest.java
@@ -0,0 +1,103 @@
+/*
+ * Sonar C++ Plugin (Community)
+ * Copyright (C) 2010 Neticoa SAS France
+ * dev@sonar.codehaus.org
+ *
+ * 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 02
+ */
+package org.sonar.plugins.cxx.xunit;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.plugins.cxx.TestUtils;
+import org.sonar.plugins.cxx.xunit.MSTestResultsProvider.MSTestResultsAggregator;
+import org.sonar.plugins.cxx.xunit.MSTestResultsProvider.MSTestResultsImportSensor;
+import org.sonar.plugins.dotnet.tests.UnitTestResults;
+import org.sonar.plugins.dotnet.tests.UnitTestResultsImportSensor;
+
+import com.google.common.collect.ImmutableList;
+
+public class MSTestResultsProviderTest {
+ private Project project;
+ private SensorContext context;
+ private MSTestResultsAggregator resultsAggregator;
+ private MSTestResultsImportSensor sensor;
+
+ @Before
+ public void setUp() {
+ new DefaultFileSystem();
+ project = TestUtils.mockProject();
+ context = mock(SensorContext.class);
+ File resourceMock = mock(File.class);
+ when(context.getResource((File) anyObject())).thenReturn(resourceMock);
+ }
+
+ @Test
+ public void should_execute_on_project() {
+
+ resultsAggregator = mock(MSTestResultsAggregator.class);
+
+ when(resultsAggregator.hasUnitTestResultsProperty()).thenReturn(true);
+ assertThat(new UnitTestResultsImportSensor(resultsAggregator).shouldExecuteOnProject(project)).isTrue();
+
+ when(resultsAggregator.hasUnitTestResultsProperty()).thenReturn(false);
+ assertThat(new UnitTestResultsImportSensor(resultsAggregator).shouldExecuteOnProject(project)).isFalse();
+ }
+
+ @Test
+ public void should_not_analyze_on_reactor_project() {
+ when(project.isRoot()).thenReturn(true);
+ when(project.getModules()).thenReturn(ImmutableList.of(mock(Project.class)));
+
+ resultsAggregator = mock(MSTestResultsAggregator.class);
+ sensor = new MSTestResultsImportSensor(resultsAggregator);
+ sensor.analyse(project, context);
+
+ verify(context, Mockito.never()).saveMeasure(Mockito.any(Metric.class), Mockito.anyDouble());
+ }
+
+ @Test
+ public void should_analyze_on_multi_module_modules() {
+ when(project.isRoot()).thenReturn(false);
+
+ resultsAggregator = mock(MSTestResultsAggregator.class);
+
+ UnitTestResults results = mock(UnitTestResults.class);
+ when(results.tests()).thenReturn(1.0);
+ when(results.passedPercentage()).thenCallRealMethod();
+ when(results.skipped()).thenReturn(0.0);
+ when(results.failed()).thenReturn(1.0);
+ when(results.errors()).thenReturn(0.0);
+
+ when(resultsAggregator.aggregate(Mockito.any(UnitTestResults.class))).thenReturn(results);
+ sensor = new MSTestResultsImportSensor(resultsAggregator);
+ sensor.analyse(project, context);
+
+ verify(context, Mockito.atLeastOnce()).saveMeasure(Mockito.any(Metric.class), Mockito.anyDouble());
+ }
+}
+