/// <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); }
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); }