public void ObjectValidator()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <OptOneOfEach>("verb", verb =>
            {
                verb.AddOption(x => x.Option, x => x.WithShortAndLongName("o", "opt"));

                verb.ValidateObject = (obj) => obj.Option < 50 ? null : "Too much!";
            })
                           .Build();

            IParseResult pr = fp.Parse(new string[] { "verb", "-o", "10" });

            Assert.IsType <SuccessfulParse <OptOneOfEach> >(pr);
            Assert.True(pr.Ok);
            Assert.Empty(pr.Errors);

            pr = fp.Parse(new string[] { "verb", "--opt", "999" });
            Assert.IsType <FailedParseWithVerb <OptOneOfEach> >(pr);
            Assert.False(pr.Ok);
            Assert.Equal(1, pr.Errors.Count);
            var error = pr.Errors.First();

            Assert.Equal(ErrorCode.ObjectFailedValidation, error.ErrorCode);
            Assert.Equal("Too much!", error.Message);
        }
示例#2
0
        public void DefaultHelpSwitch_ErrorCodeHelpRequested()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <OptEmpty>("blah", (verb) => { }).Build();
            IParseResult result1 = fp.Parse(new string[] { "-?" });
            IParseResult result2 = fp.Parse("--help");
            Error        err     = result1.Errors.Single();

            Assert.Equal(ErrorCode.HelpRequested, err.ErrorCode);
            Assert.Empty(err.Message);
            err = result2.Errors.Single();
            Assert.Equal(ErrorCode.HelpRequested, err.ErrorCode);
            Assert.Empty(err.Message);
        }
示例#3
0
        public void DependencyWhenShorthand()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <VerbVariety>("default", verb =>
            {
                verb.AddValue(x => x.Value, x =>
                {
                    x.HelpText = "h"; x.HasDependency.RequiredWhen(x => x.OptionNullable > 50).WithErrorMessage("Only required if OptionNullable is larger than 50");
                });

                verb.AddOption(x => x.OptionNullable, x => { x.ShortName = "o"; x.LongName = "option"; x.DefaultValue = null; x.HelpText = "h"; });
            })
                           .Build();

            // We're basically saying first: MyValue is required
            IParseResult res = fp.Parse(new string[] { "default", "MyValue", "-o", "55" });

            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "55" });
            Assert.False(res.Ok);
            // And now we're saying MyValue is not required (So it should work either way)
            res = fp.Parse(new string[] { "default", "MyValue", "-o", "30" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "30" });
            Assert.True(res.Ok);


            fp = new CliParserBuilder()
                 .AddVerb <VerbVariety>("default", verb =>
            {
                verb.AddValue(x => x.Value, x =>
                {
                    x.HelpText = "h"; x.HasDependency.MustNotAppearWhen(x => x.OptionNullable > 50).WithErrorMessage("Shouldn't appear if OptionNullable is larger than 50");
                });

                verb.AddOption(x => x.OptionNullable, x => { x.ShortName = "o"; x.LongName = "option"; x.DefaultValue = null; x.HelpText = "h"; });
            })
                 .Build();

            // We're basically saying first: MyValue is required
            res = fp.Parse(new string[] { "default", "MyValue", "-o", "55" });
            Assert.False(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "55" });
            Assert.True(res.Ok);
            // And now we're saying MyValue is not required (So it should work either way)
            res = fp.Parse(new string[] { "default", "MyValue", "-o", "30" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "30" });
            Assert.True(res.Ok);
        }
        internal static void ComplexParsing(string[] args, bool shouldBeSuccessful, ComplexVerb1?expectedResult)
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <ComplexVerb1>("default", verb =>
            {
                verb.HelpText = "My Test Verb";

                verb.AddValue(x => x.RequiredValue, x => x.HelpText = "h");

                verb.AddValue(x => x.ConvertedValue, x => x.HelpText = "h");

                verb.AddValueNullable(x => x.OptionalValue, x => { x.DefaultValue = null; x.HelpText = "h"; });

                verb.AddSwitch(x => x.Switch1, x => { x.ShortName = "s1"; x.LongName = "ss1"; x.HelpText = "h"; });

                verb.AddSwitch(x => x.DefaultValueSwitch, x => { x.ShortName = "s2"; x.LongName = "ss2"; x.DefaultValue = true; x.HelpText = "h"; });

                verb.AddSwitchCore(a => a.ConvertedSwitch, new Arguments.Config.NamedArgConfig <ComplexVerb1, string, bool>()
                {
                    Converter = v => Converted <string, string> .Value(v.ToString()),
                    HelpText  = "h",
                    ShortName = "s3",
                    LongName  = "ss3"
                });

                verb.AddSwitchCore(a => a.DefaultValueConvertedSwitch, new Arguments.Config.NamedArgConfig <ComplexVerb1, string, bool>()
                {
                    Converter    = v => Converted <string, string> .Value(v.ToString()),
                    DefaultValue = "Default",
                    HelpText     = "h",
                    ShortName    = "s4",
                    LongName     = "ss4"
                });

                verb.AddOption(x => x.RequiredOption, x => { x.ShortName = "o1"; x.LongName = "oo1"; x.HelpText = "h"; });
                verb.AddOption(x => x.OptionalOption, x => { x.ShortName = "o2"; x.LongName = "oo2"; x.DefaultValue = "Default"; x.HelpText = "h"; });
                verb.AddOption(x => x.ConvertedOption, x => { x.ShortName = "o3"; x.LongName = "oo3"; x.HelpText = "h"; });
            }).Build();

            IParseResult result = fp.Parse(args);

            Assert.Equal(shouldBeSuccessful, result.Ok);
            if (shouldBeSuccessful)
            {
                SuccessfulParse <ComplexVerb1> tResult = Assert.IsType <SuccessfulParse <ComplexVerb1> >(result);
                Assert.NotNull(tResult.Object);
                ComplexVerb1 x = tResult.Object !;
                Assert.True(expectedResult !.RequiredValue == x.RequiredValue);
                Assert.True(expectedResult.ConvertedValue == x.ConvertedValue);
                Assert.True(expectedResult.OptionalValue == x.OptionalValue);
                Assert.True(expectedResult.Switch1 == x.Switch1);
                Assert.True(expectedResult.DefaultValueSwitch == x.DefaultValueSwitch);
                Assert.True(expectedResult.ConvertedSwitch == x.ConvertedSwitch);
                Assert.True(expectedResult.DefaultValueConvertedSwitch == x.DefaultValueConvertedSwitch);
                Assert.True(expectedResult.RequiredOption == x.RequiredOption);
                Assert.True(expectedResult.OptionalOption == x.OptionalOption);
                Assert.True(expectedResult.ConvertedOption == x.ConvertedOption);
            }
        }
示例#5
0
        public void DependencyNotNull()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <VerbVariety>("default", verb =>
            {
                verb.AddValue(x => x.Value, x =>
                {
                    x.HelpText = "h"; x.HasDependency.RequiredIf(e => e.OptionNullable).IsNotNull().WithErrorMessage("If OptionNullable is not null, you must specify a value");
                });

                verb.AddOption(x => x.OptionNullable, x => { x.ShortName = "o"; x.LongName = "option"; x.DefaultValue = null; x.HelpText = "h"; });
            })
                           .Build();

            IParseResult res = fp.Parse(new string[] { "default", "MyValue", "-o", "30" });

            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "30" });
            Assert.False(res.Ok);
            res = fp.Parse(new string[] { "default", "MyValue" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default" });
            Assert.True(res.Ok);


            fp = new CliParserBuilder()
                 .AddVerb <VerbVariety>("default", verb =>
            {
                verb.AddValue(x => x.Value, x =>
                {
                    x.HelpText = "h"; x.HasDependency.MustNotAppearIf(e => e.OptionNullable).IsNotNull().WithErrorMessage("If OptionNullable is not null, you must NOT specify a value");
                });

                verb.AddOption(x => x.OptionNullable, x => { x.ShortName = "o"; x.LongName = "option"; x.DefaultValue = null; x.HelpText = "h"; });
            })
                 .Build();

            res = fp.Parse(new string[] { "default", "MyValue", "-o", "30" });
            Assert.False(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "30" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "MyValue" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default" });
            Assert.True(res.Ok);
        }
        public void ParsingConverters_Nullable()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <EveryPrimitiveTypeNullable>("default", verb =>
            {
                verb.AddOptionNullable(x => x.Str, x => x.ShortName = "-Str");
                verb.AddOption(x => x.Short, x => x.ShortName       = "-Short");
                verb.AddOption(x => x.UShort, x => x.ShortName      = "-UShort");
                verb.AddOption(x => x.Int, x => x.ShortName         = "-Int");
                verb.AddOption(x => x.UInt, x => x.ShortName        = "-UInt");
                verb.AddOption(x => x.Long, x => x.ShortName        = "-Long");
                verb.AddOption(x => x.ULong, x => x.ShortName       = "-ULong");
                verb.AddOption(x => x.Float, x => x.ShortName       = "-Float");
                verb.AddOption(x => x.Double, x => x.ShortName      = "-Double");
                verb.AddOption(x => x.Decimal, x => x.ShortName     = "-Decimal");
                verb.AddOption(x => x.MyEnum, x => x.ShortName      = "-MyEnum");
                verb.AddOption(x => x.DateTime, x => x.ShortName    = "-DateTime");
                verb.AddOption(x => x.TimeSpan, x => x.ShortName    = "-TimeSpan");
                verb.AddOption(x => x.Guid, x => x.ShortName        = "-Guid");
            }).Build();

            IParseResult parseResult = fp.Parse(new string[]
                                                { "default",
                                                  "-Str", "SomeString",
                                                  "-Short", "10",
                                                  "-UShort", "20",
                                                  "-Int", "-30",
                                                  "-UInt", "40",
                                                  "-Long", "50",
                                                  "-ULong", "60",
                                                  "-Float", "70.5",
                                                  "-Double", "95.2",
                                                  "-Decimal", "100.130",
                                                  "-MyEnum", "SomeValue",
                                                  "-DateTime", "2020-10-10T05:05:05.123",
                                                  "-TimeSpan", "12:00:00",
                                                  "-Guid", "123e4567-e89b-12d3-a456-426614174000" });

            EveryPrimitiveTypeNullable pr = Assert.IsType <SuccessfulParse <EveryPrimitiveTypeNullable> >(parseResult).Object;

            Assert.Equal("SomeString", pr.Str);
            Assert.Equal(10, pr.Short !.Value);
            Assert.Equal(20, pr.UShort !.Value);
            Assert.Equal(-30, pr.Int);
            Assert.True(40U == pr.UInt);
            Assert.Equal(50, pr.Long);
            Assert.True(60UL == pr.ULong);
            Assert.Equal(70.5, pr.Float !.Value);
            Assert.Equal(95.2, pr.Double);
            Assert.True(100.130m == pr.Decimal);
            Assert.Equal(MyEnum.SomeValue, pr.MyEnum);
            Assert.Equal(new DateTime(2020, 10, 10, 5, 5, 5, 123), pr.DateTime);
            Assert.Equal(new TimeSpan(12, 0, 0), pr.TimeSpan);
            Assert.Equal(new Guid(0x123e4567, 0xe89b, 0x12d3, 0xa4, 0x56, 0x42, 0x66, 0x14, 0x17, 0x40, 0x00), pr.Guid);
        }
示例#7
0
        public void DependencyMultipleRules()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <VerbVariety>("default", verb =>
            {
                verb.AddValue(x => x.Value, x =>
                {
                    x.HelpText = "h";
                    // Optional if it's between 45 to 50, inclusive
                    x.HasDependency.MustNotAppearIf(e => e.OptionNullable).When(v => v > 50).WithErrorMessage("Must not be provided if OptionNullable is > 50");
                    x.HasDependency.RequiredIf(e => e.OptionNullable).When(v => v < 45).WithErrorMessage("Must be provided if OptionNullable is < 45");
                });

                verb.AddOption(x => x.OptionNullable, x => { x.ShortName = "o"; x.LongName = "option"; x.DefaultValue = null; x.HelpText = "h"; });
            })
                           .Build();

            IParseResult res = fp.Parse(new string[] { "default", "MyValue", "-o", "55" });

            Assert.False(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "55" });
            Assert.True(res.Ok);

            res = fp.Parse(new string[] { "default", "MyValue", "-o", "47" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "47" });
            Assert.True(res.Ok);

            res = fp.Parse(new string[] { "default", "MyValue", "-o", "40" });
            Assert.True(res.Ok);
            res = fp.Parse(new string[] { "default", "-o", "40" });
            Assert.False(res.Ok);
        }
        public void VerbParsing()
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <Verb1>("verb1", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb2>("verb2", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb3>("verb3", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb4>("verb4", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb5>("verb5", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb6>("verb6", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb7>("verb7", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb8>("verb8", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb9>("verb9", v => v.AddValue(v => v.Value, x => x.HelpText   = "h"))
                           .AddVerb <Verb10>("verb10", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb11>("verb11", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb12>("verb12", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb13>("verb13", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb14>("verb14", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb15>("verb15", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .AddVerb <Verb16>("verb16", v => v.AddValue(v => v.Value, x => x.HelpText = "h"))
                           .Build();

            string[] args = new string[2];
            int      i    = 1;

            Check <Verb1>();
            Check <Verb2>();
            Check <Verb3>();
            Check <Verb4>();
            Check <Verb5>();
            Check <Verb6>();
            Check <Verb7>();
            Check <Verb8>();
            Check <Verb9>();
            Check <Verb10>();
            Check <Verb11>();
            Check <Verb12>();
            Check <Verb13>();
            Check <Verb14>();
            Check <Verb15>();
            Check <Verb16>();

            void Check <T>() where T : Options.Verb, new()
            {
                args[0] = $"verb{i}";
                args[1] = "Value";
                IParseResult parsed = fp.Parse(args);

                Assert.NotNull(parsed.Verb);
                Assert.Equal(args[0], parsed.Verb !.LongName);
                i++;
            }
        }
示例#9
0
        static void Main(string[] args)
        {
            CliParser parser = new CliParserBuilder()
                               .AddVerb <Input>("encrypt", verb =>
            {
                verb.HelpText = "Encrypts the input text";
                verb.Invoke   = EncryptText;

                verb.AddValue(theClass => theClass.Text, x =>
                {
                    x.DescriptiveName = "Input Text";
                    x.HelpText        = "The text which has to be processed";
                });

                verb.AddOption(theClass => theClass.Shift, x =>
                {
                    x.ShortName       = "-s";
                    x.LongName        = "--shift";
                    x.DescriptiveName = "Shift";
                    x.HelpText        = "The number oharachters to shift";
                    x.Required        = false;
                });
            })
                               .AddVerb <Input>("decrypt", verb =>
            {
                verb.HelpText = "Decrypts the input text";
                verb.Invoke   = DecryptText;

                verb.AddValue(theClass => theClass.Text, x =>
                {
                    x.DescriptiveName = "Input Text";
                    x.HelpText        = "The text which has to be processed";
                });

                verb.AddOption(theClass => theClass.Shift, x =>
                {
                    x.ShortName       = "-s";
                    x.LongName        = "--shift";
                    x.DescriptiveName = "Shift";
                    x.HelpText        = "The number oharachters to shift";
                    x.Required        = false;
                });
            })
                               .Build();

            IParseResult result = parser.Parse(args);

            parser.Handle(result);
        }
示例#10
0
        internal static void ManyValueParsing(string[] args, bool shouldBeSuccessful, OptOneOfEach expectedResult)
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <OptOneOfEach>("default", verb =>
            {
                verb.AddMultiValue(x => x.ManyValues, x => x.HelpText = "h");
                verb.AddOption(x => x.Option, x => { x.ShortName = "o"; x.LongName = "oo"; x.DefaultValue = 0; x.HelpText = "h"; });
                verb.AddSwitch(x => x.Switch, x => { x.ShortName = "s"; x.LongName = "ss"; x.HelpText = "h"; });
            }).Build();

            IParseResult result = fp.Parse(args);

            Assert.Equal(shouldBeSuccessful, result.Ok);
            if (shouldBeSuccessful)
            {
                SuccessfulParse <OptOneOfEach> tResult = Assert.IsType <SuccessfulParse <OptOneOfEach> >(result);
                OptOneOfEach x = tResult.Object !;
                Assert.NotNull(x);
                Assert.True(expectedResult.Option == x.Option);
                Assert.True(expectedResult.Switch == x.Switch);
                Assert.True(expectedResult.ManyValues.SequenceEqual(x.ManyValues));
            }
        }
示例#11
0
        public void ManyValueAccumulators()
        {
            CliParser fp          = new CliParserBuilder().AddVerb <OptArray>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var       objOptArray = Assert.IsType <SuccessfulParse <OptArray> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptArray.Collection);
            Assert.Contains("String2", objOptArray.Collection);
            Assert.Contains("String3", objOptArray.Collection);

            fp = new CliParserBuilder().AddVerb <OptList>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptList = Assert.IsType <SuccessfulParse <OptList> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptList.Collection);
            Assert.Contains("String2", objOptList.Collection);
            Assert.Contains("String3", objOptList.Collection);

            fp = new CliParserBuilder().AddVerb <OptIList>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptIList = Assert.IsType <SuccessfulParse <OptIList> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptIList.Collection);
            Assert.Contains("String2", objOptIList.Collection);
            Assert.Contains("String3", objOptIList.Collection);

            fp = new CliParserBuilder().AddVerb <OptIReadOnlyList>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptIReadOnlyList = Assert.IsType <SuccessfulParse <OptIReadOnlyList> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptIReadOnlyList.Collection);
            Assert.Contains("String2", objOptIReadOnlyList.Collection);
            Assert.Contains("String3", objOptIReadOnlyList.Collection);

            fp = new CliParserBuilder().AddVerb <OptICollection>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptICollection = Assert.IsType <SuccessfulParse <OptICollection> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptICollection.Collection);
            Assert.Contains("String2", objOptICollection.Collection);
            Assert.Contains("String3", objOptICollection.Collection);

            fp = new CliParserBuilder().AddVerb <OptIReadOnlyCollection>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptIReadOnlyCollection = Assert.IsType <SuccessfulParse <OptIReadOnlyCollection> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptIReadOnlyCollection.Collection);
            Assert.Contains("String2", objOptIReadOnlyCollection.Collection);
            Assert.Contains("String3", objOptIReadOnlyCollection.Collection);

            fp = new CliParserBuilder().AddVerb <OptIEnumerable>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptIEnumerable = Assert.IsType <SuccessfulParse <OptIEnumerable> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptIEnumerable.Collection);
            Assert.Contains("String2", objOptIEnumerable.Collection);
            Assert.Contains("String3", objOptIEnumerable.Collection);

            fp = new CliParserBuilder().AddVerb <OptHashSet>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptHashSet = Assert.IsType <SuccessfulParse <OptHashSet> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptHashSet.Collection);
            Assert.Contains("String2", objOptHashSet.Collection);
            Assert.Contains("String3", objOptHashSet.Collection);

            fp = new CliParserBuilder().AddVerb <OptStack>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptStack = Assert.IsType <SuccessfulParse <OptStack> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptStack.Collection);
            Assert.Contains("String2", objOptStack.Collection);
            Assert.Contains("String3", objOptStack.Collection);

            fp = new CliParserBuilder().AddVerb <OptQueue>("default", verb => verb.AddMultiValue(x => x.Collection, x => { })).Build();
            var objOptQueue = Assert.IsType <SuccessfulParse <OptQueue> >(fp.Parse(new string[] { "default", "String1", "String2", "String3" })).Object;

            Assert.Contains("String1", objOptQueue.Collection);
            Assert.Contains("String2", objOptQueue.Collection);
            Assert.Contains("String3", objOptQueue.Collection);
        }
示例#12
0
        internal static void SimpleParsing(bool outcome, bool isValidVerb, Components components, string[] args)
        {
            CliParser fp = new CliParserBuilder()
                           .AddVerb <OptOneOfEach>("default", verb =>
            {
                if ((components & Components.Value) == Components.Value)
                {
                    verb.AddValue(x => x.Value, x => x.HelpText = "h");
                }
                if ((components & Components.Switch) == Components.Switch)
                {
                    verb.AddSwitch(x => x.Switch, x => { x.ShortName = "-s"; x.LongName = "--switch"; x.HelpText = "h"; });
                }
                if ((components & Components.Option) == Components.Option)
                {
                    verb.AddOption(x => x.Option, x => { x.ShortName = "-o"; x.LongName = "--option"; x.HelpText = "h"; });
                }
            }).Build();

            IParseResult parsed = fp.Parse(args);

            if (outcome)
            {
                Assert.True(parsed.Ok);
                SuccessfulParse <OptOneOfEach> parseResult = Assert.IsType <SuccessfulParse <OptOneOfEach> >(parsed);
                Assert.NotNull(parseResult.Object);
                OptOneOfEach parsedObject = parseResult.Object !;

                Assert.NotNull(parsedObject);
                if ((components & Components.Value) == Components.Value)
                {
                    Assert.Equal("Value", parsedObject.Value);
                }
                if ((components & Components.Switch) == Components.Switch)
                {
                    Assert.True(parsedObject.Switch, $"Switch was specified but didn't set property to true");
                }
                else
                {
                    Assert.False(parsedObject.Switch, $"Switch was specified but didn't set property to false");
                }
                if ((components & Components.Option) == Components.Option)
                {
                    Assert.Equal(30, parsedObject.Option);
                }
            }
            else
            {
                Assert.False(parsed.Ok);
                // Verb still shouldn't be null, since for our test cases we DO pass the verb
                if (isValidVerb)
                {
                    Assert.NotNull(parsed.Verb);
                }
                else
                {
                    Assert.Null(parsed.Verb);
                }
                Assert.NotEmpty(parsed.Errors);
            }
        }