From d443a51aeb3a418425e970542b3b96e9da5f62e2 Mon Sep 17 00:00:00 2001 From: moh-hassan Date: Thu, 6 Aug 2020 12:59:37 +0300 Subject: [PATCH 01/12] Update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb001542..eea8ad12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. CommandLineParser project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.9.0-preview2] + +### Added +- Properly assign arguments after a double dash to values, fix #605 by [@robnasby, PR# 610](https://github.com/commandlineparser/commandline/pull/610). + +### Changed +- Drop "Add multi-instance option support". + + ## [2.9.0-preview1] - 2020-7-24 ### Added From 2e1fff3657ef52a1633d9586edd866fca07e0538 Mon Sep 17 00:00:00 2001 From: Misha Gorshenin Date: Sat, 22 May 2021 22:23:01 +0500 Subject: [PATCH 02/12] Add cast support for resource types --- .gitignore | 1 + src/CommandLine/CastExtensions.cs | 100 ++++++++++++++++++ src/CommandLine/CommandLine.csproj | 1 + .../LocalizableAttributeProperty.cs | 12 +-- .../CommandLine.Tests/Fakes/ResourceFakes.cs | 63 +++++++++++ .../Unit/BaseAttributeTests.cs | 10 +- 6 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 src/CommandLine/CastExtensions.cs diff --git a/.gitignore b/.gitignore index 55f900a1..7cccb220 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,6 @@ artifacts/* *.DotSettings.user # Visual Studio 2015 cache/options directory .vs/ +.idea/ [R|r]elease/** diff --git a/src/CommandLine/CastExtensions.cs b/src/CommandLine/CastExtensions.cs new file mode 100644 index 00000000..828a18e4 --- /dev/null +++ b/src/CommandLine/CastExtensions.cs @@ -0,0 +1,100 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace CommandLine +{ + public static class CastExtensions + { + private const string ImplicitCastMethodName = "op_Implicit"; + private const string ExplicitCastMethodName = "op_Explicit"; + + public static bool CanCast(this Type baseType) + { + return baseType.CanImplicitCast() || baseType.CanExplicitCast(); + } + + public static bool CanCast(this object obj) + { + var objType = obj.GetType(); + return objType.CanCast(); + } + + public static T Cast(this object obj) + { + try + { + return (T) obj; + } + catch (InvalidCastException) + { + if (obj.CanImplicitCast()) + return obj.ImplicitCast(); + if (obj.CanExplicitCast()) + return obj.ExplicitCast(); + else + throw; + } + } + + private static bool CanImplicitCast(this Type baseType) + { + return baseType.CanCast(ImplicitCastMethodName); + } + + private static bool CanImplicitCast(this object obj) + { + var baseType = obj.GetType(); + return baseType.CanImplicitCast(); + } + + private static bool CanExplicitCast(this Type baseType) + { + return baseType.CanCast(ExplicitCastMethodName); + } + + private static bool CanExplicitCast(this object obj) + { + var baseType = obj.GetType(); + return baseType.CanExplicitCast(); + } + + private static bool CanCast(this Type baseType, string castMethodName) + { + var targetType = typeof(T); + return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static) + .Where(mi => mi.Name == castMethodName && mi.ReturnType == targetType) + .Any(mi => + { + ParameterInfo pi = mi.GetParameters().FirstOrDefault(); + return pi != null && pi.ParameterType == baseType; + }); + } + + private static T ImplicitCast(this object obj) + { + return obj.Cast(ImplicitCastMethodName); + } + + private static T ExplicitCast(this object obj) + { + return obj.Cast(ExplicitCastMethodName); + } + + private static T Cast(this object obj, string castMethodName) + { + var objType = obj.GetType(); + MethodInfo conversionMethod = objType.GetMethods(BindingFlags.Public | BindingFlags.Static) + .Where(mi => mi.Name == castMethodName && mi.ReturnType == typeof(T)) + .SingleOrDefault(mi => + { + ParameterInfo pi = mi.GetParameters().FirstOrDefault(); + return pi != null && pi.ParameterType == objType; + }); + if (conversionMethod != null) + return (T) conversionMethod.Invoke(null, new[] {obj}); + else + throw new InvalidCastException($"No method to cast {objType.FullName} to {typeof(T).FullName}"); + } + } +} diff --git a/src/CommandLine/CommandLine.csproj b/src/CommandLine/CommandLine.csproj index 04496eb8..b2e65413 100644 --- a/src/CommandLine/CommandLine.csproj +++ b/src/CommandLine/CommandLine.csproj @@ -27,6 +27,7 @@ 8.0 true snupkg + 5.0.0 diff --git a/src/CommandLine/Infrastructure/LocalizableAttributeProperty.cs b/src/CommandLine/Infrastructure/LocalizableAttributeProperty.cs index 9edd621b..26714cca 100644 --- a/src/CommandLine/Infrastructure/LocalizableAttributeProperty.cs +++ b/src/CommandLine/Infrastructure/LocalizableAttributeProperty.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; namespace CommandLine.Infrastructure { @@ -43,15 +40,16 @@ private string GetLocalizedValue() return _value; if (_localizationPropertyInfo == null) { - // Static class IsAbstract + // Static class IsAbstract if (!_type.IsVisible) throw new ArgumentException($"Invalid resource type '{_type.FullName}'! {_type.Name} is not visible for the parser! Change resources 'Access Modifier' to 'Public'", _propertyName); - PropertyInfo propertyInfo = _type.GetProperty(_value, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static); - if (propertyInfo == null || !propertyInfo.CanRead || propertyInfo.PropertyType != typeof(string)) + PropertyInfo propertyInfo = _type.GetProperty(_value, BindingFlags.Public | BindingFlags.Static); + if (propertyInfo == null || !propertyInfo.CanRead || (propertyInfo.PropertyType != typeof(string) && !propertyInfo.PropertyType.CanCast())) throw new ArgumentException("Invalid resource property name! Localized value: {_value}", _propertyName); _localizationPropertyInfo = propertyInfo; } - return (string)_localizationPropertyInfo.GetValue(null, null); + + return _localizationPropertyInfo.GetValue(null, null).Cast(); } } diff --git a/tests/CommandLine.Tests/Fakes/ResourceFakes.cs b/tests/CommandLine.Tests/Fakes/ResourceFakes.cs index f7b46bac..1b18da6e 100644 --- a/tests/CommandLine.Tests/Fakes/ResourceFakes.cs +++ b/tests/CommandLine.Tests/Fakes/ResourceFakes.cs @@ -3,6 +3,10 @@ public static class StaticResource { public static string HelpText { get { return "Localized HelpText"; } } + public static TypeWithImplicitCast ImplicitCastHelpText => new TypeWithImplicitCast("Localized HelpText"); + public static TypeWithExplicitCast ExplicitCastHelpText => new TypeWithExplicitCast("Localized HelpText"); + public static TypeWithWrongImplicitCast WrongImplicitCastHelpText => new TypeWithWrongImplicitCast(); + public static TypeWithWrongExplicitCast WrongExplicitCastHelpText => new TypeWithWrongExplicitCast(); } public class NonStaticResource @@ -10,6 +14,10 @@ public class NonStaticResource public static string HelpText { get { return "Localized HelpText"; } } public static string WriteOnlyText { set { value?.ToString(); } } private static string PrivateHelpText { get { return "Localized HelpText"; } } + public static TypeWithImplicitCast ImplicitCastHelpText => new TypeWithImplicitCast("Localized HelpText"); + public static TypeWithExplicitCast ExplicitCastHelpText => new TypeWithExplicitCast("Localized HelpText"); + public static TypeWithWrongImplicitCast WrongImplicitCastHelpText => new TypeWithWrongImplicitCast(); + public static TypeWithWrongExplicitCast WrongExplicitCastHelpText => new TypeWithWrongExplicitCast(); } public class NonStaticResource_WithNonStaticProperty @@ -22,4 +30,59 @@ internal class InternalResource public static string HelpText { get { return "Localized HelpText"; } } } + public class TypeWithImplicitCast + { + private string value; + + public TypeWithImplicitCast(string value) + { + this.value = value; + } + + public static implicit operator string(TypeWithImplicitCast obj) + { + return obj.value; + } + + public static implicit operator int(TypeWithImplicitCast obj) + { + return 0; + } + } + + public class TypeWithWrongImplicitCast + { + public static implicit operator int(TypeWithWrongImplicitCast obj) + { + return 0; + } + } + + public class TypeWithExplicitCast + { + private string value; + + public TypeWithExplicitCast(string value) + { + this.value = value; + } + + public static explicit operator string(TypeWithExplicitCast obj) + { + return obj.value; + } + + public static explicit operator int(TypeWithExplicitCast obj) + { + return 0; + } + } + + public class TypeWithWrongExplicitCast + { + public static explicit operator int(TypeWithWrongExplicitCast obj) + { + return 0; + } + } } diff --git a/tests/CommandLine.Tests/Unit/BaseAttributeTests.cs b/tests/CommandLine.Tests/Unit/BaseAttributeTests.cs index 3c2bfbbd..ab566255 100644 --- a/tests/CommandLine.Tests/Unit/BaseAttributeTests.cs +++ b/tests/CommandLine.Tests/Unit/BaseAttributeTests.cs @@ -21,12 +21,16 @@ public static void Default(object defaultValue) [InlineData("Help text", null, "Help text")] [InlineData("HelpText", typeof(Fakes.StaticResource), "Localized HelpText")] [InlineData("HelpText", typeof(Fakes.NonStaticResource), "Localized HelpText")] + [InlineData("ImplicitCastHelpText", typeof(Fakes.StaticResource), "Localized HelpText")] + [InlineData("ImplicitCastHelpText", typeof(Fakes.NonStaticResource), "Localized HelpText")] + [InlineData("ExplicitCastHelpText", typeof(Fakes.StaticResource), "Localized HelpText")] + [InlineData("ExplicitCastHelpText", typeof(Fakes.NonStaticResource), "Localized HelpText")] public static void HelpText(string helpText, Type resourceType, string expected) { TestBaseAttribute baseAttribute = new TestBaseAttribute(); baseAttribute.HelpText = helpText; baseAttribute.ResourceType = resourceType; - + Assert.Equal(expected, baseAttribute.HelpText); } @@ -35,6 +39,10 @@ public static void HelpText(string helpText, Type resourceType, string expected) [InlineData("WriteOnlyText", typeof(Fakes.NonStaticResource))] [InlineData("PrivateOnlyText", typeof(Fakes.NonStaticResource))] [InlineData("HelpText", typeof(Fakes.InternalResource))] + [InlineData("WrongImplicitCastHelpText", typeof(Fakes.StaticResource))] + [InlineData("WrongExplicitCastHelpText", typeof(Fakes.StaticResource))] + [InlineData("WrongImplicitCastHelpText", typeof(Fakes.NonStaticResource))] + [InlineData("WrongExplicitCastHelpText", typeof(Fakes.NonStaticResource))] public void ThrowsHelpText(string helpText, Type resourceType) { TestBaseAttribute baseAttribute = new TestBaseAttribute(); From 5b693d5386de984c855586b0a1b608275314dbd2 Mon Sep 17 00:00:00 2001 From: Misha Gorshenin Date: Sat, 22 May 2021 22:35:45 +0500 Subject: [PATCH 03/12] Reset nuget version --- src/CommandLine/CommandLine.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CommandLine/CommandLine.csproj b/src/CommandLine/CommandLine.csproj index b2e65413..04496eb8 100644 --- a/src/CommandLine/CommandLine.csproj +++ b/src/CommandLine/CommandLine.csproj @@ -27,7 +27,6 @@ 8.0 true snupkg - 5.0.0 From 705b421b6f0bc93a1de72af0c1266e2a51593925 Mon Sep 17 00:00:00 2001 From: Mike Perrin Date: Mon, 8 Nov 2021 12:33:21 +0000 Subject: [PATCH 04/12] added link to Option groups --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68b10659..79a16fa7 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ __This library provides _hassle free_ command line parsing with a constantly upd - Support Mutable and Immutable types. - Support HelpText localization. - Support ordering of options in HelpText. -- Support [Mutually Exclusive Options](https://github.com/commandlineparser/commandline/wiki/Mutually-Exclusive-Options) and Options groups. +- Support [Mutually Exclusive Options](https://github.com/commandlineparser/commandline/wiki/Mutually-Exclusive-Options) and [Option groups](https://github.com/commandlineparser/commandline/wiki/Option-Groups). - Support named and value options. - Support Asynchronous programming with async and await. - Unparsing support: `CommandLine.Parser.Default.FormatCommandLine(T options)`. From dffb7517a7b7e0a46a5b6cc17259a0220fc4fe28 Mon Sep 17 00:00:00 2001 From: Eric Newton Date: Thu, 12 May 2022 16:26:27 -0400 Subject: [PATCH 05/12] update nuget api key --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 91a36832..30fc9fe9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -55,7 +55,7 @@ deploy: - provider: NuGet api_key: - secure: e2gJJ3r6Uls5trJwryaudAZd49QniNfIjax/A+tfywlchSnIQVOzOQCO9tTSNccI + secure: llMIgYMuLHh9thyKMEAmkWraTaA9Zvcm1F8/yRwm0HCiPIt/ehR/GI4kJKyMTPyf artifact: /.*(\.|\.s)nupkg/ on: APPVEYOR_REPO_TAG: true From b0b0ec9f5470bacc0823c013a599ba3b4e115900 Mon Sep 17 00:00:00 2001 From: Eric Newton Date: Thu, 12 May 2022 17:07:06 -0400 Subject: [PATCH 06/12] update appveyor, remove github deployment for now, bump version to 2.9.1 --- appveyor.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 30fc9fe9..d11d6abf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ #version should be only changed with RELEASE eminent, see RELEASE.md -version: 2.9.0-ci-{build} +version: 2.9.1-ci-{build} image: Visual Studio 2019 @@ -44,15 +44,6 @@ on_failure: appveyor PushArtifact .\files.lst -DeploymentName "Failed Build File Listing" deploy: -- provider: GitHub - auth_token: - secure: hVyVwHl0JiVq0VxXB4VMRWbUtrGclIzadfnWFcWCQBLvbgMLahLBnWlwGglT63pZ - artifact: /.*(\.|\.s)nupkg/ - prerelease: false - force_update: true #fsharp package runs as separate build job, so have to force_update to add fsharp.nuget added - on: - APPVEYOR_REPO_TAG: true - - provider: NuGet api_key: secure: llMIgYMuLHh9thyKMEAmkWraTaA9Zvcm1F8/yRwm0HCiPIt/ehR/GI4kJKyMTPyf From 5ece267c5bf988a1135be49dac76c2c81c73bff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D0=BE=D1=80=D1=88=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=28Gorshenin=5FMV=29?= Date: Tue, 7 Jun 2022 18:29:11 +0500 Subject: [PATCH 07/12] mark CastExtensions as internal class --- src/CommandLine/CastExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CommandLine/CastExtensions.cs b/src/CommandLine/CastExtensions.cs index 828a18e4..fa34928c 100644 --- a/src/CommandLine/CastExtensions.cs +++ b/src/CommandLine/CastExtensions.cs @@ -4,7 +4,7 @@ namespace CommandLine { - public static class CastExtensions + internal static class CastExtensions { private const string ImplicitCastMethodName = "op_Implicit"; private const string ExplicitCastMethodName = "op_Explicit"; From 72677c5858f7b41117f31f366e8cdb03ccafd940 Mon Sep 17 00:00:00 2001 From: Bjarte Aarmo Lund Date: Tue, 20 Dec 2022 15:33:20 +0100 Subject: [PATCH 08/12] A minor spelling mistake (with few items => with fewer items) --- demo/ReadText.LocalizedDemo/Properties/Resources.Designer.cs | 2 +- demo/ReadText.LocalizedDemo/Properties/Resources.resx | 2 +- src/CommandLine/Text/SentenceBuilder.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/ReadText.LocalizedDemo/Properties/Resources.Designer.cs b/demo/ReadText.LocalizedDemo/Properties/Resources.Designer.cs index cc414359..f2ca4b31 100644 --- a/demo/ReadText.LocalizedDemo/Properties/Resources.Designer.cs +++ b/demo/ReadText.LocalizedDemo/Properties/Resources.Designer.cs @@ -331,7 +331,7 @@ public static string SentenceSequenceOutOfRangeErrorOption { } /// - /// Looks up a localized string similar to A sequence value not bound to option name is defined with few items than required.. + /// Looks up a localized string similar to A sequence value not bound to option name is defined with fewer items than required.. /// public static string SentenceSequenceOutOfRangeErrorValue { get { diff --git a/demo/ReadText.LocalizedDemo/Properties/Resources.resx b/demo/ReadText.LocalizedDemo/Properties/Resources.resx index afdea3d0..b002fc43 100644 --- a/demo/ReadText.LocalizedDemo/Properties/Resources.resx +++ b/demo/ReadText.LocalizedDemo/Properties/Resources.resx @@ -208,7 +208,7 @@ A sequence option '{0}' is defined with fewer or more items than required. - A sequence value not bound to option name is defined with few items than required. + A sequence value not bound to option name is defined with fewer items than required. Error setting value to option '{0}': {1} diff --git a/src/CommandLine/Text/SentenceBuilder.cs b/src/CommandLine/Text/SentenceBuilder.cs index c8537542..842ae675 100644 --- a/src/CommandLine/Text/SentenceBuilder.cs +++ b/src/CommandLine/Text/SentenceBuilder.cs @@ -138,7 +138,7 @@ public override Func FormatError case ErrorType.SequenceOutOfRangeError: var seqOutRange = ((SequenceOutOfRangeError)error); return seqOutRange.NameInfo.Equals(NameInfo.EmptyName) - ? "A sequence value not bound to option name is defined with few items than required." + ? "A sequence value not bound to option name is defined with fewer items than required." : "A sequence option '".JoinTo(seqOutRange.NameInfo.NameText, "' is defined with fewer or more items than required."); case ErrorType.BadVerbSelectedError: From 6514645610d6f56ebb143e69516a986ec2aefe78 Mon Sep 17 00:00:00 2001 From: Eric Newton Date: Tue, 7 Mar 2023 13:41:45 -0500 Subject: [PATCH 09/12] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..29c526ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Fork from this fiddle and paste link here: https://dotnetfiddle.net/mh9CjX + +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. From 1e3607b97af6141743edb3c434c06d5b492f6fb3 Mon Sep 17 00:00:00 2001 From: Eric Newton Date: Tue, 7 Mar 2023 13:42:40 -0500 Subject: [PATCH 10/12] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 29c526ef..c6020604 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,7 +11,9 @@ assignees: '' A clear and concise description of what the bug is. **To Reproduce** -Fork from this fiddle and paste link here: https://dotnetfiddle.net/mh9CjX +Either fork from this fiddle and paste link here: https://dotnetfiddle.net/mh9CjX + +or Steps to reproduce the behavior: 1. Go to '...' From 0d18b610cf358c1629250a99b488aaea131e4c5b Mon Sep 17 00:00:00 2001 From: phani vanka Date: Thu, 25 May 2023 21:29:06 -0400 Subject: [PATCH 11/12] add specification gaurd against dictionary types --- src/CommandLine/Core/SpecificationGuards.cs | 8 +++++++- .../Unit/Core/InstanceBuilderTests.cs | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/CommandLine/Core/SpecificationGuards.cs b/src/CommandLine/Core/SpecificationGuards.cs index b6d7d122..985dbca9 100644 --- a/src/CommandLine/Core/SpecificationGuards.cs +++ b/src/CommandLine/Core/SpecificationGuards.cs @@ -13,7 +13,8 @@ static class SpecificationGuards Tuple.Create(GuardAgainstScalarWithRange(), "Scalar option specifications do not support range specification."), Tuple.Create(GuardAgainstSequenceWithWrongRange(), "Bad range in sequence option specifications."), Tuple.Create(GuardAgainstSequenceWithZeroRange(), "Zero is not allowed in range of sequence option specifications."), - Tuple.Create(GuardAgainstOneCharLongName(), "Long name should be longer than one character.") + Tuple.Create(GuardAgainstOneCharLongName(), "Long name should be longer than one character."), + Tuple.Create(GaurdAgainstUnsupportedSequenceTypes(), "Unsupported sequence type specification.") }; private static Func GuardAgainstScalarWithRange() @@ -39,5 +40,10 @@ private static Func GuardAgainstSequenceWithZeroRange() && (spec.HavingMin(min => min == 0) || spec.HavingMax(max => max == 0)); } + + private static Func GaurdAgainstUnsupportedSequenceTypes() + { + return spec => spec.TargetType == TargetType.Sequence && spec.ConversionType.GetGenericArguments().Length != 1; + } } } diff --git a/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs b/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs index 2f8d02b7..f3e888ea 100644 --- a/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs +++ b/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs @@ -685,6 +685,17 @@ public void Parse_fsharp_option_int(string[] arguments, int expectedValue, bool #endif + [Fact] + public void Dictionary_type_throws_exception() + { + // Exercize system + Action test = () => InvokeBuild( + new string[] { }); + + // Verify outcome + Assert.Throws(test); + } + [Fact] public void Min_constraint_set_to_zero_throws_exception() { From 87db170ee6915cdcf03d9261e60c7a2e40eaec08 Mon Sep 17 00:00:00 2001 From: phani vanka Date: Fri, 26 May 2023 19:58:28 -0400 Subject: [PATCH 12/12] add missing fake for testing Dictionay specification type --- .../Fakes/Options_With_Dictionary_Specification.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/CommandLine.Tests/Fakes/Options_With_Dictionary_Specification.cs diff --git a/tests/CommandLine.Tests/Fakes/Options_With_Dictionary_Specification.cs b/tests/CommandLine.Tests/Fakes/Options_With_Dictionary_Specification.cs new file mode 100644 index 00000000..0b5382a2 --- /dev/null +++ b/tests/CommandLine.Tests/Fakes/Options_With_Dictionary_Specification.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommandLine.Tests.Fakes +{ + class Options_With_Dictionary_Specification + { + [Option('d', "dict")] + public Dictionary KeyValuePairs { get; set; } + } +}