diff --git a/src/GoCommando.Tests/GoCommando.Tests.csproj b/src/GoCommando.Tests/GoCommando.Tests.csproj index 19fab1b..321fee5 100644 --- a/src/GoCommando.Tests/GoCommando.Tests.csproj +++ b/src/GoCommando.Tests/GoCommando.Tests.csproj @@ -53,6 +53,7 @@ + diff --git a/src/GoCommando.Tests/Helpers/TestArgParser.cs b/src/GoCommando.Tests/Helpers/TestArgParser.cs index d8a30e0..5abf096 100644 --- a/src/GoCommando.Tests/Helpers/TestArgParser.cs +++ b/src/GoCommando.Tests/Helpers/TestArgParser.cs @@ -5,7 +5,7 @@ using GoCommando.Parameters; using NUnit.Framework; -namespace GoCommando.Tests +namespace GoCommando.Tests.Helpers { [TestFixture] public class TestArgParser : FixtureBase @@ -43,7 +43,7 @@ public void EmptyArrayYieldsNoArguments() [Test] public void DoesNotThrowIfItsAFlag() { - var parameter = parser.Parse(new[]{"/param"}).Cast().Single(); + var parameter = parser.Parse(new[]{"-param"}).Cast().Single(); Assert.AreEqual("param", parameter.Name); Assert.AreEqual("True", parameter.Value); } @@ -51,7 +51,7 @@ public void DoesNotThrowIfItsAFlag() [Test] public void CanParseArrayOfArguments() { - var args = new []{"some.assembly", "another.assembly", "/param2:bimmelim", "/param1:boom"}; + var args = new []{"some.assembly", "another.assembly", "-param2:bimmelim", "-param1:boom"}; var parameters = parser.Parse(args); Assert.AreEqual(4, parameters.Count); @@ -69,8 +69,19 @@ public void CanParseArrayOfArguments() [Test] public void ThrowsIfPositionalParametersAreMixedWithNamedParameters() { - Assert.Throws(() => parser.Parse(new[] {"/named:parameter", "positional.parameter"})); - Assert.Throws(() => parser.Parse(new[] {"/named.flag", "positional.parameter"})); + Assert.Throws(() => parser.Parse(new[] {"-named:parameter", "positional.parameter"})); + Assert.Throws(() => parser.Parse(new[] {"-named.flag", "positional.parameter"})); + } + + [Test] + public void AcceptsSlashAsPositionalParameter() + { + var args = new []{"/src/somepath", "/src/anotherpath"}; + var parameters = parser.Parse(args); + + Assert.AreEqual(2, parameters.Count); + Assert.IsTrue(parameters[0] is PositionalCommandLineParameter); + Assert.IsTrue(parameters[1] is PositionalCommandLineParameter); } void AssertYieldsNoParameters(string[] args) @@ -82,4 +93,4 @@ void AssertYieldsNoParameters(string[] args) argsAsString); } } -} +} \ No newline at end of file diff --git a/src/GoCommando.Tests/Integration/ErrorTestCases.cs b/src/GoCommando.Tests/Integration/ErrorTestCases.cs new file mode 100644 index 0000000..2ac815f --- /dev/null +++ b/src/GoCommando.Tests/Integration/ErrorTestCases.cs @@ -0,0 +1,84 @@ +using GoCommando.Api; +using GoCommando.Attributes; +using NUnit.Framework; +using DescriptionAttribute = NUnit.Framework.DescriptionAttribute; + +namespace GoCommando.Tests.Integration +{ + [TestFixture] + public class ErrorTestCases + { + [SetUp] + public void SetUp() + { + CommandoWithTwoArguments.SomePathStatic = null; + CommandoWithTwoArguments.AnotherPathStatic = null; + } + + [Test, Description("This error was due to named argument syntax using slash, thus resulting in arguments with forward slash (e.g. an URL) being interpreted as such")] + public void ReproduceError() + { + var errorCode = Go.Run(new[] {"/src/somepath", "/src/anotherpath"}); + + Assert.AreEqual(0, errorCode); + Assert.AreEqual("/src/somepath", CommandoWithTwoArguments.SomePathStatic); + Assert.AreEqual("/src/anotherpath", CommandoWithTwoArguments.AnotherPathStatic); + } + + class CommandoWithTwoArguments : ICommando + { + [PositionalArgument] + public string SomePath { get; set; } + + [PositionalArgument] + public string AnotherPath { get; set; } + + public void Run() + { + SomePathStatic = SomePath; + AnotherPathStatic = AnotherPath; + } + + public static string SomePathStatic { get; set; } + public static string AnotherPathStatic { get; set; } + } + + [Test, Description("This was the actual parameters resulting in an error")] + public void HowAboutThis() + { + var errorCode = Go.Run(new[] + { + @"src\Noder.Test\bin\Debug\Noder.Test.dll", + @"src\Noder.Test\Features\00_basics.feature" + }); + + Assert.AreEqual(0, errorCode); + Assert.AreEqual(@"src\Noder.Test\bin\Debug\Noder.Test.dll", CommandoWithThreeArguments.SomePathStatic); + Assert.AreEqual(@"src\Noder.Test\Features\00_basics.feature", CommandoWithThreeArguments.AnotherPathStatic); + Assert.IsFalse(CommandoWithThreeArguments.SomeFlagStatic); + } + + class CommandoWithThreeArguments : ICommando + { + [PositionalArgument] + public string SomePath { get; set; } + + [PositionalArgument] + public string AnotherPath { get; set; } + + [NamedArgument("flag", "f")] + public bool SomeFlag { get; set; } + + public void Run() + { + SomePathStatic = SomePath; + AnotherPathStatic = AnotherPath; + SomeFlagStatic = SomeFlag; + } + + public static string SomePathStatic { get; set; } + public static string AnotherPathStatic { get; set; } + public static bool SomeFlagStatic { get; set; } + } + } +} \ No newline at end of file diff --git a/src/GoCommando/Go.cs b/src/GoCommando/Go.cs index 1b0b28a..88f1e64 100644 --- a/src/GoCommando/Go.cs +++ b/src/GoCommando/Go.cs @@ -99,7 +99,7 @@ public BindingContext() static bool RequiredParameterMissing(BindingReport bindingReport) { - return bindingReport.PropertiesNotBound.Any(); + return bindingReport.RequiredPropertiesNotBound.Any(); } static void ShowHelpText(ICommando commando) diff --git a/src/GoCommando/Helpers/ArgParser.cs b/src/GoCommando/Helpers/ArgParser.cs index 4ebf85e..3f2b933 100644 --- a/src/GoCommando/Helpers/ArgParser.cs +++ b/src/GoCommando/Helpers/ArgParser.cs @@ -31,7 +31,7 @@ public List Parse(string[] args) CommandLineParameter ToCommandLineParameter(string arg, ParserContext context) { return - !arg.StartsWith("/") + !arg.StartsWith("-") ? CreatePositionalCommandLineParameter(arg, context) : CreateNamedCommandLineParameter(arg, context); } diff --git a/src/GoCommando/Helpers/Binder.cs b/src/GoCommando/Helpers/Binder.cs index 4486fb1..2f57148 100644 --- a/src/GoCommando/Helpers/Binder.cs +++ b/src/GoCommando/Helpers/Binder.cs @@ -35,7 +35,12 @@ public BindingContext() readonly BindingReport report = new BindingReport(); - public int Position { get; set; } + public int Position { get; private set; } + + public void IncrementPosition() + { + Position++; + } public BindingReport Report { @@ -48,7 +53,6 @@ void Bind(object commando, PropertyInfo property, List par if (attribute is PositionalArgumentAttribute) { BindPositional(commando, property, parameters, (PositionalArgumentAttribute) attribute, context); - context.Position++; } else if (attribute is NamedArgumentAttribute) { @@ -98,6 +102,7 @@ void BindPositional(object commando, PropertyInfo property, List requiredPropertiesNotBound = new List(); readonly List propertiesNotBound = new List(); readonly List propertiesBound = new List(); @@ -17,5 +18,10 @@ public List PropertiesBound { get { return propertiesBound; } } + + public List RequiredPropertiesNotBound + { + get { return requiredPropertiesNotBound; } + } } } \ No newline at end of file