Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

383 lines
16 KiB
C#

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace CmdLine.Tests
{
extern alias migrate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
public class CommandLineTest
{
[Fact]
public void CommandLineTokenizesQuestionMarkSwitches()
{
var args = new[] { "/?" };
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var tokens = migrate::CmdLine.CommandLine.Tokenize();
Assert.Equal(1, migrate::CmdLine.CommandLine.Args.Length);
Assert.Equal(1, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count);
Assert.Equal(0, migrate::CmdLine.CommandLine.GetParameters(tokens).Count);
Assert.True(tokens[0].IsCommand());
Assert.Equal("?", tokens[0].Command);
}
[Fact]
public void CommandLineTokenizesSwitchesAndParameters()
{
var args = new[]
{
"C:\\Foo And Bar\\Some Long File.txt", "/1:Test", "-2:Some Quoted Arg", "/3=Arg with in it", "/Y-",
"And another",
"Another", "One", "Word", "Args"
};
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var tokens = migrate::CmdLine.CommandLine.Tokenize();
Assert.Equal(10, migrate::CmdLine.CommandLine.Args.Length);
Assert.Equal(4, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count);
Assert.Equal(6, migrate::CmdLine.CommandLine.GetParameters(tokens).Count);
Assert.True(tokens[0].IsParameter());
Assert.True(tokens[1].IsCommand());
Assert.True(tokens[2].IsCommand());
Assert.True(tokens[3].IsCommand());
Assert.True(tokens[4].IsCommand());
Assert.True(tokens[5].IsParameter());
Assert.True(tokens[6].IsParameter());
Assert.True(tokens[7].IsParameter());
Assert.True(tokens[8].IsParameter());
Assert.True(tokens[9].IsParameter());
for (var i = 0; i < args.Length; i++)
{
Assert.Equal(args[i], tokens[i].Token);
}
}
[Fact]
public void ParseDoesNotThrowWhenNullCommandLine()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
migrate::CmdLine.CommandLine.Parse<object>();
}
[Fact]
public void MissingRequiredSwitchArgShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineRequiredArgumentMissingException(typeof(string), "N", -1).Message,
Assert.Throws<migrate::CmdLine.CommandLineRequiredArgumentMissingException>(
() => migrate::CmdLine.CommandLine.Parse<TestArgs>()).Message);
}
[Fact]
public void AttributeWithNoCommandNameShouldUsePropertyName()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/b1-");
var actual = migrate::CmdLine.CommandLine.Parse<PropWithNoCommandName>();
Assert.False(actual.b1);
}
[Fact]
public void MissingRequiredPositionArgShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineRequiredArgumentMissingException(typeof(string), "String 1", 1).Message,
Assert.Throws<migrate::CmdLine.CommandLineRequiredArgumentMissingException>(
() => migrate::CmdLine.CommandLine.Parse<ThreeRequiredPositionArgs>()).Message);
}
[Fact]
public void DuplicateArgsShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/N:123 /N:345");
var commandArg = new migrate::CmdLine.CommandArgument("/N:345", 7);
commandArg.Command = "N";
Assert.Equal(
new migrate::CmdLine.CommandLineArgumentInvalidException(typeof(string), commandArg).Message,
Assert.Throws<migrate::CmdLine.CommandLineArgumentInvalidException>(() => migrate::CmdLine.CommandLine.Parse<TestArgs>()).
Message);
}
[Fact]
public void DuplicateArgsWithListShouldNotThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/N:123 /N:345");
var actual = migrate::CmdLine.CommandLine.Parse<TestArgsWithList>();
Assert.Equal(2, actual.NList.Count);
Assert.Equal("123", actual.NList[0]);
Assert.Equal("345", actual.NList[1]);
}
[Fact]
public void DefaultArgsAreApplied()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/n:123");
var target = migrate::CmdLine.CommandLine.Parse<TestArgs>();
Assert.True(target.BoolT);
Assert.False(target.BoolY);
Assert.Equal(TestArgs.StringArgDefault, target.StringArg);
}
/// <summary>
/// Verifies that you can use alternate seperators
/// </summary>
[Fact]
public void CommandLineTokenizesWithAlternateSwitchChars()
{
var args = new[]
{
"C:\\Foo And Bar\\Some Long File.txt", "~1|Test", "~2|Some Quoted Arg", "~3|Arg with in it", "_Y-",
"And another",
"Another", "One", "Word", "Args"
};
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
// Save the seperators since they are static members
var oldSep = migrate::CmdLine.CommandLine.CommandSeparators;
var oldValueSep = migrate::CmdLine.CommandLine.ValueSeparators;
migrate::CmdLine.CommandLine.CommandSeparators = new List<string>
{
"~",
"_"
};
migrate::CmdLine.CommandLine.ValueSeparators = new List<string>
{
"|"
};
var tokens = migrate::CmdLine.CommandLine.Tokenize();
// Restore the seperators
migrate::CmdLine.CommandLine.CommandSeparators = oldSep;
migrate::CmdLine.CommandLine.ValueSeparators = oldValueSep;
Assert.Equal(10, migrate::CmdLine.CommandLine.Args.Length);
Assert.Equal(4, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count);
Assert.Equal(6, migrate::CmdLine.CommandLine.GetParameters(tokens).Count);
Assert.True(tokens[0].IsParameter());
Assert.True(tokens[1].IsCommand());
Assert.True(tokens[2].IsCommand());
Assert.True(tokens[3].IsCommand());
Assert.True(tokens[4].IsCommand());
Assert.True(tokens[5].IsParameter());
Assert.True(tokens[6].IsParameter());
Assert.True(tokens[7].IsParameter());
Assert.True(tokens[8].IsParameter());
Assert.True(tokens[9].IsParameter());
for (var i = 0; i < args.Length; i++)
{
Assert.Equal(args[i], tokens[i].Token);
}
}
///<summary>
/// Verifies positional args work
///</summary>
[Fact]
public void PositionalArgsAreApplied()
{
var args = new[]
{
@"D:\Documents and Settings\MY.USERNAME\My Documents\*", @"E:\MYBACKUP\My Documents\", "/A",
@"/EXCLUDE:SomeQuoted String"
, "/I", "/D:7-8-2011"
};
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var xcopyCommand = migrate::CmdLine.CommandLine.Parse<XCopyCommandArgs>();
Assert.NotNull(xcopyCommand);
Assert.Equal(args[0], xcopyCommand.Source);
Assert.Equal(args[1], xcopyCommand.Destination);
Assert.Equal("SomeQuoted String", xcopyCommand.ExcludeFiles);
Assert.True(xcopyCommand.ArchivedBit);
Assert.True(xcopyCommand.InferDirectory);
Assert.Equal(DateTime.Parse("7-8-2011"), xcopyCommand.ChangedAfterDate);
}
[Fact]
public void EmbeddedSeparatorsDoNotCountAsSwitch()
{
var args = new[] { "/S:Value/With:Separators", "/Y-", "/t", "/N:123" };
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var actual = migrate::CmdLine.CommandLine.Parse<TestArgs>();
Assert.Equal("Value/With:Separators", actual.StringArg);
Assert.True(actual.BoolT);
Assert.False(actual.BoolY);
}
[Fact]
public void CaseSensitiveAllowsUpperAndLowerWithSameSwitch()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/t:lower /T:UPPER /y /Y-");
var oldValue = migrate::CmdLine.CommandLine.CaseSensitive;
migrate::CmdLine.CommandLine.CaseSensitive = true;
var actual = migrate::CmdLine.CommandLine.Parse<TypeWithUpperAndLower>();
migrate::CmdLine.CommandLine.CaseSensitive = oldValue;
Assert.Equal("lower", actual.Lower);
Assert.Equal("UPPER", actual.Upper);
Assert.True(actual.YLower);
Assert.False(actual.YUpper);
}
[Fact]
public void NoMatchingPropertyShouldThrow()
{
var args = new[] { "/?" };
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
try
{
migrate::CmdLine.CommandLine.Parse<TestArgs>();
Assert.True(false, "Parse did not throw an exception");
}
catch (migrate::CmdLine.CommandLineArgumentInvalidException exception)
{
Assert.NotNull(exception.ArgumentHelp);
Assert.Equal(4, exception.ArgumentHelp.ValidArguments.Count());
}
}
[Fact]
public void NoMatchingPropertyWithInferredShouldThrow()
{
var args = new[] { "/NoMatch" };
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var commandArg = new migrate::CmdLine.CommandArgument("/NoMatch", 0);
commandArg.Command = "NoMatch";
Assert.Equal(
new migrate::CmdLine.CommandLineArgumentInvalidException(typeof(string), commandArg).Message,
Assert.Throws<migrate::CmdLine.CommandLineArgumentInvalidException>(
() => migrate::CmdLine.CommandLine.Parse<InferredTestArgs>()).Message);
}
[Fact]
public void TwoPropsWithSameSwitchShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineException("Duplicate Command \"B\"").Message,
Assert.Throws<migrate::CmdLine.CommandLineException>(() => migrate::CmdLine.CommandLine.Parse<TwoPropsWithSameSwitch>()).
Message);
}
[Fact]
public void WhenNoAttributesParseWillUsePropertyNames()
{
var args = new[] { "/StringArg:Value/With:Separators", "/BoolY-", "/BoolT", "/Date:12-1-2011", "/Number:23" };
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args);
var actual = migrate::CmdLine.CommandLine.Parse<InferredTestArgs>();
Assert.Equal("Value/With:Separators", actual.StringArg);
Assert.True(actual.BoolT);
Assert.False(actual.BoolY);
Assert.Equal(DateTime.Parse("12-1-2011"), actual.Date);
Assert.Equal(23, actual.Number);
}
[Fact]
public void WhenNoPositionOneShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineException(
"Out of order parameter \"source\" should have be at parameter index 1 but was found at 2").Message,
Assert.Throws<migrate::CmdLine.CommandLineException>(() => migrate::CmdLine.CommandLine.Parse<BadPositionArgNoOne>()).
Message);
}
[Fact]
public void WhenNoPositionTwoShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineException(
"Out of order parameter \"destination\" should have be at parameter index 2 but was found at 3").
Message,
Assert.Throws<migrate::CmdLine.CommandLineException>(() => migrate::CmdLine.CommandLine.Parse<BadPositionArgMissingTwo>()).
Message);
}
[Fact]
public void WhenDuplicatePositionShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new migrate::CmdLine.CommandLineException("Duplicate Parameter Index [1] on Property \"S2\"").Message,
Assert.Throws<migrate::CmdLine.CommandLineException>(
() => migrate::CmdLine.CommandLine.Parse<TypeWithDuplicateParamIndex>()).Message);
}
[Fact]
public void WhenBadParameterIndexShouldThrow()
{
migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment();
Assert.Equal(
new CustomAttributeFormatException("'ParameterIndex' property specified was not found.").Message,
Assert.Throws<CustomAttributeFormatException>(() => migrate::CmdLine.CommandLine.Parse<TypeWithBadParamIndex>()).Message);
}
}
public class TestArgsWithList
{
[migrate::CmdLine.CommandLineParameterAttribute(Command = "N")]
public List<string> NList { get; set; }
}
public class TypeWithUpperAndLower
{
[migrate::CmdLine.CommandLineParameterAttribute("t")]
public string Lower { get; set; }
[migrate::CmdLine.CommandLineParameterAttribute("T")]
public string Upper { get; set; }
[migrate::CmdLine.CommandLineParameterAttribute("y")]
public bool YLower { get; set; }
[migrate::CmdLine.CommandLineParameterAttribute("Y")]
public bool YUpper { get; set; }
}
public class TypeWithBadParamIndex
{
[migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = -1)]
public string S1 { get; set; }
}
public class TypeWithDuplicateParamIndex
{
[migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = 1)]
public string S1 { get; set; }
[migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = 1)]
public string S2 { get; set; }
}
}