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)); } }); }); }
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); }); }