diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index 4dbd576cc6ddff..f612dcb76be527 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -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 @@ private static Func> CreateFunctionAcceptingArray() }; } + public static Task SynchronousTask() + { + return Task.CompletedTask; + } + + public static async Task AsynchronousTask() + { + await Task.Yield(); + } + + public static Task SynchronousTaskInt(int i) + { + return Task.FromResult(i); + } + + public static async Task 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 SynchronousValueTaskInt(int i) + { + return ValueTask.FromResult(i); + } + + public static async ValueTask 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 { diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs index fb52d1d58f4a7c..b4b20b30c80499 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs @@ -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 @@ public static void InvokeJSNotInGlobalScope() var result = Runtime.InvokeJS(@"var test_local_variable_name = 5; globalThis.test_local_variable_name"); Assert.Null(result); } + + private static async Task 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."); + } } }