예제 #1
0
        /// <summary>
        /// Creates a instance of the given <see cref="type"/>
        /// </summary>
        /// <param name="type">
        /// The dictionaryType to create
        /// </param>
        /// <param name="currentSetupItem">
        /// The setup for the current object dictionaryType
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// Created instance of the given <see cref="Type"/>
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Throws exception if the constructor could not be created by filler setup
        /// </exception>
        private object CreateInstanceOfType(Type type, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            var constructorArgs = new List <object>();

            if (type.GetConstructors().All(ctor => ctor.GetParameters().Length != 0))
            {
                IEnumerable <ConstructorInfo> ctorInfos;
                if ((ctorInfos = type.GetConstructors().Where(ctr => ctr.GetParameters().Length != 0)).Any())
                {
                    foreach (ConstructorInfo ctorInfo in ctorInfos.OrderBy(x => x.GetParameters().Length))
                    {
                        Type[] paramTypes = ctorInfo.GetParameters().Select(p => p.ParameterType).ToArray();

                        if (paramTypes.All(ctorParamType => TypeIsValidForObjectFiller(ctorParamType, currentSetupItem) && ctorParamType != type))
                        {
                            foreach (Type paramType in paramTypes)
                            {
                                constructorArgs.Add(this.CreateAndFillObject(paramType, currentSetupItem, typeTracker));
                            }

                            break;
                        }
                    }

                    if (constructorArgs.Count == 0)
                    {
                        var message = "Could not found a constructor for type [" + type.Name
                                      + "] where the parameters can be filled with the current objectfiller setup";
                        throw new InvalidOperationException(message);
                    }
                }
            }

            object result = Activator.CreateInstance(type, constructorArgs.ToArray());

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Creates and fills a list of the given <see cref="propertyType"/>
        /// </summary>
        /// <param name="propertyType">
        /// Type of the list
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// Created and filled list of the given <see cref="propertyType"/>
        /// </returns>
        private IList GetFilledList(Type propertyType, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            Type genType = propertyType.GetGenericTypeArguments()[0];

            if (this.CheckForCircularReference(genType, typeTracker, currentSetupItem))
            {
                return(null);
            }

            IList list;

            if (!propertyType.IsInterface() &&
                propertyType.GetImplementedInterfaces().Any(x => x == typeof(IList)))
            {
                list = (IList)Activator.CreateInstance(propertyType);
            }
            else if (propertyType.IsGenericType() && propertyType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ||
                     propertyType.GetImplementedInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(IEnumerable <>)))
            {
                Type openListType    = typeof(List <>);
                Type genericListType = openListType.MakeGenericType(genType);
                list = (IList)Activator.CreateInstance(genericListType);
            }
            else
            {
                list = (IList)Activator.CreateInstance(propertyType);
            }

            int maxListItems = Random.Next(currentSetupItem.ListMinCount, currentSetupItem.ListMaxCount);

            for (int i = 0; i < maxListItems; i++)
            {
                object listObject = this.CreateAndFillObject(genType, currentSetupItem, typeTracker);
                list.Add(listObject);
            }

            return(list);
        }
예제 #3
0
        /// <summary>
        /// Creates and fills a list of the given <see cref="propertyType"/>
        /// </summary>
        /// <param name="propertyType">
        /// Type of the list
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// Created and filled list of the given <see cref="propertyType"/>
        /// </returns>
        private IEnumerable GetFilledCollection(Type propertyType, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            Type genType = propertyType.GetGenericTypeArguments()[0];

            if (this.CheckForCircularReference(genType, typeTracker, currentSetupItem))
            {
                return(null);
            }

            IEnumerable target;

            if (!propertyType.IsInterface() &&
                propertyType.GetImplementedInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(ICollection <>)))
            {
                target = (IEnumerable)Activator.CreateInstance(propertyType);
            }
            else if (propertyType.IsGenericType() && propertyType.GetGenericTypeDefinition() == typeof(ICollection <>) ||
                     propertyType.GetImplementedInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(ICollection <>)))
            {
                Type openListType    = typeof(List <>);
                Type genericListType = openListType.MakeGenericType(genType);
                target = (IEnumerable)Activator.CreateInstance(genericListType);
            }
            else
            {
                target = (IEnumerable)Activator.CreateInstance(propertyType);
            }

            int maxListItems = Random.Next(currentSetupItem.ListMinCount, currentSetupItem.ListMaxCount);

            for (int i = 0; i < maxListItems; i++)
            {
                object     listObject = this.CreateAndFillObject(genType, currentSetupItem, typeTracker);
                MethodInfo method     = target.GetType().GetMethod("Add");
                method.Invoke(target, new object[] { listObject });
            }

            return(target);
        }
예제 #4
0
        /// <summary>
        /// Creates and fills a list of the given <see cref="propertyType"/>
        /// </summary>
        /// <param name="propertyType">
        /// Type of the list
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// Created and filled list of the given <see cref="propertyType"/>
        /// </returns>
        private IList GetFilledList(Type propertyType, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            bool derivedList = !propertyType.GetGenericTypeArguments().Any();
            Type genType     = !derivedList?propertyType.GetGenericTypeArguments()[0]
                               : propertyType.GetTypeInfo().BaseType.GetGenericTypeArguments()[0];

            if (this.CheckForCircularReference(genType, typeTracker, currentSetupItem))
            {
                return(null);
            }

            IList list;

            if (!propertyType.IsInterface() &&
                propertyType.GetImplementedInterfaces().Any(x => x == typeof(IList)))
            {
                list = (IList)Activator.CreateInstance(propertyType);
            }
            else if (propertyType.IsGenericType() && propertyType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ||
                     propertyType.GetImplementedInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(IEnumerable <>)))
            {
                Type openListType    = typeof(List <>);
                Type genericListType = openListType.MakeGenericType(genType);
                list = (IList)Activator.CreateInstance(genericListType);
            }
            else
            {
                list = (IList)Activator.CreateInstance(propertyType);
            }

            int maxListItems = Random.Next(currentSetupItem.ListMinCount, currentSetupItem.ListMaxCount);

            for (int i = 0; i < maxListItems; i++)
            {
                object listObject = this.CreateAndFillObject(genType, currentSetupItem, typeTracker);
                list.Add(listObject);
            }

            if (derivedList)
            {
                var remainingProperties = propertyType.GetProperties(true)
                                          .Where(prop => this.GetSetMethodOnDeclaringType(prop) != null)
                                          .ToArray();

                this.FillProperties(list, remainingProperties, currentSetupItem, typeTracker);
            }

            return(list);
        }
예제 #5
0
        /// <summary>
        /// Creates and fills a dictionary of the target <see cref="propertyType"/>
        /// </summary>
        /// <param name="propertyType">
        /// The dictionaryType of the dictionary
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// A created and filled dictionary
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Throws exception if the setup was made in a way that the keys of the dictionary are always the same
        /// </exception>
        private IDictionary GetFilledDictionary(
            Type propertyType,
            FillerSetupItem currentSetupItem,
            HashStack <Type> typeTracker)
        {
            IDictionary dictionary = (IDictionary)Activator.CreateInstance(propertyType);

            bool derivedType = !propertyType.GetGenericTypeArguments().Any();

            Type keyType = !derivedType
                            ? propertyType.GetGenericTypeArguments()[0]
                            : propertyType.GetTypeInfo().BaseType.GetGenericTypeArguments()[0];

            Type valueType = !derivedType
                            ? propertyType.GetGenericTypeArguments()[1]
                            : propertyType.GetTypeInfo().BaseType.GetGenericTypeArguments()[1];

            int maxDictionaryItems = 0;

            if (keyType.IsEnum())
            {
                maxDictionaryItems = Enum.GetValues(keyType).Length;
            }
            else
            {
                maxDictionaryItems = Random.Next(
                    currentSetupItem.DictionaryKeyMinCount,
                    currentSetupItem.DictionaryKeyMaxCount);
            }

            for (int i = 0; i < maxDictionaryItems; i++)
            {
                object keyObject = null;
                if (keyType.IsEnum())
                {
                    keyObject = Enum.GetValues(keyType).GetValue(i);
                }
                else
                {
                    keyObject = this.CreateAndFillObject(keyType, currentSetupItem, typeTracker);
                }

                if (dictionary.Contains(keyObject))
                {
                    string message =
                        string.Format(
                            "Generating Keyvalue failed because it generates always the same data for dictionaryType [{0}]. Please check your setup.",
                            keyType);
                    throw new ArgumentException(message);
                }

                object valueObject = this.CreateAndFillObject(valueType, currentSetupItem, typeTracker);
                dictionary.Add(keyObject, valueObject);
            }

            if (derivedType)
            {
                var remainingProperties = propertyType.GetProperties(true)
                                          .Where(prop => this.GetSetMethodOnDeclaringType(prop) != null)
                                          .ToArray();

                this.FillProperties(dictionary, remainingProperties, currentSetupItem, typeTracker);
            }

            return(dictionary);
        }
예제 #6
0
        /// <summary>
        /// This method will fill the given <see cref="properties"/> of the given <see cref="objectToFill"/>
        /// </summary>
        /// <param name="objectToFill">The object to fill</param>
        /// <param name="properties">The properties of the <see cref="objectToFill"/> which shall get filled</param>
        /// <param name="currentSetup">
        /// The setup for the current object
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        private void FillProperties(object objectToFill, PropertyInfo[] properties, FillerSetupItem currentSetup, HashStack <Type> typeTracker)
        {
            if (properties.Length == 0)
            {
                return;
            }

            Queue <PropertyInfo> orderedProperties = this.OrderPropertiers(currentSetup, properties);

            while (orderedProperties.Count != 0)
            {
                PropertyInfo property = orderedProperties.Dequeue();

                if (currentSetup.TypesToIgnore.Contains(property.PropertyType))
                {
                    continue;
                }

                if (this.IgnoreProperty(property, currentSetup))
                {
                    continue;
                }

                if (this.ContainsProperty(currentSetup.PropertyToRandomFunc.Keys, property))
                {
                    PropertyInfo propertyInfo =
                        this.GetPropertyFromProperties(currentSetup.PropertyToRandomFunc.Keys, property).Single();
                    this.SetPropertyValue(property, objectToFill, currentSetup.PropertyToRandomFunc[propertyInfo]());
                    continue;
                }

                if (this.justConfiguredProperties &&
                    !this.setupManager.FillerSetup.TypeToFillerSetup.ContainsKey(property.PropertyType))
                {
                    continue;
                }

                object filledObject = this.CreateAndFillObject(property.PropertyType, currentSetup, typeTracker);

                this.SetPropertyValue(property, objectToFill, filledObject);
            }
        }
예제 #7
0
        /// <summary>
        /// Generates keys for a randomized dictionary.  If <paramref name="keyType"/> is an enumeration, special
        /// handling is taken to ensure that duplicates aren't created.
        /// </summary>
        /// <param name="keyType">The dictionary key type</param>
        /// <param name="currentSetupItem">The current setup item</param>
        /// <param name="typeTracker">The dictionaryType tracker to find circular dependencies</param>
        /// <returns></returns>
        private List <object> GenerateDictionaryKeys(Type keyType, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            List <object> keys = new List <object>();

            if (keyType.IsEnum)
            {
                // TODO: The result of this could be cached for performance if desired
                var enumValues = Enum.GetValues(keyType).Cast <object>().ToList();

                int maxDictionaryItems = Random.Next(
                    Math.Min(enumValues.Count, currentSetupItem.DictionaryKeyMinCount),
                    Math.Min(enumValues.Count, currentSetupItem.DictionaryKeyMaxCount));

                for (int i = 0; i < maxDictionaryItems; i++)
                {
                    int randomIndex = Random.Next(enumValues.Count);
                    var key         = enumValues[randomIndex];
                    keys.Add(key);
                    enumValues.Remove(key);
                }
            }
            else
            {
                int maxDictionaryItems = Random.Next(
                    currentSetupItem.DictionaryKeyMinCount,
                    currentSetupItem.DictionaryKeyMaxCount);

                for (int i = 0; i < maxDictionaryItems; i++)
                {
                    keys.Add(this.CreateAndFillObject(keyType, currentSetupItem, typeTracker));
                }
            }

            return(keys);
        }