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
|
||||
{
|
||||
public class ProjectReader
|
||||
public class ProjectReader : IProjectReader
|
||||
{
|
||||
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)
|
||||
{
|
||||
return new ProjectReader().ReadProject(projectPath, settings);
|
||||
}
|
||||
|
||||
public Project ReadProject(string projectPath, ProjectReaderSettings settings)
|
||||
{
|
||||
projectPath = ProjectPathHelper.NormalizeProjectFilePath(projectPath);
|
||||
|
||||
|
@ -70,7 +75,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
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",
|
||||
dotnetTestParams.Config,
|
||||
$"{dotnetTestParams.ProjectPath}"
|
||||
$"{dotnetTestParams.ProjectOrAssemblyPath}"
|
||||
};
|
||||
|
||||
// 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 _portOption;
|
||||
private CommandOption _parentProcessIdOption;
|
||||
private CommandArgument _projectPath;
|
||||
private CommandArgument _projectOrAssemblyPath;
|
||||
private CommandOption _noBuildOption;
|
||||
private CommandOption _testRunner;
|
||||
|
||||
public int? Port { get; set; }
|
||||
|
||||
|
@ -38,7 +39,7 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
public string Output { get; set; }
|
||||
|
||||
public string ProjectPath { get; set; }
|
||||
public string ProjectOrAssemblyPath { get; set; }
|
||||
|
||||
public NuGetFramework Framework { get; set; }
|
||||
|
||||
|
@ -50,6 +51,10 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
|
||||
public bool Help { get; set; }
|
||||
|
||||
public string TestRunner { get; set; }
|
||||
|
||||
public bool HasTestRunner => !string.IsNullOrWhiteSpace(TestRunner);
|
||||
|
||||
public DotnetTestParams()
|
||||
{
|
||||
_app = new CommandLineApplication(false)
|
||||
|
@ -69,10 +74,10 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
_app.OnExecute(() =>
|
||||
{
|
||||
// Locate the project and get the name and full path
|
||||
ProjectPath = _projectPath.Value;
|
||||
if (string.IsNullOrEmpty(ProjectPath))
|
||||
ProjectOrAssemblyPath = _projectOrAssemblyPath.Value;
|
||||
if (string.IsNullOrEmpty(ProjectOrAssemblyPath))
|
||||
{
|
||||
ProjectPath = Directory.GetCurrentDirectory();
|
||||
ProjectOrAssemblyPath = Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
if (_parentProcessIdOption.HasValue())
|
||||
|
@ -156,9 +161,16 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
CommandOptionType.SingleValue);
|
||||
_noBuildOption =
|
||||
_app.Option("--no-build", "Do not build project before testing", CommandOptionType.NoValue);
|
||||
_projectPath = _app.Argument(
|
||||
"<PROJECT>",
|
||||
"The project to test, defaults to the current directory. Can be a path to a project.json or a project directory.");
|
||||
_testRunner =
|
||||
_app.Option(
|
||||
"-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);
|
||||
}
|
||||
|
||||
var projectPath = GetProjectPath(dotnetTestParams.ProjectPath);
|
||||
var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath);
|
||||
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime) ?
|
||||
new[] { dotnetTestParams.Runtime } :
|
||||
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers();
|
||||
|
|
|
@ -9,24 +9,24 @@ namespace Microsoft.DotNet.Tools.Test
|
|||
{
|
||||
public class AssemblyTestRunnerResolver : ITestRunnerResolver
|
||||
{
|
||||
private readonly string _assemblyUnderTestPath;
|
||||
private readonly string _directoryOfAssemblyUnderTest;
|
||||
|
||||
private readonly IDirectory _directory;
|
||||
|
||||
public AssemblyTestRunnerResolver(string assemblyUnderTestPath) :
|
||||
this(assemblyUnderTestPath, FileSystemWrapper.Default.Directory)
|
||||
public AssemblyTestRunnerResolver(string directoryOfAssemblyUnderTest) :
|
||||
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;
|
||||
}
|
||||
|
||||
public string ResolveTestRunner()
|
||||
{
|
||||
var testRunnerPath = _directory.GetFiles(_assemblyUnderTestPath, "dotnet-test-*").FirstOrDefault();
|
||||
var testRunnerPath = _directory.GetFiles(_directoryOfAssemblyUnderTest, "dotnet-test-*").FirstOrDefault();
|
||||
|
||||
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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using FluentAssertions;
|
||||
|
@ -14,20 +15,21 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
|||
{
|
||||
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 static readonly string TestRunnerFileName = $"{TestRunnerName}.dll";
|
||||
|
||||
[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();
|
||||
|
||||
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();
|
||||
|
||||
|
@ -39,11 +41,11 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
|||
{
|
||||
var directoryMock = new DirectoryMock();
|
||||
|
||||
directoryMock.AddFile(PathToAssemblyUnderTest, TestRunnerFileName);
|
||||
directoryMock.AddFile(PathToAssemblyUnderTest, "dotnet-test-someOtherTestRunner.dll");
|
||||
directoryMock.AddFile(PathToAssemblyUnderTest, "dotnet-test-AndYetAnotherTestRunner.dll");
|
||||
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, TestRunnerFileName);
|
||||
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, "dotnet-test-someOtherTestRunner.dll");
|
||||
directoryMock.AddFile(DirectoryOfAssemblyUnderTest, "dotnet-test-AndYetAnotherTestRunner.dll");
|
||||
|
||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(PathToAssemblyUnderTest, directoryMock);
|
||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(DirectoryOfAssemblyUnderTest, directoryMock);
|
||||
|
||||
var bestEffortTestRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
||||
|
||||
|
@ -55,7 +57,7 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
|||
{
|
||||
var directoryMock = new DirectoryMock();
|
||||
|
||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(PathToAssemblyUnderTest, directoryMock);
|
||||
var assemblyTestRunnerResolver = new AssemblyTestRunnerResolver(DirectoryOfAssemblyUnderTest, directoryMock);
|
||||
|
||||
var testRunner = assemblyTestRunnerResolver.ResolveTestRunner();
|
||||
|
||||
|
|
|
@ -48,13 +48,13 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
|||
[Fact]
|
||||
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]
|
||||
public void It_sets_the_project_path_to_the_passed_value()
|
||||
{
|
||||
_dotnetTestFullParams.ProjectPath.Should().Be(ProjectJson);
|
||||
_dotnetTestFullParams.ProjectOrAssemblyPath.Should().Be(ProjectJson);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
Loading…
Reference in a new issue