Added an ITestRunnerResolverFactory that decides on which resolver to use based on the set of parameters received.

This commit is contained in:
Livar Cunha 2016-08-22 21:29:14 -07:00
parent 8e432e567a
commit 0667e84069
10 changed files with 184 additions and 29 deletions

View 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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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.");
}
}
}

View file

@ -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();

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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>();
}
}
}

View file

@ -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();

View file

@ -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]