0% found this document useful (0 votes)
132 views

Command Line

The document defines classes and interfaces for parsing command line arguments in C#. It includes classes for defining arguments, parsing arguments, and testing the argument parser. The main classes are Arguments for defining the available arguments, Parser for parsing arguments, and tests for the argument parser.

Uploaded by

sambram
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
132 views

Command Line

The document defines classes and interfaces for parsing command line arguments in C#. It includes classes for defining arguments, parsing arguments, and testing the argument parser. The main classes are Arguments for defining the available arguments, Parser for parsing arguments, and tests for the argument parser.

Uploaded by

sambram
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

using

using
using
using
using

System.Collections.Generic;
System.IO;
System.Linq;
System.Reflection;
CommandLineParser.Arguments;

namespace CodingChallange1_800
{
public class Arguments : IArgumentsConfig<IArgumentsValues>, IArgumentsValue
s
{
private const char InputFileShortName = 'I';
private const char DictionaryShortName = 'D';
internal const string InputFileLongName = "input-file";
internal const string DictionaryLongName = "dictionary-file";
private readonly FileArgument _inputFile;
private readonly FileArgument _dictionaryFile;
public Arguments()
{
_inputFile = new FileArgument(InputFileShortName, InputFileLongName,
Help.InputFileArgument);
_dictionaryFile = new FileArgument(DictionaryShortName, DictionaryLo
ngName,
Help.DictionaryFileArgument)
{
DefaultValue = new FileInfo("defaultDictionary")
};
}
public IEnumerable<Argument> All
{
get
{
return GetType().GetFields(BindingFlags.Instance | BindingFlags.
NonPublic)
.Select(field => field.GetValue(this)).OfType<Argument>().To
List();
}
}
public FileInfo InputFile
{
get { return _inputFile.Value; }
}
public FileInfo DictionaryFile
{
get { return _dictionaryFile.Value; }
}
public IArgumentsValues AsOutput()
{
return this;
}
}
[TestFixture]
public class ArgumentsTest

{
private Arguments _arguments;
[SetUp]
public void SetUp()
{
_arguments = new Arguments();
}
[Test]
public void AllCollectsAllArguments()
{
AssertArgument<FileArgument>(Arguments.InputFileLongName);
AssertArgument<FileArgument>(Arguments.DictionaryLongName);
}
private void AssertArgument<T>(string longName) where T : Argument
{
var argument = FindArgument(longName);
Assert.IsNotNull(argument, "there should be an argument " + longName
);
Assert.IsInstanceOf(typeof(T), argument, "argument " + longName);
}
private Argument FindArgument(string longName)
{
return _arguments.All.First(x => x.LongName == longName);
}
[Test]
public void AllArgumentsShouldHaveDifferentShortNames()
{
var shortNames = _arguments.All.Select(x => x.ShortName).Where(x =>
x != ' ');
Assert.AreEqual(shortNames, shortNames.Distinct(), "distinct short n
ames");
}
[Test]
public void AllArgumentsShouldHaveDifferentLongNames()
{
var longNames = _arguments.All.Select(x => x.LongName);
Assert.AreEqual(longNames, longNames.Distinct(), "distinct long name
s");
}
[Test]
public void PropertiesHaveTheValueOfTheCorrespondingArguments()
{
InputFileArgument.Value = new FileInfo("inputFileName");
Assert.AreEqual(InputFileArgument.Value, _arguments.InputFile, "Argu
ments.InputFileName");
DictionaryFileArgument.Value = new FileInfo("dictionaryFileName");
Assert.AreEqual(DictionaryFileArgument.Value, _arguments.DictionaryF
ile,
"Arguments.DictionaryFileName");
}
[Test]
public void DictionaryArgumentIsDefaultDictionaryByDedfault()
{
Assert.AreEqual(new FileInfo("defaultDictionary").FullName, Dictiona
ryFileArgument.DefaultValue.FullName,
"DictionaryFileArgument default value");
}
[Test]
public void ReturnsItselfAsOutput()
{

Assert.AreSame(_arguments, _arguments.AsOutput(), "Arguments.AsOutpu


t");
}
private FileArgument DictionaryFileArgument
{
get { return (FileArgument)FindArgument(Arguments.DictionaryLongName
); }
}
private FileArgument InputFileArgument
{
get { return (FileArgument)FindArgument(Arguments.InputFileLongName)
; }
}
}
public static class Help
{
internal static readonly string InputFileArgument = Format(
"Input file argument");
internal static readonly string DictionaryFileArgument = Format(
"Dictionary file argument");
private static string Format(params string[] lines)
{
return String.Join("\r\n\t\t", lines);
}
}
public interface IArgumentsConfig<T>
{
IEnumerable<Argument> All { get; }
T AsOutput();
}
public interface IArgumentsValues
{
FileInfo InputFile { get; }
FileInfo DictionaryFile { get; }
}
public interface ICommandLine
{
string CommandLine { get; }
}
public interface IParser<T> : ICommandLine
{
string Usage { get; }
bool UsageShouldBeDisplayed { get; }
void ReadArgs(string[] args);
T Parse();
}
public class Parser<T> : IParser<T>
{
public const int SuccessExitCode = 0;
public const int FailureExitCode = -1;
private readonly CommandLineParser.CommandLineParser _parser;
private readonly IArgumentsConfig<T> _arguments;

private string[] _args = new string[0];


internal Parser(IArgumentsConfig<T> arguments)
{
_arguments = arguments;
_parser = new CommandLineParser.CommandLineParser();
_parser.IgnoreCase = true;
_parser.Arguments.AddRange(_arguments.All);
}
public string Usage
{
get
{
TextWriter str = new StringWriter();
_parser.PrintUsage(str);
return str.ToString().Trim();
}
}
public string CommandLine
{
get { return String.Join(" ", _args); }
}
public T Parse()
{
_parser.ParseCommandLine(_args);
return _arguments.AsOutput();
}
public void ReadArgs(string[] args)
{
_args = args;
}
public bool UsageShouldBeDisplayed
{
get { return (_args.Contains("--help") || _args.Contains("/help") ||
_args.Contains("/?")); }
}
}
[TestFixture]
public class ParserTest
{
private Parser<object> _parser;
private TestArguments _arguments;
[SetUp]
public void SetUp()
{
_arguments = new TestArguments();
_parser = null;
}
[Test]
public void PublishesTheUsageString()
{
GivenANewParser();
AssertIsUsage(_parser.Usage);
}
[Test]
public void ShowsUsageWithHelpArgs()
{
GivenANewParser();

_parser.ReadArgs(new [] { "--help"});
Assert.IsTrue(_parser.UsageShouldBeDisplayed, "Parser.UsageShouldBeD
isplayed");
}
[Test]
public void DoesNotShowUsageWithValidArgs()
{
ParseArgumentsWithUser();
Assert.IsFalse(_parser.UsageShouldBeDisplayed, "Parser.UsageShouldBe
Displayed");
}
[Test]
public void ByDefaultCommandLineIsEmpty()
{
GivenANewParser();
Assert.AreEqual("", _parser.CommandLine, "Command Line");
}
[Test]
public void KnowsTheActualCommandLineTextAfterAParsing()
{
var args = new[] {TestArguments.UserShortArg, "spoke", TestArguments
.NumberShortArg, "42"};
ParseArguments(args);
Assert.AreEqual(string.Join(" ", args), _parser.CommandLine, "Comman
d line");
}
[Test]
public void ActuallyParsesTheCommandLine()
{
const string User = "Bob";
const int Number = 12;
ParseArguments(TestArguments.UserShortArg, User, TestArguments.Numbe
rShortArg, Number.ToString());
Assert.AreEqual(User, _arguments.User.Value, "Parsed user argument")
;
Assert.AreEqual(Number, _arguments.Number.Value, "Parsed number argu
ment");
}
[Test, ExpectedException(typeof(InvalidConversionException))]
public void ThrowsWhenAParsingErrorOccurs()
{
ParseArgumentsWithUser(TestArguments.NumberShortArg, "malformed numb
er ...");
}
[Test]
public void CreatesTheOutputOnSuccessfulParsing()
{
Assert.AreEqual(_arguments.Output, ParseArgumentsWithUser(), "Output
built by the parser");
}
[Test]
public void HandlesUperCaseArguments()
{
const string User = "Client";
ParseArguments("--" + TestArguments.UserLongName.ToUpper(), User);
Assert.AreEqual(User, _arguments.User.Value, "User specified with up
case argument name");
}
private object ParseArgumentsWithUser(params string[] extraArgs)
{

var allArgs = new List<string> { TestArguments.UserShortArg, "Jimmy"


};
allArgs.AddRange(extraArgs);
return ParseArguments(allArgs.ToArray());
}
private object ParseArguments(params string[] args)
{
GivenANewParser();
_parser.ReadArgs(args);
return _parser.Parse();
}
private void GivenANewParser()
{
_parser = new Parser<object>(_arguments);
}
private static void AssertIsUsage(string text)
{
Assert.That(text, Is.StringStarting("Usage:"), "Command line usage")
;
Assert.That(text, Is.StringContaining(TestArguments.UserShortArg), "
Command line usage");
Assert.That(text, Is.StringContaining(TestArguments.NumberShortArg),
"Command line usage");
}
}
public class TestArguments : IArgumentsConfig<object>
{
internal const char UserShortName = 'U';
internal const string UserLongName = "user";
internal static readonly string UserShortArg = "-" + UserShortName;
internal const char NumberShortName = 'N';
internal static readonly string NumberShortArg = "-" + NumberShortName;
internal readonly ValueArgument<string> User = new ValueArgument<string>
(UserShortName, UserLongName)
{
Optional = false
};
internal readonly ValueArgument<int> Number = new ValueArgument<int>(Num
berShortName, "number");
public IEnumerable<Argument> All
{
get { return new Argument[] {User, Number}; }
}
internal readonly object Output = new object();
public object AsOutput()
{
return Output;
}
}

You might also like