Adding tests for command line parsing

Fixes #10
This commit is contained in:
Pranav K 2016-09-07 16:38:38 -07:00 коммит произвёл GitHub
Родитель d046091727
Коммит 0e54281e8b
12 изменённых файлов: 546 добавлений и 42 удалений

Просмотреть файл

@ -19,6 +19,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0398AFFF-5
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests", "test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests\Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests.xproj", "{46C9A4B2-8B1C-451B-B670-C194901D66AC}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests", "test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests\Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests.xproj", "{46C9A4B2-8B1C-451B-B670-C194901D66AC}"
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools.Test", "test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools.Test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools.Test.xproj", "{B58E3380-D451-4E54-B522-CD21404FCD58}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Test", "test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Test\Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Test.xproj", "{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -37,6 +41,14 @@ Global
{46C9A4B2-8B1C-451B-B670-C194901D66AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {46C9A4B2-8B1C-451B-B670-C194901D66AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46C9A4B2-8B1C-451B-B670-C194901D66AC}.Release|Any CPU.ActiveCfg = Release|Any CPU {46C9A4B2-8B1C-451B-B670-C194901D66AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46C9A4B2-8B1C-451B-B670-C194901D66AC}.Release|Any CPU.Build.0 = Release|Any CPU {46C9A4B2-8B1C-451B-B670-C194901D66AC}.Release|Any CPU.Build.0 = Release|Any CPU
{B58E3380-D451-4E54-B522-CD21404FCD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B58E3380-D451-4E54-B522-CD21404FCD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B58E3380-D451-4E54-B522-CD21404FCD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B58E3380-D451-4E54-B522-CD21404FCD58}.Release|Any CPU.Build.0 = Release|Any CPU
{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -45,5 +57,7 @@ Global
{4339FC9B-AEC6-442A-B413-A41555ED76C7} = {02F7AA35-91AF-491E-9F0E-03CFAF86C720} {4339FC9B-AEC6-442A-B413-A41555ED76C7} = {02F7AA35-91AF-491E-9F0E-03CFAF86C720}
{F8BF7D95-0633-407F-BB0B-02563F13C068} = {02F7AA35-91AF-491E-9F0E-03CFAF86C720} {F8BF7D95-0633-407F-BB0B-02563F13C068} = {02F7AA35-91AF-491E-9F0E-03CFAF86C720}
{46C9A4B2-8B1C-451B-B670-C194901D66AC} = {0398AFFF-505E-4283-89DA-BBD9D28B53DB} {46C9A4B2-8B1C-451B-B670-C194901D66AC} = {0398AFFF-505E-4283-89DA-BBD9D28B53DB}
{B58E3380-D451-4E54-B522-CD21404FCD58} = {0398AFFF-505E-4283-89DA-BBD9D28B53DB}
{E0D75B4E-839F-4F80-9B1F-B33F616BCC5F} = {0398AFFF-505E-4283-89DA-BBD9D28B53DB}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

Просмотреть файл

@ -37,10 +37,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.Error.WriteLine(ex.Message); Error.WriteLine(ex.Message);
#if DEBUG Error.WriteLine(ex.StackTrace);
Console.Error.WriteLine(ex);
#endif
return 1; return 1;
} }
} }
@ -48,14 +46,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
private string GetInformationalVersion() private string GetInformationalVersion()
{ {
var assembly = _callingType.GetTypeInfo().Assembly; var assembly = _callingType.GetTypeInfo().Assembly;
var attributes = assembly.GetCustomAttributes( var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute[]; return attribute.InformationalVersion;
var versionAttribute = attributes.Length == 0 ?
assembly.GetName().Version.ToString() :
attributes[0].InformationalVersion;
return versionAttribute;
} }
} }
} }

Просмотреть файл

@ -24,13 +24,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
{ {
public class PrecompileRunCommand public class PrecompileRunCommand
{ {
public static readonly string ApplicationNameTemplate = "--applicationName"; public static readonly string ApplicationNameTemplate = "--application-name";
public static readonly string OutputPathTemplate = "--output-path"; public static readonly string OutputPathTemplate = "--output-path";
private static readonly ParallelOptions ParalellOptions = new ParallelOptions private static readonly ParallelOptions ParalellOptions = new ParallelOptions
{ {
MaxDegreeOfParallelism = 4 MaxDegreeOfParallelism = 4
}; };
private CommandLineApplication Application { get; set; }
private CommandOption OutputPathOption { get; set; } private CommandOption OutputPathOption { get; set; }
private CommandOption ApplicationNameOption { get; set; } private CommandOption ApplicationNameOption { get; set; }
@ -45,6 +47,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
public void Configure(CommandLineApplication app) public void Configure(CommandLineApplication app)
{ {
Application = app;
Options.Configure(app); Options.Configure(app);
StrongNameOptions.Configure(app); StrongNameOptions.Configure(app);
@ -63,7 +66,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
private int Execute() private int Execute()
{ {
ParseArguments(); if (!ParseArguments())
{
return 1;
}
MvcServiceProvider = new MvcServiceProvider( MvcServiceProvider = new MvcServiceProvider(
ProjectPath, ProjectPath,
@ -71,7 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
Options.ContentRootOption.Value(), Options.ContentRootOption.Value(),
Options.ConfigureCompilationType.Value()); Options.ConfigureCompilationType.Value());
Console.WriteLine("Running Razor view precompilation."); Application.Out.WriteLine("Running Razor view precompilation.");
var stopWatch = Stopwatch.StartNew(); var stopWatch = Stopwatch.StartNew();
var results = GenerateCode(); var results = GenerateCode();
@ -83,7 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
success = false; success = false;
foreach (var error in result.GeneratorResults.ParserErrors) foreach (var error in result.GeneratorResults.ParserErrors)
{ {
Console.Error.WriteLine($"{error.Location.FilePath} ({error.Location.LineIndex}): {error.Message}"); Application.Error.WriteLine($"{error.Location.FilePath} ({error.Location.LineIndex}): {error.Message}");
} }
} }
} }
@ -104,15 +110,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
{ {
foreach (var diagnostic in emitResult.Diagnostics) foreach (var diagnostic in emitResult.Diagnostics)
{ {
Console.Error.WriteLine(CSharpDiagnosticFormatter.Instance.Format(diagnostic)); Application.Error.WriteLine(CSharpDiagnosticFormatter.Instance.Format(diagnostic));
} }
return 1; return 1;
} }
stopWatch.Stop(); stopWatch.Stop();
Console.WriteLine($"Precompiled views emitted to {assemblyPath}."); Application.Out.WriteLine($"Precompiled views emitted to {assemblyPath}.");
Console.WriteLine($"Successfully compiled {results.Length} Razor views in {stopWatch.ElapsedMilliseconds}ms."); Application.Out.WriteLine($"Successfully compiled {results.Length} Razor views in {stopWatch.ElapsedMilliseconds}ms.");
return 0; return 0;
} }
@ -198,23 +204,34 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal
return codeGenerator.Compilation; return codeGenerator.Compilation;
} }
private void ParseArguments() private bool ParseArguments()
{ {
ProjectPath = Options.ProjectArgument.Value; ProjectPath = Options.ProjectArgument.Value;
if (string.IsNullOrEmpty(ProjectPath)) if (string.IsNullOrEmpty(ProjectPath))
{ {
throw new ArgumentException("Project path not specified."); Application.Error.WriteLine("Project path not specified.");
return false;
} }
if (!OutputPathOption.HasValue()) if (!OutputPathOption.HasValue())
{ {
throw new ArgumentException($"Option {OutputPathTemplate} does not specify a value."); Application.Error.WriteLine($"Option {OutputPathTemplate} does not specify a value.");
return false;
} }
if (!ApplicationNameOption.HasValue()) if (!ApplicationNameOption.HasValue())
{ {
throw new ArgumentException($"Option {ApplicationNameTemplate} does not specify a value."); Application.Error.WriteLine($"Option {ApplicationNameTemplate} does not specify a value.");
return false;
} }
if (!Options.ContentRootOption.HasValue())
{
Application.Error.WriteLine($"Option {CommonOptions.ContentRootTemplate} does not specify a value.");
return false;
}
return true;
} }
private ViewCompilationInfo[] GenerateCode() private ViewCompilationInfo[] GenerateCode()

Просмотреть файл

@ -17,6 +17,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
{ {
public class PrecompileDispatchCommand public class PrecompileDispatchCommand
{ {
private CommandLineApplication Application { get; set; }
private CommonOptions Options { get; } = new CommonOptions(); private CommonOptions Options { get; } = new CommonOptions();
private CommandOption FrameworkOption { get; set; } private CommandOption FrameworkOption { get; set; }
@ -25,10 +27,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
private CommandOption OutputPathOption { get; set; } private CommandOption OutputPathOption { get; set; }
private NuGetFramework TargetFramework { get; set; }
private CommandOption BuildBasePathOption { get; set; } private CommandOption BuildBasePathOption { get; set; }
private NuGetFramework TargetFramework { get; set; }
private CommandOption DumpFilesOption { get; set; } private CommandOption DumpFilesOption { get; set; }
private string ProjectPath { get; set; } private string ProjectPath { get; set; }
@ -39,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
public void Configure(CommandLineApplication app) public void Configure(CommandLineApplication app)
{ {
Application = app;
Options.Configure(app); Options.Configure(app);
FrameworkOption = app.Option( FrameworkOption = app.Option(
"-f|--framework", "-f|--framework",
@ -52,7 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
OutputPathOption = app.Option( OutputPathOption = app.Option(
"-o|--output-path", "-o|--output-path",
"Published path of the application.", "Output path.",
CommandOptionType.SingleValue); CommandOptionType.SingleValue);
app.OnExecute(() => Execute()); app.OnExecute(() => Execute());
@ -60,7 +63,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
private int Execute() private int Execute()
{ {
ParseArguments(); if (!ParseArguments())
{
return 1;
}
var runtimeContext = GetRuntimeContext(); var runtimeContext = GetRuntimeContext();
@ -125,41 +131,45 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal
toolName: toolName); toolName: toolName);
var commandExitCode = dispatchCommand var commandExitCode = dispatchCommand
.ForwardStdErr(Console.Error) .ForwardStdErr(Application.Error)
.ForwardStdOut(Console.Out) .ForwardStdOut(Application.Out)
.Execute() .Execute()
.ExitCode; .ExitCode;
return commandExitCode; return commandExitCode;
} }
private void ParseArguments() private bool ParseArguments()
{ {
ProjectPath = GetProjectPath(); ProjectPath = GetProjectPath(Options.ProjectArgument.Value);
Configuration = ConfigurationOption.Value() ?? DotNet.Cli.Utils.Constants.DefaultConfiguration; Configuration = ConfigurationOption.Value() ?? DotNet.Cli.Utils.Constants.DefaultConfiguration;
if (!FrameworkOption.HasValue()) if (!FrameworkOption.HasValue())
{ {
throw new Exception($"Option {FrameworkOption.Template} does not have a value."); Application.Error.WriteLine($"Option {FrameworkOption.Template} does not have a value.");
return false;
} }
TargetFramework = NuGetFramework.Parse(FrameworkOption.Value()); TargetFramework = NuGetFramework.Parse(FrameworkOption.Value());
if (!OutputPathOption.HasValue()) if (!OutputPathOption.HasValue())
{ {
throw new Exception($"Option {OutputPathOption.Template} does not have a value."); Application.Error.WriteLine($"Option {OutputPathOption.Template} does not have a value.");
return false;
} }
OutputPath = OutputPathOption.Value(); OutputPath = OutputPathOption.Value();
return true;
} }
private string GetProjectPath() public static string GetProjectPath(string projectArgument)
{ {
string projectPath; string projectPath;
if (!string.IsNullOrEmpty(Options.ProjectArgument.Value)) if (!string.IsNullOrEmpty(projectArgument))
{ {
projectPath = Path.GetFullPath(Options.ProjectArgument.Value); projectPath = Path.GetFullPath(projectArgument);
if (string.Equals(Path.GetFileName(ProjectPath), "project.json", StringComparison.OrdinalIgnoreCase)) if (string.Equals(Path.GetFileName(projectPath), "project.json", StringComparison.OrdinalIgnoreCase))
{ {
projectPath = Path.GetDirectoryName(ProjectPath); projectPath = Path.GetDirectoryName(projectPath);
} }
if (!Directory.Exists(projectPath)) if (!Directory.Exists(projectPath))

Просмотреть файл

@ -25,7 +25,9 @@
"xmlDoc": true "xmlDoc": true
}, },
"dependencies": { "dependencies": {
"Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design": { "target": "project" }, "Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design": {
"target": "project"
},
"Microsoft.DotNet.Cli.Utils": "1.0.0-*", "Microsoft.DotNet.Cli.Utils": "1.0.0-*",
"Microsoft.Extensions.CommandLineUtils": "1.1.0-*", "Microsoft.Extensions.CommandLineUtils": "1.1.0-*",
"Microsoft.Extensions.DotnetToolDispatcher.Sources": { "Microsoft.Extensions.DotnetToolDispatcher.Sources": {

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>e0d75b4e-839f-4f80-9b1f-b33f616bcc5f</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

Просмотреть файл

@ -0,0 +1,193 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools
{
public class PrecompileRunCommandTest
{
[Fact]
public void RunPrintsHelp_WhenHelpOptionIsSpecified()
{
// Arrange
var expected =
$@"Microsoft Razor Precompilation Utility {GetToolVersion()}
Usage: razor-precompile [arguments] [options]
Arguments:
project The path to the project (project folder or project.json) with precompilation.
Options:
-?|-h|--help Show help information
--configure-compilation-type Type with Configure method
--content-root The application's content root.
--embed-view-sources Embed view sources as resources in the generated assembly.
--key-file Strong name key path
--delay-sign Determines if the precompiled view assembly is to be delay signed.
--public-sign Determines if the precompiled view assembly is to be public signed.
--output-path Path to the emit the precompiled assembly to.
--application-name Name of the application to produce precompiled assembly for.";
var args = new[]
{
"--help"
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(0, result.ExitCode);
Assert.Equal(expected, result.Out.Trim(), ignoreLineEndingDifferences: true);
Assert.Empty(result.Error);
}
[Fact]
public void Run_PrintsHelpWhenInvalidOptionsAreSpecified()
{
// Arrange
var expectedOut = @"Specify --help for a list of available options and commands.";
var expectedError = @"Unrecognized option '--bad-option'";
var args = new[]
{
"--bad-option"
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Equal(expectedOut, result.Out.Trim());
Assert.Equal(
expectedError,
result.Error.Split(new[] { Environment.NewLine }, StringSplitOptions.None).First());
}
[Fact]
public void Run_PrintsErrorWhenArgumentIsMissing()
{
// Arrange
var expectedError = @"Project path not specified.";
var args = new string[0];
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expectedError, result.Error.Trim());
}
[Fact]
public void Run_PrintsErrorWhenOutputPathOptionIsMissing()
{
// Arrange
var expectedError = @"Option --output-path does not specify a value.";
var args = new[]
{
Directory.GetCurrentDirectory(),
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expectedError, result.Error.Trim());
}
[Fact]
public void Run_PrintsErrorWhenApplicationNameOptionIsMissing()
{
// Arrange
var expectedError = @"Option --application-name does not specify a value.";
var args = new[]
{
Directory.GetCurrentDirectory(),
"--output-path",
Directory.GetCurrentDirectory(),
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expectedError, result.Error.Trim());
}
[Fact]
public void Run_PrintsErrorWhenContentRootOptionIsMissing()
{
// Arrange
var expectedError = @"Option --content-root does not specify a value.";
var args = new[]
{
Directory.GetCurrentDirectory(),
"--output-path",
Directory.GetCurrentDirectory(),
"--application-name",
"TestApplicationName",
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expectedError, result.Error.Trim());
}
private static string GetToolVersion()
{
return typeof(Program)
.GetTypeInfo()
.Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
}
private class ExecuteResult
{
public string Out { get; set; }
public string Error { get; set; }
public int ExitCode { get; set; }
}
private ExecuteResult Execute(string[] args)
{
using (var outputWriter = new StringWriter())
using (var errorWriter = new StringWriter())
{
var app = new PrecompilationApplication(typeof(Program))
{
Out = outputWriter,
Error = errorWriter,
};
new PrecompileRunCommand().Configure(app);
var exitCode = app.Execute(args);
return new ExecuteResult
{
ExitCode = exitCode,
Out = outputWriter.ToString(),
Error = errorWriter.ToString(),
};
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
{
"dependencies": {
"dotnet-test-xunit": "2.2.0-*",
"Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools": "1.0.0-*",
"xunit": "2.2.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"net451": {}
}
},
"testRunner": "xunit"
}

Просмотреть файл

@ -64,9 +64,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.FunctionalTests
Fixture.Logger); Fixture.Logger);
// Assert - 2 // Assert - 2
Assert.Equal( var actual = response2.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
expectedViews, .OrderBy(p => p, StringComparer.OrdinalIgnoreCase);
response2.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)); Assert.Equal(expectedViews, actual);
} }
} }

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b58e3380-d451-4e54-b522-cd21404fcd58</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

Просмотреть файл

@ -0,0 +1,196 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Razor.Precompilation.Design.Internal;
using Microsoft.AspNetCore.Mvc.Razor.Precompilation.Internal;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools
{
public class PrecompileDispatchCommandTest
{
[Fact]
public void RunPrintsHelp_WhenHelpOptionIsSpecified()
{
// Arrange
var expected =
$@"Microsoft Razor Precompilation Utility {GetToolVersion()}
Usage: razor-precompile [arguments] [options]
Arguments:
project The path to the project (project folder or project.json) with precompilation.
Options:
-?|-h|--help Show help information
--configure-compilation-type Type with Configure method
--content-root The application's content root.
--embed-view-sources Embed view sources as resources in the generated assembly.
-f|--framework Target Framework
-c|--configuration Configuration
-o|--output-path Output path.";
var args = new[]
{
"--help"
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(0, result.ExitCode);
Assert.Equal(expected, result.Out.Trim(), ignoreLineEndingDifferences: true);
Assert.Empty(result.Error);
}
[Fact]
public void RunPrintsHelp_WhenInvalidOptionsAreSpecified()
{
// Arrange
var expectedOut = @"Specify --help for a list of available options and commands.";
var expectedError = @"Unrecognized option '--bad-option'";
var args = new[]
{
"--bad-option"
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Equal(expectedOut, result.Out.Trim());
Assert.Equal(
expectedError,
result.Error.Split(new[] { Environment.NewLine }, StringSplitOptions.None).First());
}
[Fact]
public void RunPrintsError_IfFrameworkIfNotSpecified()
{
// Arrange
var expected = "Option -f|--framework does not have a value.";
var args = new string[0];
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expected, result.Error.Trim());
}
[Fact]
public void RunPrintsError_IfOutputPathIfNotSpecified()
{
// Arrange
var expected = "Option -o|--output-path does not have a value.";
var args = new[]
{
"-f",
"framework"
};
// Act
var result = Execute(args);
// Assert
Assert.Equal(1, result.ExitCode);
Assert.Empty(result.Out);
Assert.Equal(expected, result.Error.Trim());
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void GetProjectPath_ReturnsCurrentDirectoryIfArgumentIsNullOrEmpty(string projectPath)
{
// Act
var actual = PrecompileDispatchCommand.GetProjectPath(projectPath);
// Assert
Assert.Equal(Directory.GetCurrentDirectory(), actual);
}
public static TheoryData GetProjectPath_ReturnsArgumentIfNotNullOrEmptyData
{
get
{
return new TheoryData<string, string>
{
{ "", Directory.GetCurrentDirectory() },
{ "project.json", Directory.GetCurrentDirectory() },
{ Path.GetTempPath(), Path.GetTempPath() },
};
}
}
[Theory]
[MemberData(nameof(GetProjectPath_ReturnsArgumentIfNotNullOrEmptyData))]
public void GetProjectPath_ReturnsArgumentIfNotNullOrEmpty(string projectPath, string expected)
{
// Act
var actual = PrecompileDispatchCommand.GetProjectPath(projectPath);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void GetProjectPath_ThrowsIfDirectoryDoesNotExist()
{
// Arrange
var nonExistent = Path.GetRandomFileName();
// Act & Assert
var ex = Assert.Throws<InvalidOperationException>(
() => PrecompileDispatchCommand.GetProjectPath(nonExistent));
Assert.Equal($"Could not find directory {Path.GetFullPath(nonExistent)}.", ex.Message);
}
private static string GetToolVersion()
{
return typeof(Program)
.GetTypeInfo()
.Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
}
private class ExecuteResult
{
public string Out { get; set; }
public string Error { get; set; }
public int ExitCode { get; set; }
}
private ExecuteResult Execute(string[] args)
{
using (var outputWriter = new StringWriter())
using (var errorWriter = new StringWriter())
{
var app = new PrecompilationApplication(typeof(Program))
{
Out = outputWriter,
Error = errorWriter,
};
new PrecompileDispatchCommand().Configure(app);
var exitCode = app.Execute(args);
return new ExecuteResult
{
ExitCode = exitCode,
Out = outputWriter.ToString(),
Error = errorWriter.ToString(),
};
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
{
"dependencies": {
"dotnet-test-xunit": "2.2.0-*",
"Microsoft.AspNetCore.Mvc.Razor.Precompilation.Tools": "1.0.0-*",
"xunit": "2.2.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"net451": {}
}
},
"testRunner": "xunit"
}