Browse Source

added UnitBuilder macro

Simon Krajewski 12 năm trước cách đây
mục cha
commit
42521e9c65
2 tập tin đã thay đổi với 89 bổ sung90 xóa
  1. 9 90
      tests/unit/TestSpecification.hx
  2. 80 0
      tests/unit/UnitBuilder.hx

+ 9 - 90
tests/unit/TestSpecification.hx

@@ -1,94 +1,5 @@
 package unit;
 
-class TestSpecification extends Test 
-{
-	public function testStdIs() {
-		// null subject
-		var known:String = null;
-		f(Std.is(known, String));
-		
-		var unknown = null;
-		f(Std.is(unknown, String));
-		
-		f(Std.is(null, String));
-		
-		// null class
-		f(Std.is("foo", null));
-	}
-	
-	public function testStdString() {
-		var cwts = new ClassWithToString();
-		var cwtsc = new ClassWithToStringChild();
-		var cwtsc2 = new ClassWithToStringChild2();
-		
-		eq(Std.string(cwts), "ClassWithToString.toString()");
-		eq(Std.string(cwtsc), "ClassWithToString.toString()");
-		eq(Std.string(cwtsc2), "ClassWithToStringChild2.toString()");
-		
-		eq(Std.string(SomeEnum.NoArguments), "NoArguments");
-		eq(Std.string(SomeEnum.OneArgument("foo")), "OneArgument(foo)");
-		
-		eq(Std.string(null), "null");
-	}
-	
-	public function testStdInt() {
-		eq( Std.int(-1.7), -1 );
-		eq( Std.int(-1.2), -1 );
-		eq( Std.int(1.7), 1 );
-		eq( Std.int(1.2), 1 );
-		eq( Std.int(-0.7), 0 );
-		eq( Std.int(-0.2), 0 );
-		eq( Std.int(0.7), 0 );
-		eq( Std.int(0.2), 0 );
-	}
-	
-	public function testStdParseInt() {
-		eq( Std.parseInt("0"), 0 );
-		eq( Std.parseInt("   5"), 5 );
-		eq( Std.parseInt("0001"), 1 );
-		eq( Std.parseInt("0010"), 10 );
-		eq( Std.parseInt("100"), 100 );
-		eq( Std.parseInt("-100"), -100 );
-		eq( Std.parseInt("100x123"), 100 );
-		eq( Std.parseInt("12foo13"), 12 );
-		eq( Std.parseInt(""), null );
-		eq( Std.parseInt("abcd"), null );
-		eq( Std.parseInt("a10"), null );
-		eq( Std.parseInt(null), null );
-		eq( Std.parseInt("0xFF"), 255 );
-		eq( Std.parseInt("0x123"), 291 );
-		eq( Std.parseInt("0XFF"), 255 );
-		eq( Std.parseInt("0X123"), 291 );	
-		eq( Std.parseInt("0X01"), 1 );
-		eq( Std.parseInt("0x01"), 1 );
-		unspec(function() Std.parseInt("0xFG"));		
-	}
-	
-	public function testStdParseFloat() {
-		eq( Std.parseFloat("0"), 0. );
-		eq( Std.parseFloat("   5.3"), 5.3 );
-		eq( Std.parseFloat("0001"), 1. );
-		eq( Std.parseFloat("100.45"), 100.45 );
-		eq( Std.parseFloat("-100.01"), -100.01 );
-		eq( Std.parseFloat("100x123"), 100. );
-		t( Math.isNaN(Std.parseFloat("")) );
-		t( Math.isNaN(Std.parseFloat("abcd")) );
-		t( Math.isNaN(Std.parseFloat("a10")) );
-		t( Math.isNaN(Std.parseFloat(null)) );
-		eq( Std.parseFloat("5.3 "), 5.3 );
-		eq( Std.parseFloat("0.0"), 0. );
-		eq( Std.parseFloat("5.3 1"), 5.3 );		
-	}
-	
-	function testStdRandom() {
-		var x = Std.random(2);
-		t( x == 0 || x == 1);
-		eq(Std.random(1), 0);
-		eq(Std.random(0), 0);
-		eq(Std.random(-100), 0);
-	}	
-}
-
 private class EmptyClass {
 	public function new() { }
 }
@@ -109,4 +20,12 @@ private class ClassWithToStringChild2 extends ClassWithToString {
 private enum SomeEnum<T> {
 	NoArguments;
 	OneArgument(t:T);
-}
+}
+
+#if !macro
+@:build(unit.UnitBuilder.build("unitstd"))
+#end
+class TestSpecification extends Test 
+{
+
+}

+ 80 - 0
tests/unit/UnitBuilder.hx

@@ -0,0 +1,80 @@
+package unit;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+using StringTools;
+
+class UnitBuilder {
+	
+	@:macro static public function build(basePath:String):Array<Field> {
+		basePath = basePath.endsWith("\\") || basePath.endsWith("/") ? basePath : basePath + "/";
+		var dir = sys.FileSystem.readDirectory(basePath);
+		var ret = Context.getBuildFields();
+		var numFiles = 0;
+		for (file in dir) {
+			if (file.endsWith(".hxunit")) {
+				numFiles++;
+				var func = {
+					args: [],
+					ret: null,
+					params: [],
+					expr: read(basePath + file)
+				}
+				ret.push( {
+					name: "test" + ~/\./.map(file, function(_) return "_"),
+					kind: FFun(func),
+					pos: Context.makePosition( { min:0, max:0, file:basePath + file } ),
+					access: [APublic],
+					doc: null,
+					meta: []
+				});
+			}
+		}
+		trace("Added " +numFiles + " .hxunit files");
+		return ret;
+	}
+	
+	#if macro
+	static function collapseToOrExpr(el:Array<Expr>) {
+		return switch(el) {
+			case []: throw "";
+			case [e]: e;
+		case _:
+			var e = el.pop();
+			{ expr: EBinop(OpBoolOr, e, collapseToOrExpr(el)), pos: e.pos }
+		}
+	}
+	
+	static public function read(path:String) {
+		var p = Context.makePosition( { min:0, max:0, file:path } );
+		var file = sys.io.File.getContent(path);
+		var code = Context.parseInlineString("{" + file + "}", p);
+		var block = switch(code.expr) {
+			case EBlock(b): b;
+			case _: throw "false";
+		}
+		var ret = [];
+		for (e in block) {
+			var e = switch(e.expr) {
+				case EBinop(OpEq, e, { expr: EConst(CIdent("false")) } )
+				| EBinop(OpEq, { expr: EConst(CIdent("false")) }, e):
+					macro f($e);					
+				case EBinop(OpEq, e, { expr: EConst(CIdent("true")) } )
+				| EBinop(OpEq, { expr: EConst(CIdent("true")) }, e):
+					macro t($e);
+				case EBinop(OpEq, e1, e2):
+					macro eq($e1, $e2);
+				case EIn(e1, {expr:EArrayDecl(el) }):
+					var el2 = [];
+					for (e in el)
+						el2.push(macro $e1 == $e);
+					collapseToOrExpr(el2);
+				case _:
+					e;
+			}
+			ret.push(e);
+		}
+		return macro { $[ret]; };
+	}
+	#end
+}