Example #1
0
        /// <summary>
        /// parces the infor about property line. For example, such lines
        /// >| strcutProp1	| Name	    | Value |
        /// </summary>
        /// <typeparam name="T">The type of the parent class</typeparam>
        /// <param name="level">Level in the string data</param>
        /// <param name="line">raw text of the line</param>
        /// <returns></returns>
        private MetaInfo ParseMetaLine(MetaInfo parentInfo, String line)
        {
            var result = new MetaInfo();

            var rawProps = line
                           .Replace(">", String.Empty)
                           .Split('|')
                           .Where(s => !String.IsNullOrWhiteSpace(s))                              //ignore empty names on the left and right sides of the source string. Note, it's assumend that a property name can't be empty!
                           .Select(s => s.Trim());

            //For the first level, the prop type was already parsed
            if (parentInfo.FirstLine)
            {
                result.PropType     = parentInfo.PropType;
                result.IsCollection = parentInfo.IsCollection;

                //The names of the properties specified in the test data
                result.SubPropNames = rawProps.ToArray();
            }
            else
            {
                //For the non-first levels, we have to extract data form the parent class and the line

                //the name of the complex property
                result.PropName = rawProps.First();

                PropertyInfo prop = parentInfo.PropType.GetProperties().FirstOrDefault(p => p.Name.Equals(result.PropName));

                if (prop == null)
                {
                    throw new ArgumentException($"The property {result.PropName} is absent in the {result.PropType.Name} class");
                }

                result = CheckCollectionClass(prop.PropertyType, result);

                //The names of the properties specified in the test data
                //we skip the property name in the parent class
                result.SubPropNames = rawProps.Skip(1).ToArray();
            }

            //lets check that we will be able to create instances of the item type
            if (result.PropType.GetConstructor(Type.EmptyTypes) == null)
            {
                throw new ArgumentException($"The generic type '{result.PropType.Name}' has to have a parameterless constructor.");
            }

            result.SubPropInfo = result.PropType.GetProperties();

            return(result);
        }
Example #2
0
        private MetaInfo CheckCollectionClass(Type type, MetaInfo meta)
        {
            meta.IsCollection = typeof(IEnumerable).IsAssignableFrom(type);

            //If the type is a collection then we need the item type
            if (meta.IsCollection)
            {
                //actually we need the collection item type.
                //We support the collections of only one generic type
                Type[] genericTypes = type.GetGenericArguments();
                if (genericTypes.Count() != 1)
                {
                    throw new ArgumentException("currently TestMarrow supports collection of only one generic type");
                }

                meta.PropType = genericTypes[0];
            }
            else
            {
                meta.PropType = type;
            }

            return(meta);
        }