mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
7.5 KiB
303 lines
7.5 KiB
using System; |
|
using System.IO; |
|
using System.Reflection; |
|
|
|
using NUnit.Core; |
|
using NUnit.Core.Extensibility; |
|
|
|
using Mono.Cecil.Cil; |
|
|
|
namespace Mono.Cecil.Tests { |
|
|
|
public abstract class TestCecilAttribute : Attribute { |
|
|
|
bool verify = true; |
|
Type symbol_reader_provider; |
|
Type symbol_writer_provider; |
|
|
|
public bool Verify { |
|
get { return verify; } |
|
set { verify = value; } |
|
} |
|
|
|
public Type SymbolReaderProvider { |
|
get { return symbol_reader_provider; } |
|
set { symbol_reader_provider = value; } |
|
} |
|
|
|
public Type SymbolWriterProvider { |
|
get { return symbol_writer_provider; } |
|
set { symbol_writer_provider = value; } |
|
} |
|
|
|
public abstract string GetModuleLocation (Assembly assembly); |
|
} |
|
|
|
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)] |
|
public sealed class TestModuleAttribute : TestCecilAttribute { |
|
|
|
readonly string module; |
|
|
|
public string Module { |
|
get { return module; } |
|
} |
|
|
|
public TestModuleAttribute (string assembly) |
|
{ |
|
this.module = assembly; |
|
} |
|
|
|
public override string GetModuleLocation (Assembly assembly) |
|
{ |
|
return BaseTestFixture.GetAssemblyResourcePath (module, assembly); |
|
} |
|
} |
|
|
|
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)] |
|
public sealed class TestCSharpAttribute : TestCecilAttribute { |
|
|
|
readonly string file; |
|
|
|
public string File { |
|
get { return file; } |
|
} |
|
|
|
public TestCSharpAttribute (string file) |
|
{ |
|
this.file = file; |
|
} |
|
|
|
public override string GetModuleLocation (Assembly assembly) |
|
{ |
|
return CompilationService.CompileResource ( |
|
BaseTestFixture.GetCSharpResourcePath (file, assembly)); |
|
} |
|
} |
|
|
|
[AttributeUsage (AttributeTargets.Method, AllowMultiple = false)] |
|
public sealed class TestILAttribute : TestCecilAttribute { |
|
|
|
readonly string file; |
|
|
|
public string File { |
|
get { return file; } |
|
} |
|
|
|
public TestILAttribute (string file) |
|
{ |
|
this.file = file; |
|
} |
|
|
|
public override string GetModuleLocation (Assembly assembly) |
|
{ |
|
return CompilationService.CompileResource ( |
|
BaseTestFixture.GetILResourcePath (file, assembly)); |
|
} |
|
} |
|
|
|
class CecilTestCase : NUnitTestMethod { |
|
|
|
readonly TestCecilAttribute attribute; |
|
readonly TestCaseType type; |
|
|
|
public CecilTestCase (MethodInfo method, TestCecilAttribute attribute, TestCaseType type) |
|
: base (method) |
|
{ |
|
this.TestName.Name = type.ToString (); |
|
this.TestName.FullName = method.DeclaringType.FullName + "." + method.Name + "." + type; |
|
this.attribute = attribute; |
|
this.type = type; |
|
} |
|
|
|
ModuleDefinition GetModule () |
|
{ |
|
var location = attribute.GetModuleLocation (this.Method.DeclaringType.Assembly); |
|
|
|
var parameters = new ReaderParameters { |
|
SymbolReaderProvider = GetSymbolReaderProvider (attribute), |
|
}; |
|
|
|
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; |
|
} |
|
} |
|
|
|
static ISymbolReaderProvider GetSymbolReaderProvider (TestCecilAttribute attribute) |
|
{ |
|
if (attribute.SymbolReaderProvider == null) |
|
return null; |
|
|
|
return (ISymbolReaderProvider) Activator.CreateInstance (attribute.SymbolReaderProvider); |
|
} |
|
|
|
static ISymbolWriterProvider GetSymbolWriterProvider (TestCecilAttribute attribute) |
|
{ |
|
if (attribute.SymbolReaderProvider == null) |
|
return null; |
|
|
|
return (ISymbolWriterProvider) Activator.CreateInstance (attribute.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 (attribute), |
|
}; |
|
|
|
Reflect.InvokeMethod (Method, Fixture, new object [] { module }); |
|
|
|
module.Write (rt_module, writer_parameters); |
|
|
|
if (attribute.Verify) |
|
CompilationService.Verify (rt_module); |
|
|
|
return ModuleDefinition.ReadModule (rt_module, reader_parameters); |
|
} |
|
|
|
public override void RunTestMethod (TestCaseResult testResult) |
|
{ |
|
var module = GetModule (); |
|
if (module == null) |
|
return; |
|
|
|
Reflect.InvokeMethod (Method, Fixture, new object [] { module }); |
|
|
|
testResult.Success (); |
|
} |
|
} |
|
|
|
class CecilTestSuite : TestSuite { |
|
|
|
public CecilTestSuite (MethodInfo method) |
|
: base (method.DeclaringType.FullName, method.Name) |
|
{ |
|
} |
|
|
|
public override TestResult Run (EventListener listener, ITestFilter filter) |
|
{ |
|
if (this.Parent != null) |
|
this.Fixture = this.Parent.Fixture; |
|
|
|
return base.Run (listener, filter); |
|
} |
|
|
|
protected override void DoOneTimeSetUp (TestResult suiteResult) |
|
{ |
|
} |
|
|
|
protected override void DoOneTimeTearDown (TestResult suiteResult) |
|
{ |
|
} |
|
} |
|
|
|
enum TestCaseType { |
|
ReadImmediate, |
|
ReadDeferred, |
|
WriteFromImmediate, |
|
WriteFromDeferred, |
|
} |
|
|
|
static class CecilTestFactory { |
|
|
|
public static CecilTestSuite CreateTestSuite (MethodInfo method) |
|
{ |
|
if (method == null) |
|
throw new ArgumentNullException ("method"); |
|
|
|
var suite = new CecilTestSuite (method); |
|
|
|
NUnitFramework.ApplyCommonAttributes (method, suite); |
|
PopulateTestSuite (method, suite); |
|
|
|
return suite; |
|
} |
|
|
|
static void PopulateTestSuite (MethodInfo method, CecilTestSuite suite) |
|
{ |
|
var attribute = GetTestCecilAttribute (method); |
|
if (attribute == null) |
|
throw new ArgumentException (); |
|
|
|
foreach (var value in Enum.GetValues (typeof (TestCaseType))) { |
|
var test = CreateTestCase (method, attribute, (TestCaseType) value); |
|
if (test != null) |
|
suite.Add (test); |
|
} |
|
} |
|
|
|
static CecilTestCase CreateTestCase (MethodInfo method, TestCecilAttribute attribute, TestCaseType type) |
|
{ |
|
return new CecilTestCase (method, attribute, type); |
|
} |
|
|
|
static TestCecilAttribute GetTestCecilAttribute (MethodInfo method) |
|
{ |
|
foreach (var attribute in method.GetCustomAttributes (false)) { |
|
var test = attribute as TestCecilAttribute; |
|
if (test != null) |
|
return test; |
|
} |
|
|
|
return null; |
|
} |
|
} |
|
|
|
[NUnitAddin] |
|
public class CecilTestAddin : IAddin, ITestCaseBuilder { |
|
|
|
public bool Install (IExtensionHost host) |
|
{ |
|
if (host == null) |
|
throw new ArgumentNullException ("host"); |
|
|
|
var builders = host.GetExtensionPoint ("TestCaseBuilders"); |
|
if (builders == null) |
|
return false; |
|
|
|
builders.Install (this); |
|
return true; |
|
} |
|
|
|
public Test BuildFrom (MethodInfo method) |
|
{ |
|
if (method == null) |
|
throw new ArgumentNullException ("method"); |
|
|
|
return CecilTestFactory.CreateTestSuite (method); |
|
} |
|
|
|
public bool CanBuildFrom (MethodInfo method) |
|
{ |
|
if (method == null) |
|
return false; |
|
|
|
return IsCecilTestMethod (method); |
|
} |
|
|
|
static bool IsCecilTestMethod (MethodInfo method) |
|
{ |
|
return Reflect.HasAttribute (method, typeof (TestModuleAttribute).FullName, false) |
|
|| Reflect.HasAttribute (method, typeof (TestILAttribute).FullName, false) |
|
|| Reflect.HasAttribute (method, typeof (TestCSharpAttribute).FullName, false); |
|
} |
|
} |
|
}
|
|
|