The filler setup item contains the setup for the object filler. The setup can be made per type, property and so on
Beispiel #1
0
        /// <summary>
        /// Creates and fills a list of the given <paramref name="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 <paramref name="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 <>)
#if (!NET35 && !NET40)
                                                            || x.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>)
#endif
                                                            ))
            {
                target = (IEnumerable)Activator.CreateInstance(propertyType);
            }
            else if (propertyType.IsGenericType() &&
                     propertyType.GetGenericTypeDefinition() == typeof(ICollection <>) ||
                     propertyType.GetImplementedInterfaces().Any(x => x.IsGenericType() && x.GetGenericTypeDefinition() == typeof(ICollection <>))
#if (!NET35 && !NET40)
                     || propertyType.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>) ||
                     propertyType.GetImplementedInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>))
#endif
                     )
            {
                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);
        }
Beispiel #2
0
        /// <summary>
        /// Gets a random value of the given <paramref name="propertyType"/>
        /// </summary>
        /// <param name="propertyType">
        /// The property dictionaryType.
        /// </param>
        /// <param name="setupItem">
        /// The setup item.
        /// </param>
        /// <returns>
        /// A random value of the given <paramref name="propertyType"/>
        /// </returns>
        /// <exception cref="TypeInitializationException">
        /// Throws exception if object filler was not able to create random data
        /// </exception>
        private object GetRandomValue(Type propertyType, FillerSetupItem setupItem)
        {
            if (setupItem.TypeToRandomFunc.ContainsKey(propertyType))
            {
                return(setupItem.TypeToRandomFunc[propertyType]());
            }

            if (setupItem.IgnoreAllUnknownTypes)
            {
                return(GetDefaultValueOfType(propertyType));
            }

            string message = "The type [" + propertyType.Name + "] was not registered in the randomizer.";

            throw new TypeInitializationException(propertyType.FullName, new Exception(message));
        }
Beispiel #3
0
        /// <summary>
        /// Creates and fills a POCO class
        /// </summary>
        /// <param name="type">
        /// The target dictionaryType.
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// The created and filled POCO class
        /// </returns>
        private object GetFilledPoco(Type type, FillerSetupItem currentSetupItem, HashStack <Type> typeTracker)
        {
            if (this.CheckForCircularReference(type, typeTracker, currentSetupItem))
            {
                return(GetDefaultValueOfType(type));
            }

            typeTracker.Push(type);

            object result = this.CreateInstanceOfType(type, currentSetupItem, typeTracker);

            this.FillInternal(result, typeTracker);

            typeTracker.Pop();

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// This method will fill the given <paramref name="properties"/> of the given <paramref name="objectToFill"/>
        /// </summary>
        /// <param name="objectToFill">The object to fill</param>
        /// <param name="properties">The properties of the <paramref name="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);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates a object of the target <see cref="type"/> and fills it up with data according to the given <see cref="currentSetupItem"/>
        /// </summary>
        /// <param name="type">
        /// The target dictionaryType to create and fill
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// The created and filled object of the given <see cref="type"/>
        /// </returns>
        private object CreateAndFillObject(
            Type type,
            FillerSetupItem currentSetupItem,
            HashStack <Type> typeTracker = null)
        {
            if (HasTypeARandomFunc(type, currentSetupItem))
            {
                return(this.GetRandomValue(type, currentSetupItem));
            }

            if (TypeIsDictionary(type))
            {
                IDictionary dictionary = this.GetFilledDictionary(type, currentSetupItem, typeTracker);

                return(dictionary);
            }

            if (TypeIsList(type))
            {
                IList list = this.GetFilledList(type, currentSetupItem, typeTracker);
                return(list);
            }

            if (type.IsInterface || type.IsAbstract)
            {
                return(this.CreateInstanceOfInterfaceOrAbstractClass(type, currentSetupItem, typeTracker));
            }

            if (TypeIsEnum(type))
            {
                return(this.GetRandomEnumValue(type));
            }

            if (TypeIsPoco(type))
            {
                return(this.GetFilledPoco(type, currentSetupItem, typeTracker));
            }

            object newValue = this.GetRandomValue(type, currentSetupItem);

            return(newValue);
        }
Beispiel #6
0
        /// <summary>
        /// Sorts the properties like the <paramref name="currentSetupItem"/> wants to have it
        /// </summary>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <param name="properties">
        /// The properties to sort
        /// </param>
        /// <returns>
        /// Sorted properties as a queue
        /// </returns>
        private Queue <PropertyInfo> OrderPropertiers(FillerSetupItem currentSetupItem, PropertyInfo[] properties)
        {
            var propertyQueue   = new Queue <PropertyInfo>();
            var firstProperties =
                currentSetupItem.PropertyOrder.Where(
                    x => x.Value == At.TheBegin && this.ContainsProperty(properties, x.Key)).Select(x => x.Key).ToList();

            var lastProperties =
                currentSetupItem.PropertyOrder.Where(
                    x => x.Value == At.TheEnd && this.ContainsProperty(properties, x.Key)).Select(x => x.Key).ToList();

            var propertiesWithoutOrder =
                properties.Where(x => !this.ContainsProperty(currentSetupItem.PropertyOrder.Keys, x)).ToList();

            firstProperties.ForEach(propertyQueue.Enqueue);
            propertiesWithoutOrder.ForEach(propertyQueue.Enqueue);
            lastProperties.ForEach(propertyQueue.Enqueue);

            return(propertyQueue);
        }
        /// <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.GetGenericArguments()[0];

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

            IList list;

            if (!propertyType.IsInterface &&
                propertyType.GetInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(ICollection <>)))
            {
                list = (IList)Activator.CreateInstance(propertyType);
            }
            else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ||
                     propertyType.GetInterfaces().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);
        }
Beispiel #8
0
        /// <summary>
        /// Checks if the given dictionaryType was already been used in the object hierarchy
        /// </summary>
        /// <param name="targetType">
        /// The target dictionaryType.
        /// </param>
        /// <param name="typeTracker">
        /// The dictionaryType tracker to find circular dependencies
        /// </param>
        /// <param name="currentSetupItem">
        /// The current setup item.
        /// </param>
        /// <returns>
        /// True if there is a circular dependency
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Throws exception if a circular dependency exists and the setup is set to throw exception on circular dependency
        /// </exception>
        private bool CheckForCircularReference(
            Type targetType,
            HashStack <Type> typeTracker,
            FillerSetupItem currentSetupItem)
        {
            if (typeTracker != null)
            {
                if (typeTracker.Contains(targetType))
                {
                    if (currentSetupItem.ThrowExceptionOnCircularReference)
                    {
                        throw new InvalidOperationException(
                                  string.Format(
                                      "The type {0} was already encountered before, which probably means you have a circular reference in your model. Either ignore the properties which cause this or specify explicit creation rules for them which do not rely on types.",
                                      targetType.Name));
                    }

                    return(true);
                }
            }

            return(false);
        }
Beispiel #9
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);
        }
Beispiel #10
0
        /// <summary>
        /// Creates a instance of an interface or abstract class. Like an IoC-Framework
        /// </summary>
        /// <param name="interfaceType">
        /// The dictionaryType of interface or abstract class
        /// </param>
        /// <param name="setupItem">
        /// The setup item.
        /// </param>
        /// <param name="typeTracker">
        /// The type tracker to find circular dependencies
        /// </param>
        /// <returns>
        /// The created and filled instance of the <paramref name="interfaceType"/>
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Throws Exception if no dictionaryType was registered for the given <paramref name="interfaceType"/>
        /// </exception>
        private object CreateInstanceOfInterfaceOrAbstractClass(
            Type interfaceType,
            FillerSetupItem setupItem,
            HashStack <Type> typeTracker)
        {
            object result;

            if (setupItem.TypeToRandomFunc.ContainsKey(interfaceType))
            {
                return(setupItem.TypeToRandomFunc[interfaceType]());
            }

            if (setupItem.InterfaceToImplementation.ContainsKey(interfaceType))
            {
                Type implType = setupItem.InterfaceToImplementation[interfaceType];
                result = this.CreateInstanceOfType(implType, setupItem, typeTracker);
            }
            else
            {
                if (setupItem.InterfaceMocker == null)
                {
                    string message =
                        string.Format(
                            "ObjectFiller Interface mocker missing and type [{0}] not registered",
                            interfaceType.Name);
                    throw new InvalidOperationException(message);
                }

                MethodInfo method        = setupItem.InterfaceMocker.GetType().GetMethod("Create");
                MethodInfo genericMethod = method.MakeGenericMethod(new[] { interfaceType });
                result = genericMethod.Invoke(setupItem.InterfaceMocker, null);
            }

            this.FillInternal(result, typeTracker);
            return(result);
        }
Beispiel #11
0
 /// <summary>
 /// Initializes static members of the <see cref="Randomizer{T}"/> class.
 /// </summary>
 static Randomizer()
 {
     Setup = new FillerSetupItem();
 }
Beispiel #12
0
        /// <summary>
        /// Creates and fills a dictionary of the target <paramref name="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);
        }
Beispiel #13
0
 /// <summary>
 /// Checks if there is a random function for the given <see cref="Type"/>
 /// </summary>
 /// <param name="type">
 /// The dictionaryType.
 /// </param>
 /// <param name="currentSetupItem">
 /// The current setup item.
 /// </param>
 /// <returns>
 /// True if there is a random function in the <paramref name="currentSetupItem"/> for the given <see cref="Type"/>
 /// </returns>
 private static bool HasTypeARandomFunc(Type type, FillerSetupItem currentSetupItem)
 {
     return(currentSetupItem.TypeToRandomFunc.ContainsKey(type));
 }
Beispiel #14
0
 /// <summary>
 /// Checks if a property is ignored by the <paramref name="currentSetupItem"/>
 /// </summary>
 /// <param name="property">
 /// The property to check for ignorance
 /// </param>
 /// <param name="currentSetupItem">
 /// The current setup item.
 /// </param>
 /// <returns>
 /// True if the <paramref name="property"/> should be ignored
 /// </returns>
 private bool IgnoreProperty(PropertyInfo property, FillerSetupItem currentSetupItem)
 {
     return(this.ContainsProperty(currentSetupItem.PropertiesToIgnore, property));
 }