using Nemerle.Compiler using Nemerle.Compiler.Parsetree using NUnit.Framework using Nemerle.IO using Nemerle.Collections namespace NemerleUnit macro assert( expr ) syntax("assert", expr) def message = $"at line $(expr.Location.Line)" <[Assert.IsTrue( $expr, $(message: string) )]> macro assert_equals(exp1,exp2) syntax("assert", exp1, "equals", exp2) <[Assert.AreEqual( $exp2 ,$exp1 )]> macro assert_does_not_equal(exp,exp2) syntax("assert", exp, "does", "not", "equal", exp2) def message = $"at line $(exp.Location.Line)" <[Assert.IsFalse($exp2.Equals($exp),$(message: string))]> macro test(name, code, exception = null) syntax ("test", name, Optional("expected", exception), code) def (sequence,sequence_teardown) = Store.getSetupAndTeardownSequences(Nemerle.Macros.ImplicitCTX().CurrentType.Name) def test_body = match(code) | <[{..$expresions}]> => List.Flatten( [sequence,expresions,sequence_teardown]) | _ => [<[]>] mutable attrs = [<[Test]>]; when (exception != null) attrs ::= <[ExpectedException(typeof($exception))]>; def mods = Modifiers(NemerleAttributes.Public, attrs); def a_test = <[ decl: ..$mods public $(name.ToString().Replace("\"", "") : dyn)(): void { ..$test_body } ]>; Nemerle.Macros.ImplicitCTX().CurrentType.Define(a_test) Nemerle.Macros.ImplicitCTX().CurrentType.GetModifiers().AddCustomAttribute (<[ TestFixture ]>) <[]> macro setup(code) syntax ("setup", code) Nemerle.Macros.ImplicitCTX().Manager.Options.Warnings.Disable(168) Store.PutSetup(Nemerle.Macros.ImplicitCTX().CurrentType.Name,code) <[]> macro teardown(code) syntax ("teardown", code) Store.PutTeardown(Nemerle.Macros.ImplicitCTX().CurrentType.Name, code) <[]> class Store static setup: Hashtable[string,PExpr] = Hashtable() static teardown: Hashtable[string,PExpr] = Hashtable() static public getSetupAndTeardownSequences(class_name: string) : list[PExpr] * list[PExpr] def extract_sequence(dict) if (dict.Contains(class_name)) dict[class_name] else <[]> def strip_brackets(body) | <[{ .. $expresions}]> => expresions | _ => [<[]>] (strip_brackets(extract_sequence(setup)),strip_brackets(extract_sequence(teardown))) static public PutSetup(class_name: string, code: PExpr): void setup[class_name] = code static public PutTeardown(class_name: string, code: PExpr): void teardown[class_name] = code