public void GenerateSwitches(OptionsParser optionsParser)
        {
            // here we assume that all descriptors from `descriptors` array
            // have the same basic attributes (name, description, switches, etc.)
            // they should differ only in configuration and path
            SwitchOption             = optionsParser.WithOption <bool>(descriptors[0].ShortSwitch ?? Tokenizer.NullCharacter, descriptors[0].LongSwitch);
            SwitchOption.Description = descriptors[0].Description;

            if (descriptors[0].ProvidesHelp)
            {
                HelpOption             = optionsParser.WithOption <bool>(string.Format("help-{0}", descriptors[0].LongSwitch));
                HelpOption.Description = string.Format("Show help for {0}", descriptors[0].Name);
            }
        }
        public void ShouldRecreateMixedShortFlag()
        {
            var args   = new [] { "-AwB" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('A');
            parser.WithOption <bool>('B');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('A', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('B', parser.ParsedOptions.Last().Flag.ShortName);
            Assert.AreEqual("-w", parser.RecreateUnparsedArguments());
        }
        public void ShouldRemoveEmptyShortFlagPrefix()
        {
            var args   = new [] { "-AB" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('A');
            parser.WithOption <bool>('B');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('A', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('B', parser.ParsedOptions.Last().Flag.ShortName);
            Assert.AreEqual(string.Empty, parser.RecreateUnparsedArguments());
        }
        public void ShouldParseShortSwitchWithStringValue()
        {
            var args   = new [] { "-nmValue" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('n');
            parser.WithOption <String>('m');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('n', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('m', parser.ParsedOptions.Skip(1).First().Flag.ShortName);
            Assert.AreEqual("Value", parser.ParsedOptions.Skip(1).First().Value);
        }
        public void GenerateSwitches(OptionsParser optionsParser, bool defaultOption = false)
        {
            // here we assume that all descriptors from `descriptors` array
            // have the same basic attributes (name, description, switches, etc.)
            // they should differ only in configuration and path
            SwitchOption = optionsParser.WithOption<bool>(descriptors[0].ShortSwitch ?? Tokenizer.NullCharacter, descriptors[0].LongSwitch);
            SwitchOption.Description = descriptors[0].Description;

            if(defaultOption) 
            {
                SwitchOption.Description += " (default)";
            }

            if(descriptors[0].ProvidesHelp)
            {
                HelpOption = optionsParser.WithOption<bool>(string.Format("help-{0}", descriptors[0].LongSwitch));
                HelpOption.Description = string.Format("Show help for {0}", descriptors[0].Name);
            }
        }
        public void ShouldDetectLongSwitch()
        {
            var args = new [] { "--long" };
            var parser = new OptionsParser();
            parser.WithOption<bool>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);
        }
        public void ShouldDetectShortSwitch()
        {
            var args   = new [] { "-c" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);
        }
        public void ShouldDetectLongSwitch()
        {
            var args   = new [] { "--long" };
            var parser = new OptionsParser();

            parser.WithOption <bool>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);
        }
        public void ShouldParseLongSwitchWithStringWithAssignmentOperator()
        {
            var args   = new [] { "--long=test" };
            var parser = new OptionsParser();

            parser.WithOption <string>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("test", parser.ParsedOptions.First().Value);
        }
        public void ShouldParseOptionWithSpacesInValue()
        {
            var args   = new [] { "--option=Value with spaces" };
            var parser = new OptionsParser();

            parser.WithOption <string>("option");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("option", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("Value with spaces", parser.ParsedOptions.First().Value);
        }
        public void ShouldParseShortOptionWithSeparatedValue()
        {
            var args   = new [] { "-n", "123" };
            var parser = new OptionsParser();

            parser.WithOption <int>('n');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('n', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual(123, parser.ParsedOptions.First().Value);
        }
        public void ShouldNotRecreatedParsedValue()
        {
            var args   = new [] { "--switch", "value" };
            var parser = new OptionsParser();

            parser.WithOption <string>("switch");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual(args[1], parser.ParsedOptions.First().Value);
            Assert.IsEmpty(parser.RecreateUnparsedArguments());
        }
        public void ShouldParseLongSwitchWithValue()
        {
            var args   = new [] { "--number", "123" };
            var parser = new OptionsParser();

            parser.WithOption <int>("number");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("number", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual(123, parser.ParsedOptions.First().Value);
        }
        public void ShouldAcceptExpectedValues()
        {
            var args = new [] { "-a", "-b", "value-1", "-c", "value-2", "-d", "value-3" };
            var parser = new OptionsParser();
            parser.WithValue("val1");
            parser.WithValue("val2");
            parser.WithOption<bool>('a');
            parser.WithOption<bool>('b');
            parser.WithOption<bool>('c');
            parser.WithOption<bool>('d');

            parser.Parse(args);

            Assert.AreEqual(4, parser.ParsedOptions.Count());
            Assert.AreEqual('a', parser.ParsedOptions.ElementAt(0).Flag.ShortName);
            Assert.AreEqual('b', parser.ParsedOptions.ElementAt(1).Flag.ShortName);
            Assert.AreEqual('c', parser.ParsedOptions.ElementAt(2).Flag.ShortName);
            Assert.AreEqual('d', parser.ParsedOptions.ElementAt(3).Flag.ShortName);
            Assert.AreEqual(2, parser.Values.Count());
            Assert.AreEqual("value-1", parser.Values.ElementAt(0).Value);
            Assert.AreEqual("value-2", parser.Values.ElementAt(1).Value);
            Assert.AreEqual("value-3", parser.RecreateUnparsedArguments());
        }
        public void ShouldParseOptionValueWithHyphen()
        {
            var args   = new [] { "-c", "value-with-hyphen" };
            var parser = new OptionsParser();

            parser.WithOption <string>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual("value-with-hyphen", parser.ParsedOptions.First().Value);

            Assert.AreEqual(0, parser.UnexpectedArguments.Count());
        }
        public void ShouldDetectedUnexpectedShortSwitchWithValue()
        {
            var args = new [] { "-cx", "value with whitespace" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);

            Assert.AreEqual(2, parser.UnexpectedArguments.Count());
            Assert.AreEqual("x", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("value with whitespace", parser.UnexpectedArguments.ElementAt(1).Value);
        }
        public void ShouldAcceptExpectedValues()
        {
            var args   = new [] { "-a", "-b", "value-1", "-c", "value-2", "-d", "value-3" };
            var parser = new OptionsParser();

            parser.WithValue("val1");
            parser.WithValue("val2");
            parser.WithOption <bool>('a');
            parser.WithOption <bool>('b');
            parser.WithOption <bool>('c');
            parser.WithOption <bool>('d');

            parser.Parse(args);

            Assert.AreEqual(4, parser.ParsedOptions.Count());
            Assert.AreEqual('a', parser.ParsedOptions.ElementAt(0).Flag.ShortName);
            Assert.AreEqual('b', parser.ParsedOptions.ElementAt(1).Flag.ShortName);
            Assert.AreEqual('c', parser.ParsedOptions.ElementAt(2).Flag.ShortName);
            Assert.AreEqual('d', parser.ParsedOptions.ElementAt(3).Flag.ShortName);
            Assert.AreEqual(2, parser.Values.Count());
            Assert.AreEqual("value-1", parser.Values.ElementAt(0).Value);
            Assert.AreEqual("value-2", parser.Values.ElementAt(1).Value);
            Assert.AreEqual("value-3", parser.RecreateUnparsedArguments());
        }
        public void ShouldDetectUnexpectedShortSwitch()
        {
            var args   = new [] { "-xc" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("x", parser.UnexpectedArguments.First().Value);
        }
        public void ShouldDetectUnexpectedLongSwitch()
        {
            var args   = new [] { "--long", "--secondLong" };
            var parser = new OptionsParser();

            parser.WithOption <bool>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("secondLong", parser.UnexpectedArguments.First().Value);
        }
        public void ShouldRecreateUnparsedArguments()
        {
            var args = new [] {
                "--expected",
                "-x",
                "value",
                "-y1",
                "--another-expected",
                "-Aw",
                "-z'this was unexpected'"
            };
            var parser = new OptionsParser();

            parser.WithOption <bool>("expected");
            parser.WithOption <bool>("another-expected");
            parser.WithOption <bool>('A');

            parser.Parse(args);

            Assert.AreEqual(3, parser.ParsedOptions.Count());
            Assert.AreEqual("expected", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("another-expected", parser.ParsedOptions.ElementAt(1).Flag.LongName);
            Assert.AreEqual(@"-x value -y1 -w ""-z'this was unexpected'""", parser.RecreateUnparsedArguments());
        }
        public void ShouldDetectedUnexpectedShortSwitchWithValue()
        {
            var args   = new [] { "-cx", "value with whitespace" };
            var parser = new OptionsParser();

            parser.WithOption <bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);

            Assert.AreEqual(2, parser.UnexpectedArguments.Count());
            Assert.AreEqual("x", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("value with whitespace", parser.UnexpectedArguments.ElementAt(1).Value);
        }
        public void ShouldRecreateUnparsedArgument15()
        {
            var args   = new[] { "--port=8888", "--no-xwt" };
            var parser = new OptionsParser();

            parser.WithOption <int>("port");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("port", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual(8888, parser.ParsedOptions.First().Value);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("no-xwt", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("--no-xwt", parser.RecreateUnparsedArguments());
        }
        public void ShouldRecreateUnparsedArgument13()
        {
            var args   = new[] { "-n", "123", "--wrong-arg" };
            var parser = new OptionsParser();

            parser.WithOption <int>('n');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('n', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual(123, parser.ParsedOptions.First().Value);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("wrong-arg", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("--wrong-arg", parser.RecreateUnparsedArguments());
        }
        public void ShouldDetectOptionHavingBothShortAndLongName()
        {
            var argsShort = new [] { "-l" };
            var argsLong  = new [] { "--long" };

            foreach (var args in new [] { argsShort, argsLong })
            {
                var parser = new OptionsParser();
                parser.WithOption <bool>('l', "long");

                parser.Parse(args);

                Assert.AreEqual(1, parser.ParsedOptions.Count());
                var flag = parser.ParsedOptions.First().Flag;
                Assert.AreEqual('l', flag.ShortName);
                Assert.AreEqual("long", flag.LongName);
            }
        }
        public void ShouldRecreateUnparsedArgument7()
        {
            var args   = new[] { "positional argument", "--port=8888", "--wrong-arg" };
            var parser = new OptionsParser();

            parser.WithOption <int>("port");
            var options = new OptionsWithMultipleArguments();

            parser.Parse(options, args);

            Assert.AreEqual("positional argument", options.Value);
            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("port", parser.ParsedOptions.ToArray()[0].Flag.LongName);
            Assert.AreEqual(8888, parser.ParsedOptions.ToArray()[0].Value);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("wrong-arg", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("--wrong-arg", parser.RecreateUnparsedArguments());
        }
        public void ShouldRecreateUnparsedArgument3()
        {
            var args   = new[] { "positional argument", "-p8888", "--wrong-arg" };
            var parser = new OptionsParser();

            parser.WithOption <int>('p');
            var options = new OptionsWithMultipleArguments();

            parser.Parse(options, args);

            Assert.AreEqual("positional argument", options.Value);
            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('p', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual(8888, parser.ParsedOptions.First().Value);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("wrong-arg", parser.UnexpectedArguments.ElementAt(0).Value);
            Assert.AreEqual("--wrong-arg", parser.RecreateUnparsedArguments());
        }
        public void ShouldThrowAnExceptionForLongOptionRequiringValueWhenThereIsNone()
        {
            var args   = new [] { "--long" };
            var parser = new OptionsParser(new ParserConfiguration {
                ThrowValidationException = true
            });

            parser.WithOption <int>("long");

            try
            {
                parser.Parse(args);
                Assert.Fail("Should throw an exception");
            }
            catch (ValidationException e)
            {
                Assert.IsTrue(e.Message.Contains("requires parameter of type"));
            }
        }
        public void ShouldRemoveEmptyShortFlagPrefix()
        {
            var args = new [] { "-AB" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('A');
            parser.WithOption<bool>('B');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('A', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('B', parser.ParsedOptions.Last().Flag.ShortName);
            Assert.AreEqual(string.Empty, parser.RecreateUnparsedArguments());
        }
        public void ShouldParseOptionValueWithHyphen()
        {
            var args = new [] { "-c", "value-with-hyphen" };
            var parser = new OptionsParser();
            parser.WithOption<string>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual("value-with-hyphen", parser.ParsedOptions.First().Value);

            Assert.AreEqual(0, parser.UnexpectedArguments.Count());
        }
        public void ShouldDetectOptionHavingBothShortAndLongName()
        {
            var argsShort = new [] { "-l" };
            var argsLong = new [] { "--long" };

            foreach(var args in new [] { argsShort, argsLong })
            {
                var parser = new OptionsParser();
                parser.WithOption<bool>('l', "long");

                parser.Parse(args);

                Assert.AreEqual(1, parser.ParsedOptions.Count());
                var flag = parser.ParsedOptions.First().Flag;
                Assert.AreEqual('l', flag.ShortName);
                Assert.AreEqual("long", flag.LongName);
            }
        }
        public void ShouldParseLongSwitchWithValue()
        {
            var args = new [] { "--number", "123" };
            var parser = new OptionsParser();
            parser.WithOption<int>("number");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("number", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual(123, parser.ParsedOptions.First().Value);
        }
        public void ShouldParseOptionWithSpacesInValue()
        {
            var args = new [] { "--option=Value with spaces" };
            var parser = new OptionsParser();
            parser.WithOption<string>("option");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("option", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("Value with spaces", parser.ParsedOptions.First().Value);
        }
        public void ShouldDetectUnexpectedShortSwitch()
        {
            var args = new [] { "-xc" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("x", parser.UnexpectedArguments.First().Value);
        }
        public void ShouldRecreateUnparsedArguments()
        {
            var args = new [] {
                "--expected",
                "-x",
                "value",
                "-y1",
                "--another-expected",
                "-Aw",
                "-z'this was unexpected'"
            };
            var parser = new OptionsParser();
            parser.WithOption<bool>("expected");
            parser.WithOption<bool>("another-expected");
            parser.WithOption<bool>('A');

            parser.Parse(args);

            Assert.AreEqual(3, parser.ParsedOptions.Count());
            Assert.AreEqual("expected", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("another-expected", parser.ParsedOptions.ElementAt(1).Flag.LongName);
            Assert.AreEqual(@"-x value -y1 -w ""-z'this was unexpected'""", parser.RecreateUnparsedArguments());
        }
        public void ShouldDetectShortSwitch()
        {
            var args = new [] { "-c" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('c');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('c', parser.ParsedOptions.First().Flag.ShortName);
        }
        public void ShouldParseShortSwitchWithValue()
        {
            var args = new [] { "-n123" };
            var parser = new OptionsParser();
            parser.WithOption<int>('n');

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual('n', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual(123, parser.ParsedOptions.First().Value);
        }
        public void ShouldNotRecreatedParsedValue()
        {
            var args = new [] { "--switch", "value" };
            var parser = new OptionsParser();
            parser.WithOption<string>("switch");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual(args[1], parser.ParsedOptions.First().Value);
            Assert.IsEmpty(parser.RecreateUnparsedArguments());
        }
        public void ShouldRecreateMixedShortFlag()
        {
            var args = new [] { "-AwB" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('A');
            parser.WithOption<bool>('B');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('A', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('B', parser.ParsedOptions.Last().Flag.ShortName);
            Assert.AreEqual("-w", parser.RecreateUnparsedArguments());
        }
        public void ShouldParseShortSwitchWithStringValue()
        {
            var args = new [] { "-nmValue" };
            var parser = new OptionsParser();
            parser.WithOption<bool>('n');
            parser.WithOption<String>('m');

            parser.Parse(args);

            Assert.AreEqual(2, parser.ParsedOptions.Count());
            Assert.AreEqual('n', parser.ParsedOptions.First().Flag.ShortName);
            Assert.AreEqual('m', parser.ParsedOptions.Skip(1).First().Flag.ShortName);
            Assert.AreEqual("Value", parser.ParsedOptions.Skip(1).First().Value);
        }
        public void ShouldDetectUnexpectedLongSwitch()
        {
            var args = new [] { "--long", "--secondLong" };
            var parser = new OptionsParser();
            parser.WithOption<bool>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);

            Assert.AreEqual(1, parser.UnexpectedArguments.Count());
            Assert.AreEqual("secondLong", parser.UnexpectedArguments.First().Value);
        }
        public void ShouldParseLongSwitchWithStringWithAssignmentOperator()
        {
            var args = new [] { "--long=test" };
            var parser = new OptionsParser();
            parser.WithOption<string>("long");

            parser.Parse(args);

            Assert.AreEqual(1, parser.ParsedOptions.Count());
            Assert.AreEqual("long", parser.ParsedOptions.First().Flag.LongName);
            Assert.AreEqual("test", parser.ParsedOptions.First().Value);
        }
        public void ShouldThrowAnExceptionForShortOptionRequiringValueWhenThereIsNone()
        {
            var args = new [] { "-n" };
            var parser = new OptionsParser(new ParserConfiguration { ThrowValidationException = true });
            parser.WithOption<int>('n');

            try
            {
                parser.Parse(args);
                Assert.Fail("Should throw an exception");
            }
            catch (ValidationException e)
            {
                Assert.IsTrue(e.Message.Contains("requires parameter of type"));
            }
        }