private ParserResult ParseOptions(IEnumerable <string> arguments, Type targetType)
        {
            var optionProperties = targetType.GetOptionProperties();

            if (optionProperties == null || !optionProperties.Any())
            {
                throw new InvalidOperationException(
                          $"The specified type {targetType.Name} does not have any properties marked with {nameof(OptionAttribute)}.");
            }

            var tokens = Tokenizer.Tokenize(arguments);

            if (tokens == null || !tokens.Any())
            {
                PrintHelpForTypes(new[] { targetType });
                return(new NotParsedResult());
            }

            var pairs = TokenPartitioner.Partition(tokens);

            try
            {
                var newObj = Activator.CreateInstance(targetType);
                OptionMapper.Map(optionProperties, pairs, newObj);

                return(new ParsedResult(newObj));
            }
            catch (InvalidOperationException)
            {
                PrintHelpForTypes(new[] { targetType });
            }

            return(new NotParsedResult());
        }
Пример #2
0
        public void Partition_sequence_returns_sequence_with_duplicates()
        {
            // Fixture setup
            var expectedSequence = new[]
            {
                new KeyValuePair <string, IEnumerable <string> >("i", new[] { "10", "10", "30", "40" })
            };
            var specs = new[]
            {
                new OptionSpecification(string.Empty, "stringvalue", false, string.Empty, Maybe.Nothing <int>(), Maybe.Nothing <int>(), '\0', null, string.Empty, string.Empty, new List <string>(), typeof(string), TargetType.Scalar, string.Empty, flagCounter: false, hidden: false),
                new OptionSpecification("i", string.Empty, false, string.Empty, Maybe.Just(3), Maybe.Just(4), '\0', null, string.Empty, string.Empty, new List <string>(), typeof(IEnumerable <int>), TargetType.Sequence, string.Empty, flagCounter: false, hidden: false)
            };

            // Exercize system
            var result = TokenPartitioner.Partition(
                new[] { Token.Name("i"), Token.Value("10"), Token.Value("10"), Token.Value("30"), Token.Value("40") },
                name => TypeLookup.FindTypeDescriptorAndSibling(name, specs, StringComparer.Ordinal)
                );

            // Verify outcome
            var options = result.Item1;

            Assert.True(expectedSequence.All(a => options.Any(r => a.Key.Equals(r.Key) && a.Value.SequenceEqual(r.Value))));

            // Teardown
        }
Пример #3
0
        public void Partition_sequence_multi_instance()
        {
            var expected = new[]
            {
                Token.Name("seq"),
                Token.Value("seqval0"),
                Token.Value("seqval1"),
                Token.Value("seqval2"),
                Token.Value("seqval3"),
                Token.Value("seqval4"),
            };

            var tokens = TokenPartitioner.PartitionTokensByType(
                new[]
            {
                Token.Name("str"), Token.Value("strvalue"), Token.Value("freevalue"),
                Token.Name("seq"), Token.Value("seqval0"), Token.Value("seqval1"),
                Token.Name("x"), Token.Value("freevalue2"),
                Token.Name("seq"), Token.Value("seqval2"), Token.Value("seqval3"),
                Token.Name("seq"), Token.Value("seqval4")
            },
                name =>
                new[] { "seq" }.Contains(name)
                        ? Maybe.Just(TypeDescriptor.Create(TargetType.Sequence, Maybe.Nothing <int>()))
                        : Maybe.Nothing <TypeDescriptor>());
            var result = tokens.Item3;  // Switch, Scalar, *Sequence*, NonOption

            var actual = result.ToArray();

            Assert.Equal(expected, actual);
        }
Пример #4
0
        public void ArePropertiesMappedCorrectly()
        {
            var optionProperties = typeof(TestClassValid).GetOptionProperties();

            var tokens        = Tokenizer.Tokenize(TestClassValidArgs);
            var keyValuePairs = TokenPartitioner.Partition(tokens);

            var obj = new TestClassValid();

            OptionMapper.Map(optionProperties, keyValuePairs, obj);

            Assert.AreEqual("value1", obj.Option1);
            Assert.AreEqual("value2", obj.Option2);
        }
Пример #5
0
        public void Partition_switch_values_from_empty_token_sequence()
        {
            var expected = new Token[] { };

            var tokens = TokenPartitioner.PartitionTokensByType(
                new Token[] { },
                name =>
                new[] { "x", "switch" }.Contains(name)
                        ? Maybe.Just(TypeDescriptor.Create(TargetType.Switch, Maybe.Nothing <int>()))
                        : Maybe.Nothing <TypeDescriptor>());
            var result = tokens.Item1;  // *Switch*, Scalar, Sequence, NonOption

            expected.Should().BeEquivalentTo(result);
        }
Пример #6
0
        public void Partition_switch_values()
        {
            var expected = new [] { Token.Name("x") };

            var tokens = TokenPartitioner.PartitionTokensByType(
                new []
            {
                Token.Name("str"), Token.Value("strvalue"), Token.Value("freevalue"),
                Token.Name("x"), Token.Value("freevalue2")
            },
                name =>
                new[] { "x", "switch" }.Contains(name)
                        ? Maybe.Just(TypeDescriptor.Create(TargetType.Switch, Maybe.Nothing <int>()))
                        : Maybe.Nothing <TypeDescriptor>());
            var result = tokens.Item1;  // *Switch*, Scalar, Sequence, NonOption

            expected.Should().BeEquivalentTo(result);
        }
Пример #7
0
        public void Partition_sequence_values_only()
        {
            var expected = new[]
            {
                Token.Name("seq"), Token.Value("seqval0"), Token.Value("seqval1")
            };

            var tokens = TokenPartitioner.PartitionTokensByType(
                new[]
            {
                Token.Name("seq"), Token.Value("seqval0"), Token.Value("seqval1")
            },
                name =>
                new[] { "seq" }.Contains(name)
                        ? Maybe.Just(TypeDescriptor.Create(TargetType.Sequence, Maybe.Nothing <int>()))
                        : Maybe.Nothing <TypeDescriptor>());
            var result = tokens.Item3;  // Switch, Scalar, *Sequence*, NonOption

            expected.Should().BeEquivalentTo(result);
        }
Пример #8
0
        public void Partition_sequence_multi_instance_with_max()
        {
            var incorrect = new[]
            {
                Token.Name("seq"),
                Token.Value("seqval0"),
                Token.Value("seqval1"),
                Token.Value("seqval2"),
                Token.Value("seqval3"),
                Token.Value("seqval4"),
                Token.Value("seqval5"),
            };

            var expected = new[]
            {
                Token.Name("seq"),
                Token.Value("seqval0"),
                Token.Value("seqval1"),
                Token.Value("seqval2"),
            };

            var tokens = TokenPartitioner.PartitionTokensByType(
                new[]
            {
                Token.Name("str"), Token.Value("strvalue"), Token.Value("freevalue"),
                Token.Name("seq"), Token.Value("seqval0"), Token.Value("seqval1"),
                Token.Name("x"), Token.Value("freevalue2"),
                Token.Name("seq"), Token.Value("seqval2"), Token.Value("seqval3"),
                Token.Name("seq"), Token.Value("seqval4"), Token.Value("seqval5"),
            },
                name =>
                new[] { "seq" }.Contains(name)
                        ? Maybe.Just(TypeDescriptor.Create(TargetType.Sequence, Maybe.Just <int>(3)))
                        : Maybe.Nothing <TypeDescriptor>());
            var result = tokens.Item3;  // Switch, Scalar, *Sequence*, NonOption

            // Max of 3 will apply to the total values, so there should only be 3 values, not 6
            Assert.NotEqual(incorrect, result);
            Assert.Equal(expected, result);
        }
Пример #9
0
        public void Partition_sequence_returns_sequence()
        {
            // Fixture setup
            var expectedSequence = new[]
            {
                new KeyValuePair <string, IEnumerable <string> >("i", new[] { "10", "20", "30", "40" })
            };
            var specs = new[]
            {
                new OptionSpecification(string.Empty, "stringvalue", false, string.Empty, -1, -1, null, typeof(string), string.Empty, string.Empty, new List <string>()),
                new OptionSpecification("i", string.Empty, false, string.Empty, 3, 4, null, typeof(IEnumerable <int>), string.Empty, string.Empty, new List <string>())
            };

            // Exercize system
            var result = TokenPartitioner.Partition(
                new[] { Token.Name("i"), Token.Value("10"), Token.Value("20"), Token.Value("30"), Token.Value("40") },
                name => TypeLookup.GetDescriptorInfo(name, specs, StringComparer.InvariantCulture)
                );

            // Verify outcome
            Assert.True(expectedSequence.All(a => result.Item1.Any(r => a.Key.Equals(r.Key) && a.Value.SequenceEqual(r.Value))));

            // Teardown
        }