a couple of parser unit tests

This commit is contained in:
jonsequitur 2017-03-03 13:14:36 -08:00
parent 614f71d19f
commit 8b0dd3579c
6 changed files with 132 additions and 79 deletions

View file

@ -7,14 +7,11 @@ using System.Linq;
using System.Text; using System.Text;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Command = Microsoft.DotNet.Cli.CommandLine.Command;
namespace Microsoft.DotNet.Tools.Complete namespace Microsoft.DotNet.Tools.Complete
{ {
public class CompleteCommand public class CompleteCommand
{ {
private static readonly Command dotnetCommand = Create.DotnetCommand();
public static int Run(string[] args) public static int Run(string[] args)
{ {
DebugHelper.HandleDebugSwitch(ref args); DebugHelper.HandleDebugSwitch(ref args);
@ -22,7 +19,11 @@ namespace Microsoft.DotNet.Tools.Complete
var log = new StringBuilder(); var log = new StringBuilder();
log.AppendLine($"args: {string.Join(" ", args.Select(a => $"\"{a}\""))}"); log.AppendLine($"args: {string.Join(" ", args.Select(a => $"\"{a}\""))}");
var result = dotnetCommand["complete"].Parse(args); // get the parser for the current subcommand
var completeCommandParser = ParserFor.DotnetCommand["complete"];
// parse the arguments
var result = completeCommandParser.Parse(args);
log.AppendLine("diagram (1): " + result.Diagram()); log.AppendLine("diagram (1): " + result.Diagram());
@ -57,7 +58,7 @@ namespace Microsoft.DotNet.Tools.Complete
} }
} }
var result = dotnetCommand.Parse(input); var result = ParserFor.DotnetCommand.Parse(input);
log.AppendLine("diagram (2): " + result.Diagram()); log.AppendLine("diagram (2): " + result.Diagram());

View file

@ -0,0 +1,11 @@
using System;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Tools
{
public static class ParserExtensions
{
public static void ShowHelp(this ParseResult parseResult) =>
Console.WriteLine(parseResult.Command().HelpView());
}
}

View file

@ -9,18 +9,18 @@ using System.Net.Http;
using System.Threading; using System.Threading;
using Microsoft.Build.Evaluation; using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools.Common;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using static Microsoft.DotNet.Cli.CommandLine.Accept; using static Microsoft.DotNet.Cli.CommandLine.Accept;
using static Microsoft.DotNet.Cli.CommandLine.Create; using static Microsoft.DotNet.Cli.CommandLine.Create;
using Command = Microsoft.DotNet.Cli.CommandLine.Command; using Command = Microsoft.DotNet.Cli.CommandLine.Command;
namespace Microsoft.DotNet.Tools.Complete namespace Microsoft.DotNet.Tools
{ {
public static class Create public static class ParserFor
{ {
public static Command DotnetCommand() => private static readonly Command _dotnetCommand = Command("dotnet",
Command("dotnet", ".NET Command Line Tools",
".NET Command Line Tools (2.0.0-alpha-alpha-004866)",
NoArguments, NoArguments,
New(), New(),
Restore(), Restore(),
@ -41,7 +41,45 @@ namespace Microsoft.DotNet.Tools.Complete
Complete(), Complete(),
HelpOption(), HelpOption(),
Option("--info", ""), Option("--info", ""),
VerbosityOption()); VerbosityOption(),
Option("-d", ""));
public static Command DotnetCommand { get; } = _dotnetCommand;
private static Command Add() =>
Command("add",
".NET Add Command",
ExactlyOneArgument.DefaultToCurrentDirectory(),
Command("package",
".NET Add Package reference Command",
ExactlyOneArgument
.WithSuggestionsFrom(QueryNuGet),
HelpOption(),
Option("-v|--version",
"Version for the package to be added.",
ExactlyOneArgument
.With(name: "VERSION")),
Option("-f|--framework",
"Add reference only when targetting a specific framework",
ExactlyOneArgument
.With(name: "FRAMEWORK")),
Option("-n|--no-restore ",
"Add reference without performing restore preview and compatibility check."),
Option("-s|--source",
"Use specific NuGet package sources to use during the restore."),
Option("--package-directory",
"Restore the packages to this Directory .",
ExactlyOneArgument
.With(name: "PACKAGE_DIRECTORY"))),
Command("reference",
"Command to add project to project reference",
OneOrMoreArguments,
HelpOption(),
Option("-f|--framework",
"Add reference only when targetting a specific framework",
AnyOneOf(TargetFrameworksFromProjectFile)
.With(name: "FRAMEWORK"))),
HelpOption());
private static Command Complete() => private static Command Complete() =>
Command("complete", "", Command("complete", "",
@ -52,14 +90,6 @@ namespace Microsoft.DotNet.Tools.Complete
.With(name: "command"), .With(name: "command"),
o => int.Parse(o.Arguments.Single()))); o => int.Parse(o.Arguments.Single())));
private static Command Add() =>
Command("add",
".NET Add Command",
ExactlyOneArgument,
Package(),
Reference(),
HelpOption());
private static Command Build() => private static Command Build() =>
Command("build", Command("build",
".NET Builder", ".NET Builder",
@ -73,7 +103,7 @@ namespace Microsoft.DotNet.Tools.Complete
AnyOneOf(TargetFrameworksFromProjectFile)), AnyOneOf(TargetFrameworksFromProjectFile)),
Option("-r|--runtime", Option("-r|--runtime",
"Target runtime to build for. The default is to build a portable application.", "Target runtime to build for. The default is to build a portable application.",
WithSuggestionsFrom(_ => RunTimesFromProjectFile())), AnyOneOf(RunTimesFromProjectFile)),
Option("-c|--configuration", Option("-c|--configuration",
"Configuration to use for building the project. Default for most projects is \"Debug\".", "Configuration to use for building the project. Default for most projects is \"Debug\".",
ExactlyOneArgument ExactlyOneArgument
@ -106,10 +136,11 @@ namespace Microsoft.DotNet.Tools.Complete
private static Command List() => private static Command List() =>
Command("list", Command("list",
".NET List Command", ".NET List Command",
ExactlyOneArgument ZeroOrOneArgument
.With(name: "PROJECT", .With(name: "PROJECT",
description: description:
"The project file to operate on. If a file is not specified, the command will search the current directory for one."), "The project file to operate on. If a file is not specified, the command will search the current directory for one.")
.DefaultToCurrentDirectory(),
HelpOption(), HelpOption(),
Command("reference", "Command to list project to project references", Command("reference", "Command to list project to project references",
ExactlyOneArgument ExactlyOneArgument
@ -252,31 +283,7 @@ namespace Microsoft.DotNet.Tools.Complete
.With(name: "VERSION_SUFFIX")), .With(name: "VERSION_SUFFIX")),
Option("-s|--serviceable", Option("-s|--serviceable",
"Set the serviceable flag in the package. For more information, please see https://aka.ms/nupkgservicing."), "Set the serviceable flag in the package. For more information, please see https://aka.ms/nupkgservicing."),
VerbosityOption() VerbosityOption());
);
private static Command Package() =>
Command("package",
".NET Add Package reference Command",
ExactlyOneArgument
.WithSuggestionsFrom(QueryNuGet),
HelpOption(),
Option("-v|--version",
"Version for the package to be added.",
ExactlyOneArgument
.With(name: "VERSION")),
Option("-f|--framework",
"Add reference only when targetting a specific framework",
ExactlyOneArgument
.With(name: "FRAMEWORK")),
Option("-n|--no-restore ",
"Add reference without performing restore preview and compatibility check."),
Option("-s|--source",
"Use specific NuGet package sources to use during the restore."),
Option("--package-directory",
"Restore the packages to this Directory .",
ExactlyOneArgument
.With(name: "PACKAGE_DIRECTORY")));
private static Command Publish() => private static Command Publish() =>
Command("publish", Command("publish",
@ -289,7 +296,7 @@ namespace Microsoft.DotNet.Tools.Complete
.With(name: "FRAMEWORK")), .With(name: "FRAMEWORK")),
Option("-r|--runtime", Option("-r|--runtime",
"Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.", "Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.",
ExactlyOneArgument AnyOneOf(RunTimesFromProjectFile)
.With(name: "RUNTIME_IDENTIFIER")), .With(name: "RUNTIME_IDENTIFIER")),
Option("-o|--output", Option("-o|--output",
"Output directory in which to place the published artifacts.", "Output directory in which to place the published artifacts.",
@ -307,32 +314,22 @@ namespace Microsoft.DotNet.Tools.Complete
private static Command Remove() => private static Command Remove() =>
Command("remove", Command("remove",
".NET Remove Command", ".NET Remove Command",
ZeroOrOneArgument
.With(name: "PROJECT")
.DefaultToCurrentDirectory(),
HelpOption(), HelpOption(),
Command("package", Command("package",
"Command to remove package reference.", "Command to remove package reference.",
HelpOption()), HelpOption()),
Command("reference", Command("reference",
"Command to remove project to project reference", "Command to remove project to project reference",
WithSuggestionsFrom(_ => ProjectReferencesFromProjectFile()), AnyOneOf(ProjectReferencesFromProjectFile),
HelpOption(), HelpOption(),
Option("-f|--framework", Option("-f|--framework",
"Remove reference only when targetting a specific framework", "Remove reference only when targetting a specific framework",
ExactlyOneArgument ExactlyOneArgument
.With(name: "FRAMEWORK")))); .With(name: "FRAMEWORK"))));
private static Command Reference() =>
Command("reference",
"Command to add project to project reference",
OneOrMoreArguments,
HelpOption(),
Option("-f|--framework",
"Add reference only when targetting a specific framework",
ExactlyOneArgument
.WithSuggestionsFrom(
_ => TargetFrameworksFromProjectFile().ToArray())
// .With(name: "FRAMEWORK")
));
private static Command Restore() => private static Command Restore() =>
Command("restore", Command("restore",
".NET dependency restorer", ".NET dependency restorer",
@ -343,7 +340,7 @@ namespace Microsoft.DotNet.Tools.Complete
.With(name: "SOURCE")), .With(name: "SOURCE")),
Option("-r|--runtime", Option("-r|--runtime",
"Target runtime to restore packages for.", "Target runtime to restore packages for.",
WithSuggestionsFrom(_ => RunTimesFromProjectFile()) AnyOneOf(RunTimesFromProjectFile)
.With(name: "RUNTIME_IDENTIFIER")), .With(name: "RUNTIME_IDENTIFIER")),
Option("--packages", Option("--packages",
"Directory to install packages in.", "Directory to install packages in.",
@ -381,6 +378,7 @@ namespace Microsoft.DotNet.Tools.Complete
private static Command Sln() => private static Command Sln() =>
Command("sln", Command("sln",
".NET modify solution file command", ".NET modify solution file command",
HelpOption(), HelpOption(),
Command("add", Command("add",
".NET Add project(s) to a solution file Command", ".NET Add project(s) to a solution file Command",
@ -441,6 +439,9 @@ namespace Microsoft.DotNet.Tools.Complete
"Do not build project before testing."), "Do not build project before testing."),
VerbosityOption()); VerbosityOption());
private static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) =>
rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));
private static Option HelpOption() => private static Option HelpOption() =>
Option("-h|--help", Option("-h|--help",
"Show help information", "Show help information",
@ -455,21 +456,6 @@ namespace Microsoft.DotNet.Tools.Complete
"n[ormal]", "n[ormal]",
"d[etailed]")); "d[etailed]"));
public static string[] KnownRuntimes =
{
"win10-x86",
"win10-x64",
"win10-arm64",
"osx.10.11-x64",
"centos.7-x64",
"debian.8-x64",
"linuxmint.17-x64",
"opensuse.13.2-x64",
"rhel.7.2-x64",
"ubuntu.14.04-x64",
"ubuntu.16.04-x64",
};
private static IEnumerable<string> QueryNuGet(string match) private static IEnumerable<string> QueryNuGet(string match)
{ {
var httpClient = new HttpClient(); var httpClient = new HttpClient();

View file

@ -39,7 +39,7 @@
<PackageReference Include="Microsoft.Win32.Registry" Version="4.3.0" /> <PackageReference Include="Microsoft.Win32.Registry" Version="4.3.0" />
<PackageReference Include="Microsoft.Build" Version="$(CLI_MSBuild_Version)" /> <PackageReference Include="Microsoft.Build" Version="$(CLI_MSBuild_Version)" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(PlatformAbstractionsVersion)" /> <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(PlatformAbstractionsVersion)" />
<PackageReference Include="Microsoft.DotNet.Cli.CommandLine" Version="[0.1.0-alpha-57,)" /> <PackageReference Include="Microsoft.DotNet.Cli.CommandLine" Version="[0.1.0-alpha-67,)" />
<PackageReference Include="Microsoft.TemplateEngine.Abstractions" Version="$(TemplateEngineVersion)" /> <PackageReference Include="Microsoft.TemplateEngine.Abstractions" Version="$(TemplateEngineVersion)" />
<PackageReference Include="Microsoft.TemplateEngine.Cli" Version="$(TemplateEngineVersion)" /> <PackageReference Include="Microsoft.TemplateEngine.Cli" Version="$(TemplateEngineVersion)" />
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="$(TemplateEngineVersion)" /> <PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="$(TemplateEngineVersion)" />

View file

@ -0,0 +1,54 @@
using System;
using System.IO;
using FluentAssertions;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using Microsoft.DotNet.Tools.Common;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.DotNet.Tests
{
public class AddReferenceParserTests
{
private readonly ITestOutputHelper output;
public AddReferenceParserTests(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public void dotnet_add_reference_has_default_argument_set_to_current_directory()
{
var command = ParserFor.DotnetCommand;
var result = command.Parse("dotnet add reference my.csproj");
output.WriteLine(result.Diagram());
result["dotnet"]["add"]
.Arguments
.Should()
.BeEquivalentTo(
PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));
}
[Fact]
public void dotnet_add_reference_without_argument_results_in_an_error()
{
var command = ParserFor.DotnetCommand["add"];
var result = command.Parse("add reference");
output.WriteLine(result.Diagram());
result
.Errors
.Select(e => e.Message)
.Should()
.BeEquivalentTo("Required argument missing for command: reference");
}
}
}

View file

@ -42,5 +42,6 @@
<PackageReference Include="xunit" Version="2.2.0-beta4-build3444" /> <PackageReference Include="xunit" Version="2.2.0-beta4-build3444" />
<PackageReference Include="xunit.netcore.extensions" Version="1.0.0-prerelease-00206" /> <PackageReference Include="xunit.netcore.extensions" Version="1.0.0-prerelease-00206" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(PlatformAbstractionsVersion)" /> <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(PlatformAbstractionsVersion)" />
<PackageReference Include="Microsoft.DotNet.Cli.CommandLine" Version="[0.1.0-alpha-67,)" />
</ItemGroup> </ItemGroup>
</Project> </Project>