diff options
Diffstat (limited to 'Test/Mono.Cecil.Tests/BaseTestFixture.cs')
-rw-r--r-- | Test/Mono.Cecil.Tests/BaseTestFixture.cs | 248 |
1 files changed, 235 insertions, 13 deletions
diff --git a/Test/Mono.Cecil.Tests/BaseTestFixture.cs b/Test/Mono.Cecil.Tests/BaseTestFixture.cs index e160f48..2d0dcb2 100644 --- a/Test/Mono.Cecil.Tests/BaseTestFixture.cs +++ b/Test/Mono.Cecil.Tests/BaseTestFixture.cs @@ -1,7 +1,7 @@ using System; using System.IO; using System.Reflection; - +using Mono.Cecil.Cil; using NUnit.Framework; using Mono.Cecil.PE; @@ -10,6 +10,12 @@ namespace Mono.Cecil.Tests { public abstract class BaseTestFixture { + protected static void IgnoreOnMono () + { + if (Platform.OnMono) + Assert.Ignore (); + } + public static string GetResourcePath (string name, Assembly assembly) { return Path.Combine (FindResourcesDirectory (assembly), name); @@ -30,35 +36,35 @@ namespace Mono.Cecil.Tests { return GetResourcePath (Path.Combine ("il", name), assembly); } - public static ModuleDefinition GetResourceModule (string name) + public ModuleDefinition GetResourceModule (string name) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly)); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly)); } - public static ModuleDefinition GetResourceModule (string name, ReaderParameters parameters) + public ModuleDefinition GetResourceModule (string name, ReaderParameters parameters) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), parameters); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), parameters); } - public static ModuleDefinition GetResourceModule (string name, ReadingMode mode) + public ModuleDefinition GetResourceModule (string name, ReadingMode mode) { - return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), new ReaderParameters (mode)); + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), new ReaderParameters (mode)); } - internal static Image GetResourceImage (string name) + internal Image GetResourceImage (string name) { - using (var fs = new FileStream (GetAssemblyResourcePath (name, typeof (BaseTestFixture).Assembly), FileMode.Open, FileAccess.Read)) + using (var fs = new FileStream (GetAssemblyResourcePath (name, GetType ().Assembly), FileMode.Open, FileAccess.Read)) return ImageReader.ReadImageFrom (fs); } - public static ModuleDefinition GetCurrentModule () + public ModuleDefinition GetCurrentModule () { - return ModuleDefinition.ReadModule (typeof (BaseTestFixture).Module.FullyQualifiedName); + return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName); } - public static ModuleDefinition GetCurrentModule (ReaderParameters parameters) + public ModuleDefinition GetCurrentModule (ReaderParameters parameters) { - return ModuleDefinition.ReadModule (typeof (BaseTestFixture).Module.FullyQualifiedName, parameters); + return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName, parameters); } public static string FindResourcesDirectory (Assembly assembly) @@ -72,5 +78,221 @@ namespace Mono.Cecil.Tests { return Path.Combine (path, "Resources"); } + + public static void TestModule (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null) + { + Run (new ModuleTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider)); + } + + public static void TestCSharp (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null) + { + Run (new CSharpTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider)); + } + + public static void TestIL (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null) + { + Run (new ILTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider)); + } + + private static void Run (TestCase testCase) + { + using (var runner = new TestRunner (testCase, TestCaseType.ReadDeferred)) + runner.RunTest (); + + using (var runner = new TestRunner (testCase, TestCaseType.ReadImmediate)) + runner.RunTest (); + + if (testCase.ReadOnly) + return; + + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred)) + runner.RunTest(); + + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate)) + runner.RunTest(); + } + } + + abstract class TestCase { + + public readonly bool Verify; + public readonly bool ReadOnly; + public readonly Type SymbolReaderProvider; + public readonly Type SymbolWriterProvider; + public readonly Action<ModuleDefinition> Test; + + public abstract string ModuleLocation { get; } + + protected Assembly Assembly { get { return Test.Method.Module.Assembly; } } + + protected TestCase (Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider) + { + Test = test; + Verify = verify; + ReadOnly = readOnly; + SymbolReaderProvider = symbolReaderProvider; + SymbolWriterProvider = symbolWriterProvider; + } + } + + class ModuleTestCase : TestCase { + + public readonly string Module; + + public ModuleTestCase (string module, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider) + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider) + { + Module = module; + } + + public override string ModuleLocation + { + get { return BaseTestFixture.GetAssemblyResourcePath (Module, Assembly); } + } + } + + class CSharpTestCase : TestCase { + + public readonly string File; + + public CSharpTestCase (string file, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider) + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider) + { + File = file; + } + + public override string ModuleLocation + { + get + { + return CompilationService.CompileResource (BaseTestFixture.GetCSharpResourcePath (File, Assembly)); + } + } + } + + class ILTestCase : TestCase { + + public readonly string File; + + public ILTestCase (string file, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider) + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider) + { + File = file; + } + + public override string ModuleLocation + { + get + { + return CompilationService.CompileResource (BaseTestFixture.GetILResourcePath (File, Assembly)); ; + } + } + } + + class TestRunner : IDisposable { + + readonly TestCase test_case; + readonly TestCaseType type; + + ModuleDefinition test_module; + DefaultAssemblyResolver test_resolver; + + public TestRunner (TestCase testCase, TestCaseType type) + { + this.test_case = testCase; + this.type = type; + } + + ModuleDefinition GetModule () + { + var location = test_case.ModuleLocation; + var directory = Path.GetDirectoryName (location); + + test_resolver = new DefaultAssemblyResolver (); + test_resolver.AddSearchDirectory (directory); + + var parameters = new ReaderParameters { + SymbolReaderProvider = GetSymbolReaderProvider (), + AssemblyResolver = test_resolver, + }; + + switch (type) { + case TestCaseType.ReadImmediate: + parameters.ReadingMode = ReadingMode.Immediate; + return ModuleDefinition.ReadModule (location, parameters); + case TestCaseType.ReadDeferred: + parameters.ReadingMode = ReadingMode.Deferred; + return ModuleDefinition.ReadModule (location, parameters); + case TestCaseType.WriteFromImmediate: + parameters.ReadingMode = ReadingMode.Immediate; + return RoundTrip (location, parameters, "cecil-irt"); + case TestCaseType.WriteFromDeferred: + parameters.ReadingMode = ReadingMode.Deferred; + return RoundTrip (location, parameters, "cecil-drt"); + default: + return null; + } + } + + ISymbolReaderProvider GetSymbolReaderProvider () + { + if (test_case.SymbolReaderProvider == null) + return null; + + return (ISymbolReaderProvider) Activator.CreateInstance (test_case.SymbolReaderProvider); + } + + ISymbolWriterProvider GetSymbolWriterProvider () + { + if (test_case.SymbolReaderProvider == null) + return null; + + return (ISymbolWriterProvider) Activator.CreateInstance (test_case.SymbolWriterProvider); + } + + ModuleDefinition RoundTrip (string location, ReaderParameters reader_parameters, string folder) + { + var module = ModuleDefinition.ReadModule (location, reader_parameters); + var rt_folder = Path.Combine (Path.GetTempPath (), folder); + if (!Directory.Exists (rt_folder)) + Directory.CreateDirectory (rt_folder); + var rt_module = Path.Combine (rt_folder, Path.GetFileName (location)); + + var writer_parameters = new WriterParameters { + SymbolWriterProvider = GetSymbolWriterProvider (), + }; + + test_case.Test (module); + + module.Write (rt_module, writer_parameters); + + if (test_case.Verify) + CompilationService.Verify (rt_module); + + return ModuleDefinition.ReadModule (rt_module, reader_parameters); + } + + public void RunTest () + { + var module = GetModule (); + if (module == null) + return; + + test_module = module; + test_case.Test (module); + } + + public void Dispose () + { + test_module.Dispose (); + test_resolver.Dispose (); + } + } + + enum TestCaseType { + ReadImmediate, + ReadDeferred, + WriteFromImmediate, + WriteFromDeferred, } } |