internal static List <Type> GetFactoryInputTypes(List <Type> objectTypes)
        {
            List <Type> demandedTypes = new List <Type>();

            foreach (Type t in objectTypes)
            {
                List <Type> dependencies = DiscoverableInputHelper.GetFactoryInputTypes(t);
                foreach (Type demandedType in dependencies)
                {
                    if (!demandedTypes.Contains(demandedType))
                    {
                        demandedTypes.Add(demandedType);
                    }
                }
            }
            return(demandedTypes);
        }
Beispiel #2
0
        /// <summary>
        /// Populates Input properties for a Factory or Action
        /// </summary>
        /// <param name="consumer">Object to be populated</param>
        /// <param name="random">Deterministic Random source</param>
        /// <param name="state">Supporting State Object</param>
        /// <param name="recursionLimit">Recursion depth - ie - how many parent invocations does the current code have?</param>
        /// <returns></returns>
        private static bool PopulateDiscoverableInputs(IDiscoverableObject consumer, DeterministicRandom random, ConvenienceStressState state, int recursionDepth)
        {
            List <PropertyDescriptor> inputProperties = DiscoverableInputHelper.GetInputProperties(consumer.GetType());

            foreach (PropertyDescriptor property in inputProperties)
            {
                //Determine desired type
                Type   consumedType = property.PropertyType;
                Object result       = null;

                InputAttribute inputAttribute = (InputAttribute)property.Attributes[typeof(InputAttribute)];
                if (inputAttribute == null)
                {
                    inputAttribute = InputAttribute.CreateFromFactory;
                }

                switch (inputAttribute.ContentInputSource)
                {
                //
                case ContentInputSource.GetFromLogicalTree:
                    // Factories can not consume existing objects - Only actions can do so
                    if (consumer.GetType().IsSubclassOf(typeof(DiscoverableFactory)))
                    {
                        throw new InvalidOperationException("A Factory cannot consume from state");
                    }
                    //Get Property from window surface Area
                    Trace.WriteLine("[DiscoverableActionSequencer] Getting a Logical Tree Item");
                    result = state.GetFromLogicalTree(consumedType, random);

                    //For object from Logical tree, null means item not found, thus failed.
                    if (result == null)
                    {
                        return(false);
                    }
                    break;

                case ContentInputSource.GetFromVisualTree:
                    // Factories can not consume existing objects - Only actions can do so
                    if (consumer.GetType().IsSubclassOf(typeof(DiscoverableFactory)))
                    {
                        throw new InvalidOperationException("A Factory cannot consume from state");
                    }
                    //Get Property from window surface Area
                    Trace.WriteLine("[DiscoverableActionSequencer] Getting a Visual Tree item");
                    result = state.GetFromVisualTree(consumedType, random);

                    //For object from Visual tree, null result means item not found, thus failed.
                    if (result == null)
                    {
                        return(false);
                    }
                    break;

                case ContentInputSource.GetWindowListFromState:
                    // Factories can not consume existing objects - Only actions can do so
                    if (consumer.GetType().IsSubclassOf(typeof(DiscoverableFactory)))
                    {
                        throw new InvalidOperationException("A Factory cannot consume from state");
                    }

                    Trace.WriteLine("[DiscoverableActionSequencer] Getting WindowList property of state");
                    result = state.WindowList;
                    break;

                //Populate data from Type.Property specific constraints system
                //
                case ContentInputSource.CreateFromConstraints:
                    Trace.WriteLine("[DiscoverableActionSequencer] Getting a Constraint based item");
                    result = state.MakeFromConstraint(consumer.GetType(), property.Name, random);
                    break;

                case ContentInputSource.GetFromObjectTree:
                    Trace.WriteLine("[DiscoverableActionSequencer] Getting a object from Object tree.");
                    result = state.GetFromObjectTree(consumedType, random);

                    //For object from Object tree, null result means item not found, thus failed.
                    if (result == null)
                    {
                        return(false);
                    }
                    break;

                //Default behavior is to produce content from factories
                default:
                    if (recursionDepth < standardRecursionLimit ||
                        (recursionDepth < absoluteRecursionLimit && inputAttribute.IsEssentialContent))
                    {
                        Trace.WriteLine("[DiscoverableActionSequencer] Producing factory content");
                        //Basic workflow for producing Factory content
                        if (!consumedType.IsGenericType)
                        {
                            result = MakeItem(consumedType, state, random, recursionDepth + 1);
                        }
                        else
                        {
                            if (consumedType.GetGenericTypeDefinition() == typeof(List <>))
                            {
                                result = MakeList(consumedType, state, random, recursionDepth + 1, inputAttribute.MinListSize, inputAttribute.MaxListSize);
                            }
                            else
                            {
                                throw new InvalidOperationException("We can't work with this type yet:. " + consumedType.GetGenericTypeDefinition());
                            }
                        }
                    }
                    else if (recursionDepth >= absoluteRecursionLimit && inputAttribute.IsEssentialContent)
                    {
                        throw new InvalidOperationException("The stress test factory has reached the absolute recursion limit and is still demanding essential content. Is there a cyclic chain only involving factories requiring their inputs?");
                    }
                    else      //Factory Recursion depth exceeded. We are leaving non-essential property null
                    {
                        //No Operation
                    }
                    break;
                }

                //Set value to desired input
                property.SetValue(consumer, result);
                if (result != null)
                {
                    Trace.WriteLine(String.Format("[DiscoverableActionSequencer] Provided a [{0}] of type {1} for {2}", result, result.GetType(), consumer));
                }
                else
                {
                    Trace.WriteLine(String.Format("[DiscoverableActionSequencer] Provided a null for {1}", result, consumer));
                }
            }

            return(true);
        }