Refactoring dotnet-compile to make adding the script variable testable. So far, moved it to have a compiler controller and two separate compilers: native and managed. Also moved the script runner to its own class so that we can mock it into the managed controller.
Adding a ICommand interface and factory that we can use to mock Commands and avoid actually running them in unit tests.
This commit is contained in:
parent
732f3d7abd
commit
4e1ec4c159
21 changed files with 1179 additions and 632 deletions
|
@ -0,0 +1,83 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.Tools.Compiler;
|
||||
using Moq;
|
||||
using NuGet.Frameworks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Tests
|
||||
{
|
||||
public class GivenACompilationDriverController
|
||||
{
|
||||
private string _projectJson;
|
||||
private Mock<ICompiler> _managedCompilerMock;
|
||||
private Mock<ICompiler> _nativeCompilerMock;
|
||||
private List<ProjectContext> _contexts;
|
||||
private CompilerCommandApp _args;
|
||||
|
||||
public GivenACompilationDriverController()
|
||||
{
|
||||
_projectJson =
|
||||
Path.Combine(AppContext.BaseDirectory, "TestAssets", "TestProjects", "TestApp", "project.json");
|
||||
_managedCompilerMock = new Mock<ICompiler>();
|
||||
_managedCompilerMock.Setup(c => c
|
||||
.Compile(It.IsAny<ProjectContext>(), It.IsAny<CompilerCommandApp>()))
|
||||
.Returns(true);
|
||||
_nativeCompilerMock = new Mock<ICompiler>();
|
||||
_nativeCompilerMock.Setup(c => c
|
||||
.Compile(It.IsAny<ProjectContext>(), It.IsAny<CompilerCommandApp>()))
|
||||
.Returns(true);
|
||||
|
||||
_contexts = new List<ProjectContext>
|
||||
{
|
||||
ProjectContext.Create(_projectJson, new NuGetFramework(string.Empty))
|
||||
};
|
||||
|
||||
_args = new CompilerCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_compiles_all_project_contexts()
|
||||
{
|
||||
var compiledProjectContexts = new List<ProjectContext>();
|
||||
_managedCompilerMock.Setup(c => c
|
||||
.Compile(It.IsAny<ProjectContext>(), It.IsAny<CompilerCommandApp>()))
|
||||
.Callback<ProjectContext, CompilerCommandApp>((p, c) => compiledProjectContexts.Add(p))
|
||||
.Returns(true);
|
||||
|
||||
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
|
||||
|
||||
compilerController.Compile(_contexts, _args);
|
||||
|
||||
compiledProjectContexts.Should().BeEquivalentTo(_contexts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_does_not_compile_native_when_the_native_parameter_is_not_passed()
|
||||
{
|
||||
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
|
||||
|
||||
compilerController.Compile(_contexts, _args);
|
||||
|
||||
_nativeCompilerMock.Verify(c => c.Compile(It.IsAny<ProjectContext>(), It.IsAny<CompilerCommandApp>()), Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_does_compile_native_when_the_native_parameter_is_passed()
|
||||
{
|
||||
var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
|
||||
|
||||
_args.IsNativeValue = true;
|
||||
|
||||
compilerController.Compile(_contexts, _args);
|
||||
|
||||
_nativeCompilerMock.Verify(c => c.Compile(It.IsAny<ProjectContext>(), It.IsAny<CompilerCommandApp>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Moq;
|
||||
using NuGet.Frameworks;
|
||||
using Xunit;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using FluentAssertions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler.Tests
|
||||
{
|
||||
public class GivenThatICareAboutScriptVariablesFromAManagedCompiler : IClassFixture<ScriptVariablesFixture>
|
||||
{
|
||||
private readonly ScriptVariablesFixture _fixture;
|
||||
|
||||
public GivenThatICareAboutScriptVariablesFromAManagedCompiler(ScriptVariablesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_TargetFramework_variable_to_the_pre_compile_scripts()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().ContainKey("compile:TargetFramework");
|
||||
_fixture.PreCompileScriptVariables["compile:TargetFramework"].Should().Be("dnxcore,Version=v5.0");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_Configuration_variable_to_the_pre_compile_scripts()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().ContainKey("compile:Configuration");
|
||||
_fixture.PreCompileScriptVariables["compile:Configuration"].Should().Be(
|
||||
ScriptVariablesFixture.ConfigValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_OutputFile_variable_to_the_pre_compile_scripts()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().ContainKey("compile:OutputFile");
|
||||
_fixture.PreCompileScriptVariables["compile:OutputFile"].Should().Be(ScriptVariablesFixture.OutputFile);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_OutputDir_variable_to_the_pre_compile_scripts()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().ContainKey("compile:OutputDir");
|
||||
_fixture.PreCompileScriptVariables["compile:OutputDir"].Should().Be(ScriptVariablesFixture.OutputPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_ResponseFile_variable_to_the_pre_compile_scripts()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().ContainKey("compile:ResponseFile");
|
||||
_fixture.PreCompileScriptVariables["compile:ResponseFile"].Should().Be(ScriptVariablesFixture.ResponseFile);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_does_not_pass_a_RuntimeOutputDir_variable_to_the_pre_compile_scripts_if_rid_is_not_set_in()
|
||||
{
|
||||
_fixture.PreCompileScriptVariables.Should().NotContainKey("compile:RuntimeOutputDir");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_RuntimeOutputDir_variable_to_the_pre_compile_scripts_if_rid_is_set_in_the_ProjectContext()
|
||||
{
|
||||
var fixture = ScriptVariablesFixture.GetFixtureWithRids(new[] { "win7-x64" });
|
||||
fixture.PreCompileScriptVariables.Should().ContainKey("compile:RuntimeOutputDir");
|
||||
fixture.PreCompileScriptVariables["compile:RuntimeOutputDir"].Should().Be(
|
||||
ScriptVariablesFixture.RuntimeOutputDir);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_TargetFramework_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:TargetFramework");
|
||||
_fixture.PostCompileScriptVariables["compile:TargetFramework"].Should().Be("dnxcore,Version=v5.0");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_Configuration_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:Configuration");
|
||||
_fixture.PostCompileScriptVariables["compile:Configuration"].Should().Be(
|
||||
ScriptVariablesFixture.ConfigValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_OutputFile_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:OutputFile");
|
||||
_fixture.PostCompileScriptVariables["compile:OutputFile"].Should().Be(ScriptVariablesFixture.OutputFile);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_OutputDir_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:OutputDir");
|
||||
_fixture.PostCompileScriptVariables["compile:OutputDir"].Should().Be(ScriptVariablesFixture.OutputPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_ResponseFile_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:ResponseFile");
|
||||
_fixture.PostCompileScriptVariables["compile:ResponseFile"].Should().Be(ScriptVariablesFixture.ResponseFile);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_CompilerExitCode_variable_to_the_post_compile_scripts()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().ContainKey("compile:CompilerExitCode");
|
||||
_fixture.PostCompileScriptVariables["compile:CompilerExitCode"].Should().Be("0");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_does_not_pass_a_RuntimeOutputDir_variable_to_the_post_compile_scripts_if_rid_is_not_set_in_the_ProjectContext()
|
||||
{
|
||||
_fixture.PostCompileScriptVariables.Should().NotContainKey("compile:RuntimeOutputDir");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_passes_a_RuntimeOutputDir_variable_to_the_post_compile_scripts_if_rid_is_set_in_the_ProjectContext()
|
||||
{
|
||||
var fixture = ScriptVariablesFixture.GetFixtureWithRids(new [] { "win7-x64" });
|
||||
fixture.PostCompileScriptVariables.Should().ContainKey("compile:RuntimeOutputDir");
|
||||
fixture.PostCompileScriptVariables["compile:RuntimeOutputDir"].Should().Be(
|
||||
ScriptVariablesFixture.RuntimeOutputDir);
|
||||
}
|
||||
}
|
||||
|
||||
public class ScriptVariablesFixture
|
||||
{
|
||||
public const string ConfigValue = "Debug";
|
||||
|
||||
public static string TestAssetPath = Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
"TestAssets",
|
||||
"TestProjects",
|
||||
"TestApp");
|
||||
|
||||
public static string OutputPath = Path.Combine(
|
||||
TestAssetPath,
|
||||
"bin",
|
||||
ConfigValue,
|
||||
"dnxcore50");
|
||||
|
||||
public static string RuntimeOutputDir = Path.Combine(OutputPath, "win7-x64");
|
||||
|
||||
public static string OutputFile = Path.Combine(OutputPath, "TestApp.dll");
|
||||
|
||||
public static string ResponseFile = Path.Combine(
|
||||
TestAssetPath,
|
||||
"obj",
|
||||
ConfigValue,
|
||||
"dnxcore50",
|
||||
"dotnet-compile.rsp");
|
||||
|
||||
public Dictionary<string, string> PreCompileScriptVariables { get; private set; }
|
||||
public Dictionary<string, string> PostCompileScriptVariables { get; private set; }
|
||||
|
||||
public ScriptVariablesFixture() : this(Enumerable.Empty<string>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private ScriptVariablesFixture(IEnumerable<string> rids)
|
||||
{
|
||||
var projectJson = Path.Combine(TestAssetPath, "project.json");
|
||||
var command = new Mock<ICommand>();
|
||||
command.Setup(c => c.Execute()).Returns(new CommandResult());
|
||||
command.Setup(c => c.OnErrorLine(It.IsAny<Action<string>>())).Returns(() => command.Object);
|
||||
command.Setup(c => c.OnOutputLine(It.IsAny<Action<string>>())).Returns(() => command.Object);
|
||||
var commandFactory = new Mock<ICommandFactory>();
|
||||
commandFactory.Setup(c => c
|
||||
.Create(
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<IEnumerable<string>>(),
|
||||
It.IsAny<NuGetFramework>(),
|
||||
It.IsAny<bool>()))
|
||||
.Returns(command.Object);
|
||||
|
||||
var _args = new CompilerCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform");
|
||||
_args.ConfigValue = ConfigValue;
|
||||
|
||||
PreCompileScriptVariables = new Dictionary<string, string>();
|
||||
PostCompileScriptVariables = new Dictionary<string, string>();
|
||||
|
||||
var _scriptRunner = new Mock<IScriptRunner>();
|
||||
_scriptRunner.Setup(
|
||||
s =>
|
||||
s.RunScripts(It.IsAny<ProjectContext>(), It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
|
||||
.Callback<ProjectContext, string, Dictionary<string, string>>((p, n, v) =>
|
||||
{
|
||||
if (n.Equals(ScriptNames.PreCompile))
|
||||
{
|
||||
PreCompileScriptVariables = v;
|
||||
}
|
||||
|
||||
if (n.Equals(ScriptNames.PostCompile))
|
||||
{
|
||||
PostCompileScriptVariables = v;
|
||||
}
|
||||
});
|
||||
|
||||
var managedCompiler = new ManagedCompiler(_scriptRunner.Object, commandFactory.Object);
|
||||
|
||||
var context = ProjectContext.Create(projectJson, new NuGetFramework("dnxcore", new Version(5, 0)), rids);
|
||||
managedCompiler.Compile(context, _args);
|
||||
}
|
||||
|
||||
public static ScriptVariablesFixture GetFixtureWithRids(IEnumerable<string> rids)
|
||||
{
|
||||
return new ScriptVariablesFixture(rids);
|
||||
}
|
||||
}
|
||||
}
|
19
test/dotnet-compile.UnitTests/dotnet-compile.UnitTests.xproj
Normal file
19
test/dotnet-compile.UnitTests/dotnet-compile.UnitTests.xproj
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>920b71d8-62da-4f5e-8a26-926c113f1d97</ProjectGuid>
|
||||
<RootNamespace>dotnet-compile.UnitTests</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
34
test/dotnet-compile.UnitTests/project.json
Normal file
34
test/dotnet-compile.UnitTests/project.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.0.0-rc2-23805",
|
||||
|
||||
"Microsoft.DotNet.Cli.Utils": {
|
||||
"target": "project",
|
||||
"type": "build"
|
||||
},
|
||||
|
||||
"dotnet": { "target": "project" },
|
||||
"Microsoft.DotNet.ProjectModel": { "target": "project" },
|
||||
|
||||
"xunit": "2.1.0",
|
||||
"dotnet-test-xunit": "1.0.0-dev-48273-16",
|
||||
"moq.netcore": "4.4.0-beta8",
|
||||
"FluentAssertions": "4.2.2"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
"imports": "portable-net451+win8"
|
||||
}
|
||||
},
|
||||
|
||||
"content": [
|
||||
"../../TestAssets/TestProjects/TestLibrary/*",
|
||||
"../../TestAssets/TestProjects/TestApp/*",
|
||||
"../../TestAssets/TestProjects/global.json"
|
||||
],
|
||||
|
||||
"testRunner": "xunit"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue