Browse Source

Enable server tests again and start on DCE tests (#7813)

* [tests] bring back server tests

* [tests] make server checks more robust

* [tests] start on DCE tests

closes #7805

* uhm

* right

* more time?
Simon Krajewski 6 years ago
parent
commit
1147a49bfe

+ 5 - 0
src/context/common.ml

@@ -105,6 +105,7 @@ class compiler_callbacks = object(self)
 	val mutable after_typing = [];
 	val mutable before_save = [];
 	val mutable after_save = [];
+	val mutable after_filters = [];
 	val mutable after_generation = [];
 	val mutable null_safety_report = [];
 
@@ -120,6 +121,9 @@ class compiler_callbacks = object(self)
 	method add_after_save (f : unit -> unit) : unit =
 		after_save <- f :: after_save
 
+	method add_after_filters (f : unit -> unit) : unit =
+		after_filters <- f :: after_filters
+
 	method add_after_generation (f : unit -> unit) : unit =
 		after_generation <- f :: after_generation
 
@@ -130,6 +134,7 @@ class compiler_callbacks = object(self)
 	method get_after_typing = after_typing
 	method get_before_save = before_save
 	method get_after_save = after_save
+	method get_after_filters = after_filters
 	method get_after_generation = after_generation
 	method get_null_safety_report = null_safety_report
 end

+ 8 - 0
src/context/display/displayJson.ml

@@ -233,6 +233,14 @@ let handler =
 			) ();
 			hctx.send_result (jarray !l)
 		);
+		(* TODO: wait till gama complains about the naming, then change it to something else *)
+		"typer/compiledTypes", (fun hctx ->
+			hctx.com.callbacks#add_after_filters (fun () ->
+				let ctx = create_context GMFull in
+				let l = List.map (generate_module_type ctx) hctx.com.types in
+				hctx.send_result (jarray l)
+			);
+		);
 	] in
 	List.iter (fun (s,f) -> Hashtbl.add h s f) l;
 	h

+ 2 - 1
src/filters/filters.ml

@@ -904,4 +904,5 @@ let run com tctx main =
 	in
 	let t = filter_timer detail_times ["type 3"] in
 	List.iter (fun t -> List.iter (fun f -> f tctx t) type_filters) com.types;
-	t()
+	t();
+	List.iter (fun f -> f()) (List.rev com.callbacks#get_after_filters)

+ 5 - 3
tests/runci/targets/Js.hx

@@ -89,8 +89,10 @@ class Js {
 		changeDirectory(optDir);
 		runCommand("haxe", ["run.hxml"]);
 		haxelibInstall("utest");
-		// changeDirectory(serverDir);
-		// runCommand("haxe", ["build.hxml"]);
-		// runCommand("node", ["test.js"]);
+
+		runci.targets.Java.getJavaDependencies(); // this is awkward
+		changeDirectory(serverDir);
+		runCommand("haxe", ["build.hxml"]);
+		runCommand("node", ["test.js"]);
 	}
 }

+ 3 - 3
tests/server/src/AsyncMacro.hx

@@ -7,17 +7,17 @@ class AsyncMacro {
 			case EBlock(el): el;
 			case _: Context.error("Block expression expected", e.pos);
 		}
-		el.unshift(macro var _done = utest.Assert.createAsync(1000));
+		el.unshift(macro var _done = utest.Assert.createAsync(5000));
 		el.push(macro _done());
 		function loop(el:Array<Expr>) {
 			var e0 = el.shift();
 			return if (el.length == 0) {
 				e0;
 			} else switch (e0) {
-				case macro haxe($a{args}):
+				case macro runHaxe($a{args}):
 					var e = loop(el);
 					args.push(macro () -> $e);
-					macro haxe($a{args});
+					macro runHaxe($a{args});
 				case _:
 					macro { $e0; ${loop(el)}};
 			}

+ 3 - 3
tests/server/src/HaxeServer.hx

@@ -62,14 +62,14 @@ private class DisplayRequest {
         return Buffer.concat(chunks, length + 4);
     }
 
-    public function processResult(data:String) {
+    public function processResult(context:Context, data:String) {
         var buf = new StringBuf();
         var hasError = false;
         for (line in data.split("\n")) {
             switch (line.fastCodeAt(0)) {
                 case 0x01: // print
                     var line = line.substring(1).replace("\x01", "\n");
-                    trace("Haxe print:\n" + line);
+					context.sendLogMessage("Haxe print: " + line + "\n");
                 case 0x02: // error
                     hasError = true;
                 default:
@@ -229,7 +229,7 @@ class HaxeServer {
             if (currentRequest != null) {
                 var request = currentRequest;
                 currentRequest = null;
-                request.processResult(msg);
+                request.processResult(context, msg);
                 checkQueue();
             }
         }

+ 59 - 28
tests/server/src/HaxeServerTestCase.hx

@@ -1,14 +1,13 @@
-import HaxeServer;
+import haxe.display.JsonModuleTypes.JsonModuleType;
 import haxe.Json;
+import HaxeServer;
 import utest.Assert;
 using StringTools;
-
-typedef Message<T> = {
-	kind: String,
-	data: T
-}
+using Lambda;
 
 class TestContext {
+	public var messages:Array<String> = []; // encapsulation is overrated
+
 	public var displayServerConfig:DisplayServerConfigBase;
 
 	public function new(config:DisplayServerConfigBase) {
@@ -17,7 +16,12 @@ class TestContext {
 
 	public function sendErrorMessage(msg:String) { }
 
-	public function sendLogMessage(msg:String) { }
+	public function sendLogMessage(msg:String) {
+		var split = msg.split("\n");
+		for (message in split) {
+			messages.push(message.trim());
+		}
+	}
 }
 
 class HaxeServerTestCase {
@@ -25,7 +29,7 @@ class HaxeServerTestCase {
 	var server:HaxeServer;
 	var vfs:Vfs;
 	var testDir:String;
-	var messages:Array<Message<Any>>;
+	var storedTypes:Array<JsonModuleType<Any>>;
 
 	public function new() {
 		testDir = "test/cases/" + Type.getClassName(Type.getClass(this));
@@ -46,13 +50,16 @@ class HaxeServerTestCase {
 		server.stop();
 	}
 
-	function haxe(args:Array<String>, done:Void -> Void) {
-		args = args.concat(["-D", "compilation-server-test"]);
+	function runHaxe(args:Array<String>, storeTypes = false, done:Void -> Void) {
+		context.messages = [];
+		storedTypes = [];
+		if (storeTypes) {
+			args = args.concat(['--display', '{ "method": "typer/compiledTypes", "id": 1 }']);
+		}
 		server.process(args, null, function(result) {
-			if (result == "") {
-				result = "{}";
+			if (storeTypes) {
+				storedTypes = Json.parse(result).result.result;
 			}
-			messages = Json.parse(result);
 			done();
 		}, function(message) {
 			Assert.fail(message);
@@ -64,36 +71,60 @@ class HaxeServerTestCase {
 		return sys.io.File.getContent("test/templates/" + templateName);
 	}
 
-	function hasMessage<T>(msg:{kind: String, data:T}) {
-		function compareData(data1:Dynamic, data2:Dynamic) {
-			return switch (msg.kind) {
-				case "reusing" | "notCached": data1 == data2;
-				case "skipping": data1.skipped == data2.skipped && data1.dependency == data2.dependency;
-				case "print": Std.string(data1).trim() == Std.string(data2).trim();
-				case _: false;
-			}
-		}
-		for (message in messages) {
-			if (message.kind == msg.kind && compareData(message.data, cast msg.data)) {
+	function hasMessage<T>(msg:String) {
+		for (message in context.messages) {
+			if (message.endsWith(msg)) {
 				return true;
 			}
 		}
 		return false;
 	}
 
+	function getStoredType(typePackage:String, typeName:String) {
+		for (type in storedTypes) {
+			if (type.pack.join(".") == typePackage && type.name == typeName) {
+				return type;
+			}
+		}
+		return null;
+	}
+
 	function assertHasPrint(line:String, ?p:haxe.PosInfos) {
-		Assert.isTrue(hasMessage({kind: "print", data: line}), null, p);
+		Assert.isTrue(hasMessage("Haxe print: " + line), null, p);
 	}
 
 	function assertReuse(module:String, ?p:haxe.PosInfos) {
-		Assert.isTrue(hasMessage({kind: "reusing", data: module}), null, p);
+		Assert.isTrue(hasMessage('reusing $module'), null, p);
 	}
 
 	function assertSkipping(module:String, ?dependency:String, ?p:haxe.PosInfos) {
-		Assert.isTrue(hasMessage({kind: "skipping", data: {skipped: module, dependency: dependency == null ? module : dependency}}), null, p);
+		var msg = 'skipping $module';
+		if (dependency != null) {
+			msg += '($dependency)';
+		}
+		Assert.isTrue(hasMessage(msg), null, p);
 	}
 
 	function assertNotCacheModified(module:String, ?p:haxe.PosInfos) {
-		Assert.isTrue(hasMessage({kind: "notCached", data: module}), null, p);
+		Assert.isTrue(hasMessage('$module not cached (modified)'), null, p);
+	}
+
+	function assertHasType(typePackage:String, typeName:String, ?p:haxe.PosInfos) {
+		Assert.isTrue(getStoredType(typePackage, typeName) != null, null, p);
+	}
+
+	function assertHasField(typePackage:String, typeName:String, fieldName:String, isStatic:Bool, ?p:haxe.PosInfos) {
+		var type = getStoredType(typePackage, typeName);
+		Assert.isTrue(type != null);
+		function check<T>(type:JsonModuleType<T>) {
+			return switch [type.kind, type.args] {
+				case [Class, c]:
+					(isStatic ? c.statics : c.fields).exists(cf -> cf.name == fieldName);
+				case _: false;
+			}
+		}
+		if (type != null) {
+			Assert.isTrue(check(type), null, p);
+		}
 	}
 }

+ 25 - 13
tests/server/src/Main.hx

@@ -6,10 +6,10 @@ class NoModification extends HaxeServerTestCase {
 		async({
 			vfs.putContent("HelloWorld.hx", getTemplate("HelloWorld.hx"));
 			var args = ["-main", "HelloWorld.hx", "--no-output", "-js", "no.js"];
-			haxe(args);
-			haxe(args);
+			runHaxe(args);
+			runHaxe(args);
 			assertReuse("HelloWorld");
-			haxe(args);
+			runHaxe(args);
 			assertReuse("HelloWorld");
 		});
 	}
@@ -20,9 +20,9 @@ class Modification extends HaxeServerTestCase {
 		async({
 			vfs.putContent("HelloWorld.hx", getTemplate("HelloWorld.hx"));
 			var args = ["-main", "HelloWorld.hx", "--no-output", "-js", "no.js"];
-			haxe(args);
+			runHaxe(args);
 			vfs.touchFile("HelloWorld.hx");
-			haxe(args);
+			runHaxe(args);
 			assertSkipping("HelloWorld");
 			assertNotCacheModified("HelloWorld");
 		});
@@ -35,12 +35,12 @@ class Dependency extends HaxeServerTestCase {
 			vfs.putContent("WithDependency.hx", getTemplate("WithDependency.hx"));
 			vfs.putContent("Dependency.hx", getTemplate("Dependency.hx"));
 			var args = ["-main", "WithDependency.hx", "--no-output", "-js", "no.js"];
-			haxe(args);
+			runHaxe(args);
 			vfs.touchFile("Dependency.hx");
-			haxe(args);
+			runHaxe(args);
 			assertSkipping("WithDependency", "Dependency");
 			assertNotCacheModified("Dependency");
-			haxe(args);
+			runHaxe(args);
 			assertReuse("Dependency");
 			assertReuse("WithDependency");
 		});
@@ -53,24 +53,35 @@ class Macro extends HaxeServerTestCase {
 			vfs.putContent("MacroMain.hx", getTemplate("MacroMain.hx"));
 			vfs.putContent("Macro.hx", getTemplate("Macro.hx"));
 			var args = ["-main", "MacroMain.hx", "--no-output", "-js", "no.js"];
-			haxe(args);
+			runHaxe(args);
 			assertHasPrint("1");
 			vfs.touchFile("MacroMain.hx");
-			haxe(args);
+			runHaxe(args);
 			assertHasPrint("1");
 			vfs.touchFile("Macro.hx");
-			haxe(args);
+			runHaxe(args);
 			assertHasPrint("1");
 			vfs.putContent("Macro.hx", getTemplate("Macro.hx").replace("1", "2"));
-			haxe(args);
+			runHaxe(args);
 			assertHasPrint("2");
 			vfs.touchFile("MacroMain.hx");
-			haxe(args);
+			runHaxe(args);
 			assertHasPrint("2");
 		});
 	}
 }
 
+class DceEmpty extends HaxeServerTestCase {
+	public function test() {
+		async({
+			vfs.putContent("Empty.hx", getTemplate("Empty.hx"));
+			var args = ["-main", "Empty", "--no-output", "-java", "java"];
+			runHaxe(args);
+			runHaxe(args, true);
+			assertHasField("", "Type", "enumIndex", true);
+		});
+	}
+}
 
 class Main {
 	static public function main() {
@@ -80,6 +91,7 @@ class Main {
 		runner.addCase(new Modification());
 		runner.addCase(new Dependency());
 		runner.addCase(new Macro());
+		runner.addCase(new DceEmpty());
 		utest.ui.Report.create(runner);
 		runner.run();
 	}

+ 5 - 0
tests/server/test/templates/Empty.hx

@@ -0,0 +1,5 @@
+class Empty {
+	public static function main() {
+
+	}
+}