/// <summary>
        /// Consumes type members including fields, properties, methods and events.
        /// </summary>
        /// <param name="typeScope">The scope to be used as the containing scope.</param>
        /// <param name="type">The type whose members are to be consumed.</param>
        protected void ConsumeMembers(IPatternScope typeScope, ITypeInfo type)
        {
            BindingFlags bindingFlags = GetMemberBindingFlags(type);

            // TODO: We should probably process groups of members in sorted order working outwards
            //       from the base type, like an onion.
            foreach (IFieldInfo field in CodeElementSorter.SortMembersByDeclaringType(type.GetFields(bindingFlags)))
            {
                typeScope.Consume(field, false, DefaultFieldPattern);
            }

            foreach (IPropertyInfo property in CodeElementSorter.SortMembersByDeclaringType(type.GetProperties(bindingFlags)))
            {
                typeScope.Consume(property, false, DefaultPropertyPattern);
            }

            foreach (IMethodInfo method in CodeElementSorter.SortMembersByDeclaringType(type.GetMethods(bindingFlags)))
            {
                typeScope.Consume(method, false, DefaultMethodPattern);
            }

            foreach (IEventInfo @event in CodeElementSorter.SortMembersByDeclaringType(type.GetEvents(bindingFlags)))
            {
                typeScope.Consume(@event, false, DefaultEventPattern);
            }
        }
 /// <summary>
 /// Consumes nested types.
 /// </summary>
 /// <param name="typeScope">The scope to be used as the containing scope.</param>
 /// <param name="type">The type whose nested types are to be consumed.</param>
 protected void ConsumeNestedTypes(IPatternScope typeScope, ITypeInfo type)
 {
     foreach (ITypeInfo nestedType in type.GetNestedTypes(NestedTypeBindingFlags))
     {
         typeScope.Consume(nestedType, false, DefaultNestedTypePattern);
     }
 }
        /// <inheritdoc />
        public override void Consume(IPatternScope containingScope, ICodeElementInfo codeElement, bool skipChildren)
        {
            //TODO: Review: Issue 762: Shouldn't the base method be invoked here?
            //base.Consume(containingScope, codeElement, skipChildren);
            if (!IsReadableFieldOrProperty(codeElement))
            {
                ThrowUsageErrorException("This attribute may only be applied to fields and properties with getters.");
            }

            ISlotInfo slot      = (ISlotInfo)codeElement;
            ITypeInfo mixinType = slot.ValueType;

            if (!mixinType.IsClass || !AttributeUtils.HasAttribute(mixinType, typeof(MixinAttribute), true))
            {
                ThrowUsageErrorException(String.Format("The field or property value type must be a class with the [Mixin] attribute applied.  "
                                                       + "The type {0} does not appear to be a valid mixin class.", mixinType));
            }

            // TODO: Detect cycles.
            // TODO: Modify how fixture types and instances are interpreted in the mixin.

            IPatternScope mixinScope = containingScope.CreateScope(codeElement,
                                                                   containingScope.TestBuilder, null, containingScope.TestDataContextBuilder.CreateChild(), false);

            mixinScope.Consume(mixinType, skipChildren, null);
        }
Exemple #4
0
 /// <summary>
 /// Populates the children of the assembly test all at once.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The default implementation processes all public and non-public types within the assembly.
 /// </para>
 /// </remarks>
 /// <param name="assemblyScope">The assembly scope.</param>
 /// <param name="assembly">The assembly.</param>
 protected virtual void PopulateChildrenImmediately(IPatternScope assemblyScope, IAssemblyInfo assembly)
 {
     foreach (ITypeInfo type in assembly.GetTypes())
     {
         if (!type.IsNested)
         {
             assemblyScope.Consume(type, false, DefaultTypePattern);
         }
     }
 }
 /// <summary>
 /// Consumes type constructors.
 /// </summary>
 /// <param name="typeScope">The scope to be used as the containing scope.</param>
 /// <param name="type">The type whose constructors are to be consumed.</param>
 protected void ConsumeConstructors(IPatternScope typeScope, ITypeInfo type)
 {
     if (ShouldConsumeConstructors(type))
     {
         // FIXME: Currently we arbitrarily choose the first constructor and throw away the rest.
         //        This should be replaced by a more intelligent mechanism that supports a constructor
         //        selection policy based on some criterion.
         IConstructorInfo constructor = GetFirstConstructorWithPreferenceForPublicConsructor(type);
         if (constructor != null)
         {
             typeScope.Consume(constructor, false, DefaultConstructorPattern);
         }
     }
 }
Exemple #6
0
        /// <summary>
        /// Prepares to populate the children of the assembly test on demand by
        /// adding a deferred populator with <see cref="IPatternScope.AddDeferredComponentPopulator" />.
        /// </summary>
        /// <param name="assemblyScope">The assembly scope.</param>
        /// <param name="assembly">The assembly.</param>
        protected virtual void PrepareToPopulateChildrenOnDemand(IPatternScope assemblyScope, IAssemblyInfo assembly)
        {
            var populatedTypes = new GallioHashSet <ITypeInfo>();

            assemblyScope.AddDeferredComponentPopulator(childCodeElementHint =>
            {
                ITypeInfo type = childCodeElementHint as ITypeInfo;
                if (type != null && !type.IsNested && !populatedTypes.Contains(type) && assembly.Equals(type.Assembly))
                {
                    populatedTypes.Add(type);
                    assemblyScope.Consume(type, false, DefaultTypePattern);
                }
            });
        }
        /// <summary>
        /// Initializes a test for a method after it has been added to the test model.
        /// </summary>
        /// <param name="methodScope">The method scope.</param>
        /// <param name="method">The method.</param>
        protected virtual void InitializeTest(IPatternScope methodScope, IMethodInfo method)
        {
            string xmlDocumentation = method.GetXmlDocumentation();

            if (xmlDocumentation != null)
            {
                methodScope.TestBuilder.AddMetadata(MetadataKeys.XmlDocumentation, xmlDocumentation);
            }

            methodScope.Process(method);

            if (method.IsGenericMethodDefinition)
            {
                foreach (IGenericParameterInfo parameter in method.GenericArguments)
                {
                    methodScope.Consume(parameter, false, DefaultGenericParameterPattern);
                }
            }

            foreach (IParameterInfo parameter in method.Parameters)
            {
                methodScope.Consume(parameter, false, DefaultMethodParameterPattern);
            }
        }
Exemple #8
0
        /// <summary>
        /// Initializes the <see cref="PatternTestDataContext" />.
        /// </summary>
        /// <param name="dataContextScope">The data context scope.</param>
        /// <param name="constructor">The constructor.</param>
        protected virtual void InitializeDataContext(IPatternScope dataContextScope, IConstructorInfo constructor)
        {
            ITypeInfo declaringType = constructor.DeclaringType;

            if (declaringType.IsGenericTypeDefinition)
            {
                dataContextScope.TestDataContextBuilder.ImplicitDataBindingIndexOffset = declaringType.GenericArguments.Count;
            }

            foreach (IParameterInfo parameter in constructor.Parameters)
            {
                dataContextScope.Consume(parameter, false, DefaultConstructorParameterPattern);
            }

            dataContextScope.Process(constructor);
        }
        private bool BuildAssemblyTest(IAssemblyInfo assembly, bool skipChildren)
        {
            bool fullyPopulated;

            if (assemblies.TryGetValue(assembly, out fullyPopulated))
            {
                return(fullyPopulated);
            }

            IList <PatternTestFrameworkExtensionInfo> extensions = extensionProvider(assembly);

            if (extensions.Count == 0)
            {
                fullyPopulated = true;
            }

            assemblies.Add(assembly, fullyPopulated);

            if (!fullyPopulated)
            {
                IPatternScope rootScope = evaluator.RootScope;

                InitializeAssembly(rootScope, assembly);

                rootScope.Consume(assembly, skipChildren, TestAssemblyPatternAttribute.DefaultInstance);

                foreach (PatternTest assemblyTest in evaluator.GetDeclaredTests(assembly))
                {
                    if (extensions.Count == 1 && assemblyTest.Kind == TestKinds.Assembly)
                    {
                        assemblyTest.Kind = extensions[0].AssemblyKind;
                    }

                    foreach (var extension in extensions)
                    {
                        assemblyTest.Metadata.Add(MetadataKeys.Framework, extension.Name);
                    }
                }
            }

            return(fullyPopulated);
        }
        /// <summary>
        /// Initializes a test for a type after it has been added to the test model.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The members of base types are processed before those of subtypes.
        /// </para>
        /// <para>
        /// The default implementation processes all public members of the type including
        /// the first constructor found, then recurses to process all public and non-public
        /// nested types.  Non-public members other than nested types are ignored.
        /// </para>
        /// </remarks>
        /// <param name="typeScope">The type scope.</param>
        /// <param name="type">The type.</param>
        protected virtual void InitializeTest(IPatternScope typeScope, ITypeInfo type)
        {
            string xmlDocumentation = type.GetXmlDocumentation();

            if (xmlDocumentation != null)
            {
                typeScope.TestBuilder.AddMetadata(MetadataKeys.XmlDocumentation, xmlDocumentation);
            }

            typeScope.Process(type);

            if (type.IsGenericTypeDefinition)
            {
                foreach (IGenericParameterInfo parameter in type.GenericArguments)
                {
                    typeScope.Consume(parameter, false, DefaultGenericParameterPattern);
                }
            }

            ConsumeMembers(typeScope, type);
            ConsumeConstructors(typeScope, type);
            ConsumeNestedTypes(typeScope, type);
        }
        /// <summary>
        /// Initializes a test for a method after it has been added to the test model.
        /// </summary>
        /// <param name="methodScope">The method scope.</param>
        /// <param name="method">The method.</param>
        protected virtual void InitializeTest(IPatternScope methodScope, IMethodInfo method)
        {
            string xmlDocumentation = method.GetXmlDocumentation();
            if (xmlDocumentation != null)
                methodScope.TestBuilder.AddMetadata(MetadataKeys.XmlDocumentation, xmlDocumentation);

            methodScope.Process(method);

            if (method.IsGenericMethodDefinition)
            {
                foreach (IGenericParameterInfo parameter in method.GenericArguments)
                    methodScope.Consume(parameter, false, DefaultGenericParameterPattern);
            }

            foreach (IParameterInfo parameter in method.Parameters)
                methodScope.Consume(parameter, false, DefaultMethodParameterPattern);
        }
        /// <summary>
        /// Initializes the <see cref="PatternTestDataContext" />.
        /// </summary>
        /// <param name="dataContextScope">The data context scope.</param>
        /// <param name="constructor">The constructor.</param>
        protected virtual void InitializeDataContext(IPatternScope dataContextScope, IConstructorInfo constructor)
        {
            ITypeInfo declaringType = constructor.DeclaringType;
            if (declaringType.IsGenericTypeDefinition)
                dataContextScope.TestDataContextBuilder.ImplicitDataBindingIndexOffset = declaringType.GenericArguments.Count;

            foreach (IParameterInfo parameter in constructor.Parameters)
                dataContextScope.Consume(parameter, false, DefaultConstructorParameterPattern);

            dataContextScope.Process(constructor);
        }
 /// <summary>
 /// Prepares to populate the children of the assembly test on demand by
 /// adding a deferred populator with <see cref="IPatternScope.AddDeferredComponentPopulator" />.
 /// </summary>
 /// <param name="assemblyScope">The assembly scope.</param>
 /// <param name="assembly">The assembly.</param>
 protected virtual void PrepareToPopulateChildrenOnDemand(IPatternScope assemblyScope, IAssemblyInfo assembly)
 {
     var populatedTypes = new HashSet<ITypeInfo>();
     assemblyScope.AddDeferredComponentPopulator(childCodeElementHint =>
     {
         ITypeInfo type = childCodeElementHint as ITypeInfo;
         if (type != null && ! type.IsNested && !populatedTypes.Contains(type) && assembly.Equals(type.Assembly))
         {
             populatedTypes.Add(type);
             assemblyScope.Consume(type, false, DefaultTypePattern);
         }
     });
 }
 /// <summary>
 /// Populates the children of the assembly test all at once.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The default implementation processes all public and non-public types within the assembly.
 /// </para>
 /// </remarks>
 /// <param name="assemblyScope">The assembly scope.</param>
 /// <param name="assembly">The assembly.</param>
 protected virtual void PopulateChildrenImmediately(IPatternScope assemblyScope, IAssemblyInfo assembly)
 {
     foreach (ITypeInfo type in assembly.GetTypes())
     {
         if (!type.IsNested)
             assemblyScope.Consume(type, false, DefaultTypePattern);
     }
 }