[wasm] Add task marshaling tests. (#61324)
authorMarek Fišera <mara@neptuo.com>
Wed, 10 Nov 2021 09:20:40 +0000 (10:20 +0100)
committerGitHub <noreply@github.com>
Wed, 10 Nov 2021 09:20:40 +0000 (10:20 +0100)
Add various tests for marshaling task to JavaScript promise.

- Sync and async.
- Task and ValueTask.
- Generic and non-generic.
- Successful and failed.

src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs
src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs

index 4dbd576..f612dcb 100644 (file)
@@ -4,6 +4,7 @@
 using System.Runtime.InteropServices.JavaScript;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Runtime.InteropServices.JavaScript.Tests
@@ -641,6 +642,69 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
             };
         }
 
+        public static Task SynchronousTask() 
+        {
+            return Task.CompletedTask;
+        }
+
+        public static async Task AsynchronousTask() 
+        {
+            await Task.Yield();
+        }
+
+        public static Task<int> SynchronousTaskInt(int i) 
+        {
+            return Task.FromResult(i);
+        }
+
+        public static async Task<int> AsynchronousTaskInt(int i) 
+        {
+            await Task.Yield();
+            return i;
+        }
+
+        public static Task FailedSynchronousTask() 
+        {
+            return Task.FromException(new Exception());
+        }
+
+        public static async Task FailedAsynchronousTask() 
+        {
+            await Task.Yield();
+            throw new Exception();
+        }
+
+        public static async ValueTask AsynchronousValueTask() 
+        {
+            await Task.Yield();
+        }
+
+        public static ValueTask SynchronousValueTask() 
+        {
+            return ValueTask.CompletedTask;
+        }
+
+        public static ValueTask<int> SynchronousValueTaskInt(int i) 
+        {
+            return ValueTask.FromResult(i);
+        }
+
+        public static async ValueTask<int> AsynchronousValueTaskInt(int i) 
+        {
+            await Task.Yield();
+            return i;
+        }
+
+        public static ValueTask FailedSynchronousValueTask() 
+        {
+            return ValueTask.FromException(new Exception());
+        }
+
+        public static async ValueTask FailedAsynchronousValueTask() 
+        {
+            await Task.Yield();
+            throw new Exception();
+        }
     }
 
     public enum TestEnum : uint {
index fb52d1d..b4b20b3 100644 (file)
@@ -3,6 +3,8 @@
 
 using System.Runtime.InteropServices.JavaScript;
 using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Runtime.InteropServices.JavaScript.Tests
@@ -899,5 +901,122 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
             var result = Runtime.InvokeJS(@"var test_local_variable_name = 5; globalThis.test_local_variable_name");
             Assert.Null(result);
         }
+
+        private static async Task<bool> MarshalTask(string helperMethodName, string helperMethodArgs = "", string resolvedBody = "") 
+        {
+            Runtime.InvokeJS(
+                @"globalThis.__test_promise_completed = false; " +
+                @"globalThis.__test_promise_resolved = false; " +
+                @"globalThis.__test_promise_failed = false; " +
+                $@"var t = App.call_test_method ('{helperMethodName}', [ {helperMethodArgs} ], 'i'); " +
+                "t.finally(result => { globalThis.__test_promise_completed = true; }); " + 
+                "t.then(result => { globalThis.__test_promise_resolved = true; " + resolvedBody + " }); " + 
+                "t.catch(e => { console.log(e); globalThis.__test_promise_failed = true; }); "
+            );
+
+            await Task.Delay(1);
+
+            var completed = bool.Parse(Runtime.InvokeJS(@"globalThis.__test_promise_completed"));
+            Assert.True(completed, "JavasScript promise did not completed.");
+
+            var resolved = bool.Parse(Runtime.InvokeJS(@"globalThis.__test_promise_resolved"));
+            return resolved;
+        }
+
+        private static async Task MarshalTaskReturningInt(string helperMethodName)
+        {
+            HelperMarshal._intValue = 0;
+
+            bool success = await MarshalTask(helperMethodName, "7", "App.call_test_method ('InvokeInt', [ result ], 'i');");
+
+            Assert.True(success, $"{helperMethodName} didn't succeeded.");
+            Assert.Equal(7, HelperMarshal._intValue);
+        }
+
+        [Fact]
+        public static async Task MarshalSynchronousTask()
+        {
+            bool success = await MarshalTask("SynchronousTask");
+            Assert.True(success, "SynchronousTask didn't succeeded.");
+        }
+
+        [Fact]
+        public static async Task MarshalAsynchronousTask()
+        {
+            bool success = await MarshalTask("AsynchronousTask");
+            Assert.True(success, "AsynchronousTask didn't succeeded.");
+        }
+
+        [Fact]
+        public static Task MarshalSynchronousTaskInt()
+        {
+            return MarshalTaskReturningInt("SynchronousTaskInt");
+        }
+
+        [Fact]
+        public static Task MarshalAsynchronousTaskInt()
+        {
+            return MarshalTaskReturningInt("AsynchronousTaskInt");
+        }
+
+        [Fact]
+        public static async Task MarshalFailedSynchronousTask()
+        {
+            bool success = await MarshalTask("FailedSynchronousTask");
+            Assert.False(success, "FailedSynchronousTask didn't failed.");
+        }
+
+        [Fact]
+        public static async Task MarshalFailedAsynchronousTask()
+        {
+            bool success = await MarshalTask("FailedAsynchronousTask");
+            Assert.False(success, "FailedAsynchronousTask didn't failed.");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static async Task MarshalSynchronousValueTaskDoesNotWorkYet()
+        {
+            bool success = await MarshalTask("SynchronousValueTask");
+            Assert.True(success, "SynchronousValueTask didn't succeeded.");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static async Task MarshalAsynchronousValueTaskDoesNotWorkYet()
+        {
+            bool success = await MarshalTask("AsynchronousValueTask");
+            Assert.True(success, "AsynchronousValueTask didn't succeeded.");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static Task MarshalSynchronousValueTaskIntDoesNotWorkYet()
+        {
+            return MarshalTaskReturningInt("SynchronousValueTaskInt");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static Task MarshalAsynchronousValueTaskIntDoesNotWorkYet()
+        {
+            return MarshalTaskReturningInt("AsynchronousValueTaskInt");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static async Task MarshalFailedSynchronousValueTaskDoesNotWorkYet()
+        {
+            bool success = await MarshalTask("FailedSynchronousValueTask");
+            Assert.False(success, "FailedSynchronousValueTask didn't failed.");
+        }
+
+        [Fact]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/61368")]
+        public static async Task MarshalFailedAsynchronousValueTaskDoesNotWorkYet()
+        {
+            bool success = await MarshalTask("FailedAsynchronousValueTask");
+            Assert.False(success, "FailedAsynchronousValueTask didn't failed.");
+        }
     }
 }