/// <summary> /// Asserts that the emitted IL for a type is the same as the expected IL. /// Many core library types are in different assemblies on .Net Framework, and .Net Core. /// Therefore this test is likely to fail unless you only run it only only on one of these frameworks, /// or you run it on both, but provide a different expected output string for each. /// See <see cref="ExecutionConditionUtil"/>. /// </summary> /// <param name="typeName">The non-fully-qualified name of the type</param> /// <param name="expected">The expected IL</param> public void VerifyTypeIL(string typeName, string expected) { var output = new ICSharpCode.Decompiler.PlainTextOutput(); using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default); IList <ModuleData> moduleData = testEnvironment.GetAllModuleData(); var mainModule = moduleData.Single(md => md.FullName == mainModuleFullName); using (var moduleMetadata = ModuleMetadata.CreateFromImage(testEnvironment.GetMainImage())) { var peFile = new PEFile(mainModuleFullName, moduleMetadata.Module.PEReaderOpt); var metadataReader = moduleMetadata.GetMetadataReader(); bool found = false; foreach (var typeDefHandle in metadataReader.TypeDefinitions) { var typeDef = metadataReader.GetTypeDefinition(typeDefHandle); if (metadataReader.GetString(typeDef.Name) == typeName) { var disassembler = new ICSharpCode.Decompiler.Disassembler.ReflectionDisassembler(output, default); disassembler.DisassembleType(peFile, typeDefHandle); found = true; break; } } Assert.True(found, "Could not find type named " + typeName); } } AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString(), escapeQuotes: false); }
public void Emit(string expectedOutput, int?expectedReturnCode, string[] args, IEnumerable <ResourceDescription> manifestResources, EmitOptions emitOptions, Verification peVerify, SignatureDescription[] expectedSignatures) { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions); _allModuleData = testEnvironment.GetAllModuleData(); if (peVerify == Verification.Passes) { testEnvironment.PeVerify(); } else if (peVerify == Verification.Fails) { Assert.Throws <PeVerifyException>(() => testEnvironment.PeVerify()); } if (expectedSignatures != null) { MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures); } if (expectedOutput != null || expectedReturnCode != null) { var returnCode = testEnvironment.Execute(mainModuleName, args, expectedOutput); if (expectedReturnCode is int exCode) { Assert.Equal(exCode, returnCode); } } } }
public void Emit( string expectedOutput, bool trimOutput, int?expectedReturnCode, string[] args, IEnumerable <ResourceDescription> manifestResources, EmitOptions emitOptions, Verification peVerify, SignatureDescription[] expectedSignatures) { using var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies); string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions); _allModuleData = testEnvironment.GetAllModuleData(); testEnvironment.Verify(peVerify); #if NETCOREAPP ILVerify(peVerify); #endif if (expectedSignatures != null) { MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures); } if (expectedOutput != null || expectedReturnCode != null) { var returnCode = testEnvironment.Execute(mainModuleName, args, expectedOutput, trimOutput); if (expectedReturnCode is int exCode) { Assert.Equal(exCode, returnCode); } } }
// TODO(tomat): Fold into CompileAndVerify. // Replace bool verify parameter with string[] expectedPeVerifyOutput. If null, no verification. If empty verify have to succeed. Otherwise compare errors. public void EmitAndVerify(params string[] expectedPeVerifyOutput) { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleName = Emit(testEnvironment, null, null); string[] actualOutput = testEnvironment.VerifyModules(new[] { mainModuleName }); Assert.Equal(expectedPeVerifyOutput, actualOutput); } }
public static void ContinueRunScriptWithOutput <T>(Task <ScriptState <T> > scriptState, string code, string expectedOutput) { string output; string errorOutput; RuntimeEnvironmentFactory.CaptureOutput(() => { scriptState.ContinueWith(code).Wait(); }, expectedOutput.Length, out output, out errorOutput); Assert.Equal(expectedOutput, output.Trim()); }
public static T EvaluateScriptWithOutput <T>(Script <T> script, string expectedOutput) { string output; string errorOutput; T result = default(T); RuntimeEnvironmentFactory.CaptureOutput(() => { var task = script.EvaluateAsync(); task.Wait(); result = task.Result; }, expectedOutput.Length, out output, out errorOutput); Assert.Equal(expectedOutput, output.Trim()); return(result); }
public static ScriptState <T> RunScriptWithOutput <T>(Script <T> script, string expectedOutput) { string output; string errorOutput; ScriptState <T> result = null; RuntimeEnvironmentFactory.CaptureOutput(() => { var task = script.RunAsync(); task.Wait(); result = task.Result; }, expectedOutput.Length, out output, out errorOutput); Assert.Equal(expectedOutput, output.Trim()); return(result); }
public string Dump() { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default); IList <ModuleData> moduleDatas = testEnvironment.GetAllModuleData(); string mainModuleSimpleName = moduleDatas.Single(md => md.FullName == mainModuleFullName).SimpleName; RuntimeEnvironmentUtilities.DumpAssemblyData(moduleDatas, out var dumpDir); string modulePath = Path.Combine(dumpDir, mainModuleSimpleName + ".dll"); var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(modulePath, new ICSharpCode.Decompiler.DecompilerSettings()); var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(); return(syntaxTree.ToString()); } }
public void Emit(string expectedOutput, IEnumerable <ResourceDescription> manifestResources, EmitOptions emitOptions, bool peVerify, SignatureDescription[] expectedSignatures) { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions); _allModuleData = testEnvironment.GetAllModuleData(); if (peVerify) { testEnvironment.PeVerify(); } if (expectedSignatures != null) { MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures); } if (expectedOutput != null) { testEnvironment.Execute(mainModuleName, expectedOutput); } } }
public string Dump(string methodName = null) { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default); IList <ModuleData> moduleDatas = testEnvironment.GetAllModuleData(); var mainModule = moduleDatas.Single(md => md.FullName == mainModuleFullName); RuntimeEnvironmentUtilities.DumpAssemblyData(moduleDatas, out var dumpDir); string extension = mainModule.Kind == OutputKind.ConsoleApplication ? ".exe" : ".dll"; string modulePath = Path.Combine(dumpDir, mainModule.SimpleName + extension); var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(modulePath, new ICSharpCode.Decompiler.DecompilerSettings() { AsyncAwait = false }); if (methodName != null) { var map = new Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod>(); listMethods(decompiler.TypeSystem.MainModule.RootNamespace, map); if (map.TryGetValue(methodName, out var method)) { return(decompiler.DecompileAsString(method.MetadataToken)); } else { throw new Exception($"Didn't find method '{methodName}'. Available/distinguishable methods are: \r\n{string.Join("\r\n", map.Keys)}"); } } return(decompiler.DecompileWholeModuleAsString()); } void listMethods(ICSharpCode.Decompiler.TypeSystem.INamespace @namespace, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result) { foreach (var nestedNS in @namespace.ChildNamespaces) { if (nestedNS.FullName != "System" && nestedNS.FullName != "Microsoft") { listMethods(nestedNS, result); } } foreach (var type in @namespace.Types) { listMethodsInType(type, result); } } void listMethodsInType(ICSharpCode.Decompiler.TypeSystem.ITypeDefinition type, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result) { foreach (var nestedType in type.NestedTypes) { listMethodsInType(nestedType, result); } foreach (var method in type.Methods) { if (result.ContainsKey(method.FullName)) { // There is a bug with FullName on methods in generic types result.Remove(method.FullName); } else { result.Add(method.FullName, method); } } } }