/// <summary> /// Extended construction. /// </summary> /// <remarks> /// This constructor tries to create an instance of the custom converter automatically, but /// only in case of parameter <paramref name="enabled"/> is set to <c>true</c>. /// </remarks> /// <param name="property"> /// An instance of property information to be applied. /// </param> /// <param name="attribute"> /// An instance of a parameter object attribute to be applied. /// </param> /// <param name="enabled"> /// True to enable automatic custom converter construction and false to disable this feature. /// </param> /// <seealso cref="ArgumentProcessorSetting(PropertyInfo, ParameterObjectAttribute)"/> public ArgumentProcessorSetting(PropertyInfo property, ParameterObjectAttribute attribute, Boolean enabled) : base() { this.Property = property ?? throw new ArgumentNullException(nameof(property)); this.Attribute = attribute ?? throw new ArgumentNullException(nameof(attribute)); this.CustomConverter = enabled ? this.GetCustomConverter(property) : null; }
/// <summary> /// Standard construction. /// </summary> /// <remarks> /// The only one and default constructor of this class. /// </remarks> /// <param name="property"> /// An instance of property information to be applied. /// </param> /// <param name="setting"> /// An instance of a parameter object attribute to be applied. /// </param> /// <param name="summary"> /// An instance of a help summary attribute to be applied. /// </param> public HelpProcessorSetting(PropertyInfo property, ParameterObjectAttribute setting, HelpSummaryAttribute summary) : base() { this.Property = property ?? throw new ArgumentNullException(nameof(property)); this.Setting = setting ?? throw new ArgumentNullException(nameof(setting)); this.Summary = summary ?? throw new ArgumentNullException(nameof(summary)); }
public void IsVerbalParameter_ArgumentProcessorSettingWithAttribute_ResultAsExpected(Type type, Boolean expected) { ParameterObjectAttribute attribute = null; if (type == typeof(SwitchParameterAttribute)) { attribute = new SwitchParameterAttribute(); } else if (type == typeof(OptionParameterAttribute)) { attribute = new OptionParameterAttribute(); } else if (type == typeof(VerbalParameterAttribute)) { attribute = new VerbalParameterAttribute(); } else if (type == typeof(UnsupportedParameterAttribute)) { attribute = new UnsupportedParameterAttribute(); } ArgumentProcessorSetting setting = new ArgumentProcessorSetting(new TestPropertyInfo(typeof(Object)), attribute); Assert.That(setting.IsVerbalParameter(), Is.EqualTo(expected)); }
public ToParameterLabelTestItem(ToParameterLabelTestClassBase candidate, String expected) { PropertyInfo property = candidate.GetType().GetRuntimeProperty(nameof(ToParameterLabelTestClassBase.TestProperty)); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(SwitchParameterAttribute)); this.Setting = new ArgumentProcessorSetting(property, attribute); this.Expected = expected; }
public void Construction_TestClassConverter_CustomConverterIsEnabled() { TestClassConverter candidate = new TestClassConverter(); PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); ArgumentProcessorSetting actual = new ArgumentProcessorSetting(property, attribute, true); Assert.That(actual.CustomConverter, Is.Not.Null); Assert.That(actual.HasCustomConverter, Is.True); }
public void InvokeCustomConverter_ConvertMethodInvocation_ParametersAsExpected() { TestClassConverter candidate = new TestClassConverter(); PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); ArgumentProcessorSetting actual = new ArgumentProcessorSetting(property, attribute, true); actual.InvokeCustomConverter("parameter", "argument", "delimiter"); Assert.That(ArgumentProcessorSettingTests.parameter, Is.EqualTo("parameter")); Assert.That(ArgumentProcessorSettingTests.argument, Is.EqualTo("argument")); Assert.That(ArgumentProcessorSettingTests.delimiter, Is.EqualTo("delimiter")); }
public void IsConverterSupported_WrongParameterObjectAttributeType_ResultIsFalse(Type type) { ParameterObjectAttribute attribute = null; if (type == typeof(SwitchParameterAttribute)) { attribute = new SwitchParameterAttribute(); } else if (type == typeof(VerbalParameterAttribute)) { attribute = new VerbalParameterAttribute(); } else if (type == typeof(UnsupportedParameterAttribute)) { attribute = new UnsupportedParameterAttribute(); } Assert.That(attribute.IsConverterSupported(null), Is.False); }
/// <summary> /// Convenient method to check if a parameter type is one of the supported type. /// </summary> /// <remarks> /// This convenient method checks if a parameter type is one of the supported type. /// </remarks> /// <param name="parameter"> /// The parameter to check its type. /// </param> /// <param name="property"> /// The property information that contain additional type information. /// </param> /// <returns> /// True, if type is supported and false otherwise. /// </returns> public static Boolean IsSupportedDataType(this ParameterObjectAttribute parameter, PropertyInfo property) { if (parameter is SwitchParameterAttribute) { return(property.PropertyType == typeof(Boolean) || property.PropertyType == typeof(Boolean?)); } else if (parameter is OptionParameterAttribute) { return(OptionTypeConverter.IsSupportedType(property.PropertyType)); } else if (parameter is VerbalParameterAttribute) { return(property.PropertyType == typeof(List <String>) || property.PropertyType == typeof(String[])); } else { return(false); } }
public void Construction_InvalidArguments_ThrowsArgumentNullException(Type nullType, Boolean?enabled) { TestClassStandard candidate = new TestClassStandard(); PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); property = nullType == typeof(PropertyInfo) ? null : property; attribute = nullType == typeof(ParameterObjectAttribute) ? null : attribute; if (enabled.HasValue) { Assert.Throws <ArgumentNullException>(() => { new ArgumentProcessorSetting(property, attribute, enabled.Value); }); } else { Assert.Throws <ArgumentNullException>(() => { new ArgumentProcessorSetting(property, attribute); }); } }
public void InvokeCustomConverter_ConvertMethodInvocationThrows_ThrowsCustomConverterException(Type type) { Object candidate = null; if (type == typeof(TestClassInvokeConvertThrowsNotImplementedException)) { candidate = new TestClassInvokeConvertThrowsNotImplementedException(); } else if (type == typeof(TestClassInvokeConvertThrowsCustomConverterException)) { candidate = new TestClassInvokeConvertThrowsCustomConverterException(); } PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); ArgumentProcessorSetting actual = new ArgumentProcessorSetting(property, attribute, true); Assert.That(() => actual.InvokeCustomConverter("parameter", "argument", "delimiter"), Throws.InstanceOf <CustomConverterException>()); }
public void InvokeCustomConverter_CustomConverterIsDisabled_ThrowsCustomConverterException(Boolean?enabled) { TestClassStandard candidate = new TestClassStandard(); PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); ArgumentProcessorSetting actual = null; if (enabled.HasValue) { actual = new ArgumentProcessorSetting(property, attribute, enabled.Value); } else { actual = new ArgumentProcessorSetting(property, attribute); } Assert.That(() => actual.InvokeCustomConverter("parameter", "argument", "delimiter"), Throws.InstanceOf <CustomConverterException>()); }
public void Construction_TestClassOfSpecificType_CustomConverterIsDisabled(Type type) { Object candidate = null; if (type == typeof(TestClassStandard)) { candidate = new TestClassStandard(); } else if (type == typeof(TestClassNullConverter)) { candidate = new TestClassNullConverter(); } else if (type == typeof(TestClassConverterConstructorThrows)) { candidate = new TestClassConverterConstructorThrows(); } else if (type == typeof(TestClassWrongConverterWrongDataType)) { candidate = new TestClassWrongConverterWrongDataType(); } else if (type == typeof(TestClassWrongConverterNoGenericType)) { candidate = new TestClassWrongConverterNoGenericType(); } else if (type == typeof(TestClassWrongConverterWrongInterfaceType)) { candidate = new TestClassWrongConverterWrongInterfaceType(); } else if (type == typeof(TestClassWrongConverterNoGenericInterface)) { candidate = new TestClassWrongConverterNoGenericInterface(); } PropertyInfo property = candidate.GetType().GetRuntimeProperty("TestType"); ParameterObjectAttribute attribute = (ParameterObjectAttribute)property.GetCustomAttribute(typeof(OptionParameterAttribute)); ArgumentProcessorSetting actual = new ArgumentProcessorSetting(property, attribute, true); Assert.That(actual.CustomConverter, Is.Null); Assert.That(actual.HasCustomConverter, Is.False); }
/// <summary> /// Determines whether a property contains a custom converter attribute. /// </summary> /// <remarks> /// This method determines whether a property contains a custom converter /// attribute. /// </remarks> /// <param name="parameter"> /// The attribute type to be checked. At the moment, this attribute must /// be of type <see cref="OptionParameterAttribute"/>. /// </param> /// <param name="property"> /// The property information that contain additional attribute information. /// </param> /// <returns> /// True, if a custom type converter attribute with a fitting data type /// is supported and false if not. /// </returns> /// <seealso cref="OptionParameterAttribute"/> /// <seealso cref="CustomConverterAttribute"/> /// <seealso cref="ICustomConverter{TTarget}"/> public static Boolean IsConverterSupported(this ParameterObjectAttribute parameter, PropertyInfo property) { if (parameter is OptionParameterAttribute) { foreach (Attribute attribute in property.GetCustomAttributes()) { if (attribute is CustomConverterAttribute converter) { if (converter.Instance is null) { continue; } foreach (Type realization in converter.Instance.GetInterfaces()) { if (!realization.IsGenericType) { continue; } if (realization.GetGenericTypeDefinition() != typeof(ICustomConverter <>)) { continue; } if (!realization.GetGenericArguments().Any(x => x == property.PropertyType)) { continue; } return(true); } } } } return(false); }
/// <summary> /// Initializes an instance of this class. /// </summary> /// <remarks> /// This method initializes an instance of this class and implicitly /// performs an argument validation. /// </remarks> public void Initialize() { try { this.Settings = new List <ArgumentProcessorSetting>(); VerbalParameterAttribute lastVerbal = null; Dictionary <String, PropertyInfo> solidLabels = new Dictionary <String, PropertyInfo>(); Dictionary <String, PropertyInfo> briefLabels = new Dictionary <String, PropertyInfo>(); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty; PropertyInfo[] properties = this.Instance.GetType().GetProperties(flags); if (properties != null) { foreach (PropertyInfo property in properties) { IEnumerable <Attribute> attributes = property.GetCustomAttributes(); if (attributes != null) { foreach (Attribute current in attributes) { if (current is ParameterObjectAttribute) { ParameterObjectAttribute attribute = current as ParameterObjectAttribute; if (attribute is SwitchParameterAttribute || attribute is OptionParameterAttribute) { if (attribute.IsSolidLabel || attribute.IsBriefLabel) { if (attribute.IsSolidLabel) { if (!solidLabels.ContainsKey(attribute.SolidLabel)) { solidLabels[attribute.SolidLabel] = property; } else { throw new UtilizeViolationException( $"The solid label \"{attribute.SolidLabel}\" of property \"{property.Name}\" is already used " + $"by property \"{solidLabels[attribute.SolidLabel].Name}\". All solid labels must be unique."); } } if (attribute.IsBriefLabel) { if (!briefLabels.ContainsKey(attribute.BriefLabel)) { briefLabels[attribute.BriefLabel] = property; } else { throw new UtilizeViolationException( $"The brief label \"{attribute.BriefLabel}\" of property \"{property.Name}\" is already used " + $"by property \"{briefLabels[attribute.BriefLabel].Name}\". All brief labels must be unique."); } } } else { throw new UtilizeViolationException( $"Neither the solid label nor the brief label is used by property \"{property.Name}\". " + $"Empty labels are only supported by verbal parameter types."); } } else if (attribute is VerbalParameterAttribute) { if (lastVerbal == null) { lastVerbal = attribute as VerbalParameterAttribute; } else { throw new VerbalViolationException( $"More than one verbal parameter is not supported " + $"per instance of \"{this.Instance.GetType().Name}\"."); } } else { throw new SupportViolationException( $"A property attribute of type \"{attribute.GetType().Name}\" " + $"is not supported."); } if (attribute.IsSupportedDataType(property)) { this.Settings.Add(this.ApplyDefaultValue(new ArgumentProcessorSetting(property, attribute))); } else if (attribute.IsConverterSupported(property)) { this.Settings.Add(new ArgumentProcessorSetting(property, attribute, true)); } // TODO: Remove obsolete code later on. /* obsolete start */ else if (property.PropertyType.HasConverter()) { this.Settings.Add(new ArgumentProcessorSetting(property, attribute)); } /* obsolete end */ else { throw new SupportViolationException( $"Type \"{property.PropertyType}\" of property \"{property.Name}\" " + $"is not supported."); } } } } } } } catch (Exception exception) { exception.ThrowArgumentParserException(); } }
/// <summary> /// Initializes this instance with its default values. /// </summary> /// <remarks> /// This method initializes this instance with its default values. /// </remarks> public void Initialize() { this.License = null; this.Preface = null; this.Closure = null; this.Utilizes = new List <HelpUtilizeAttribute>(); this.Settings = new List <HelpProcessorSetting>(); foreach (Attribute current in Attribute.GetCustomAttributes(this.Instance.GetType())) { if (current is HelpLicenseAttribute) { this.License = this.FixupLicense(current as HelpLicenseAttribute); } else if (current is HelpPrefaceAttribute) { this.Preface = this.FixupPreface(current as HelpPrefaceAttribute); } else if (current is HelpClosureAttribute) { this.Closure = current as HelpClosureAttribute; } else if (current is HelpUtilizeAttribute) { this.Utilizes.Add(this.FixupUtilize(current as HelpUtilizeAttribute)); } } BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty; PropertyInfo[] properties = this.Instance.GetType().GetProperties(flags); if (properties != null) { foreach (PropertyInfo property in properties) { HelpSummaryAttribute summary = null; ParameterObjectAttribute parameter = null; IEnumerable <Attribute> attributes = property.GetCustomAttributes(); if (attributes != null) { foreach (Attribute attribute in attributes) { if (attribute is ParameterObjectAttribute) { parameter = attribute as ParameterObjectAttribute; } else if (attribute is HelpSummaryAttribute) { summary = attribute as HelpSummaryAttribute; } } } if (property != null && parameter != null && summary != null) { this.Settings.Add(this.FixupSetting(new HelpProcessorSetting(property, parameter, summary))); } } } }
/// <summary> /// Standard construction. /// </summary> /// <remarks> /// This constructor does not try to create an instance of a custom converter automatically. /// </remarks> /// <param name="property"> /// An instance of property information to be applied. /// </param> /// <param name="attribute"> /// An instance of a parameter object attribute to be applied. /// </param> /// <seealso cref="ArgumentProcessorSetting(PropertyInfo, ParameterObjectAttribute, Boolean)"/> public ArgumentProcessorSetting(PropertyInfo property, ParameterObjectAttribute attribute) : this(property, attribute, false) { }