#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters /// <summary> /// Constructor that requires an explicit implementation of /// <see cref="ILoopClient"/>. /// </summary> /// <param name="commandType">Type that defines syntax for commands.</param> /// <param name="loopClient">The client to use.</param> /// <param name="argSetAttribute">Optionally provides attribute info /// for the argument set that will be dynamically created for this loop.</param> /// <param name="options">Optionally provides additional options for /// this loop's execution.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="commandType" /> /// is null.</exception> public Loop(Type commandType, ILoopClient loopClient, ArgumentSetAttribute argSetAttribute = null, LoopOptions options = null) { if (commandType == null) { throw new ArgumentNullException(nameof(commandType)); } _client = loopClient ?? throw new ArgumentNullException(nameof(loopClient)); _client.TokenCompleter = new TokenCompleter(this); _options = options?.DeepClone() ?? new LoopOptions(); _options.ParserOptions.DisplayUsageInfoOnError = false; _options.ParserOptions.Reporter = error => _client.OnError(error.ToString().TrimEnd()); var inputConfigurer = _options.ParserOptions.ServiceConfigurer; _options.ParserOptions.ServiceConfigurer = collection => ConfigureServices(collection, inputConfigurer); var constructedType = ConstructCommandTypeFactory(commandType, out _objectFactory); _argSet = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet( constructedType, attribute: argSetAttribute, serviceConfigurer: _options.ParserOptions.ServiceConfigurer); }
private static ArgumentDefinition CreateArgumentDescriptor( IMutableMemberInfo member, ArgumentBaseAttribute attribute, object defaultValues, ArgumentSetAttribute setAttribute, CommandLineParserOptions options, object fixedDestination) { if (!member.IsReadable || !member.IsWritable) { var declaringType = member.MemberInfo.DeclaringType; throw new InvalidArgumentSetException(member, string.Format( CultureInfo.CurrentCulture, Strings.MemberNotSupported, member.MemberInfo.Name, declaringType?.Name)); } var defaultFieldValue = (defaultValues != null) ? member.GetValue(defaultValues) : null; return(new ArgumentDefinition(member, attribute, setAttribute, options, defaultFieldValue, fixedDestination: fixedDestination)); }
public void InvalidSeparators() { var attribs = new ArgumentSetAttribute(); Action setSeparators = () => attribs.ArgumentValueSeparators = null; setSeparators.ShouldThrow <ArgumentNullException>(); }
public override CommandResult Execute() { Console.WriteLine("Entering loop."); var keyBindingSet = ConsoleKeyBindingSet.CreateDefaultSet(); keyBindingSet.Bind('c', ConsoleModifiers.Control, ConsoleInputOperation.Abort); ++_count; var parameters = new LoopInputOutputParameters { Prompt = new ColoredString($"Loop{new string('>', _count)} ", ConsoleColor.Cyan), KeyBindingSet = keyBindingSet, EndOfLineCommentCharacter = '#' }; var attrib = new ArgumentSetAttribute { Style = ArgumentSetStyle.GetOpt }; new Loop(typeof(MainCommandType), parameters, attrib).Execute(); --_count; Console.WriteLine("Exited loop."); return(CommandResult.Success); }
public void InvalidSeparators() { var attribs = new ArgumentSetAttribute(); attribs.ArgumentValueSeparators = null; attribs.ArgumentValueSeparators.Should().NotBeNull(); attribs.ArgumentValueSeparators.Should().BeEmpty(); }
public void SelectingInvalidStyleThrows() { var attrib = new ArgumentSetAttribute(); Action a = () => attrib.Style = (ArgumentSetStyle)0xFF; a.Should().Throw <ArgumentOutOfRangeException>(); }
public void StyleIsUnreadable() { var attrib = new ArgumentSetAttribute(); Action a = () => { var x = attrib.Style; }; a.Should().Throw <NotSupportedException>(); }
public void TestThatLogoIsSettableWithString() { var attrib = new ArgumentSetAttribute { Logo = "Test" }; attrib.Logo.Should().BeOfType <string>().And.Be("Test"); }
public void TestThatLogoIsNotSettableWithColoredString() { var attrib = new ArgumentSetAttribute(); Action a = () => attrib.Logo = new ColoredString("Test", ConsoleColor.Yellow); a.Should().Throw <ArgumentOutOfRangeException>(); }
public void TestThatLogoThrowsOnUnsupportedTypes() { var attrib = new ArgumentSetAttribute(); Action a = () => { attrib.Logo = 3; }; a.Should().Throw <ArgumentOutOfRangeException>(); }
public void LogoIsSettableWithString() { var attrib = new ArgumentSetAttribute { Logo = "Test" }; attrib.LogoString.ToString().Should().Be("Test"); }
public void TestThatLogoStringIsFixedToNull() { var attrib = new ArgumentSetAttribute(); #pragma warning disable CS0618 // Type or member is obsolete attrib.LogoString.Should().BeNull(); #pragma warning restore CS0618 // Type or member is obsolete }
/// <summary> /// Primary constructor. /// </summary> /// <param name="member">Field to describe.</param> /// <param name="attribute">Argument attribute on the field.</param> /// <param name="setAttribute">Attribute on the containing argument set.</param> /// <param name="options">Provides parser options.</param> /// <param name="defaultFieldValue">Default value for the field.</param> /// <param name="parentMember">Parent member under which this field sits.</param> /// <param name="fixedDestination">Optionally provides fixed parse destination object.</param> public ArgumentDefinition(IMutableMemberInfo member, ArgumentBaseAttribute attribute, ArgumentSetAttribute setAttribute, CommandLineParserOptions options, object defaultFieldValue = null, IMutableMemberInfo parentMember = null, object fixedDestination = null) { Debug.Assert(attribute != null); Debug.Assert(member != null); Member = member; ParentMember = parentMember; Attribute = attribute; _setAttribute = setAttribute; FixedDestination = fixedDestination; _isPositional = attribute is PositionalArgumentAttribute; _reporter = options?.Reporter ?? (s => { }); ArgumentType = Attribute.GetArgumentType(member.MemberType); _collectionArgType = AsCollectionType(ArgumentType); HasDefaultValue = attribute.ExplicitDefaultValue || attribute.DynamicDefaultValue; _validationAttributes = GetValidationAttributes(ArgumentType, Member); _argumentParseContext = CreateParseContext(attribute, _setAttribute, options); LongName = GetLongName(attribute, setAttribute, member.MemberInfo); ExplicitShortName = HasExplicitShortName(attribute); ShortName = GetShortName(attribute, setAttribute, member.MemberInfo); DefaultValue = GetDefaultValue(attribute, member, defaultFieldValue); var nullableBase = Nullable.GetUnderlyingType(member.MemberType); if (_collectionArgType != null) { _collectionValues = new ArrayList(); _valueType = _collectionArgType.ElementType; } else if (nullableBase != null) { // For nullable arguments, we use the wrapped type (T in // Nullable<T>) as the value type. Parsing an enum or int is the // same as parsing an enum? or int?, for example, since null can // only arise if the value was not provided at all. _valueType = Attribute.GetArgumentType(nullableBase); } else { _valueType = ArgumentType; } Debug.Assert(_valueType != null); if (Unique && !IsCollection) { throw new InvalidArgumentSetException(member, Strings.UniqueUsedOnNonCollectionArgument); } Debug.Assert(!string.IsNullOrEmpty(LongName)); }
/// <summary> /// Constructs an empty argument set. /// </summary> /// <param name="options">Optionally provides additional options /// controlling how parsing proceeds.</param> /// <param name="setAttribute">Optionally provides attribute information /// describing the attribute set.</param> public ArgumentSetDefinition(CommandLineParserOptions options = null, ArgumentSetAttribute setAttribute = null) { // Save off the options provided; if none were provided, construct some defaults. _options = options?.Clone() ?? new CommandLineParserOptions(); // Save off set attributes; if none were provided, construct some defaults. Attribute = setAttribute ?? new ArgumentSetAttribute(); // Set up private fields dependent on the ArgumentSetAttribute. _namedArgumentsByName = new Dictionary <string, ArgumentDefinition>(StringComparerToUse); }
public void LogoIsSettableWithColoredString() { var attrib = new ArgumentSetAttribute { Logo = new ColoredString("Test", ConsoleColor.Yellow) }; attrib.LogoString.Content.Should().HaveCount(1); attrib.LogoString.Content[0].Content.Should().Be("Test"); attrib.LogoString.Content[0].ForegroundColor.Should().Be(ConsoleColor.Yellow); }
public void InvalidPrefixes() { var attribs = new ArgumentSetAttribute(); Action setPrefixes = () => attribs.NamedArgumentPrefixes = null; setPrefixes.ShouldThrow <ArgumentNullException>(); setPrefixes = () => attribs.ShortNameArgumentPrefixes = null; setPrefixes.ShouldThrow <ArgumentNullException>(); }
public void TestThatAllowingElidingSeparatorAfterShortNameIsUnsupportedIfNamedArgPrefixesOverlap() { var attrib = new ArgumentSetAttribute { Style = ArgumentSetStyle.WindowsCommandLine }; attrib.NamedArgumentPrefixes.Overlaps(attrib.ShortNameArgumentPrefixes).Should().BeTrue(); attrib.AllowElidingSeparatorAfterShortName = true; attrib.Invoking(a => a.Validate()).Should().Throw <InvalidArgumentSetException>(); }
public void TestThatMultipleShortNamesInOneTokenIsUnsupportedIfNamedArgPrefixesOverlap() { var attrib = new ArgumentSetAttribute { Style = ArgumentSetStyle.WindowsCommandLine }; attrib.NamedArgumentPrefixes.Overlaps(attrib.ShortNameArgumentPrefixes).Should().BeTrue(); attrib.AllowMultipleShortNamesInOneToken = true; attrib.Invoking(a => a.Validate()).Should().Throw <InvalidArgumentSetException>(); }
/// <summary> /// Constructs an empty argument set. /// </summary> /// <param name="setAttribute">Optionally provides attribute information describing the /// argument set.</param> public ArgumentSetDefinition(ArgumentSetAttribute setAttribute = null) { // Save off set attributes; if none were provided, construct some defaults. // Make sure to validate the attributes. Attribute = setAttribute ?? new ArgumentSetAttribute(); Attribute.Validate(); // Set up private fields dependent on the ArgumentSetAttribute. _namedArgumentsByName = new Dictionary <string, ArgumentDefinition>(StringComparerToUse); _namedArgumentsByShortName = new Dictionary <string, ArgumentDefinition>(StringComparerToUse); _namedArgumentsByLongName = new Dictionary <string, ArgumentDefinition>(StringComparerToUse); }
public void NullPrefixes() { var attribs = new ArgumentSetAttribute(); attribs.NamedArgumentPrefixes = null; attribs.NamedArgumentPrefixes.Should().NotBeNull(); attribs.NamedArgumentPrefixes.Should().BeEmpty(); attribs.ShortNameArgumentPrefixes = null; attribs.ShortNameArgumentPrefixes.Should().NotBeNull(); attribs.ShortNameArgumentPrefixes.Should().BeEmpty(); }
public void LongNameArgPrefixesCannotOverlapShortNameArgPrefixes() { var attrib = new ArgumentSetAttribute { NamedArgumentPrefixes = Array.Empty <string>(), ShortNameArgumentPrefixes = Array.Empty <string>() }; attrib.AllowMultipleShortNamesInOneToken = true; attrib.ShortNameArgumentPrefixes = new[] { "-", "/" }; attrib.NamedArgumentPrefixes = new[] { ":", "-" }; attrib.Invoking(a => a.Validate()).Should().Throw <InvalidArgumentSetException>(); }
public void LongNameArgPrefixesCannotOverlapShortNameArgPrefixes() { var attrib = new ArgumentSetAttribute { NamedArgumentPrefixes = Array.Empty <string>(), ShortNameArgumentPrefixes = Array.Empty <string>() }; attrib.AllowMultipleShortNamesInOneToken = true; attrib.ShortNameArgumentPrefixes = new[] { "-", "/" }; Action a = () => attrib.NamedArgumentPrefixes = new[] { ":", "-" }; a.ShouldThrow <ArgumentOutOfRangeException>(); }
public void CertainOptionsAreUnsupportedIfNamedArgPrefixesOverlap() { var attrib = new ArgumentSetAttribute { Style = ArgumentSetStyle.WindowsCommandLine }; attrib.NamedArgumentPrefixes.Overlaps(attrib.ShortNameArgumentPrefixes).Should().BeTrue(); Action a = () => attrib.AllowMultipleShortNamesInOneToken = true; a.ShouldThrow <NotSupportedException>(); a = () => attrib.AllowElidingSeparatorAfterShortName = true; a.ShouldThrow <NotSupportedException>(); }
public void TestThatGetLogoYieldsEmptyStringLogoCannotBeExpanded() { var attrib = new ArgumentSetAttribute { Logo = "{", ExpandLogo = true }; var argSet = new ArgumentSetDefinition(attrib); var usageInfo = new ArgumentSetUsageInfo(argSet, null); var logo = usageInfo.Logo; logo.Should().BeEmpty(); }
private static string GetLongName(ArgumentBaseAttribute attribute, ArgumentSetAttribute argSetAttribute, MemberInfo member) { if (attribute.LongName != null) { return(attribute.LongName); } var longName = member.Name; if (argSetAttribute.NameGenerationFlags.HasFlag(ArgumentNameGenerationFlags.GenerateHyphenatedLowerCaseLongNames)) { longName = longName.ToHyphenatedLowerCase(); } return(longName); }
public void LogoIsSettableWithColoredMultistring() { var attrib = new ArgumentSetAttribute { Logo = new ColoredMultistring(new[] { new ColoredString("Test", ConsoleColor.Yellow), new ColoredString("String", null, ConsoleColor.Cyan) }) }; attrib.LogoString.Content.Should().HaveCount(2); attrib.LogoString.Content[0].Content.Should().Be("Test"); attrib.LogoString.Content[0].ForegroundColor.Should().Be(ConsoleColor.Yellow); attrib.LogoString.Content[1].Content.Should().Be("String"); attrib.LogoString.Content[1].BackgroundColor.Should().Be(ConsoleColor.Cyan); }
private static string GetShortNameOrNull(ArgumentBaseAttribute attribute, ArgumentSetAttribute argSetAttribute, MemberInfo member) { if (attribute is PositionalArgumentAttribute) { return(null); } if (HasExplicitShortName(attribute)) { var namedAttribute = (NamedArgumentAttribute)attribute; return(namedAttribute.ShortName.Length == 0 ? null : namedAttribute.ShortName); } var longName = GetLongName(attribute, argSetAttribute, member); var shortName = longName.Substring(0, 1); if (argSetAttribute.NameGenerationFlags.HasFlag(ArgumentNameGenerationFlags.PreferLowerCaseForShortNames)) { shortName = shortName.ToLower(); } return(shortName); }
public static ArgumentSetDefinition CreateArgumentSet( Type typeToReflectOn, ArgumentSetAttribute attribute = null, object defaultValues = null, object fixedDestination = null, ServiceConfigurer serviceConfigurer = null) { // Find high-level metadata for the argument set. var argSetAttrib = attribute ?? GetSetAttributeOrDefault(typeToReflectOn); // Construct an empty definition. var argSet = new ArgumentSetDefinition(argSetAttrib); // Add arguments. AddToArgumentSet( argSet, typeToReflectOn, defaultValues: defaultValues, fixedDestination: fixedDestination, serviceConfigurer: serviceConfigurer); return(argSet); }
/// <summary> /// Constructor that creates a loop with a default client. /// </summary> /// <param name="commandType">Type that defines syntax for commands.</param> /// <param name="parameters">Optionally provides parameters controlling /// the loop's input and output behaviors; if not provided, default /// parameters are used.</param> /// <param name="argSetAttribute">Optionally provides attribute info /// for the argument set that will be dynamically created for this loop.</param> /// <param name="options">Optionally provides additional options for /// this loop's execution.</param> public Loop(Type commandType, LoopInputOutputParameters parameters = null, ArgumentSetAttribute argSetAttribute = null, LoopOptions options = null) : this(commandType, CreateClient(parameters ?? new LoopInputOutputParameters()), argSetAttribute, options) { }
public void CanSelectWindowsCommandLineStyleWithoutThrowingException() { var attrib = new ArgumentSetAttribute { Style = ArgumentSetStyle.WindowsCommandLine }; }