/// <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));
 }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
            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;
            }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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"));
        }
Exemplo n.º 7
0
        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);
     }
 }
Exemplo n.º 9
0
        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); });
            }
        }
Exemplo n.º 10
0
        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>());
        }
Exemplo n.º 11
0
        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>());
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 14
0
        /// <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)
 {
 }