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()); }
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 }
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); }
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); }
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); }
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); }
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); }
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); }
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 }