public void NonReadOnlyValidation()
        {
            Type[] types = new Type[] {
                // cannot add service operation, since the parameters collection is passed in the constructor and is always cached.
                typeof(ResourceSet),
                typeof(ResourceType),
                typeof(ResourceProperty),
                typeof(ServiceOperationParameter)
            };

            AstoriaTestNS.TestUtil.RunCombinations(
                types,
                (t) =>
            {
                object instance = ResourceTypeUtils.GetTestInstance(t);

                // Make sure exception is throw if any of the public setters are called
                AstoriaTestNS.TestUtil.RunCombinations(
                    t.GetProperties(BindingFlags.Instance | BindingFlags.Public),
                    (propertyInfo) =>
                {
                    //Ignoring custom state, since its not governed by part of readonly
                    if (propertyInfo.Name == "CustomState")
                    {
                        return;
                    }

                    // call the getter twice and make sure they return the same instance for reference types i.e. caching takes place.
                    MethodInfo getter = propertyInfo.GetGetMethod();
                    if (getter != null && typeof(IList).IsAssignableFrom(propertyInfo.PropertyType))
                    {
                        object value1 = getter.Invoke(instance, null);
                        object value2 = getter.Invoke(instance, null);
                        Assert.IsTrue(!Object.ReferenceEquals(value1, value2), String.Format("For non-readonly types, the collection properties should not return the same instance. Property: {0}", propertyInfo.Name));
                    }
                });
            });
        }
示例#2
0
        public void InvalidCasesTest()
        {
            ResourceType rt = (ResourceType)ResourceTypeUtils.GetTestInstance(typeof(ResourceType));

            ResourceType complexType = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "Namespace", "Address", false);
            ResourceType entityType  = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Namespace", "Order", false);
            ResourceType primitiveOrComplexCollectionType = ResourceType.GetCollectionResourceType(complexType);
            ResourceType entityCollectionType             = ResourceType.GetEntityCollectionResourceType(entityType);
            ResourceType namedStreamType = ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream));

            AstoriaTestNS.TestUtil.RunCombinations(
                GetPropertyKindValues(),
                new ResourceType[] { entityType, complexType, primitiveOrComplexCollectionType, entityCollectionType }.Concat(ResourceTypeUtils.GetPrimitiveResourceTypes()),
                (kind, type) =>
            {
                bool invalidCase = true;

                if (IsValidValue(kind))
                {
                    if ((kind.HasFlag(ResourcePropertyKind.Primitive) && type.ResourceTypeKind == ResourceTypeKind.Primitive && type != namedStreamType) ||
                        (kind.HasFlag(ResourcePropertyKind.ComplexType) && type.ResourceTypeKind == ResourceTypeKind.ComplexType) ||
                        (kind.HasFlag(ResourcePropertyKind.ResourceReference) && type.ResourceTypeKind == ResourceTypeKind.EntityType) ||
                        (kind.HasFlag(ResourcePropertyKind.ResourceSetReference) && type.ResourceTypeKind == ResourceTypeKind.EntityType) ||
                        (kind.HasFlag(ResourcePropertyKind.Collection) && type.ResourceTypeKind == ResourceTypeKind.Collection) ||
                        (kind.HasFlag(ResourcePropertyKind.Stream) && type == namedStreamType))
                    {
                        invalidCase = false;
                    }

                    if ((kind & ResourcePropertyKind.Key) == ResourcePropertyKind.Key &&
                        type.InstanceType.IsGenericType && type.InstanceType.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        invalidCase = true;
                    }
                }

                if (invalidCase)
                {
                    ExceptionUtils.ThrowsException <ArgumentException>(
                        () => new ResourceProperty("TestProperty", kind, type),
                        string.Format("resource property constructor test case. Kind: '{0}', Type: '{1}: {2}'", kind, type.ResourceTypeKind, type.InstanceType));
                }
                else
                {
                    ResourceProperty p = new ResourceProperty("TestProperty", kind, type);
                    Assert.AreEqual("TestProperty", p.Name, "Name was not stored properly");
                    Assert.AreEqual(kind, p.Kind, "Kind was not stored properly");
                    Assert.AreEqual(type, p.ResourceType, "Type was not stored properly");
                    Assert.AreEqual(p.Kind.HasFlag(ResourcePropertyKind.Stream) ? false : true, p.CanReflectOnInstanceTypeProperty, "CanReflectOnInstanceTypeProperty should be true by default on non-NamedStreams, and false on NamedStreams.");
                    Assert.IsNull(p.MimeType, "MimeType should be null by default.");

                    if (p.Kind.HasFlag(ResourcePropertyKind.Stream))
                    {
                        ExceptionUtils.ThrowsException <InvalidOperationException>(
                            () => { p.CanReflectOnInstanceTypeProperty = false; },
                            "CanReflectOnInstanceTypeProperty should be settable on non-namedstreams, and not settable on namedstreams");
                    }
                    else
                    {
                        p.CanReflectOnInstanceTypeProperty = false;
                    }

                    Assert.AreEqual(false, p.CanReflectOnInstanceTypeProperty, "CanReflectOnInstanceTypeProperty should be false.");

                    bool shouldFail = true;
                    if ((kind & ResourcePropertyKind.Primitive) == ResourcePropertyKind.Primitive)
                    {
                        shouldFail = false;
                    }

                    if (shouldFail)
                    {
                        ExceptionUtils.ThrowsException <InvalidOperationException>(
                            () => p.MimeType = "plain/text",
                            string.Format("Setting MimeType on non-primitive property should fail. Kind: '{0}', Type: '{1}: {2}'", kind, type.ResourceTypeKind, type.InstanceType));
                    }
                    else
                    {
                        p.MimeType = "plain/text";
                    }
                }
            });
        }
        public void ReadOnlyValidationTest()
        {
            Type[] types = new Type[] {
                typeof(ResourceSet),
                typeof(ResourceType),
                typeof(ResourceProperty),
                typeof(ServiceOperation),
                typeof(ServiceOperationParameter)
            };

            Dictionary <Type, object> values = new Dictionary <Type, object>();

            values.Add(typeof(string), "foo");
            values.Add(typeof(bool), true);

            AstoriaTestNS.TestUtil.RunCombinations(
                types,
                (t) =>
            {
                object instance = ResourceTypeUtils.GetTestInstance(t);

                bool isReadOnly = (bool)ReflectionUtils.GetProperty(instance, "IsReadOnly");
                Assert.IsTrue(!isReadOnly, "If the type is not set to readonly yet, the IsReadOnly property should return false");

                // Make it readonly
                ReflectionUtils.InvokeMethod(instance, "SetReadOnly");

                isReadOnly = (bool)ReflectionUtils.GetProperty(instance, "IsReadOnly");
                Assert.IsTrue(isReadOnly, "Once the type is set to readonly, the readonly method should return true");

                // Make sure exception is throw if any of the public setters are called
                AstoriaTestNS.TestUtil.RunCombinations(
                    t.GetProperties(BindingFlags.Instance | BindingFlags.Public),
                    (propertyInfo) =>
                {
                    //Ignoring custom state, since its not governed by part of readonly
                    if (propertyInfo.Name == "CustomState")
                    {
                        return;
                    }

                    MethodInfo setter = propertyInfo.GetSetMethod();
                    if (setter != null)
                    {
                        try
                        {
                            setter.Invoke(instance, new object[] { values[propertyInfo.PropertyType] });
                            Assert.Fail(String.Format("Public properties cannot be modified after the type is set to ReadOnly. Property '{0}' did not throw", propertyInfo.Name));
                        }
                        catch (TargetInvocationException e)
                        {
                            Assert.IsTrue(e.InnerException is InvalidOperationException, "Expecting invalid operation exception");
                            Assert.IsTrue(e.InnerException.Message.Contains("cannot be modified since it is already set to read-only."), String.Format("Expecting a message with read-only in it. Actual: '{0}'", e.InnerException.Message));
                        }
                    }

                    // call the getter twice and make sure they return the same instance for reference types i.e. caching takes place.
                    MethodInfo getter = propertyInfo.GetGetMethod();
                    if (getter != null && !propertyInfo.PropertyType.IsValueType)
                    {
                        object value1 = getter.Invoke(instance, null);
                        object value2 = getter.Invoke(instance, null);
                        Assert.IsTrue(Object.ReferenceEquals(value1, value2), String.Format("For Readonly types, the reference type properties should return the same instance. Property: {0}", propertyInfo.Name));
                    }
                });

                // make sure the custom state property can be set even after the type is set to readonly
                string state = "foo";
                ReflectionUtils.SetProperty(instance, "CustomState", state);
                Assert.AreSame(state, ReflectionUtils.GetProperty(instance, "CustomState"), "custom state should be modified");

                // make sure calling SetReadOnly again is a no-op
                t.GetMethod("SetReadOnly", BindingFlags.Public | BindingFlags.Instance).Invoke(instance, null);
            });
        }