public void CodeGen_CustomAttrGen_Attribute_References_Type_NotShared() { ConsoleLogger logger = new ConsoleLogger(); // Create a shared type service that says the entity's attribute is "shared" when asked whether it is shared MockSharedCodeService mockSts = new MockSharedCodeService( new Type[] { typeof(Mock_CG_Attr_Gen_TestAttribute) }, new MethodBase[0], new string[0]); // Explicitly make the typeof() ref in the attribute say it is unshared mockSts.AddUnsharedType(typeof(Mock_CG_Attr_Gen_Type)); string generatedCode = TestHelper.GenerateCode("C#", new Type[] { typeof(Mock_CG_Attr_Gen_Entity) }, logger, mockSts); TestHelper.AssertNoErrorsOrWarnings(logger); string warningComment = string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_RequiresShared, typeof(Mock_CG_Attr_Gen_TestAttribute), "MockProject"); TestHelper.AssertGeneratedCodeContains(generatedCode, "[Mock_CG_Attr_Gen_Test(typeof(global::Luma.SimpleEntity.Tests.Mock_CG_Attr_Gen_Type))]"); }
public void CodeGen_CustomAttrGen_AttributeType_Shared_Unknowable() { var logger = new ConsoleLogger(); // Create a shared type service that says the entity's attribute is "unknowable" when asked whether it is shared var mockSts = new MockSharedCodeService( new Type[] { typeof(Mock_CG_Attr_Gen_Type) }, new MethodBase[0], new string[0]); mockSts.AddUnknowableType(typeof(Mock_CG_Attr_Gen_TestAttribute)); var generatedCode = TestHelper.GenerateCode("C#", new[] { typeof(Mock_CG_Attr_Gen_Entity) }, logger, mockSts); TestHelper.AssertNoErrorsOrWarnings(logger); var warningComment = string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_RequiresShared_NoPDB, typeof(Mock_CG_Attr_Gen_TestAttribute), typeof(Mock_CG_Attr_Gen_TestAttribute).Assembly.GetName().Name, "MockProject"); // CodeDom injects comments after line breaks warningComment = warningComment.Replace("\r\n ", "\r\n // "); TestHelper.AssertGeneratedCodeContains(generatedCode, warningComment); }
public void SharedCodeService_Methods() { string projectPath, outputPath; TestHelper.GetProjectPaths("STS4", out projectPath, out outputPath); var clientProjectPath = CodeGenHelper.ClientClassLibProjectPath(projectPath); var logger = new ConsoleLogger(); using (var scs = CodeGenHelper.CreateSharedCodeService(clientProjectPath, logger)) { CodeMemberShareKind shareKind = scs.GetMethodShareKind(typeof(TestValidator).AssemblyQualifiedName, "IsValid", new string[] { typeof(TestEntity).AssemblyQualifiedName, typeof(ValidationContext).AssemblyQualifiedName }); Assert.AreEqual(CodeMemberShareKind.SharedByReference, shareKind, "Expected TestValidator.IsValid to be shared by reference"); shareKind = scs.GetMethodShareKind(typeof(TestEntity).AssemblyQualifiedName, "ServerAndClientMethod", new string[0]); Assert.AreEqual(CodeMemberShareKind.SharedByReference, shareKind, "Expected TestValidator.ServerAndClientMethod to be shared by reference"); shareKind = scs.GetMethodShareKind(typeof(TestEntity).AssemblyQualifiedName, "ServerMethod", new string[0]); Assert.AreEqual(CodeMemberShareKind.NotShared, shareKind, "Expected TestValidator.ServerMethod not to be shared"); shareKind = scs.GetMethodShareKind(typeof(TestValidatorServer).AssemblyQualifiedName, "IsValid", new string[] { typeof(TestEntity).AssemblyQualifiedName, typeof(ValidationContext).AssemblyQualifiedName }); Assert.AreEqual(CodeMemberShareKind.NotShared, shareKind, "Expected TestValidator.IsValid not to be shared"); TestHelper.AssertNoErrorsOrWarnings(logger); } }
public void CodeGen_Attribute_CustomValidation_UnsharedValidator() { ConsoleLogger logger = new ConsoleLogger(); string generatedCode = TestHelper.GenerateCode("C#", typeof(UnsharedValidatorTestEntity), logger); TestHelper.AssertNoErrorsOrWarnings(logger); Assert.IsFalse(string.IsNullOrEmpty(generatedCode), "Expected generated code"); TestHelper.AssertGeneratedCodeDoesNotContain(generatedCode, "typeof(UnsharedValidator)"); }
public void SharedCodeService_Ctors() { string projectPath = null; string outputPath = null; TestHelper.GetProjectPaths("STS5", out projectPath, out outputPath); string clientProjectPath = CodeGenHelper.ClientClassLibProjectPath(projectPath); ConsoleLogger logger = new ConsoleLogger(); using (SharedCodeService sts = CodeGenHelper.CreateSharedCodeService(clientProjectPath, logger)) { ConstructorInfo ctor = typeof(TestValidator).GetConstructor(new Type[] { typeof(string) }); Assert.IsNotNull("Failed to find string ctor on TestValidator"); CodeMemberShareKind shareKind = sts.GetMethodShareKind(typeof(TestValidator).AssemblyQualifiedName, ctor.Name, new string[] { typeof(string).AssemblyQualifiedName }); Assert.AreEqual(CodeMemberShareKind.SharedByReference, shareKind, "Expected TestValidator ctor to be shared by reference"); TestHelper.AssertNoErrorsOrWarnings(logger); } }
public void SharedAssemblies_Methods() { string projectPath, outputPath; TestHelper.GetProjectPaths("SAT", out projectPath, out outputPath); var clientProjectPath = CodeGenHelper.ClientClassLibProjectPath(projectPath); var assemblies = CodeGenHelper.ClientClassLibReferences(clientProjectPath, true); var logger = new ConsoleLogger(); var sa = new SharedAssemblies(assemblies, Enumerable.Empty<string>(), logger); var sharedMethod = sa.GetSharedMethod(typeof(TestValidator).AssemblyQualifiedName, "IsValid", new[] { typeof(TestEntity).AssemblyQualifiedName, typeof(ValidationContext).AssemblyQualifiedName }); Assert.IsNotNull(sharedMethod, "Expected TestValidator.IsValid to be shared"); Assert.IsTrue(sharedMethod.DeclaringType.Assembly.Location.Contains("ClientClassLib"), "Expected to find method in client class lib"); sharedMethod = sa.GetSharedMethod(typeof(TestEntity).AssemblyQualifiedName, "ServerAndClientMethod", new string[0]); Assert.IsNotNull(sharedMethod, "Expected TestEntity.ServerAndClientMethod to be shared"); Assert.IsTrue(sharedMethod.DeclaringType.Assembly.Location.Contains("ClientClassLib"), "Expected to find method in client class lib"); sharedMethod = sa.GetSharedMethod(typeof(TestValidator).AssemblyQualifiedName, "ServertMethod", new string[0]); Assert.IsNull(sharedMethod, "Expected TestValidator.ServerMethod not to be shared"); TestHelper.AssertNoErrorsOrWarnings(logger); }
public void SharedAssemblies_Types() { string projectPath = null; string outputPath = null; TestHelper.GetProjectPaths("SAT", out projectPath, out outputPath); string clientProjectPath = CodeGenHelper.ClientClassLibProjectPath(projectPath); List<string> assemblies = CodeGenHelper.ClientClassLibReferences(clientProjectPath, true); var logger = new ConsoleLogger(); var sa = new SharedAssemblies(assemblies, Enumerable.Empty<string>(), logger); Type sharedType = sa.GetSharedType(typeof(TestEntity).AssemblyQualifiedName); Assert.IsNotNull(sharedType, "Expected TestEntity type to be shared"); Assert.IsTrue(sharedType.Assembly.Location.Contains("ClientClassLib"), "Expected to find type in client class lib"); sharedType = sa.GetSharedType(typeof(TestValidator).AssemblyQualifiedName); Assert.IsNotNull(sharedType, "Expected TestValidator type to be shared"); Assert.IsTrue(sharedType.Assembly.Location.Contains("ClientClassLib"), "Expected to find type in client class lib"); sharedType = sa.GetSharedType(typeof(TestValidatorServer).AssemblyQualifiedName); Assert.IsNull(sharedType, "Expected TestValidatorServer type not to be shared"); TestHelper.AssertNoErrorsOrWarnings(logger); }
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("DateTimeKindProp"); Assert.IsNotNull(propertyInfo, "The property DateTimeKindProp should have been generated because the enum was shared."); Assert.AreEqual(typeof(DateTimeKind).FullName, propertyInfo.PropertyType.FullName, "Expected DateTimeKindProp to use FileAttributes"); }
public void CleanClientFiles_Deletes_Generated_Files() { CreateClientFilesTask task = null; MockBuildEngine mockBuildEngine; try { // ==================================================== // Test setup -- generate code by calling Create task // ==================================================== task = CodeGenHelper.CreateClientFilesTaskInstance("CLRCF1", /*includeClientOutputAssembly*/ false); bool success = task.Execute(); if (!success) { mockBuildEngine = task.BuildEngine as MockBuildEngine; Assert.Fail("CreateClientFilesTask failed:\r\n" + mockBuildEngine.ConsoleLogger.Errors); } string generatedCodeOutputFolder = task.GeneratedCodePath; Assert.IsTrue(Directory.Exists(generatedCodeOutputFolder), "Expected task to have created " + generatedCodeOutputFolder); string[] files = Directory.GetFiles(generatedCodeOutputFolder); Assert.AreEqual(2, files.Length, "Code gen should have generated 3 code files"); string generatedFile = Path.Combine(generatedCodeOutputFolder, "ServerClassLib.g.cs"); Assert.IsTrue(File.Exists(generatedFile), "Expected task to have generated " + generatedFile); string copiedFile = Path.Combine(generatedCodeOutputFolder, "TestEntity.shared.cs"); Assert.IsTrue(File.Exists(copiedFile), "Expected task to have copied " + copiedFile); string outputFolder = task.OutputPath; Assert.IsTrue(Directory.Exists(outputFolder), "Expected task to have created " + outputFolder); files = Directory.GetFiles(outputFolder); string generatedFiles = string.Empty; foreach (string file in files) { generatedFiles += (file + Environment.NewLine); } Assert.AreEqual(5, files.Length, "Code gen should have generated this many ancillary files but instead saw:" + Environment.NewLine + generatedFiles); string fileList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityFiles.txt"); Assert.IsTrue(File.Exists(fileList), "Expected code gen to have created " + fileList + " but saw:" + Environment.NewLine + generatedFiles); string refList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityClientRefs.txt"); Assert.IsTrue(File.Exists(refList), "Expected code gen to have created " + refList + " but saw:" + Environment.NewLine + generatedFiles); refList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityServerRefs.txt"); Assert.IsTrue(File.Exists(refList), "Expected code gen to have created " + refList + " but saw:" + Environment.NewLine + generatedFiles); string sourceFileList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntitySourceFiles.txt"); Assert.IsTrue(File.Exists(sourceFileList), "Expected code gen to have created " + sourceFileList + " but saw:" + Environment.NewLine + generatedFiles); string riaLinkList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityLinks.txt"); Assert.IsTrue(File.Exists(riaLinkList), "Expected code gen to have created " + riaLinkList + " but saw:" + Environment.NewLine + generatedFiles); // ========================================== // Main body of test -- the Clean // ========================================== // Step 1: instantiate Clean task instance and execute it, giving it same info as the Create task CleanClientFilesTask cleanTask = new CleanClientFilesTask(); mockBuildEngine = new MockBuildEngine(); cleanTask.BuildEngine = mockBuildEngine; cleanTask.OutputPath = task.OutputPath; cleanTask.GeneratedCodePath = task.GeneratedCodePath; cleanTask.ClientProjectPath = task.ClientProjectPath; success = cleanTask.Execute(); Assert.IsTrue(success, "Clean task returned false"); // No errors or warnings allowed TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Step 2: validate files created above are gone // TODO, 244509: we no longer remove empty folder // Assert.IsFalse(Directory.Exists(generatedCodeOutputFolder), "Expected clean to have deleted " + generatedCodeOutputFolder); Assert.IsFalse(File.Exists(fileList), "Expected clean to have deleted " + fileList); Assert.IsFalse(File.Exists(refList), "Expected clean to have deleted " + refList); Assert.IsFalse(File.Exists(sourceFileList), "Expected clean to have deleted " + sourceFileList); Assert.IsFalse(File.Exists(riaLinkList), "Expected clean to have deleted " + riaLinkList); // Step 3: verify redundant clean does no harm and succeeds success = cleanTask.Execute(); Assert.IsTrue(success, "Clean task returned false"); } finally { CodeGenHelper.DeleteTempFolder(task); } }
public void CleanClientFiles_Safe_File_Delete() { CleanClientFilesTask task = new CleanClientFilesTask(); MockBuildEngine mockBuildEngine = new MockBuildEngine(); task.BuildEngine = mockBuildEngine; // Test 1 -- null and empty deletes do nothing task.SafeFileDelete(null); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); task.SafeFileDelete(string.Empty); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 2 -- nonexistant file does nothing string fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Assert.IsFalse(File.Exists(fileName)); task.SafeFileDelete(fileName); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 3 -- verify delete on actual file succeeds without error File.WriteAllText(fileName, "stuff"); Assert.IsTrue(File.Exists(fileName)); task.SafeFileDelete(fileName); Assert.IsFalse(File.Exists(fileName)); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 4 -- verify delete on actual file with READONLY attribute set succeeds without error File.WriteAllText(fileName, "stuff"); File.SetAttributes(fileName, FileAttributes.ReadOnly); Assert.IsTrue(File.Exists(fileName)); task.SafeFileDelete(fileName); Assert.IsFalse(File.Exists(fileName)); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 5 -- attempt to delete while file is open. // Verify we log a warning containing the exception's message File.WriteAllText(fileName, "stuff"); Assert.IsTrue(File.Exists(fileName)); string errorMessage = null; using (StreamReader t1 = new StreamReader(fileName)) { // We do a delete here to capture the exception we expect the SafeFileDelete to encounter try { File.Delete(fileName); } catch (IOException ioe) { errorMessage = ioe.Message; } Assert.IsNotNull(errorMessage, "Expected File.Delete to throw IOException"); task.SafeFileDelete(fileName); } Assert.IsTrue(File.Exists(fileName)); File.Delete(fileName); string expectedWarning = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Delete_File_Error, fileName, errorMessage); TestHelper.AssertContainsWarnings(mockBuildEngine.ConsoleLogger, expectedWarning); }