diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index ac62fb7e2d..0864a31225 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -36,6 +36,7 @@
+
diff --git a/src/Stryker.Abstractions/Options/IStrykerOptions.cs b/src/Stryker.Abstractions/Options/IStrykerOptions.cs
index 7c7f21b66d..1095e154be 100644
--- a/src/Stryker.Abstractions/Options/IStrykerOptions.cs
+++ b/src/Stryker.Abstractions/Options/IStrykerOptions.cs
@@ -32,6 +32,7 @@ public interface IStrykerOptions
MutationLevel MutationLevel { get; init; }
OptimizationModes OptimizationMode { get; init; }
string OutputPath { get; init; }
+ string Platform { get; }
string ProjectName { get; set; }
string ProjectPath { get; init; }
string ProjectVersion { get; set; }
diff --git a/src/Stryker.CLI/Stryker.CLI.UnitTest/CommandLineConfigReaderTests.cs b/src/Stryker.CLI/Stryker.CLI.UnitTest/CommandLineConfigReaderTests.cs
index cfc6927193..4ace7574ec 100644
--- a/src/Stryker.CLI/Stryker.CLI.UnitTest/CommandLineConfigReaderTests.cs
+++ b/src/Stryker.CLI/Stryker.CLI.UnitTest/CommandLineConfigReaderTests.cs
@@ -41,7 +41,7 @@ public void ShouldHandleSingleValue()
[TestMethod]
public void ShouldHandleSingleOrNoValueWithNoValue()
{
- _target.ReadCommandLineConfig(new[] { "--since" }, _app, _inputs);
+ _target.ReadCommandLineConfig(["--since"], _app, _inputs);
_inputs.SinceInput.SuppliedInput.ShouldBe(true);
_inputs.SinceTargetInput.SuppliedInput.ShouldBe(null);
@@ -50,7 +50,7 @@ public void ShouldHandleSingleOrNoValueWithNoValue()
[TestMethod]
public void ShouldHandleSingleOrNoValueWithValue()
{
- _target.ReadCommandLineConfig(new[] { "--since:test" }, _app, _inputs);
+ _target.ReadCommandLineConfig(["--since:test"], _app, _inputs);
_inputs.SinceInput.SuppliedInput.ShouldBe(true);
_inputs.SinceTargetInput.SuppliedInput.ShouldBe("test");
@@ -59,7 +59,7 @@ public void ShouldHandleSingleOrNoValueWithValue()
[TestMethod]
public void ShouldHandleMultiValue()
{
- _target.ReadCommandLineConfig(new[] { "--reporter test", "--reporter test2" }, _app, _inputs);
+ _target.ReadCommandLineConfig(["--reporter test", "--reporter test2"], _app, _inputs);
_inputs.ReportersInput.SuppliedInput.Count().ShouldBe(2);
_inputs.ReportersInput.SuppliedInput.First().ShouldBe("test");
diff --git a/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json b/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json
index 4da7debf91..9c38a097d5 100644
--- a/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json
+++ b/src/Stryker.CLI/Stryker.CLI.UnitTest/packages.lock.json
@@ -878,6 +878,7 @@
"Stryker.DataCollector": "[1.0.0, )",
"Stryker.Regex.Parser": "[1.0.0, )",
"Stryker.RegexMutators": "[1.0.0, )",
+ "Stryker.Solutions": "[1.0.0, )",
"Stryker.TestRunner.VsTest": "[1.0.0, )",
"Stryker.Utilities": "[1.0.0, )",
"TestableIO.System.IO.Abstractions.Wrappers": "[22.1.0, )"
@@ -919,6 +920,12 @@
"Stryker.Regex.Parser": "[1.0.0, )"
}
},
+ "stryker.solutions": {
+ "type": "Project",
+ "dependencies": {
+ "Microsoft.VisualStudio.SolutionPersistence": "[1.0.52, )"
+ }
+ },
"stryker.testrunner": {
"type": "Project",
"dependencies": {
@@ -1102,6 +1109,12 @@
"NETStandard.Library": "2.0.0"
}
},
+ "Microsoft.VisualStudio.SolutionPersistence": {
+ "type": "CentralTransitive",
+ "requested": "[1.0.52, )",
+ "resolved": "1.0.52",
+ "contentHash": "oNv2JtYXhpdJrX63nibx1JT3uCESOBQ1LAk7Dtz/sr0+laW0KRM6eKp4CZ3MHDR2siIkKsY8MmUkeP5DKkQQ5w=="
+ },
"Microsoft.Web.LibraryManager.Build": {
"type": "CentralTransitive",
"requested": "[3.0.71, )",
diff --git a/src/Stryker.CLI/Stryker.CLI/packages.lock.json b/src/Stryker.CLI/Stryker.CLI/packages.lock.json
index 21a75afd8c..6d060f3857 100644
--- a/src/Stryker.CLI/Stryker.CLI/packages.lock.json
+++ b/src/Stryker.CLI/Stryker.CLI/packages.lock.json
@@ -666,6 +666,7 @@
"Stryker.DataCollector": "[1.0.0, )",
"Stryker.Regex.Parser": "[1.0.0, )",
"Stryker.RegexMutators": "[1.0.0, )",
+ "Stryker.Solutions": "[1.0.0, )",
"Stryker.TestRunner.VsTest": "[1.0.0, )",
"Stryker.Utilities": "[1.0.0, )",
"TestableIO.System.IO.Abstractions.Wrappers": "[22.1.0, )"
@@ -707,6 +708,12 @@
"Stryker.Regex.Parser": "[1.0.0, )"
}
},
+ "stryker.solutions": {
+ "type": "Project",
+ "dependencies": {
+ "Microsoft.VisualStudio.SolutionPersistence": "[1.0.52, )"
+ }
+ },
"stryker.testrunner": {
"type": "Project",
"dependencies": {
@@ -872,6 +879,12 @@
"NETStandard.Library": "2.0.0"
}
},
+ "Microsoft.VisualStudio.SolutionPersistence": {
+ "type": "CentralTransitive",
+ "requested": "[1.0.52, )",
+ "resolved": "1.0.52",
+ "contentHash": "oNv2JtYXhpdJrX63nibx1JT3uCESOBQ1LAk7Dtz/sr0+laW0KRM6eKp4CZ3MHDR2siIkKsY8MmUkeP5DKkQQ5w=="
+ },
"Microsoft.Web.LibraryManager.Build": {
"type": "CentralTransitive",
"requested": "[3.0.71, )",
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/BuildAnalyzerTestsBase.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/BuildAnalyzerTestsBase.cs
index b5b9ab37ed..ce1faa5320 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/BuildAnalyzerTestsBase.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/BuildAnalyzerTestsBase.cs
@@ -7,15 +7,16 @@
using Buildalyzer.Construction;
using Buildalyzer.Environment;
using Moq;
+using Stryker.Solutions;
using Stryker.Utilities.Buildalyzer;
namespace Stryker.Core.UnitTest.Initialisation;
-public class BuildAnalyzerTestsBase : TestBase
+public class BuildAnalyzerTestsBase : TestBase, ISolutionProvider
{
- protected internal const string DefaultFramework = "net6.0";
+ protected const string DefaultFramework = "net6.0";
protected readonly MockFileSystem FileSystem = new();
- protected string ProjectPath;
+ protected readonly string ProjectPath;
private readonly Dictionary> _projectCache = [];
protected readonly Mock BuildalyzerProviderMock = new(MockBehavior.Strict);
@@ -27,6 +28,7 @@ public BuildAnalyzerTestsBase()
ProjectPath = FileSystem.Path.Combine(filesystemRoot, "sourceproject");
}
+
///
/// Build a simple production project
///
@@ -288,6 +290,7 @@ protected Mock BuildBuildAnalyzerMock(Dictionary x.Projects)
.Returns(analyzerResults);
buildalyzerAnalyzerManagerMock.Setup(x => x.SetGlobalProperty(It.IsAny(), It.IsAny()));
+ buildalyzerAnalyzerManagerMock.Setup(x => x.RemoveGlobalProperty(It.IsAny()));
buildalyzerAnalyzerManagerMock.Setup(x => x.SolutionFilePath).Returns((string)null);
foreach (var analyzerResult in analyzerResults)
@@ -296,10 +299,19 @@ protected Mock BuildBuildAnalyzerMock(Dictionary x.GetProject(filename)).Returns(analyzerResult.Value);
}
- BuildalyzerProviderMock.Setup(x => x.Provide(It.IsAny(), It.IsAny()))
+ BuildalyzerProviderMock.Setup(x => x.Provide(It.IsAny()))
.Returns(buildalyzerAnalyzerManagerMock.Object);
BuildalyzerProviderMock.Setup(x => x.Provide(It.IsAny()))
.Returns(buildalyzerAnalyzerManagerMock.Object);
return buildalyzerAnalyzerManagerMock;
}
+
+ public SolutionFile GetSolution(string solutionPath)
+ {
+ if (!FileSystem.FileExists(solutionPath))
+ {
+ throw new InvalidOperationException($"Solution file {solutionPath} does not exist in the file system.");
+ }
+ return SolutionFile.BuildFromProjectList(_projectCache.Keys.ToList());
+ }
}
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialBuildProcessTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialBuildProcessTests.cs
index 20aa3c2c54..ed3e856ac0 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialBuildProcessTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialBuildProcessTests.cs
@@ -44,8 +44,8 @@ public void InitialBuildProcess_WithPathAsBuildCommand_ShouldThrowStrykerInputEx
var target = new InitialBuildProcess(processMock.Object, _mockFileSystem, TestLoggerFactory.CreateLogger());
- Should.Throw(() => target.InitialBuild(true, null, _cProjectsExampleCsproj, null, null,
- @"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe"))
+ Should.Throw(() => target.InitialBuild(true, null, _cProjectsExampleCsproj, null, targetFramework: null,
+ msbuildPath: @"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe"))
.Details.ShouldBe("Initial build of targeted project failed. Please make sure the targeted project is buildable. You can reproduce this error yourself using: \"\"" +
@"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe" + "\" " + Path.GetFileName(_cProjectsExampleCsproj) + "\"");
}
@@ -60,7 +60,7 @@ public void InitialBuildProcess_WithPathAsBuildCommand_TriesWithMsBuildIfDotnetF
var target = new InitialBuildProcess(processMock.Object, _mockFileSystem, TestLoggerFactory.CreateLogger());
- Should.Throw(() => target.InitialBuild(false, null, _cProjectsExampleCsproj, null, null, @"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe"))
+ Should.Throw(() => target.InitialBuild(false, null, _cProjectsExampleCsproj, null, targetFramework: null, msbuildPath: @"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe"))
.Details.ShouldBe("Initial build of targeted project failed. Please make sure the targeted project is buildable. You can reproduce this error yourself using: \"\"" +
@"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe" + "\" " + _mockFileSystem.Path.GetFileName(_cProjectsExampleCsproj) + "\"");
@@ -123,7 +123,7 @@ public void InitialBuildProcess_ShouldUseCustomMsbuildIfNotNull()
var target = new InitialBuildProcess(processMock.Object, mockFileSystem, TestLoggerFactory.CreateLogger());
- target.InitialBuild(true, "/", "./ExampleProject.sln", null, null, CustomMsBuildPath);
+ target.InitialBuild(true, "/", "./ExampleProject.sln", null, targetFramework: null, msbuildPath: CustomMsBuildPath);
processMock.Verify(x => x.Start(It.IsAny(),
It.Is(applicationParam => applicationParam == CustomMsBuildPath),
It.Is(argumentsParam => argumentsParam.Contains("ExampleProject.sln")),
@@ -132,6 +132,46 @@ public void InitialBuildProcess_ShouldUseCustomMsbuildIfNotNull()
Times.Once);
}
+ [TestMethod]
+ public void InitialBuildProcess_ShouldUseProvidedConfiguration()
+ {
+ var processMock = new Mock(MockBehavior.Strict);
+ var mockFileSystem = new MockFileSystem();
+
+ processMock.SetupProcessMockToReturn("");
+
+ var target = new InitialBuildProcess(processMock.Object, mockFileSystem, TestLoggerFactory.CreateLogger());
+
+ target.InitialBuild(false, "/", "./ExampleProject.sln", "TheDebug");
+ processMock.Verify(x => x.Start(It.IsAny(),
+ It.IsAny(),
+ It.Is(argumentsParam => argumentsParam.Contains("-c TheDebug")),
+ It.IsAny>>(),
+ It.IsAny()),
+ Times.Once);
+ }
+
+ [TestMethod]
+ public void InitialBuildProcess_ShouldUseProvidedPlatform()
+ {
+ var processMock = new Mock(MockBehavior.Strict);
+ var mockFileSystem = new MockFileSystem();
+
+ processMock.SetupProcessMockToReturn("");
+
+ var target = new InitialBuildProcess(processMock.Object, mockFileSystem, TestLoggerFactory.CreateLogger());
+
+ target.InitialBuild(false, "/", "./ExampleProject.sln", "TheDebug", "AnyCPU");
+ processMock.Verify(x => x.Start(It.IsAny(),
+ It.IsAny(),
+ It.Is(argumentsParam => argumentsParam.Contains("-c TheDebug")
+ && argumentsParam.Contains("--property:Platform=AnyCPU")),
+ It.IsAny>>(),
+ It.IsAny()),
+ Times.Once);
+ }
+
+
[TestMethod]
public void InitialBuildProcess_ShouldRunDotnetBuildIfNotDotnetFramework()
{
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialisationProcessTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialisationProcessTests.cs
index 5d0cab341b..a490d82da2 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialisationProcessTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InitialisationProcessTests.cs
@@ -79,7 +79,9 @@ public void InitialisationProcess_ShouldThrowOnFailedInitialTestRun()
}});
inputFileResolverMock.SetupGet(x => x.FileSystem).Returns(new FileSystem());
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(),
+ It.IsAny(), null, It.IsAny()));
testRunnerMock.Setup(x => x.GetTests(It.IsAny())).Returns(new TestSet());
testRunnerMock.Setup(x => x.DiscoverTests(It.IsAny())).Returns(true);
initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny(), It.IsAny(), It.IsAny())).Throws(new InputException("")); // failing test
@@ -114,7 +116,9 @@ public void InitialisationProcess_ShouldThrowIfHalfTestsAreFailing()
new[] { new SourceProjectInfo { AnalyzerResult = TestHelper.SetupProjectAnalyzerResult(references: Array.Empty()).Object, TestProjectsInfo = new TestProjectsInfo(new MockFileSystem()) } });
inputFileResolverMock.SetupGet(x => x.FileSystem).Returns(fileSystemMock);
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(),
+ null,It.IsAny()));
var failedTest = "testid";
var ranTests = new TestIdentifierList(failedTest, "othertest");
var testSet = new TestSet();
@@ -164,7 +168,8 @@ public void InitialisationProcess_ShouldThrowOnTestTestIfAskedFor(bool breakOnIn
}});
inputFileResolverMock.SetupGet(x => x.FileSystem).Returns(new FileSystem());
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
var failedTest = "testid";
var ranTests = new TestIdentifierList(failedTest, "othertest", "anothertest");
var testSet = new TestSet();
@@ -214,9 +219,9 @@ public void InitialisationProcess_ShouldRunTestSession()
inputFileResolverMock.Setup(x => x.ResolveSourceProjectInfos(It.IsAny())).Returns(
new[] { new SourceProjectInfo() { AnalyzerResult = TestHelper.SetupProjectAnalyzerResult(references: Array.Empty()).Object, TestProjectsInfo = new TestProjectsInfo(new MockFileSystem()) } });
-
inputFileResolverMock.SetupGet(x => x.FileSystem).Returns(new FileSystem());
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
var testSet = new TestSet();
testSet.RegisterTest(new TestDescription("id", "name", "test.cs"));
testRunnerMock.Setup(x => x.DiscoverTests(It.IsAny())).Returns(true);
@@ -271,7 +276,8 @@ public void InitialisationProcess_ShouldThrowOnWhenNoTestDetected(string library
TestProjectsInfo = new TestProjectsInfo(new MockFileSystem()){TestProjects = new List {new(new MockFileSystem(), testProjectAnalyzerResult)}}
}});
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
testRunnerMock.Setup(x => x.DiscoverTests(It.IsAny())).Returns(false);
testRunnerMock.Setup(x => x.GetTests(It.IsAny())).Returns(new TestSet());
initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny(), It.IsAny(), It.IsAny()))
@@ -320,7 +326,8 @@ public void InitialisationProcess_ShouldThrowOnWhenNoTestDetectedAndCorrectDepen
TestProjectsInfo = new TestProjectsInfo(new MockFileSystem()){TestProjects = new List {new(new MockFileSystem(), testProjectAnalyzerResult)}}
}});
- initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
+ initialBuildProcessMock.Setup(x => x.InitialBuild(It.IsAny(), It.IsAny(),
+ It.IsAny(), It.IsAny(), It.IsAny(), null, It.IsAny()));
testRunnerMock.Setup(x => x.DiscoverTests(It.IsAny())).Returns(false);
testRunnerMock.Setup(x => x.GetTests(It.IsAny())).Returns(new TestSet());
initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny(), It.IsAny(), It.IsAny()))
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InputFileResolverTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InputFileResolverTests.cs
index 0f53e05ecb..02a1bba7ea 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InputFileResolverTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/InputFileResolverTests.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using System.Reflection;
@@ -19,11 +20,13 @@
using Stryker.Core.ProjectComponents;
using Stryker.Core.ProjectComponents.Csharp;
using Stryker.Core.ProjectComponents.TestProjects;
+using Stryker.Solutions;
using Stryker.Utilities;
using static NuGet.Frameworks.FrameworkConstants;
namespace Stryker.Core.UnitTest.Initialisation;
+
[TestClass]
public class InputFileResolverTests : BuildAnalyzerTestsBase
{
@@ -77,9 +80,14 @@ public InputFileResolverTests()
_nugetMock = new Mock();
_nugetMock.Setup(x => x.RestorePackages(It.IsAny(), It.IsAny()));
-
}
+ private InputFileResolver BuildTestResolver(IFileSystem fileSystem) => BuildTestResolverWithSolutionProvider(fileSystem,
+ this);
+
+ private InputFileResolver BuildTestResolverWithSolutionProvider(IFileSystem fileSystem, ISolutionProvider solutionProvider)
+ => new(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, solutionProvider ,TestLoggerFactory.CreateLogger());
+
[TestMethod]
[DataRow("netcoreapp2.1", FrameworkIdentifiers.NetCoreApp, "", 2, 1, 0, 0)]
[DataRow("netstandard1.6", FrameworkIdentifiers.NetStandard, "", 1, 6, 0, 0)]
@@ -145,7 +153,7 @@ public void InitializeShouldFindFilesRecursively()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -180,7 +188,7 @@ public void InitializeShouldUseBuildalyzerResult()
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -218,7 +226,7 @@ public void ShouldUseCustomMsBuildPath()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions { MsBuildPath = "\\msbuild.exe",ProjectPath = _testPath };
var result = target.ResolveSourceProjectInfos(options).First();
@@ -249,12 +257,102 @@ public void ShouldHandleFailedAnalysis()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var action = () => target.ResolveSourceProjectInfos(_options).First();
action.ShouldThrow();
}
+ [TestMethod]
+ public void ShouldFailIfSolutionNotFound()
+ {
+ var fileSystem = new MockFileSystem(new Dictionary
+ {
+ { _sourceProjectPath, new MockFileData(_defaultTestProjectFileContents) },
+ { _testProjectPath, new MockFileData(_defaultTestProjectFileContents)},
+ { Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData(_sourceFile) },
+ { Path.Combine(_sourcePath, "Plain.cs"), new MockFileData(_sourceFile) },
+ });
+
+ var sourceProjectManagerMock = SourceProjectAnalyzerMock(_sourceProjectPath,
+ fileSystem.AllFiles.Where(s => s.EndsWith(".cs")).ToArray());
+ var testProjectManagerMock = TestProjectAnalyzerMock(_testProjectPath, _sourceProjectPath, ["netcoreapp2.1"], success: false);
+
+ var analyzerResults = new Dictionary
+ {
+ { "MyProject", sourceProjectManagerMock.Object },
+ { "MyProject.UnitTests", testProjectManagerMock.Object }
+ };
+ BuildBuildAnalyzerMock(analyzerResults);
+ var options = new StrykerOptions()
+ {
+ ProjectPath = _sourcePath,
+ SolutionPath = Path.Combine(_sourcePath, "solution.nope")
+ };
+ var target = BuildTestResolver(fileSystem);
+
+ var action = () => target.ResolveSourceProjectInfos(options).First();
+ action.ShouldThrow();
+ }
+
+ private class CustomSolutionProvider(Func loader) : ISolutionProvider
+ {
+ public SolutionFile GetSolution(string solutionPath) => loader(solutionPath);
+ }
+
+ [TestMethod]
+ public void ShouldFailIfSolutionLoadFails()
+ {
+ var fileSystem = new MockFileSystem(new Dictionary());
+
+ var sourceProjectManagerMock = SourceProjectAnalyzerMock(_sourceProjectPath,
+ fileSystem.AllFiles.Where(s => s.EndsWith(".cs")).ToArray());
+ var testProjectManagerMock = TestProjectAnalyzerMock(_testProjectPath, _sourceProjectPath, ["netcoreapp2.1"], success: false);
+
+ var analyzerResults = new Dictionary
+ {
+ { "MyProject", sourceProjectManagerMock.Object },
+ { "MyProject.UnitTests", testProjectManagerMock.Object }
+ };
+ BuildBuildAnalyzerMock(analyzerResults);
+ var options = new StrykerOptions()
+ {
+ ProjectPath = _sourcePath,
+ SolutionPath = Path.Combine(_sourcePath, "solution.sln")
+ };
+
+ var target = BuildTestResolverWithSolutionProvider(fileSystem,
+ new CustomSolutionProvider(_ => throw new IOException("Failed to read solution")));
+
+ target.ResolveSourceProjectInfos(options).ShouldBeEmpty();
+ }
+
+ [TestMethod]
+ public void ShouldFailIfSolutionCantBeAccessed()
+ {
+ var fileSystem = new MockFileSystem(new Dictionary());
+
+ var sourceProjectManagerMock = SourceProjectAnalyzerMock(_sourceProjectPath,
+ fileSystem.AllFiles.Where(s => s.EndsWith(".cs")).ToArray());
+ var testProjectManagerMock = TestProjectAnalyzerMock(_testProjectPath, _sourceProjectPath, ["netcoreapp2.1"], success: false);
+
+ var analyzerResults = new Dictionary
+ {
+ { "MyProject", sourceProjectManagerMock.Object },
+ { "MyProject.UnitTests", testProjectManagerMock.Object }
+ };
+ BuildBuildAnalyzerMock(analyzerResults);
+ var options = new StrykerOptions()
+ {
+ ProjectPath = _sourcePath,
+ SolutionPath = Path.Combine(_sourcePath, "solution.slnx")
+ };
+ var target = BuildTestResolverWithSolutionProvider(fileSystem,
+ new CustomSolutionProvider(_ => throw new UnauthorizedAccessException("Access forbidden")));
+
+ target.ResolveSourceProjectInfos(options).ShouldBeEmpty();
+ }
+
[TestMethod]
public void InitializeShouldNotSkipXamlFiles()
{
@@ -278,7 +376,7 @@ public void InitializeShouldNotSkipXamlFiles()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -328,7 +426,7 @@ public void InitializeShouldMutateAssemblyInfo()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -385,7 +483,7 @@ public void InitializeShouldNotMutateIncompleteAssemblyInfo()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -414,7 +512,7 @@ public void InitializeShouldFindSpecifiedTestProjectFile()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -471,7 +569,7 @@ public void InitializeShouldResolveImportedProject()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -517,7 +615,7 @@ public void InitializeShouldNotResolveImportedPropsFile()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -588,8 +686,7 @@ public void InitializeShouldResolveMultipleImportedProjects()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
-
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
result.ProjectContents.GetAllFiles().Count().ShouldBe(4);
@@ -636,7 +733,7 @@ public void InitializeShouldThrowOnMissingSharedProject()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
Should.Throw(() => target.ResolveSourceProjectInfos(_options));
}
@@ -688,8 +785,7 @@ public void InitializeShouldResolvePropertiesInSharedProjectImports()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
-
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
var allFiles = result.ProjectContents.GetAllFiles();
@@ -741,7 +837,7 @@ public void InitializeShouldThrowIfImportPropertyCannotBeResolved()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var exception = Should.Throw(() => target.ResolveSourceProjectInfos(_options));
exception.Message.ShouldBe($"Missing MSBuild property (SharedDir) in project reference (..{FilePathUtils.NormalizePathSeparators("/$(SharedDir)/Example.projitems")}). Please check your project file ({_sourceProjectPath}) and try again.");
@@ -772,7 +868,7 @@ public void InitializeShouldIgnoreBinFolder(string folderName)
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -793,7 +889,7 @@ public void ShouldThrowExceptionOnNullPath()
BuildBuildAnalyzerMock(new Dictionary());
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
Should.Throw(() => target.FindTestProject(null));
}
@@ -807,7 +903,7 @@ public void ShouldThrowExceptionOnNoProjectFile()
BuildBuildAnalyzerMock(new Dictionary());
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
Should.Throw(() => target.FindTestProject(Path.Combine(_sourcePath)));
}
@@ -821,7 +917,7 @@ public void ShouldThrowStrykerInputExceptionOnTwoProjectFiles_AndNoTestProjectFi
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var errorMessage =
$@"Expected exactly one .csproj file, found more than one:
@@ -846,7 +942,7 @@ public void ShouldNotThrowExceptionOnTwoProjectFilesInDifferentLocations()
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var actual = target.FindTestProject(Path.Combine(_sourcePath));
@@ -862,7 +958,7 @@ public void ShouldChooseGivenTestProjectFileIfPossible()
{ Path.Combine(_sourcePath, "TestProject.csproj"), new MockFileData(_defaultTestProjectFileContents)},
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var actual = target.FindTestProject(Path.Combine(_sourcePath, "TestProject.csproj"));
@@ -877,7 +973,7 @@ public void ShouldThrowExceptionIfGivenTestFileDoesNotExist()
{ Path.Combine(_sourcePath, "AlternateProject.csproj"), new MockFileData(_defaultTestProjectFileContents)},
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var exception = Should.Throw(() => target.FindTestProject(Path.Combine(_sourcePath, "GivenTestProject.csproj")));
exception.Message.ShouldStartWith("No .csproj or .fsproj file found, please check your project directory at");
@@ -892,7 +988,7 @@ public void ShouldChooseGivenTestProjectFileIfPossible_AtRelativeLocation()
{ Path.Combine(_sourcePath, "SubFolder", "TestProject.csproj"), new MockFileData(_defaultTestProjectFileContents)},
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var actual = target.FindTestProject(Path.Combine(_sourcePath, "SubFolder", "TestProject.csproj"));
@@ -908,7 +1004,7 @@ public void ShouldChooseGivenTestProjectFileIfPossible_AtFullPath()
{ Path.Combine(_sourcePath,"SubFolder", "TestProject.csproj"), new MockFileData(_defaultTestProjectFileContents)},
{ Path.Combine(_sourcePath, "Recursive.cs"), new MockFileData("content")}
});
- var target = new InputFileResolver(fileSystem, new Mock().Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var actual = target.FindTestProject(Path.Combine(_filesystemRoot,
FilePathUtils.NormalizePathSeparators(Path.Combine(_sourcePath, "SubFolder"))));
@@ -952,7 +1048,7 @@ public void ShouldSelectAvailableFramework_WhenDesiredNotFound(string targetFram
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
// Act
var result = target.ResolveSourceProjectInfos(options).First();
@@ -968,14 +1064,16 @@ public void ShouldSelectAvailableFramework_WhenDesiredNotFound(string targetFram
[DataRow("net3.0,net462", "net461,net2.0", "net3.0", "net3.0", "net2.0")]
[DataRow("net3.0,net462", "net461,net2.0", "net461", "net3.0", "net2.0")]
[DataRow("net3.0,net462", "net461,net2.0", "net462", "net462", "net461")]
- public void ShouldSelectFrameworkBasedOnTestProject(string testFrameworks, string projectFrameworks, string targetFramework, string expectedTestFramework,string expectedFramework)
+ public void ShouldSelectFrameworkBasedOnTestProject(string testFrameworks, string projectFrameworks
+ , string targetFramework
+ , string expectedTestFramework,string expectedFramework)
{
// Arrange
var basePath = Path.Combine(_sourcePath, "ExampleProject");
var testProjectPath = Path.Combine(_sourcePath, "TestProjectFolder", "TestProject.csproj");
var sourceProjectPath = Path.Combine(_sourcePath, "ExampleProject", "ExampleProject.csproj");
var sourceProjectNameFilter = "ExampleProject.csproj";
-
+
var fileSystem = new MockFileSystem(new Dictionary
{
{ sourceProjectPath, new MockFileData(_defaultTestProjectFileContents)},
@@ -1002,7 +1100,7 @@ public void ShouldSelectFrameworkBasedOnTestProject(string testFrameworks, strin
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
// Act
var result = target.ResolveSourceProjectInfos(options).First();
@@ -1027,7 +1125,7 @@ public void ShouldThrowOnMsTestV1Detected()
targetFramework: "netcoreapp2.1",
properties: new Dictionary() { { "Language", "C#" } },
projectFilePath: _testProjectPath,
- references: new string[] { "Microsoft.VisualStudio.QualityTools.UnitTestFramework" }).Object;
+ references: ["Microsoft.VisualStudio.QualityTools.UnitTestFramework"]).Object;
// Act
var ex = Should.Throw(() => new TestProject(fileSystem, testProjectAnalyzerResult));
@@ -1058,7 +1156,7 @@ public void ShouldSkipXamlFiles()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
// Act
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -1103,7 +1201,7 @@ public void ShouldFindAllTestProjects()
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
// Act
var result = target.ResolveSourceProjectInfos(options).First();
@@ -1131,7 +1229,7 @@ public void ShouldFindSourceProjectWhenSingleProjectReferenceAndNoFilter()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -1154,7 +1252,7 @@ public void ShouldThrowOnNoProjectReference()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var action = () => target.ResolveSourceProjectInfos(_options);
@@ -1186,7 +1284,7 @@ public void ShouldThrowOnMultipleProjectsWithoutFilter()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
// Act
var result = () => target.ResolveSourceProjectInfos(_options);
@@ -1226,7 +1324,7 @@ public void ShouldNotThrowIfMultipleProjectButOneIsAlwaysReferenced()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions
{
TestProjects = [_testProjectPath, test2Path],
@@ -1269,7 +1367,7 @@ public void ShouldMatchFromMultipleProjectByName(string shouldMatch)
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions { SourceProjectName = shouldMatch, ProjectPath = _testPath };
var result = target.ResolveSourceProjectInfos(options).First();
@@ -1306,7 +1404,7 @@ public void ShouldThrowWhenTheNameMatchesMore(string shouldMatchMoreThanOne)
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions { SourceProjectName = shouldMatchMoreThanOne, ProjectPath = _testPath };
var result = () => target.ResolveSourceProjectInfos(options);
@@ -1333,7 +1431,7 @@ public void ShouldThrowWhenTheNameMatchesNone()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions { SourceProjectName = "wrong.csprj", ProjectPath = _testPath };
var result = () => target.ResolveSourceProjectInfos(options);
@@ -1361,7 +1459,7 @@ public void ShouldFallbackToProjectReferenceIfDependencyNotFound()
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var result = target.ResolveSourceProjectInfos(_options).First();
@@ -1390,11 +1488,13 @@ public void ShouldMatchOnBothForwardAndBackwardsSlash(string shouldMatch)
};
BuildBuildAnalyzerMock(analyzerResults);
- var target = new InputFileResolver(fileSystem, BuildalyzerProviderMock.Object, _nugetMock.Object, TestLoggerFactory.CreateLogger());
+ var target = BuildTestResolver(fileSystem);
var options = new StrykerOptions { SourceProjectName = shouldMatch, ProjectPath = _testPath };
var result = target.ResolveSourceProjectInfos(_options).First();
result.AnalyzerResult.ProjectFilePath.ShouldBe(_sourceProjectPath);
}
+
+ public SolutionFile GetSolution(string solutionPath) => throw new NotImplementedException();
}
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/ProjectOrchestratorTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/ProjectOrchestratorTests.cs
index 356b10ff46..6457cc713e 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/ProjectOrchestratorTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Initialisation/ProjectOrchestratorTests.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using Buildalyzer;
using Microsoft.CodeAnalysis;
@@ -132,7 +134,7 @@ public void ShouldPassWhenProjectNameIsGiven()
}
[TestMethod]
- public void ShouldUsedDesiredConfigurationWhenDefined()
+ public void ShouldUseDesiredConfigurationWhenDefined()
{
// arrange
// when a solutionPath is given, and it's inside the current directory (basePath)
@@ -146,7 +148,7 @@ public void ShouldUsedDesiredConfigurationWhenDefined()
};
var csPathName = FileSystem.Path.Combine(ProjectPath, "someFile.cs");
- var sourceProjectAnalyzerMock = SourceProjectAnalyzerMock(csprojPathName, new[] { csPathName }).Object;
+ var sourceProjectAnalyzerMock = SourceProjectAnalyzerMock(csprojPathName, [csPathName]).Object;
var testProjectAnalyzerMock = TestProjectAnalyzerMock(testCsprojPathName, csprojPathName).Object;
// The analyzer finds two projects
var analyzerResults = new Dictionary
@@ -160,7 +162,7 @@ public void ShouldUsedDesiredConfigurationWhenDefined()
var result = target.MutateProjects(options, _reporterMock.Object, mockRunner.Object).ToList();
// assert
- buildalyzerAnalyzerManagerMock.Verify(x => x.SetGlobalProperty("Configuration", "Release"), Times.Once());
+ buildalyzerAnalyzerManagerMock.Verify(x => x.SetGlobalProperty("Configuration", "Release"), Times.AtLeastOnce);
}
[TestMethod]
@@ -214,9 +216,11 @@ public void ShouldRestoreWhenAnalysisFails()
var initialTestProcessMock = new Mock();
initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(new InitialTestRun(new TestRunResult(true), new TimeoutValueCalculator(500)));
- var inputFileResolver = new InputFileResolver(FileSystem, BuildalyzerProviderMock.Object, nugetRestoreMock.Object, TestLoggerFactory.CreateLogger());
+ var inputFileResolver = new InputFileResolver(FileSystem, BuildalyzerProviderMock.Object,
+ nugetRestoreMock.Object, this,
+ TestLoggerFactory.CreateLogger());
var initialisationProcess = new InitialisationProcess(inputFileResolver, initialBuildProcessMock.Object, initialTestProcessMock.Object, TestLoggerFactory.CreateLogger());
-
+
var serviceProviderMock = new Mock();
var mutationTestExecutorMock = new Mock();
var target = new ProjectOrchestrator(_projectMutatorMock.Object,
@@ -270,12 +274,14 @@ public void ShouldFilterInSolutionMode()
// when a solutionPath is given and it's inside the current directory (basePath)
var testCsprojPathName = FileSystem.Path.Combine(ProjectPath, "testproject.csproj");
var csprojPathName = FileSystem.Path.Combine(ProjectPath, "sourceproject.csproj");
+ var solutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln");
+ FileSystem.AddFile(solutionPath, new MockFileData("empty"));
var options = new StrykerOptions
{
ProjectPath = FileSystem.Path.GetFullPath(ProjectPath),
// provide an invalid source project name which should normally fail
SourceProjectName = "sourceprojec.csproj",
- SolutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln")
+ SolutionPath = solutionPath
};
var csPathName = FileSystem.Path.Combine(ProjectPath, "someFile.cs");
@@ -297,13 +303,16 @@ public void ShouldDiscoverUpstreamProject()
// arrange
var testCsprojPathName = FileSystem.Path.Combine(ProjectPath, "testproject.csproj");
var csprojPathName = FileSystem.Path.Combine(ProjectPath, "sourceproject.csproj");
+ var solutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln");
+ FileSystem.AddFile(solutionPath, new MockFileData("empty"));
var options = new StrykerOptions
{
ProjectPath = ProjectPath,
- SolutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln")
+ SolutionPath = solutionPath
};
var libraryProject = FileSystem.Path.Combine(ProjectPath, "libraryproject.csproj");
+
// The analyzer finds two projects
var libraryAnalyzer = SourceProjectAnalyzerMock(libraryProject, [FileSystem.Path.Combine(ProjectPath, "mylib.cs")]).Object;
var projectAnalyzer = SourceProjectAnalyzerMock(csprojPathName, [FileSystem.Path.Combine(ProjectPath, "someFile.cs")], [libraryProject]).Object;
@@ -330,10 +339,12 @@ public void ShouldDiscoverUpstreamProjectWithInvalidCasing()
// arrange
var testCsprojPathName = FileSystem.Path.Combine(ProjectPath, "testproject.csproj");
var csprojPathName = FileSystem.Path.Combine(ProjectPath, "sourceproject.csproj");
+ var solutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln");
+ FileSystem.AddFile(solutionPath, new MockFileData("empty"));
var options = new StrykerOptions
{
ProjectPath = ProjectPath,
- SolutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln")
+ SolutionPath = solutionPath
};
var libraryProject = FileSystem.Path.Combine(ProjectPath, "libraryproject.csproj");
@@ -364,10 +375,12 @@ public void ShouldDisregardInvalidReferences()
// arrange
var testCsprojPathName = FileSystem.Path.Combine(ProjectPath, "testproject.csproj");
var csprojPathName = FileSystem.Path.Combine(ProjectPath, "sourceproject.csproj");
+ var solutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln");
+ FileSystem.AddFile(solutionPath, new MockFileData("empty"));
var options = new StrykerOptions
{
ProjectPath = ProjectPath,
- SolutionPath = FileSystem.Path.Combine(ProjectPath, "MySolution.sln")
+ SolutionPath = solutionPath
};
var libraryProject = FileSystem.Path.Combine(ProjectPath, "libraryproject.csproj");
@@ -464,9 +477,12 @@ private ProjectOrchestrator BuildProjectOrchestrator(Dictionary();
initialTestProcessMock.Setup(x => x.InitialTest(It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(new InitialTestRun(new TestRunResult(true), new TimeoutValueCalculator(500)));
- var inputFileResolver = new InputFileResolver(FileSystem, BuildalyzerProviderMock.Object, new Mock().Object, TestLoggerFactory.CreateLogger());
+ var inputFileResolver = new InputFileResolver(FileSystem, BuildalyzerProviderMock.Object,
+ new Mock().Object,
+ this,
+ TestLoggerFactory.CreateLogger());
var initialisationProcess = new InitialisationProcess(inputFileResolver, initialBuildProcessMock.Object, initialTestProcessMock.Object, TestLoggerFactory.CreateLogger());
-
+
var serviceProviderMock = new Mock();
var mutationTestExecutorMock = new Mock();
return new ProjectOrchestrator(_projectMutatorMock.Object,
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Options/Inputs/ConfigurationInputTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Options/Inputs/ConfigurationInputTests.cs
index 0fe60a063e..69d38e099d 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Options/Inputs/ConfigurationInputTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Options/Inputs/ConfigurationInputTests.cs
@@ -12,7 +12,7 @@ public class ConfigurationInputTests : TestBase
public void ShouldHaveHelpText()
{
var target = new ConfigurationInput();
- target.HelpText.ShouldBe("Configuration to use when building the project(s).");
+ target.HelpText.ShouldBe("Configuration to use when building the project(s) (e.g., 'Debug' or 'Release'). If not specified, the default configuration of the project(s) will be used.");
}
[TestMethod]
@@ -34,14 +34,4 @@ public void ShouldReturnDefault()
result.ShouldBeNull();
}
-
- [TestMethod]
- public void ShouldThrowOnEmptyInput()
- {
- var target = new ConfigurationInput { SuppliedInput = " " };
-
- var ex = Should.Throw(() => target.Validate());
-
- ex.Message.ShouldBe("Please provide a non whitespace only configuration.");
- }
}
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Options/StrykerInputsTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/Options/StrykerInputsTests.cs
index 3d2e7a5adf..78f1e8be3d 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Options/StrykerInputsTests.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Options/StrykerInputsTests.cs
@@ -63,6 +63,32 @@ public void PerTestInIsolationShouldSetOptimizationFlags()
result.OptimizationMode.HasFlag(OptimizationModes.CaptureCoveragePerTest).ShouldBeTrue();
}
+ [TestMethod]
+ public void ShouldSetConfiguration()
+ {
+ _target.ConfigurationInput.SuppliedInput = "TheRelease";
+ var result = _target.ValidateAll();
+ result.Configuration.ShouldBe("TheRelease");
+ }
+
+ [TestMethod]
+ public void ShouldSetConfigurationAndPlatform()
+ {
+ _target.ConfigurationInput.SuppliedInput = "TheRelease|x64";
+ var result = _target.ValidateAll();
+ result.Configuration.ShouldBe("TheRelease");
+ result.Platform.ShouldBe("x64");
+ }
+
+ [TestMethod]
+ public void ShouldIgnoreExtraInfoInConfiguration()
+ {
+ _target.ConfigurationInput.SuppliedInput = "TheRelease|x64|Disregarded";
+ var result = _target.ValidateAll();
+ result.Configuration.ShouldBe("TheRelease");
+ result.Platform.ShouldBe("x64");
+ }
+
[TestMethod]
public void DisableBailShouldSetOptimizationFlags()
{
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/Stryker.Core.UnitTest.csproj b/src/Stryker.Core/Stryker.Core.UnitTest/Stryker.Core.UnitTest.csproj
index 609aedb5a4..a347b7e606 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/Stryker.Core.UnitTest.csproj
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/Stryker.Core.UnitTest.csproj
@@ -51,6 +51,7 @@
+
diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/TestHelper.cs b/src/Stryker.Core/Stryker.Core.UnitTest/TestHelper.cs
index 3b25eac836..05e9bb0239 100644
--- a/src/Stryker.Core/Stryker.Core.UnitTest/TestHelper.cs
+++ b/src/Stryker.Core/Stryker.Core.UnitTest/TestHelper.cs
@@ -31,6 +31,7 @@ public static Mock SetupProjectAnalyzerResult(Dictionary();
analyzerResultMock.Setup(x => x.Properties).Returns(properties);
}
+
if (projectFilePath != null)
{
analyzerResultMock.Setup(x => x.ProjectFilePath).Returns(projectFilePath);
@@ -75,4 +76,5 @@ public static Mock SetupProjectAnalyzerResult(Dictionary fullOptions = string.IsNullOrEmpty(command) ? [QuotesIfNeeded(projectFile)] : [command, QuotesIfNeeded(projectFile)];
if (!string.IsNullOrEmpty(configuration))
{
- fullOptions.Add(usingMsBuild ? $"/property:Configuration={QuotesIfNeeded(configuration)}" : $"-c {QuotesIfNeeded(configuration)}");
+ fullOptions.Add($"{(usingMsBuild ? "/property:Configuration=" : "-c ") + QuotesIfNeeded(configuration)}");
+ }
+
+ if (!string.IsNullOrEmpty(platform))
+ {
+ fullOptions.Add($"{(usingMsBuild ? "/" : "--")}property:Platform={QuotesIfNeeded(platform)}");
}
if (options is not null)
diff --git a/src/Stryker.Core/Stryker.Core/Infrastructure/ServiceCollectionExtensions.cs b/src/Stryker.Core/Stryker.Core/Infrastructure/ServiceCollectionExtensions.cs
index 59288d917c..f47d68e50f 100644
--- a/src/Stryker.Core/Stryker.Core/Infrastructure/ServiceCollectionExtensions.cs
+++ b/src/Stryker.Core/Stryker.Core/Infrastructure/ServiceCollectionExtensions.cs
@@ -7,6 +7,7 @@
using Stryker.Core.Initialisation;
using Stryker.Core.MutationTest;
using Stryker.Core.Reporters;
+using Stryker.Solutions;
using Stryker.TestRunner.VsTest;
using Stryker.Utilities.Buildalyzer;
@@ -33,6 +34,8 @@ public static IServiceCollection AddStrykerCore(this IServiceCollection services
// Initialisation services - Transient as they perform per-run operations
services.AddTransient();
services.AddTransient();
+
+ services.AddSingleton();
services.AddTransient();
services.AddTransient();
services.AddTransient();
diff --git a/src/Stryker.Core/Stryker.Core/Initialisation/InitialBuildProcess.cs b/src/Stryker.Core/Stryker.Core/Initialisation/InitialBuildProcess.cs
index 6ad776765f..5387773128 100644
--- a/src/Stryker.Core/Stryker.Core/Initialisation/InitialBuildProcess.cs
+++ b/src/Stryker.Core/Stryker.Core/Initialisation/InitialBuildProcess.cs
@@ -11,8 +11,13 @@ namespace Stryker.Core.Initialisation;
public interface IInitialBuildProcess
{
- void InitialBuild(bool fullFramework, string projectPath, string solutionPath, string configuration = null,
- string targetFramework = null, string msbuildPath = null);
+ void InitialBuild(bool fullFramework,
+ string projectPath,
+ string solutionPath,
+ string configuration = null,
+ string platform = null,
+ string targetFramework = null,
+ string msbuildPath = null);
}
public class InitialBuildProcess : IInitialBuildProcess
@@ -30,8 +35,9 @@ public InitialBuildProcess(
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
-
- public void InitialBuild(bool fullFramework, string projectPath, string solutionPath, string configuration = null, string targetFramework = null,
+
+ public void InitialBuild(bool fullFramework, string projectPath, string solutionPath, string configuration = null,
+ string platform = null, string targetFramework = null,
string msbuildPath = null)
{
if (fullFramework && string.IsNullOrEmpty(solutionPath))
@@ -50,6 +56,7 @@ public void InitialBuild(bool fullFramework, string projectPath, string solution
buildPath,
fullFramework,
configuration: configuration,
+ platform: platform,
forcedFramework: targetFramework);
if (result.ExitCode != ExitCodes.Success && !string.IsNullOrEmpty(solutionPath))
@@ -61,7 +68,7 @@ public void InitialBuild(bool fullFramework, string projectPath, string solution
buildPath,
true,
configuration,
- "-t:restore -p:RestorePackagesConfig=true", forcedFramework: targetFramework);
+ options: "-t:restore -p:RestorePackagesConfig=true", forcedFramework: targetFramework);
if (result.ExitCode != ExitCodes.Success)
{
@@ -71,8 +78,8 @@ public void InitialBuild(bool fullFramework, string projectPath, string solution
(result, exe, args) = msBuildHelper.BuildProject(directoryName,
buildPath,
true,
- configuration
- , forcedFramework: targetFramework);
+ configuration,
+ forcedFramework: targetFramework);
}
CheckBuildResult(result, target, exe, args);
diff --git a/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs b/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs
index b9e071a1cc..c058ccd2f6 100644
--- a/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs
+++ b/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs
@@ -73,7 +73,8 @@ public void BuildProjects(IStrykerOptions options, IEnumerable
/// - Reads .csproj to find project under test
/// - Scans project under test and store files to mutate
@@ -32,10 +33,11 @@ public interface IInputFileResolver
///
public class InputFileResolver : IInputFileResolver
{
- private readonly string[] _foldersToExclude = { "obj", "bin", "node_modules", "StrykerOutput" };
+ private readonly string[] _foldersToExclude = ["obj", "bin", "node_modules", "StrykerOutput"];
private readonly ILogger _logger;
private readonly IBuildalyzerProvider _analyzerProvider;
- private static readonly HashSet importantProperties =
+ private readonly ISolutionProvider _solutionProvider;
+ private static readonly HashSet ImportantProperties =
["Configuration", "Platform", "AssemblyName", "Configurations"];
private readonly INugetRestoreProcess _nugetRestoreProcess;
@@ -43,40 +45,82 @@ public class InputFileResolver : IInputFileResolver
private readonly StringWriter _buildalyzerLog = new();
public InputFileResolver(IFileSystem fileSystem,
- IBuildalyzerProvider analyzerProvider, INugetRestoreProcess nugetRestoreProcess, ILogger logger)
+ IBuildalyzerProvider analyzerProvider,
+ INugetRestoreProcess nugetRestoreProcess,
+ ISolutionProvider solutionProvider,
+ ILogger logger)
{
FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_analyzerProvider = analyzerProvider ?? throw new ArgumentNullException(nameof(analyzerProvider));
_nugetRestoreProcess = nugetRestoreProcess ?? throw new ArgumentNullException(nameof(nugetRestoreProcess));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _solutionProvider = solutionProvider ?? throw new ArgumentNullException(nameof(solutionProvider));
}
public IFileSystem FileSystem { get; }
public IReadOnlyCollection ResolveSourceProjectInfos(IStrykerOptions options)
{
- var manager = _analyzerProvider.Provide(options.SolutionPath, options.DevMode ? new AnalyzerManagerOptions { LogWriter = _buildalyzerLog } : null);
+ var manager = _analyzerProvider.Provide(options.DevMode ? new AnalyzerManagerOptions { LogWriter = _buildalyzerLog } : null);
+
+ Dictionary> findMutableAnalyzerResults;
if (options.IsSolutionContext)
{
- var projectList = manager.Projects.Values.Select(p => p.ProjectFile.Path).ToList();
+ SolutionFile solution;
+
+ try
+ {
+ solution = _solutionProvider.GetSolution(options.SolutionPath);
+ }
+ catch (IOException e)
+ {
+ _logger.LogError(e, "Failed to load solution file {0}.", options.SolutionPath);
+ return [];
+ }
+ catch (UnauthorizedAccessException e)
+ {
+ _logger.LogError(e, "Failed to access solution file {0}.", options.SolutionPath);
+ return [];
+ }
+ catch (AggregateException e) // Handles exceptions from .Result on Task
+ {
+ _logger.LogError(e, "Failed to load solution file {0}.", options.SolutionPath);
+ return [];
+ }
_logger.LogInformation("Identifying projects to mutate in {solution}. This can take a while.", options.SolutionPath);
- return AnalyzeAndIdentifyProjects(projectList, options, manager, ScanMode.NoScan);
+ // build all projects
+ var projectsWithDetails = solution.GetProjectsWithDetails(options.Configuration, options.Platform)
+ .Select(p => (p.file, options.TargetFramework, p.buildType)).ToList();
+ _logger.LogDebug("Analyzing {0} projects.", projectsWithDetails.Count);
+ // we match test projects to mutable projects
+ findMutableAnalyzerResults = FindMutableAnalyzerResults(AnalyzeAllNeededProjects(projectsWithDetails, options, manager, ScanMode.NoScan));
+
+ return findMutableAnalyzerResults.Count != 0 ? AnalyzeAndIdentifyProjects(options, findMutableAnalyzerResults)
+ : throw new InputException("No project references found. Please add a project reference to your test project and retry.");
}
// we analyze the test project(s) and identify the project to be mutated
- List testProjectFileNames;
- if (options.TestProjects != null && options.TestProjects.Any())
- {
- testProjectFileNames = options.TestProjects.Select(FindTestProject).ToList();
- }
- else
+ var testProjectFileNames = options.TestProjects.Any() ? options.TestProjects.Select(FindTestProject).ToList()
+ : [FindTestProject(options.ProjectPath)];
+
+ _logger.LogInformation("Analyzing {0} test project(s).", testProjectFileNames.Count);
+ List<(string projectFile, string framework, string configuration)> projectList =
+ [..testProjectFileNames.Select(p => (p, options.TargetFramework, options.Configuration))];
+ // we match test projects to mutable projects
+ findMutableAnalyzerResults = FindMutableAnalyzerResults(AnalyzeAllNeededProjects(projectList, options, manager, ScanMode.ScanTestProjectReferences));
+
+ if (findMutableAnalyzerResults.All(p => p.Value.All(r => !r.Succeeded)) )
{
- testProjectFileNames = [FindTestProject(options.ProjectPath)];
+ var failedProjects = findMutableAnalyzerResults
+ .Select(p => p.Key.ProjectFilePath)
+ .Distinct()
+ .ToList();
+ _logger.LogError("Aborting, analysis failed for every projects: {FailedProjects}", string.Join(", ", failedProjects));
+ // no mutable project found
+ throw new InputException("No project references found. Please add a project reference to your test project and retry.");
}
-
- _logger.LogInformation("Analyzing {count} test project(s).", testProjectFileNames.Count);
- var result = AnalyzeAndIdentifyProjects(testProjectFileNames, options, manager, ScanMode.ScanTestProjectReferences);
+ var result = AnalyzeAndIdentifyProjects(options, findMutableAnalyzerResults);
if (result.Count <= 1)
{
return result;
@@ -108,62 +152,65 @@ private enum ScanMode
ScanTestProjectReferences = 1 // add test project references during scan
}
- private List AnalyzeAndIdentifyProjects(List projectList, IStrykerOptions options,
- IAnalyzerManager manager, ScanMode mode)
+ private List AnalyzeAndIdentifyProjects(IStrykerOptions options,
+ Dictionary> findMutableAnalyzerResults)
{
- // build all projects
- if (!string.IsNullOrEmpty(options.Configuration))
- {
- manager.SetGlobalProperty("Configuration", options.Configuration);
- }
- _logger.LogDebug("Analyzing {count} projects.", manager.Projects.Count);
-
- // we match test projects to mutable projects
- var findMutableAnalyzerResults = FindMutableAnalyzerResults(AnalyzeAllNeededProjects(projectList, options, manager, mode));
-
if (findMutableAnalyzerResults.Count == 0)
{
// no mutable project found
throw new InputException("No project references found. Please add a project reference to your test project and retry.");
}
+ // we match test projects to mutable projects
var analyzerResults = findMutableAnalyzerResults.Keys.GroupBy(p => p.ProjectFilePath).ToList();
var projectInfos = new List();
foreach (var group in analyzerResults)
{
// we must select projects according to framework settings if any
var analyzerResult = SelectAnalyzerResult(group, options.TargetFramework);
-
projectInfos.Add(BuildSourceProjectInfo(options, analyzerResult, findMutableAnalyzerResults[analyzerResult]));
}
- if (projectInfos.Count == 0)
+ if (projectInfos.Count != 0)
{
- _logger.LogError("Project analysis failed.");
- throw new InputException("No valid project analysis results could be found.");
+ return projectInfos;
}
- return projectInfos;
+
+ _logger.LogError("Project analysis failed.");
+ throw new InputException("No valid project analysis results could be found.");
}
- private ConcurrentBag<(IEnumerable result, bool isTest)> AnalyzeAllNeededProjects(List projectList, IStrykerOptions options, IAnalyzerManager manager, ScanMode mode)
+ private ConcurrentBag<(IEnumerable result, bool isTest)> AnalyzeAllNeededProjects(
+ List<(string projectFile, string framework, string configuration)> projects, IStrykerOptions options
+ , IAnalyzerManager manager, ScanMode mode)
{
var mutableProjectsAnalyzerResults = new ConcurrentBag<(IEnumerable result, bool isTest)>();
+ var list = new DynamicEnumerableQueue<(string projectFile, string framework, string configuration)>(projects);
+ const string Configuration = "Configuration";
try
{
- var list = new DynamicEnumerableQueue<(string projectFile, string framework)>(projectList.Select(p => (p, options.TargetFramework)));
+ var parallelOptions = new ParallelOptions
+ { MaxDegreeOfParallelism = options.DevMode ? 1 : Math.Max(options.Concurrency, 1) };
var normalizedProjectUnderTestNameFilter = !string.IsNullOrEmpty(options.SourceProjectName) ? options.SourceProjectName.Replace("\\", "/") : null;
while (!list.Empty)
{
Parallel.ForEach(list.Consume(),
- new ParallelOptions
- { MaxDegreeOfParallelism = options.DevMode ? 1 : Math.Max(options.Concurrency, 1) }, entry =>
+ parallelOptions, entry =>
{
- var buildResult = GetProjectAndAddIt(options, manager, entry, normalizedProjectUnderTestNameFilter, mutableProjectsAnalyzerResults);
-
- foreach (var reference in ScanReferences(mode, buildResult))
+ // specify configuration if any provided
+ if (!string.IsNullOrEmpty(entry.configuration))
+ {
+ manager.SetGlobalProperty(Configuration, entry.configuration);
+ }
+ else
{
- list.Add((reference, null));
+ manager.RemoveGlobalProperty(Configuration);
}
+ var buildResult = AnalyzeThisProject(options,
+ manager.GetProject(entry.projectFile), entry.framework, normalizedProjectUnderTestNameFilter,
+ mutableProjectsAnalyzerResults);
+ // scan references if recursive scan is enabled
+ ScanReferences(mode, buildResult).ForEach(p => list.Add((p, entry.framework, options.Configuration)));
}
);
}
@@ -176,27 +223,28 @@ private List AnalyzeAndIdentifyProjects(List projectL
return mutableProjectsAnalyzerResults;
}
- private IEnumerable GetProjectAndAddIt(IStrykerOptions options, IAnalyzerManager manager,
- (string projectFile, string framework) entry, string normalizedProjectUnderTestNameFilter,
+ private IEnumerable AnalyzeThisProject(IStrykerOptions options, IProjectAnalyzer project,
+ string framework, string normalizedProjectUnderTestNameFilter,
ConcurrentBag<(IEnumerable result, bool isTest)> mutableProjectsAnalyzerResults)
{
- var project = manager.GetProject(entry.projectFile);
IEnumerable buildResult = AnalyzeSingleProject(project, options);
if (!buildResult.Any())
{
- // analysis failed
return buildResult;
}
+
var isTestProject = buildResult.IsTestProject();
if (isTestProject)
{
- buildResult = [SelectAnalyzerResult(buildResult, entry.framework)];
+ // filter frameworks for test projects (if one is selected)
+ buildResult = [SelectAnalyzerResult(buildResult, framework)];
}
// apply project name filter (except for test projects)
if (isTestProject || normalizedProjectUnderTestNameFilter == null ||
project.ProjectFile.Path.Replace('\\', '/')
- .Contains(normalizedProjectUnderTestNameFilter, StringComparison.InvariantCultureIgnoreCase))
+ .Contains(normalizedProjectUnderTestNameFilter,
+ StringComparison.InvariantCultureIgnoreCase))
{
mutableProjectsAnalyzerResults.Add((buildResult, isTestProject));
}
@@ -213,25 +261,15 @@ private IEnumerable GetProjectAndAddIt(IStrykerOptions options,
private List ScanReferences(ScanMode mode, IEnumerable buildResult)
{
var referencesToAdd = new List