private Type ValidateGeneratedEnum(Type serverEnumType, AssemblyGenerator asmGen) { Type clientEnumType = asmGen.GetGeneratedType(serverEnumType.FullName); Assert.IsNotNull(clientEnumType, "Expected to see generated " + serverEnumType + " but saw " + asmGen.GeneratedTypeNames); // validate the enum integral type is the same Type serverUnderlyingType = serverEnumType.GetEnumUnderlyingType(); Type clientUnderlyingType = clientEnumType.GetEnumUnderlyingType(); Assert.AreEqual(serverUnderlyingType.FullName, clientUnderlyingType.FullName, "Mismatch in server enum type's underlying type and generated form"); DataContractAttribute serverDCAttr = (DataContractAttribute)Attribute.GetCustomAttribute(serverEnumType, typeof(DataContractAttribute)); if (serverDCAttr != null) { IList <CustomAttributeData> cads = AssemblyGenerator.GetCustomAttributeData(clientEnumType, typeof(DataContractAttribute)); Assert.AreEqual(1, cads.Count, "Expected DataContract on " + clientEnumType); CustomAttributeData cad = cads[0]; string serverAttrName = serverDCAttr.Name; string serverAttrNamespace = serverDCAttr.Namespace; string clientAttrName = AssemblyGenerator.GetCustomAttributeValue <string>(cad, "Name"); string clientAttrNamespace = AssemblyGenerator.GetCustomAttributeValue <string>(cad, "Namespace"); Assert.AreEqual(serverAttrName, clientAttrName, "Expected DC.Name to be the same on " + clientEnumType); Assert.AreEqual(serverAttrNamespace, clientAttrNamespace, "Expected DC.Namespace to be the same on " + clientEnumType); } string[] serverMemberNames = Enum.GetNames(serverEnumType); string[] clientMemberNames = Enum.GetNames(clientEnumType); Assert.AreEqual(serverMemberNames.Length, clientMemberNames.Length, "Different number of fields generated"); for (int i = 0; i < serverMemberNames.Length; ++i) { Assert.AreEqual(serverMemberNames[i], clientMemberNames[i], "Member name difference"); // We have to use GetRawConstantValue because the ReflectionOnlyLoad does not support Enum.GetValues FieldInfo serverFieldInfo = serverEnumType.GetField(serverMemberNames[i]); Assert.IsNotNull(serverFieldInfo, "Failed to find server's " + serverMemberNames[i] + " as field info"); object serverMemberValue = serverFieldInfo.GetRawConstantValue(); FieldInfo clientFieldInfo = clientEnumType.GetField(clientMemberNames[i]); Assert.IsNotNull(clientFieldInfo, "Failed to find client's " + clientMemberNames[i] + " as field info"); object clientMemberValue = clientFieldInfo.GetRawConstantValue(); Assert.AreEqual(serverMemberValue, clientMemberValue, "Different values for field " + serverMemberNames[i]); EnumMemberAttribute enumMemberAttr = (EnumMemberAttribute)Attribute.GetCustomAttribute(serverFieldInfo, typeof(EnumMemberAttribute)); if (enumMemberAttr != null) { IList <CustomAttributeData> cads = AssemblyGenerator.GetCustomAttributeData(clientFieldInfo, typeof(EnumMemberAttribute)); Assert.AreEqual(1, cads.Count, "Expected EnumMember on " + clientEnumType + "." + clientMemberNames[i]); CustomAttributeData cad = cads[0]; string clientValue = null; AssemblyGenerator.TryGetCustomAttributeValue <string>(cad, "Value", out clientValue); string serverValue = enumMemberAttr.Value; Assert.AreEqual(serverValue, clientValue, "EnumMember had different values for Value arg for " + clientEnumType + "." + clientMemberNames[i]); } // Validate Display custom attribute propagates correctly DisplayAttribute displayAttr = (DisplayAttribute)Attribute.GetCustomAttribute(serverFieldInfo, typeof(DisplayAttribute)); if (displayAttr != null) { IList <CustomAttributeData> cads = AssemblyGenerator.GetCustomAttributeData(clientFieldInfo, typeof(DisplayAttribute)); Assert.AreEqual(1, cads.Count, "Expected [Display] on " + clientEnumType + "." + clientMemberNames[i]); CustomAttributeData cad = cads[0]; string clientValue = null; AssemblyGenerator.TryGetCustomAttributeValue <string>(cad, "Name", out clientValue); string serverValue = displayAttr.Name; Assert.AreEqual(serverValue, clientValue, "[Display] had different values for Name arg for " + clientEnumType + "." + clientMemberNames[i]); } // Validate Description custom attribute propagates correctly ComponentModelDescriptionAttribute descriptionAttr = (ComponentModelDescriptionAttribute)Attribute.GetCustomAttribute(serverFieldInfo, typeof(ComponentModelDescriptionAttribute)); if (descriptionAttr != null) { IList <CustomAttributeData> cads = AssemblyGenerator.GetCustomAttributeData(clientFieldInfo, typeof(ComponentModelDescriptionAttribute)); Assert.AreEqual(1, cads.Count, "Expected [Description] on " + clientEnumType + "." + clientMemberNames[i]); CustomAttributeData cad = cads[0]; string clientValue = null; AssemblyGenerator.TryGetCustomAttributeValue <string>(cad, "Description", out clientValue); string serverValue = descriptionAttr.Description; Assert.AreEqual(serverValue, clientValue, "[Description] had different values for Description arg for " + clientEnumType + "." + clientMemberNames[i]); } // Validate ServerOnlyAttribute does not propagate ServerOnlyAttribute serverOnlyAttr = (ServerOnlyAttribute)Attribute.GetCustomAttribute(serverFieldInfo, typeof(ServerOnlyAttribute)); if (serverOnlyAttr != null) { IList <CustomAttributeData> cads = AssemblyGenerator.GetCustomAttributeData(clientFieldInfo, typeof(ServerOnlyAttribute)); Assert.AreEqual(0, cads.Count, "Expected [ServerOnlyAttribute] *not* to be generated on " + clientEnumType + "." + clientMemberNames[i]); } } bool serverHasFlags = serverEnumType.GetCustomAttributes(false).OfType <FlagsAttribute>().Any(); // Have to use CustomAttributeData due to ReflectionOnly load IList <CustomAttributeData> clientFlagsAttributes = AssemblyGenerator.GetCustomAttributeData(clientEnumType, typeof(FlagsAttribute)); bool clientHasFlags = clientFlagsAttributes.Any(); Assert.AreEqual(serverHasFlags, clientHasFlags, "Server and client differ in appearance of [Flags]"); return(clientEnumType); }
private void VerifyEnumGenBasic(AssemblyGenerator asmGen) { // Force this type to be shared to force failure asmGen.MockSharedCodeService.AddSharedType(typeof(System.IO.FileAttributes)); string generatedCode = asmGen.GeneratedCode; Assert.IsFalse(string.IsNullOrEmpty(generatedCode), "Failed to generate code:\r\n" + asmGen.ConsoleLogger.Errors); Assembly assy = asmGen.GeneratedAssembly; Assert.IsNotNull(assy, "Assembly failed to build: " + asmGen.ConsoleLogger.Errors); TestHelper.AssertNoErrorsOrWarnings(asmGen.ConsoleLogger); // ------------------------------------------------------ // Check the properties using enums were handled properly // ------------------------------------------------------ Type clientEntityType = asmGen.GetGeneratedType(typeof(Enum_Basic_Entity).FullName); Assert.IsNotNull(clientEntityType, "Expected entity of type " + typeof(Enum_Basic_Entity)); // Validate normal enum is generated this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "SizeProperty", typeof(SizeEnum), asmGen, /* expectNullable */ false); // Validate 2nd appearance of same enum is generated and does not gen 2nd decl of entity type (would fail compile) this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "SizeProperty2", typeof(SizeEnum), asmGen, /* expectNullable */ false); // Validate nullable form of same enum is generated and does not gen 2nd decl of entity type (would fail compile) this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "NullableSizeProperty", typeof(SizeEnum), asmGen, /* expectNullable */ true); // Validate nullable form of an enum *that is the only use of that enum type* generates the enum type // Regression test for 819356. this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "NullableOnlySizeProperty", typeof(SizeEnumNullableOnly), asmGen, /* expectNullable */ true); // Validate all integral forms of enum this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "SByteEnumProp", typeof(SByteEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "ByteEnumProp", typeof(ByteEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "ShortEnumProp", typeof(ShortEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "UShortEnumProp", typeof(UShortEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "IntEnumProp", typeof(IntEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "UIntEnumProp", typeof(UIntEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "LongEnumProp", typeof(LongEnum), asmGen, /* expectNullable */ false); this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "ULongEnumProp", typeof(ULongEnum), asmGen, /* expectNullable */ false); // Validate an enum with custom attributes on fields generates properly this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "CustomAttributeEnumProp", typeof(EnumWithCustomAttributes), asmGen, /* expectNullable */ false); // Validate an enum from another namespace propagates this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "SizePropertyOther", typeof(SizeEnumOther), asmGen, /* expectNullable */ false); // Validate a [Flags] enum propagates [Flags] this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "FlagProperty", typeof(FlagEnum), asmGen, /* expectNullable */ false); // DataContract enum was propagated this.ValidateGeneratedEnumProperty(typeof(Enum_Basic_Entity), "DCEnumProp", typeof(DataContractEnum), asmGen, /* expectNullable */ false); // Non-public property should not force enum to gen PropertyInfo propertyInfo = clientEntityType.GetProperty("SizePropertyNoGen"); Assert.IsNull(propertyInfo, "The property SizePropertyNoGen should not have been generated because the property was not public."); Type clientEnumType = asmGen.GetGeneratedType(typeof(SizeEnumNoGen).FullName); Assert.IsNull(clientEnumType, "The SizeEnumNoGen type should not have been generated because only a private property exposed it."); // Non-public enum should not gen propertyInfo = clientEntityType.GetProperty("PrivateEnumProperty"); Assert.IsNull(propertyInfo, "The property PrivateEnumProperty should not have been generated because the enum was not public."); clientEnumType = asmGen.GetGeneratedType(typeof(PrivateEnum).FullName); Assert.IsNull(clientEnumType, "The PrivateEnum type should not have been generated because it was not public."); // Shared System enum was used but not propagated propertyInfo = clientEntityType.GetProperty("FileAttrProp"); Assert.IsNotNull(propertyInfo, "The property FileAttrProp should have been generated because the enum was shared."); Assert.AreEqual(typeof(FileAttributes).FullName, propertyInfo.PropertyType.FullName, "Expected FileAttrProp to use FileAttributes"); // ----------------------------------------- // Check DomainContext was generated with property custom method and invoke method // ----------------------------------------- Type domainContextType = asmGen.GetGeneratedType("EnumGen.Tests.Enum_Basic_DomainContext"); Assert.IsNotNull(domainContextType, "Expected to find domain context: EnumGen.Tests.Enum_Basic_DomainContext:\r\n" + asmGen.GeneratedTypeNames); // ------------------- // Query method // ------------------- // query method with enum arg should have generated that enum type clientEnumType = this.ValidateGeneratedEnum(typeof(QueryEnumArg), asmGen); // Query method should have been generated MethodInfo methodInfo = domainContextType.GetMethod("GetEntityWithEnumQuery"); Assert.IsNotNull(methodInfo, "Expected to find query method called GetEntityWithEnumQuery"); ParameterInfo[] parameters = methodInfo.GetParameters(); Assert.AreEqual(1, parameters.Length, "Expected query method to have 1 parameter"); this.ValidateGeneratedEnumReference(clientEnumType, parameters[0].ParameterType, /* expectNullable */ false); // Nullable form of query methodInfo = domainContextType.GetMethod("GetEntityWithNullableEnumQuery"); Assert.IsNotNull(methodInfo, "Expected to find query method called GetEntityWithNullableEnumQuery"); parameters = methodInfo.GetParameters(); Assert.AreEqual(1, parameters.Length, "Expected query method to have 1 parameter"); this.ValidateGeneratedEnumReference(clientEnumType, parameters[0].ParameterType, /* expectNullable */ true); // ------------------- // Named update method // ------------------- // Named update method with enum arg should have generated that enum type clientEnumType = this.ValidateGeneratedEnum(typeof(NamedEnumArg), asmGen); // Named update method should have been generated methodInfo = domainContextType.GetMethod("EnumNamedUpate"); Assert.IsNotNull(methodInfo, "Expected to find named update method called EnumNamedUpdate"); parameters = methodInfo.GetParameters(); Assert.AreEqual(2, parameters.Length, "Expected named update method to have 2 parameters"); this.ValidateGeneratedEnumReference(clientEnumType, parameters[1].ParameterType, /* expectNullable */ false); // Nullable form of named update method should have been generated methodInfo = domainContextType.GetMethod("EnumNamedUpateNullable"); Assert.IsNotNull(methodInfo, "Expected to find named update method called EnumNamedUpdateNullable"); parameters = methodInfo.GetParameters(); Assert.AreEqual(2, parameters.Length, "Expected named update method to have 2 parameters"); this.ValidateGeneratedEnumReference(clientEnumType, parameters[1].ParameterType, /* expectNullable */ true); // ------------------- // Invoke method // ------------------- // Should have generated the enum for the return and for its parameters Type invokeEnumRetType = this.ValidateGeneratedEnum(typeof(InvokeEnumRet), asmGen); Type invokeEnumArgType = this.ValidateGeneratedEnum(typeof(InvokeEnumArg), asmGen); // Should have generated our invoke signature methodInfo = domainContextType.GetMethod("EnumServiceOp", new Type[] { invokeEnumArgType }); Assert.IsNotNull(methodInfo, "Expected service op for EnumServiceOp"); Type returnType = methodInfo.ReturnType; Assert.IsTrue(returnType.IsGenericType, "Expected EnumServiceOp return type to be generic"); Type genericType = returnType.GetGenericArguments()[0]; Assert.AreEqual(invokeEnumRetType, genericType, "Expected EnumServiceOp<T> generic return type to be enum type"); // Should have generated our nullable enum invoke signature methodInfo = domainContextType.GetMethod("EnumServiceOpNullable", new Type[] { invokeEnumArgType }); Assert.IsNotNull(methodInfo, "Expected service op for EnumServiceOpNullable"); returnType = methodInfo.ReturnType; Assert.IsTrue(returnType.IsGenericType, "Expected EnumServiceOp return type to be generic"); genericType = returnType.GetGenericArguments()[0]; this.ValidateGeneratedEnumReference(invokeEnumRetType, genericType, /* expectNullable */ true); }