public void ShouldHaveSingleFlagWithDefault(bool defaultValue) { // Arrange var args = new string[0]; // Act var result = Args.Configure() .WithFlag("force", o => o.WithArg("-f") .WithArg("--force") .WithDefault(defaultValue) ) .Parse(args); // Assert Expect(result) .Not.To.Be.Null(); Expect(result.Flags) .Not.To.Be.Null(); Expect(result.Flags) .To.Contain.Key("force") .With.Value.Intersection.Equal.To( new { Value = defaultValue } ); }
public void ShouldStringMapParameterByName() { // Arrange var args = new[] { "-s", GetRandomString() }; var expected = args[1]; // Act var result = Args.Configure() .WithParameter( nameof(Opts.Source), o => o.WithArg("-s") ) .Parse <Opts>(args); // Assert Expect(result.Source) .To.Equal(expected); }
public void ShouldMapMultiValueParametersToList() { // Arrange var args = new[] { "-m", "one", "-m", "two", "-m", "three" }; var expected = new[] { "one", "two", "three" }; // Act var result = Args.Configure() .WithParameter( nameof(Opts.MultiValueList), o => o.WithArg("-m") .WithArg("--multi") ) .Parse <Opts>(args); // Assert Expect(result.MultiValueList) .To.Equal(expected); }
public void ShouldMapConvertable() { // Arrange var expected = GetRandomCollection <int>(2); var args = expected.Select(i => new[] { "-i", i.ToString() }) .SelectMany(o => o) .ToArray(); // Act var result = Args.Configure() .WithParameter( nameof(Opts.Ints), o => o.WithArg("-i") ) .Parse <Opts>(args); // Assert Expect(result.Ints) .To.Equal(expected); }
public void ShouldMapSingleEnum() { // Arrange var expected = GetRandom <EnumValue>(e => e != EnumValue.One); var args = new[] { GetRandomFrom(new[] { "-e", "--enum-value" }), expected.ToString() }; // Act var result = Args.Configure() .WithParameter( nameof(Opts.EnumValue), o => o.WithArg("-e") .WithArg("--enum-value") .Required() ) .Parse <Opts>(args); // Assert Expect(result.EnumValue) .To.Equal(expected); }
public void ShouldEnforceRequiredParameters() { // Arrange var args = new string[0]; // Act Expect(() => Args.Configure() .WithParameter( nameof(Opts.Source), o => o.WithArg("-s") .Required() ) .Parse <Opts>(args) ) .To.Throw <ArgumentException>() .With.Message.Containing( "Source is required" ); // Assert }
public void ShouldHaveSingleParameterWithEmptyValues() { // Arrange var args = new string[0]; // Act var result = Args.Configure() .WithParameter("source", o => o.WithArg("-s") .WithArg("--source") ) .Parse(args); // Assert Expect(result) .Not.To.Be.Null(); Expect(result.Parameters) .Not.To.Be.Null(); Expect(result.Parameters) .To.Contain.Key("source") .With.Value.Intersection.Equal.To( new { Value = new string[0] } ); }
private static bool TryParseOptionsFrom( string[] args, out Options opts) { try { opts = Args.Configure() .WithParameter( nameof(Options.Archive), o => o.WithArg("-a") .WithArg("--archive") .WithHelp("Path / URI to use for archiving") ) .WithParameter( nameof(Options.Source), o => o.WithArg("-s") .WithArg("--source") .Required() .WithHelp("Path / URI to use for source") ) .WithParameter( nameof(Options.Target), o => o.WithArg("-t") .WithArg("--target") .Required() .WithHelp("Path / URI to use for target") ) .WithParameter( nameof(Options.HistoryDatabase), o => o.WithArg("-h") .WithArg("--history-db") .WithHelp( "Override path to history database", "The default location for the database is at the root of the target" ) ) .WithFlag( nameof(Options.NoResume), o => o.WithArg("--no-resume") .WithHelp("Disable resume", "The default is to resume from the current target byte offset if less than the source size" ) ) .WithParameter( nameof(Options.ResumeCheckBytes), o => o.WithArg("--resume-check-bytes") .WithDefault(new[] { SimpleResumeStrategy.DEFAULT_CHECK_BYTES.ToString() }) .WithHelp( "How many bytes to check at the end of a partial file when considering resume") ) .WithFlag( nameof(Options.Quiet), o => o.WithArg("-q") .WithArg("--quiet") .WithHelp("Produces less output, good for non-interactive scripts") ) .WithFlag( nameof(Options.NoHistory), o => o.WithArg("-n") .WithArg("--no-history") .WithHelp("Disables the history database", "If you don't need to have a sparse target, you can disable to history database to fall back on simpler synchronisation: what's at the source must end up at the target" ) ) .WithParameter( nameof(Options.SyncMode), o => o.WithArg("-m") .WithArg("--mode") .WithHelp("Set the sync mode to one of: All or Opt-In (case-insensitive)", "All synchronises everything", "OptIn only synchronises folders which already exist or have been recorded in the history database" ) ) .WithFlag( nameof(Options.KeepStaleFiles), o => o.WithArg("--keep-stale") .WithArg("-k") .WithHelp("Keep stale files (ie files removed from source and still at the target") ) .WithFlag( nameof(Options.CreateTargetIfRequired), o => o.WithArg("-c") .WithArg("--create-missing-target") .WithHelp("Create the target folder if it's missing") ) .WithParameter( nameof(Options.Retries), o => o.WithArg("-r") .WithArg("--retries") .WithDefault(new[] { "3" }) // TODO: this is a bit ugly -- can it be better? .WithHelp("Retry failed synchronisations at most this many times") ) .WithFlag( nameof(Options.DryRun), o => o.WithArg("-d") .WithArg("--dry-run") .WithHelp("Only report what would be done instead of actually doing it") .WithDefault(false) ) .WithFlag( nameof(Options.Verbose), o => o.WithArg("-v") .WithArg("--verbose") .WithDefault(false) .WithHelp("Print a lot more logging") ) .WithFlag( nameof(Options.Version), o => o.WithArg("--version") .WithDefault(false) ) .WithHelp("BitSplat", "A simple file synchroniser aimed at media sync") .Parse <Options>(args); return(true); } catch (ArgumentException ex) { Console.WriteLine($"Error: {ex.Message}"); opts = null; return(false); } }