Added an ITestRunnerResolverFactory that decides on which resolver to use based on the set of parameters received.
This commit is contained in:
parent
8e432e567a
commit
0667e84069
10 changed files with 184 additions and 29 deletions
10
src/Microsoft.DotNet.ProjectModel/IProjectReader.cs
Normal file
10
src/Microsoft.DotNet.ProjectModel/IProjectReader.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel
|
||||||
|
{
|
||||||
|
public interface IProjectReader
|
||||||
|
{
|
||||||
|
Project ReadProject(string projectPath, ProjectReaderSettings settings = null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ using NuGet.Versioning;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel
|
namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
public class ProjectReader
|
public class ProjectReader : IProjectReader
|
||||||
{
|
{
|
||||||
public static bool TryGetProject(string path, out Project project, ProjectReaderSettings settings = null)
|
public static bool TryGetProject(string path, out Project project, ProjectReaderSettings settings = null)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null)
|
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null)
|
||||||
|
{
|
||||||
|
return new ProjectReader().ReadProject(projectPath, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Project ReadProject(string projectPath, ProjectReaderSettings settings)
|
||||||
{
|
{
|
||||||
projectPath = ProjectPathHelper.NormalizeProjectFilePath(projectPath);
|
projectPath = ProjectPathHelper.NormalizeProjectFilePath(projectPath);
|
||||||
|
|
||||||
|
@ -70,7 +75,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
using (var stream = new FileStream(projectPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
using (var stream = new FileStream(projectPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
return new ProjectReader().ReadProject(stream, name, projectPath, settings);
|
return ReadProject(stream, name, projectPath, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
$"--configuration",
|
$"--configuration",
|
||||||
dotnetTestParams.Config,
|
dotnetTestParams.Config,
|
||||||
$"{dotnetTestParams.ProjectPath}"
|
$"{dotnetTestParams.ProjectOrAssemblyPath}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the test specifically for the target framework \ rid of the ProjectContext. This avoids building the project
|
// Build the test specifically for the target framework \ rid of the ProjectContext. This avoids building the project
|
||||||
|
|
|
@ -23,8 +23,9 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
private CommandOption _configurationOption;
|
private CommandOption _configurationOption;
|
||||||
private CommandOption _portOption;
|
private CommandOption _portOption;
|
||||||
private CommandOption _parentProcessIdOption;
|
private CommandOption _parentProcessIdOption;
|
||||||
private CommandArgument _projectPath;
|
private CommandArgument _projectOrAssemblyPath;
|
||||||
private CommandOption _noBuildOption;
|
private CommandOption _noBuildOption;
|
||||||
|
private CommandOption _testRunner;
|
||||||
|
|
||||||
public int? Port { get; set; }
|
public int? Port { get; set; }
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
public string Output { get; set; }
|
public string Output { get; set; }
|
||||||
|
|
||||||
public string ProjectPath { get; set; }
|
public string ProjectOrAssemblyPath { get; set; }
|
||||||
|
|
||||||
public NuGetFramework Framework { get; set; }
|
public NuGetFramework Framework { get; set; }
|
||||||
|
|
||||||
|
@ -50,6 +51,10 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
public bool Help { get; set; }
|
public bool Help { get; set; }
|
||||||
|
|
||||||
|
public string TestRunner { get; set; }
|
||||||
|
|
||||||
|
public bool HasTestRunner => !string.IsNullOrWhiteSpace(TestRunner);
|
||||||
|
|
||||||
public DotnetTestParams()
|
public DotnetTestParams()
|
||||||
{
|
{
|
||||||
_app = new CommandLineApplication(false)
|
_app = new CommandLineApplication(false)
|
||||||
|
@ -69,10 +74,10 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
_app.OnExecute(() =>
|
_app.OnExecute(() =>
|
||||||
{
|
{
|
||||||
// Locate the project and get the name and full path
|
// Locate the project and get the name and full path
|
||||||
ProjectPath = _projectPath.Value;
|
ProjectOrAssemblyPath = _projectOrAssemblyPath.Value;
|
||||||
if (string.IsNullOrEmpty(ProjectPath))
|
if (string.IsNullOrEmpty(ProjectOrAssemblyPath))
|
||||||
{
|
{
|
||||||
ProjectPath = Directory.GetCurrentDirectory();
|
ProjectOrAssemblyPath = Directory.GetCurrentDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_parentProcessIdOption.HasValue())
|
if (_parentProcessIdOption.HasValue())
|
||||||
|
@ -156,9 +161,16 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
CommandOptionType.SingleValue);
|
CommandOptionType.SingleValue);
|
||||||
_noBuildOption =
|
_noBuildOption =
|
||||||
_app.Option("--no-build", "Do not build project before testing", CommandOptionType.NoValue);
|
_app.Option("--no-build", "Do not build project before testing", CommandOptionType.NoValue);
|
||||||
_projectPath = _app.Argument(
|
_testRunner =
|
||||||
"<PROJECT>",
|
_app.Option(
|
||||||
"The project to test, defaults to the current directory. Can be a path to a project.json or a project directory.");
|
"-t|--test-runner <TEST_RUNNER>",
|
||||||
|
"Test runner to be used to run the test when an assembly to test is specified. If this option " +
|
||||||
|
"is not provided, we will try to find a suitable runner collocated with the assembly",
|
||||||
|
CommandOptionType.SingleValue);
|
||||||
|
_projectOrAssemblyPath = _app.Argument(
|
||||||
|
"<PROJECT OR ASSEMBLY TO TEST>",
|
||||||
|
"The project or assembly to test, defaults to the current directory. Can be a path to a " +
|
||||||
|
"project.json, to a dll or a project directory.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
RegisterForParentProcessExit(dotnetTestParams.ParentProcessId.Value);
|
RegisterForParentProcessExit(dotnetTestParams.ParentProcessId.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectPath = GetProjectPath(dotnetTestParams.ProjectPath);
|
var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath);
|
||||||
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime) ?
|
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime) ?
|
||||||
new[] { dotnetTestParams.Runtime } :
|
new[] { dotnetTestParams.Runtime } :
|
||||||
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers();
|
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers();
|
||||||
|
|
|
@ -9,24 +9,24 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public class AssemblyTestRunnerResolver : ITestRunnerResolver
|
public class AssemblyTestRunnerResolver : ITestRunnerResolver
|
||||||
{
|
{
|
||||||
private readonly string _assemblyUnderTestPath;
|
private readonly string _directoryOfAssemblyUnderTest;
|
||||||
|
|
||||||
private readonly IDirectory _directory;
|
private readonly IDirectory _directory;
|
||||||
|
|
||||||
public AssemblyTestRunnerResolver(string assemblyUnderTestPath) :
|
public AssemblyTestRunnerResolver(string directoryOfAssemblyUnderTest) :
|
||||||
this(assemblyUnderTestPath, FileSystemWrapper.Default.Directory)
|
this(directoryOfAssemblyUnderTest, FileSystemWrapper.Default.Directory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal AssemblyTestRunnerResolver(string assemblyUnderTestPath, IDirectory directory)
|
internal AssemblyTestRunnerResolver(string directoryOfAssemblyUnderTest, IDirectory directory)
|
||||||
{
|
{
|
||||||
_assemblyUnderTestPath = assemblyUnderTestPath;
|
_directoryOfAssemblyUnderTest = Path.GetDirectoryName(directoryOfAssemblyUnderTest);
|
||||||
_directory = directory;
|
_directory = directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ResolveTestRunner()
|
public string ResolveTestRunner()
|
||||||
{
|
{
|
||||||
var testRunnerPath = _directory.GetFiles(_assemblyUnderTestPath, "dotnet-test-*").FirstOrDefault();
|
var testRunnerPath = _directory.GetFiles(_directoryOfAssemblyUnderTest, "dotnet-test-*").FirstOrDefault();
|
||||||
|
|
||||||
return Path.GetFileNameWithoutExtension(testRunnerPath);
|
return Path.GetFileNameWithoutExtension(testRunnerPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
|
{
|
||||||
|
public class DotnetTestRunnerResolverFactory
|
||||||
|
{
|
||||||
|
private readonly IProjectReader _projectReader;
|
||||||
|
|
||||||
|
public DotnetTestRunnerResolverFactory(IProjectReader projectReader)
|
||||||
|
{
|
||||||
|
_projectReader = projectReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITestRunnerResolver Create(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
var testRunnerResolver = dotnetTestParams.ProjectOrAssemblyPath.EndsWith(".dll") ?
|
||||||
|
GetAssemblyTestRunnerResolver(dotnetTestParams) :
|
||||||
|
GetProjectJsonTestRunnerResolver(dotnetTestParams);
|
||||||
|
|
||||||
|
return testRunnerResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITestRunnerResolver GetAssemblyTestRunnerResolver(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
ITestRunnerResolver testRunnerResolver = null;
|
||||||
|
if (dotnetTestParams.HasTestRunner)
|
||||||
|
{
|
||||||
|
testRunnerResolver = new ParameterTestRunnerResolver(dotnetTestParams.TestRunner);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
testRunnerResolver = new AssemblyTestRunnerResolver(dotnetTestParams.ProjectOrAssemblyPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return testRunnerResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITestRunnerResolver GetProjectJsonTestRunnerResolver(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
var project = _projectReader.ReadProject(dotnetTestParams.ProjectOrAssemblyPath);
|
||||||
|
return new ProjectJsonTestRunnerResolver(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.Tools.Test;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
|
{
|
||||||
|
public class GivenATestRunnerResolverFactoryAndADotnetTestParams
|
||||||
|
{
|
||||||
|
private const string PathToAFolder = "c:/some/path";
|
||||||
|
private const string PathToAnAssembly = "c:/some/path/to/assembly.dll";
|
||||||
|
private const string SomeTestRunner = "some test runner";
|
||||||
|
|
||||||
|
private readonly string _pathToAProjectJson = Path.Combine(PathToAFolder, "project.json");
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_returns_a_ProjectJsonTestRunnerResolver_when_the_path_parameter_points_to_a_project_json()
|
||||||
|
{
|
||||||
|
var dotnetTestParams = new DotnetTestParams
|
||||||
|
{
|
||||||
|
ProjectOrAssemblyPath = _pathToAProjectJson
|
||||||
|
};
|
||||||
|
|
||||||
|
var projectReaderMock = new Mock<IProjectReader>();
|
||||||
|
projectReaderMock
|
||||||
|
.Setup(p => p.ReadProject(dotnetTestParams.ProjectOrAssemblyPath, null))
|
||||||
|
.Returns(new Project());
|
||||||
|
|
||||||
|
var dotnetTestRunnerResolverFactory = new DotnetTestRunnerResolverFactory(projectReaderMock.Object);
|
||||||
|
|
||||||
|
var testRunnerResolver = dotnetTestRunnerResolverFactory.Create(dotnetTestParams);
|
||||||
|
|
||||||
|
testRunnerResolver.Should().BeOfType<ProjectJsonTestRunnerResolver>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_returns_a_ProjectJsonTestRunnerResolver_when_the_path_parameter_points_to_a_folder()
|
||||||
|
{
|
||||||
|
var dotnetTestParams = new DotnetTestParams
|
||||||
|
{
|
||||||
|
ProjectOrAssemblyPath = PathToAFolder
|
||||||
|
};
|
||||||
|
|
||||||
|
var projectReaderMock = new Mock<IProjectReader>();
|
||||||
|
projectReaderMock
|
||||||
|
.Setup(p => p.ReadProject(dotnetTestParams.ProjectOrAssemblyPath, null))
|
||||||
|
.Returns(new Project());
|
||||||
|
|
||||||
|
var dotnetTestRunnerResolverFactory = new DotnetTestRunnerResolverFactory(projectReaderMock.Object);
|
||||||
|
|
||||||
|
var testRunnerResolver = dotnetTestRunnerResolverFactory.Create(dotnetTestParams);
|
||||||
|
|
||||||
|
testRunnerResolver.Should().BeOfType<ProjectJsonTestRunnerResolver>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_returns_a_ParameterTestRunnerResolver_when_an_assembly_and_a_test_runner_are_passed()
|
||||||
|
{
|
||||||
|
var dotnetTestParams = new DotnetTestParams
|
||||||
|
{
|
||||||
|
ProjectOrAssemblyPath = PathToAnAssembly,
|
||||||
|
TestRunner = SomeTestRunner
|
||||||
|
};
|
||||||
|
|
||||||
|
var projectReaderMock = new Mock<IProjectReader>();
|
||||||
|
|
||||||
|
var dotnetTestRunnerResolverFactory = new DotnetTestRunnerResolverFactory(projectReaderMock.Object);
|
||||||
|
|
||||||
|
var testRunnerResolver = dotnetTestRunnerResolverFactory.Create(dotnetTestParams);
|
||||||
|
|
||||||
|
testRunnerResolver.Should().BeOfType<ParameterTestRunnerResolver>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
@ -14,20 +15,21 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
{
|
{
|
||||||
public class GivenAnAssemblyTestRunnerResolver
|
public class GivenAnAssemblyTestRunnerResolver
|
||||||
{
|
{
|
||||||
private const string PathToAssemblyUnderTest = "path to some assembly under test";
|
private const string DirectoryOfAssemblyUnderTest = "c:/some/path";
|
||||||
|
|
||||||
private const string TestRunnerName = "dotnet-test-someRunner";
|
private const string TestRunnerName = "dotnet-test-someRunner";
|
||||||
|
|
||||||
private static readonly string TestRunnerFileName = $"{TestRunnerName}.dll";
|
private static readonly string TestRunnerFileName = $"{TestRunnerName}.dll";
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_finds_the_runner_in_the_same_folder_as_the_assembly()
|
public void It_finds_the_runner_in_the_same_folder_as_the_assembly_when_the_path_passed_is_to_the_assembly()
|
||||||
{
|
{
|
||||||
var directoryMock = new DirectoryMock();
|
var directoryMock = new DirectoryMock();
|
||||||
|
|
||||||
directoryMock.AddFile(PathToAssemblyUnderTest, TestRunnerFileName);
|
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, TestRunnerFileName);
|
||||||
|
|
||||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(PathToAssemblyUnderTest, directoryMock);
|
var pathToAssemblyUnderTest = Path.Combine(DirectoryOfAssemblyUnderTest, TestRunnerFileName);
|
||||||
|
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(pathToAssemblyUnderTest, directoryMock);
|
||||||
|
|
||||||
var testRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
var testRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
||||||
|
|
||||||
|
@ -39,11 +41,11 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
{
|
{
|
||||||
var directoryMock = new DirectoryMock();
|
var directoryMock = new DirectoryMock();
|
||||||
|
|
||||||
directoryMock.AddFile(PathToAssemblyUnderTest, TestRunnerFileName);
|
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, TestRunnerFileName);
|
||||||
directoryMock.AddFile(PathToAssemblyUnderTest, "dotnet-test-someOtherTestRunner.dll");
|
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, "dotnet-test-someOtherTestRunner.dll");
|
||||||
directoryMock.AddFile(PathToAssemblyUnderTest, "dotnet-test-AndYetAnotherTestRunner.dll");
|
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, "dotnet-test-AndYetAnotherTestRunner.dll");
|
||||||
|
|
||||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(PathToAssemblyUnderTest, directoryMock);
|
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(DirectoryOfAssemblyUnderTest, directoryMock);
|
||||||
|
|
||||||
var bestEffortTestRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
var bestEffortTestRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
{
|
{
|
||||||
var directoryMock = new DirectoryMock();
|
var directoryMock = new DirectoryMock();
|
||||||
|
|
||||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(PathToAssemblyUnderTest, directoryMock);
|
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(DirectoryOfAssemblyUnderTest, directoryMock);
|
||||||
|
|
||||||
var testRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
var testRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
||||||
|
|
||||||
|
|
|
@ -48,13 +48,13 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_sets_the_project_path_current_folder_if_one_is_not_passed_in()
|
public void It_sets_the_project_path_current_folder_if_one_is_not_passed_in()
|
||||||
{
|
{
|
||||||
_emptyDotnetTestParams.ProjectPath.Should().Be(Directory.GetCurrentDirectory());
|
_emptyDotnetTestParams.ProjectOrAssemblyPath.Should().Be(Directory.GetCurrentDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_sets_the_project_path_to_the_passed_value()
|
public void It_sets_the_project_path_to_the_passed_value()
|
||||||
{
|
{
|
||||||
_dotnetTestFullParams.ProjectPath.Should().Be(ProjectJson);
|
_dotnetTestFullParams.ProjectOrAssemblyPath.Should().Be(ProjectJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
Loading…
Reference in a new issue