فهرست منبع

Test support in wasm

Brian Fiete 9 ماه پیش
والد
کامیت
c0ebcc8fda
4فایلهای تغییر یافته به همراه132 افزوده شده و 9 حذف شده
  1. 92 0
      BeefLibs/corlib/src/Internal.bf
  2. 17 5
      BeefTools/WasmLaunch/src/Program.bf
  3. 1 1
      IDE/src/BuildContext.bf
  4. 22 3
      IDE/src/IDEApp.bf

+ 92 - 0
BeefLibs/corlib/src/Internal.bf

@@ -1,5 +1,6 @@
 using System.Collections;
 using System.Reflection;
+using System.Diagnostics;
 
 namespace System
 {
@@ -98,6 +99,96 @@ namespace System
 		[Intrinsic("returnaddress")]
 		public static extern void* GetReturnAddress(int32 level = 0);
 
+#if BF_PLATFORM_WASM
+		static int32 sTestIdx;
+		class TestEntry
+		{
+			public String mName ~ delete _;
+			public String mFilePath ~ delete _;
+			public int mLine;
+			public int mColumn;
+			public bool mShouldFail;
+			public bool mProfile;
+			public bool mIgnore;
+			public bool mFailed;
+			public bool mExecuted;
+		}
+		static List<TestEntry> sTestEntries ~ DeleteContainerAndItems!(_);
+
+		[CallingConvention(.Cdecl), LinkName("Test_Init_Wasm")]
+		static void Test_Init(char8* testData)
+		{
+			sTestEntries = new .();
+
+			for (var cmd in StringView(testData).Split('\n'))
+			{
+				List<StringView> cmdParts = scope .(cmd.Split('\t'));
+				let attribs = cmdParts[1];
+
+				TestEntry testEntry = new TestEntry();
+				testEntry.mName = new String(cmdParts[0]);
+				testEntry.mFilePath = new String(cmdParts[2]);
+				testEntry.mLine = int32.Parse(cmdParts[3]).Get();
+				testEntry.mColumn = int32.Parse(cmdParts[4]).Get();
+				List<StringView> attributes = scope .(attribs.Split('\a'));
+				for(var i in attributes)
+				{
+					if(i.StartsWith('\v'))
+					{
+						if(i == "Sf")
+							testEntry.mShouldFail = true;
+						else if(i == "Pr")
+							testEntry.mProfile = true;
+						else if(i == "Ig")
+							testEntry.mIgnore = true;
+					}
+					else if(i.StartsWith("Name"))
+					{
+						testEntry.mName.Clear();
+						scope String(i.Substring("Name".Length)).Escape(testEntry.mName);
+					}
+				}
+				sTestEntries.Add(testEntry);
+			}
+		}
+
+		[CallingConvention(.Cdecl), LinkName("Test_Error_Wasm")]
+		static void Test_Error(char8* error)
+		{
+			Debug.WriteLine(scope $"TEST ERROR: {StringView(error)}");
+		}
+
+		[CallingConvention(.Cdecl), LinkName("Test_Write_Wasm")]
+		static void Test_Write(char8* str)
+		{
+			Debug.Write(StringView(str));
+		}
+
+		[CallingConvention(.Cdecl), LinkName("Test_Query_Wasm")]
+		static int32 Test_Query()
+		{
+			while (sTestIdx < sTestEntries.Count)
+			{
+				var testEntry = sTestEntries[sTestIdx];
+				if ((testEntry.mIgnore) || (testEntry.mShouldFail))
+				{
+					sTestIdx++;
+					continue;
+				}
+
+				Debug.WriteLine($"Test '{testEntry.mName}'");
+				break;
+			}
+			
+			return sTestIdx++;
+		}
+
+		[CallingConvention(.Cdecl), LinkName("Test_Finish_Wasm")]
+		static void Test_Finish()
+		{
+			Debug.WriteLine("Tests done.");
+		}
+#else
 		[CallingConvention(.Cdecl)]
 		static extern void Test_Init(char8* testData);
 		[CallingConvention(.Cdecl)]
@@ -108,6 +199,7 @@ namespace System
 		static extern int32 Test_Query();
 		[CallingConvention(.Cdecl)]
 		static extern void Test_Finish();
+#endif
 
 		static void* sModuleHandle;
 		[AlwaysInclude]

+ 17 - 5
BeefTools/WasmLaunch/src/Program.bf

@@ -36,18 +36,19 @@ class Program
 			process.Kill();
 	}
 
-	static void WaitForPort(int32 port)
+	static bool WaitForPort(int32 port, int32 maxWaitTime)
 	{
 		Stopwatch sw = scope .();
 		sw.Start();
 
 		Socket.Init();
-		while (sw.ElapsedMilliseconds < 5000)
+		while (sw.ElapsedMilliseconds < maxWaitTime)
 		{
 			var socket = scope Socket();
 			if (socket.Connect("127.0.0.1", port, var sockaddr) case .Ok)
-				return;
+				return true;
 		}
+		return false;
 	}
 
 	public static void OpenURL(StringView url)
@@ -109,13 +110,24 @@ class Program
 		ProcessStartInfo procInfo = scope ProcessStartInfo();
 		procInfo.UseShellExecute = false;
 		procInfo.SetFileName(serverPath);
-		procInfo.SetArguments(scope $"-p {port} {htmlDir}");
+		procInfo.SetArguments(scope $"-p {port} \"{htmlDir}\"");
 		procInfo.CreateNoWindow = true;
 
 		var process = scope SpawnedProcess();
 		process.Start(procInfo).IgnoreError();
 
-		WaitForPort(port);
+		Stopwatch sw = scope .()..Start();
+		while (true)
+		{
+			if (WaitForPort(port, 1000))
+				break;
+			if ((process.WaitFor(0)) || (sw.ElapsedMilliseconds >= 15*1000))
+			{
+				Windows.MessageBoxA(default, scope $"Failed to start miniserve on port {port}", "WASM LAUNCH ERROR", Windows.MB_ICONHAND | Windows.MB_OK);
+				return 1;
+			}
+		}
+
 		OpenURL(scope $"http://127.0.0.1:{port}/{htmlFileName}");
 
 		while (true)

+ 1 - 1
IDE/src/BuildContext.bf

@@ -1432,7 +1432,7 @@ namespace IDE
 		    String outputDir = scope String();
 			String absOutputDir = scope String();
 			
-			if (testProjectInfo != null)
+			if ((testProjectInfo != null) && (mPlatformType != .Wasm))
 			{
 				absOutputDir.Append(projectBuildDir);
 				outputDir = absOutputDir;

+ 22 - 3
IDE/src/IDEApp.bf

@@ -614,6 +614,15 @@ namespace IDE
 			}
 		}
 
+		public Workspace.PlatformType CurrentPlatform
+		{
+			get
+			{
+				Workspace.Options workspaceOptions = GetCurWorkspaceOptions();
+				return Workspace.PlatformType.GetFromName(mPlatformName, workspaceOptions.mTargetTriple);
+			}
+		}
+
 		[CallingConvention(.Stdcall), CLink]
 		static extern void IDEHelper_ProgramStart();
 		[CallingConvention(.Stdcall), CLink]
@@ -5864,6 +5873,15 @@ namespace IDE
 		[IDECommand]
 		protected void RunTests(bool includeIgnored, bool debug)
 		{
+			var workspaceOptions = GetCurWorkspaceOptions();
+			if (CurrentPlatform == .Wasm)
+			{
+				if (workspaceOptions.mBuildKind != .Test)
+					mMainFrame.mStatusBar.SelectConfig("Test");
+				CompileAndRun(true);
+				return;
+			}
+
 			if (mOutputPanel != null)
 			{
 				ShowPanel(mOutputPanel, false);
@@ -5884,7 +5902,6 @@ namespace IDE
 
 			String prevConfigName = scope String(mConfigName);
 
-			var workspaceOptions = GetCurWorkspaceOptions();
 			if (workspaceOptions.mBuildKind != .Test)
 			{
 				mMainFrame.mStatusBar.SelectConfig("Test");
@@ -5898,10 +5915,12 @@ namespace IDE
 				return;
 			}
 
+			var platformType = Workspace.PlatformType.GetFromName(gApp.mPlatformName, workspaceOptions.mTargetTriple);
+
 			mLastTestFailed = false;
 			mTestManager = new TestManager();
 			mTestManager.mPrevConfigName = new String(prevConfigName);
-			mTestManager.mDebug = debug;
+			mTestManager.mDebug = debug && (platformType != .Wasm);
 			mTestManager.mIncludeIgnored = includeIgnored;
 
 			if (mOutputPanel != null)
@@ -12093,7 +12112,7 @@ namespace IDE
 
 			if ((compileKind == .RunAfter) || (compileKind == .DebugAfter))
 			{
-				if (workspaceOptions.mBuildKind == .Test)
+				if ((workspaceOptions.mBuildKind == .Test) && (platform != .Wasm))
 				{
 					OutputErrorLine("Cannot directly run Test workspace configurations. Use the 'Test' menu to run or debug tests.");
 					return false;