diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index b6ea05e7c7f879..deda2ad9de8e51 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -56,6 +56,9 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void CancelPromiseRef(IntPtr promiseJSHandle, out int exceptionalResult, out string result); + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern void DoNothing(out int exceptionalResult); + // / // / Execute the provided string in the JavaScript context // / diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index bb909a4d5e1694..e41feb90c90121 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace System.Runtime.InteropServices.JavaScript @@ -12,6 +13,13 @@ public static partial class Runtime private const string TaskGetResultName = "get_Result"; private static readonly MethodInfo _taskGetResultMethodInfo = typeof(Task<>).GetMethod(TaskGetResultName)!; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int DoNothing() + { + Interop.Runtime.DoNothing(out int exception); + return exception; + } + /// /// Execute the provided string in the JavaScript context /// diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj index 5bfcbdfe2a41e8..1d7b0f3beb4190 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj @@ -7,16 +7,6 @@ - - - - - - - - - - diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs deleted file mode 100644 index ae247a1bb2f63c..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class ArrayTests - { - [Fact] - public static void ArrayLength() - { - Array d = new Array(); - Assert.Equal(0, d.Length); - } - - [Fact] - public static void ArrayLength1() - { - Array d = new Array(50); - Assert.Equal(50, d.Length); - } - - [Fact] - public static void Array_GetSetItem() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - IList iList = new int[] { 7, 8, 9, 10, 11, 12, 13 }; - - Assert.Equal(jsArray.Length, iList.Count); - for (int i = 0; i < iList.Count; i++) - { - Assert.Equal(jsArray[i], iList[i]); - - iList[i] = 99; - jsArray[i] = 99; - Assert.Equal(99, iList[i]); - Assert.Equal(99, jsArray[i]); - } - } - - [Fact] - public static void Array_GetSetItemInvalid() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Null(jsArray[-1]); - Assert.Null(jsArray[jsArray.Length]); - Assert.Equal(0, jsArray[-1] = 0); - Assert.Equal(0, jsArray[jsArray.Length] = 0); - } - - [Fact] - public static void Array_GetItemIndex() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Equal(7, jsArray[0]); - Assert.Equal(8, jsArray[1]); - Assert.Equal(9, jsArray[2]); - Assert.Equal(10, jsArray[3]); - Assert.Equal(11, jsArray[4]); - Assert.Equal(12, jsArray[5]); - Assert.Equal(13, jsArray[6]); - } - - [Fact] - public static void Array_GetSetItemIndex() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - for (int d = 0; d < jsArray.Length; d++) - { - jsArray[d] = (int)jsArray[d] + 1; - } - Assert.Equal(8, jsArray[0]); - Assert.Equal(9, jsArray[1]); - Assert.Equal(10, jsArray[2]); - Assert.Equal(11, jsArray[3]); - Assert.Equal(12, jsArray[4]); - Assert.Equal(13, jsArray[5]); - Assert.Equal(14, jsArray[6]); - } - - [Fact] - public static void Array_Pop() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Equal(13, jsArray.Pop()); - Assert.Equal(12, jsArray.Pop()); - Assert.Equal(11, jsArray.Pop()); - Assert.Equal(10, jsArray.Pop()); - Assert.Equal(9, jsArray.Pop()); - Assert.Equal(8, jsArray.Pop()); - Assert.Equal(7, jsArray.Pop()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_PushPop() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - jsArray.Push(objArray[d]); - } - Assert.Equal("test13", jsArray.Pop()); - Assert.Equal("test12", jsArray.Pop()); - Assert.Equal("test11", jsArray.Pop()); - Assert.Equal("test10", jsArray.Pop()); - Assert.Equal("test9", jsArray.Pop()); - Assert.Equal("test8", jsArray.Pop()); - Assert.Equal("test7", jsArray.Pop()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_PushShift() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - jsArray.Push(objArray[d]); - } - Assert.Equal("test7", jsArray.Shift()); - Assert.Equal("test8", jsArray.Shift()); - Assert.Equal("test9", jsArray.Shift()); - Assert.Equal("test10", jsArray.Shift()); - Assert.Equal("test11", jsArray.Shift()); - Assert.Equal("test12", jsArray.Shift()); - Assert.Equal("test13", jsArray.Shift()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_UnShiftShift() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - Assert.Equal(d + 1, jsArray.UnShift(objArray[d])); - } - Assert.Equal("test13", jsArray.Shift()); - Assert.Equal("test12", jsArray.Shift()); - Assert.Equal("test11", jsArray.Shift()); - Assert.Equal("test10", jsArray.Shift()); - Assert.Equal("test9", jsArray.Shift()); - Assert.Equal("test8", jsArray.Shift()); - Assert.Equal("test7", jsArray.Shift()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_IndexOf() - { - var beasts = new Array("ant", "bison", "camel", "duck", "bison"); - Assert.Equal(1, beasts.IndexOf("bison")); - Assert.Equal(4, beasts.IndexOf("bison", 2)); - Assert.Equal(-1, beasts.IndexOf("giraffe")); - } - - [Fact] - public static void Array_LastIndexOf() - { - var beasts = new Array("Dodo", "Tiger", "Penguin", "Dodo"); - Assert.Equal(3, beasts.LastIndexOf("Dodo")); - Assert.Equal(1, beasts.LastIndexOf("Tiger")); - Assert.Equal(0, beasts.LastIndexOf("Dodo", 2)); // The array is searched backwards - Assert.Equal(-1, beasts.LastIndexOf("giraffe")); - } - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs deleted file mode 100644 index 4e06bf20f005a1..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class DataViewTests - { - [Fact] - public static void DataViewConstructor() - { - // create an ArrayBuffer with a size in bytes - var buffer = new ArrayBuffer(16); - - // Create a couple of views - var view1 = new DataView(buffer); - var view2 = new DataView(buffer, 12, 4); //from byte 12 for the next 4 bytes - view1.SetInt8(12, 42); // put 42 in slot 12 - - Assert.Equal(42, view2.GetInt8(0)); - } - - public static IEnumerable ArrayBuffer_Test_Data() - { - yield return new object[] { new ArrayBuffer(12) }; - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewArrayBuffer(ArrayBuffer buffer) - { - var x = new DataView(buffer); - Assert.True(buffer == x.Buffer); - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewByteLength(ArrayBuffer buffer) - { - var x = new DataView(buffer, 4, 2); - Assert.Equal(2, x.ByteLength); - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewByteOffset(ArrayBuffer buffer) - { - var x = new DataView(buffer, 4, 2); - Assert.Equal(4, x.ByteOffset); - } - - public static IEnumerable DataView_Test_Data() - { - yield return new object[] { new DataView(new ArrayBuffer(12), 0) }; - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - - public static void DataViewGetFloat32(DataView view) - { - view.SetFloat32(1, (float)Math.PI); - Assert.Equal((float)Math.Round(Math.PI, 5), (float)Math.Round(view.GetFloat32(1), 5)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetFloat64(DataView view) - { - view.SetFloat64(1, (float)Math.PI); - Assert.Equal(Math.Round(Math.PI, 5), Math.Round(view.GetFloat64(1), 5)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt16(DataView view) - { - view.SetInt16(1, 1234); - Assert.Equal(1234, view.GetInt16(1)); - - view.SetInt16(1, -1234); - Assert.Equal(-1234, view.GetInt16(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt32(DataView view) - { - view.SetInt32(1, 1234); - Assert.Equal(1234, view.GetInt32(1)); - - view.SetInt32(1, -1234); - Assert.Equal(-1234, view.GetInt32(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt8(DataView view) - { - view.SetInt8(1, 123); - Assert.Equal(123, view.GetInt8(1)); - - view.SetInt8(1, -123); - Assert.Equal(-123, view.GetInt8(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint16(DataView view) - { - view.SetUint16(1, 1234); - Assert.Equal(1234, view.GetUint16(1)); - - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint32(DataView view) - { - view.SetUint32(1, 1234); - Assert.Equal(1234u, view.GetUint32(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint8(DataView view) - { - view.SetUint8(1, 123); - Assert.Equal(123u, view.GetUint8(1)); - } - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs deleted file mode 100644 index 1117c5fc740b1f..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ /dev/null @@ -1,450 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class DelegateTests - { - private static Function _objectPrototype; - - [Fact] - public static void InvokeFunction() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - - Runtime.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(30, HelperMarshal._functionResultValue); - Assert.Equal(60, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeFunctionInLoopUsingConstanceValues() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - - Runtime.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - for (let x = 0; x < 1000; x++) - { - res = funcDelegate (10, 20); - } - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(30, HelperMarshal._functionResultValue); - Assert.Equal(60, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeFunctionInLoopUsingIncrementedValues() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - Runtime.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - for (let x = 0; x < 1000; x++) - { - res = funcDelegate (x, x); - } - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(1998, HelperMarshal._functionResultValue); - Assert.Equal(3996, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeActionTReturnedByInvokingFuncT() - { - HelperMarshal._functionActionResultValue = 0; - HelperMarshal._functionActionResultValueOfAction = 0; - - Runtime.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegateWithAction"", [ ]); - var actionDelegate = funcDelegate (10, 20); - actionDelegate(30,40); - "); - - Assert.Equal(30, HelperMarshal._functionActionResultValue); - Assert.Equal(70, HelperMarshal._functionActionResultValueOfAction); - } - - [Fact] - public static void InvokeActionIntInt() - { - HelperMarshal._actionResultValue = 0; - - Runtime.InvokeJS(@" - var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); - actionDelegate(30,40); - "); - - Assert.Equal(70, HelperMarshal._actionResultValue); - } - - [Fact] - public static void InvokeActionFloatIntToIntInt() - { - HelperMarshal._actionResultValue = 0; - var ex = Assert.Throws(()=>Runtime.InvokeJS(@" - var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); - actionDelegate(3.14,40); - ")); - - Assert.Contains("Value is not an integer: 3.14 (number)", ex.Message); - Assert.Equal(0, HelperMarshal._actionResultValue); - } - - [Fact] - public static void InvokeDelegateMethod() - { - HelperMarshal._delMethodResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateMethod"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Hic sunt dracones", HelperMarshal._delMethodResultValue); - } - - [Fact] - public static void InvokeDelegateMethodReturnString() - { - HelperMarshal._delMethodStringResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateMethodReturnString"", [ ]); - var res = del(""Hic sunt dracones""); - App.call_test_method (""SetTestString1"", [ res ]); - "); - - Assert.Equal("Received: Hic sunt dracones", HelperMarshal._delMethodStringResultValue); - } - - [Theory] - [InlineData("CreateCustomMultiCastDelegate_VoidString", "Moin")] - [InlineData("CreateMultiCastAction_VoidString", "MoinMoin")] - public static void InvokeMultiCastDelegate_VoidString(string creator, string testStr) - { - HelperMarshal._delegateCallResult = string.Empty; - Runtime.InvokeJS($@" - var del = App.call_test_method (""{creator}"", [ ]); - del(""{testStr}""); - "); - Assert.Equal($" Hello, {testStr}! GoodMorning, {testStr}!", HelperMarshal._delegateCallResult); - } - - [Theory] - [InlineData("CreateDelegateFromAnonymousMethod_VoidString")] - [InlineData("CreateDelegateFromLambda_VoidString")] - [InlineData("CreateDelegateFromMethod_VoidString")] - [InlineData("CreateActionT_VoidString")] - public static void InvokeDelegate_VoidString(string creator) - { - HelperMarshal._delegateCallResult = string.Empty; - var s = Runtime.InvokeJS($@" - var del = App.call_test_method (""{creator}"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delegateCallResult); - } - - public static IEnumerable ArrayType_TestData() - { - _objectPrototype ??= new Function("return Object.prototype.toString;"); - yield return new object[] { _objectPrototype.Call(), "Uint8Array", Uint8Array.From(new byte[10]) }; - yield return new object[] { _objectPrototype.Call(), "Array", new Array(10) }; - } - - [Theory] - [MemberData(nameof(ArrayType_TestData))] - public static void InvokeFunctionAcceptingArrayTypes(Function objectPrototype, string creator, JSObject arrayType) - { - HelperMarshal._funcActionBufferObjectResultValue = arrayType; - Assert.Equal(10, HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length")); - Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); - - Runtime.InvokeJS($@" - var buffer = new {creator}(50); - var del = App.call_test_method (""CreateFunctionAccepting{creator}"", [ ]); - var setAction = del(buffer); - setAction(buffer); - "); - - Assert.Equal(50, HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length")); - Assert.Equal(HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length"), HelperMarshal._funcActionBufferResultLengthValue); - Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); - } - - [Fact] - public static void DispatchToDelegate() - { - var factory = new Function(@"return { - callback: null, - eventFactory:function(data){ - return { - data:data - }; - }, - fireEvent: function (evt) { - this.callback(evt); - } - };"); - var dispatcher = (JSObject)factory.Call(); - var temp = new bool[2]; - Action cb = (JSObject envt) => - { - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }; - dispatcher.SetObjectProperty("callback", cb); - var evnt0 = dispatcher.Invoke("eventFactory", 0); - var evnt1 = dispatcher.Invoke("eventFactory", 1); - dispatcher.Invoke("fireEvent", evnt0); - dispatcher.Invoke("fireEvent", evnt0); - dispatcher.Invoke("fireEvent", evnt1); - Assert.True(temp[0]); - Assert.True(temp[1]); - } - - [Fact] - public static void EventsAreNotCollected() - { - const int attempts = 100; // we fire 100 events in a loop, to try that it's GC same - var factory = new Function(@"return { - callback: null, - eventFactory:function(data){ - return { - data:data - }; - }, - fireEvent: function (evt) { - this.callback(evt); - } - };"); - var dispatcher = (JSObject)factory.Call(); - var temp = new bool[attempts]; - Action cb = (JSObject envt) => - { -#if DEBUG - envt.AssertNotDisposed(); - envt.AssertInFlight(0); -#endif - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }; - dispatcher.SetObjectProperty("callback", cb); - - var evnt = dispatcher.Invoke("eventFactory", 0); - for (int i = 0; i < attempts; i++) - { - var evnti = dispatcher.Invoke("eventFactory", i); - dispatcher.Invoke("fireEvent", evnti); - dispatcher.Invoke("fireEvent", evnt); - Runtime.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - } - } - - - [Fact] - public static void NullDelegate() - { - var factory = new Function("delegate", "callback", @" - callback(delegate); - "); - - Delegate check = null; - Action callback = (Delegate data) => - { - check = data; - }; - factory.Call(null, null, callback); - Assert.Null(check); - } - - [Fact] - public static async Task ResolveStringPromise() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve('foo'); - }, 10); - });"); - - var promise = (Task)factory.Call(); - var value = await promise; - - Assert.Equal("foo", (string)value); - - } - - [Fact] - public static async Task ResolveJSObjectPromise() - { - for (int i = 0; i < 10; i++) - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve({foo:'bar'}); - }, 10); - });"); - - var promise = (Task)factory.Call(); - var value = (JSObject)await promise; - - Assert.Equal("bar", value.GetObjectProperty("foo")); - Runtime.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - } - } - - [Fact] - public static async Task RejectPromise() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - reject('fail'); - }, 10); - });"); - - var promise = (Task)factory.Call(); - - var ex = await Assert.ThrowsAsync(async () => await promise); - Assert.Equal("fail", ex.Message); - } - - [Fact] - public static async Task RejectPromiseError() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error('fail')); - }, 10); - });"); - - var promise = (Task)factory.Call(); - - var ex = await Assert.ThrowsAsync(async () => await promise); - Assert.Equal("Error: fail", ex.Message); - } - - - [ActiveIssue("https://github.com/dotnet/runtime/issues/56963")] - [Fact] - public static void RoundtripPromise() - { - var factory = new Function(@" - var dummy=new Promise((resolve, reject) => {}); - return { - dummy:dummy, - check:(promise)=>{ - return promise===dummy ? 1:0; - } - }"); - - var obj = (JSObject)factory.Call(); - var dummy = obj.GetObjectProperty("dummy"); - Assert.IsType>(dummy); - var check = obj.Invoke("check", dummy); - Assert.Equal(1, check); - } - - - [Fact] - public static async Task ResolveTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - return task.then((data)=>{ - callback(data); - }) - "); - - int check = 0; - Action callback = (int data) => - { - check = data; - }; - Task task = tcs.Task; - // we are testing that Task is marshaled as thenable - var promise = (Task)factory.Call(null, task, callback); - tcs.SetResult(1); - // the result value is not applied until we await the promise - Assert.Equal(0, check); - await promise; - // but it's set after we do - Assert.Equal(1, check); - } - - [Fact] - public static async Task RejectTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - return task.catch((reason)=>{ - callback(reason); - }) - "); - - string check = null; - Action callback = (string data) => - { - check = data; - }; - var promise = (Task)factory.Call(null, tcs.Task, callback); - Assert.Null(check); - tcs.SetException(new Exception("test")); - Assert.Null(check); - await promise; - Assert.Contains("System.Exception: test", check); - } - - [Fact] - public static void NullTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - callback(task); - "); - - Task check = Task.FromResult(1); - Action callback = (Task data) => - { - check = data; - }; - factory.Call(null, null, callback); - Assert.Null(check); - } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/56963")] - [Fact] - public static void RoundtripTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("dummy", @" - return { - dummy:dummy, - }"); - - var obj = (JSObject)factory.Call(null, tcs.Task); - var dummy = obj.GetObjectProperty("dummy"); - Assert.IsType>(dummy); - } - } -} 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 deleted file mode 100644 index 6d290ca4d71d62..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ /dev/null @@ -1,495 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading.Tasks; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class HelperMarshal - { - internal const string INTEROP_CLASS = "[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:"; - internal static int _i32Value; - private static void InvokeI32(int a, int b) - { - _i32Value = a + b; - } - - internal static float _f32Value; - private static void InvokeFloat(float f) - { - _f32Value = f; - } - - internal static double _f64Value; - private static void InvokeDouble(double d) - { - _f64Value = d; - } - - internal static long _i64Value; - private static void InvokeLong(long l) - { - _i64Value = l; - } - - internal static byte[] _byteBuffer; - private static void MarshalArrayBuffer(ArrayBuffer buffer) - { - using (var bytes = new Uint8Array(buffer)) - _byteBuffer = bytes.ToArray(); - } - - private static void MarshalByteBuffer(Uint8Array buffer) - { - _byteBuffer = buffer.ToArray(); - } - - internal static string _stringResource; - private static void InvokeString(string s) - { - _stringResource = s; - } - - internal static string _stringResource2; - private static void InvokeString2(string s) - { - _stringResource2 = s; - } - - private static string StoreArgumentAndReturnLiteral(string s) - { - _stringResource = $"s: {s} length: {s?.Length}"; - return "1"; - } - - private static string StoreAndReturnNew(string s) - { - var sb = new System.Text.StringBuilder(); - sb.Append("Got:"); - sb.Append(' '); - sb.Append(s); - _stringResource = sb.ToString(); - return _stringResource; - } - - internal static string _marshaledString; - private static string InvokeMarshalString() - { - _marshaledString = "Hic Sunt Dracones"; - return _marshaledString; - } - - internal static object _object1; - private static object InvokeObj1(object obj) - { - _object1 = obj; - return obj; - } - - internal static object _object2; - private static object InvokeObj2(object obj) - { - _object2 = obj; - return obj; - } - - internal static object _marshaledObject; - private static object InvokeMarshalObj() - { - _marshaledObject = new object(); - return _marshaledObject; - } - - private static object InvokeReturnMarshalObj() - { - return _marshaledObject; - } - - private static int InvokeReturnInt() - { - return 42; - } - - private static long InvokeReturnLong() - { - return 42L; - } - - private static double InvokeReturnDouble() - { - return double.Pi; - } - - internal static int _valOne, _valTwo; - private static void ManipulateObject(JSObject obj) - { - _valOne = (int)obj.Invoke("inc"); - _valTwo = (int)obj.Invoke("add", 20); - } - - internal static object[] _jsObjects; - private static void MinipulateObjTypes(JSObject obj) - { - _jsObjects = new object[4]; - _jsObjects[0] = obj.Invoke("return_int"); - _jsObjects[1] = obj.Invoke("return_double"); - _jsObjects[2] = obj.Invoke("return_string"); - _jsObjects[3] = obj.Invoke("return_bool"); - } - - internal static int _jsAddFunctionResult; - private static void UseFunction(JSObject obj) - { - _jsAddFunctionResult = (int)obj.Invoke("call", null, 10, 20); - } - - internal static int _jsAddAsFunctionResult; - private static void UseAsFunction(Function func) - { - _jsAddAsFunctionResult = (int)func.Call(null, 20, 30); - } - - internal static int _intValue; - private static void InvokeInt(int value) - { - _intValue = value; - } - - internal static IntPtr _intPtrValue; - private static void InvokeIntPtr(IntPtr i) - { - _intPtrValue = i; - } - - internal static IntPtr _marshaledIntPtrValue; - private static IntPtr InvokeMarshalIntPtr() - { - _marshaledIntPtrValue = (IntPtr)42; - return _marshaledIntPtrValue; - } - - internal static object[] _jsProperties; - private static void RetrieveObjectProperties(JSObject obj) - { - _jsProperties = new object[4]; - _jsProperties[0] = obj.GetObjectProperty("myInt"); - _jsProperties[1] = obj.GetObjectProperty("myDouble"); - _jsProperties[2] = obj.GetObjectProperty("myString"); - _jsProperties[3] = obj.GetObjectProperty("myBoolean"); - } - - private static void PopulateObjectProperties(JSObject obj, bool createIfNotExist) - { - _jsProperties = new object[4]; - obj.SetObjectProperty("myInt", 100, createIfNotExist); - obj.SetObjectProperty("myDouble", 4.5, createIfNotExist); - obj.SetObjectProperty("myString", "qwerty", createIfNotExist); - obj.SetObjectProperty("myBoolean", true, createIfNotExist); - } - - private static void SetTypedArrayByte(JSObject obj) - { - var dragons = "hic sunt dracones"; - byte[] buffer = System.Text.Encoding.ASCII.GetBytes(dragons); - obj.SetObjectProperty("dracones", Uint8Array.From(buffer)); - } - - internal static byte[] _taByte; - private static void GetTypedArrayByte(JSObject obj) - { - _taByte = ((Uint8Array)obj.GetObjectProperty("dracones")).ToArray(); - } - - private static Function _sumFunction; - private static void CreateFunctionSum() - { - _sumFunction = new Function("a", "b", "return a + b"); - } - - internal static int _sumValue = 0; - private static void CallFunctionSum() - { - if (_sumFunction == null) - throw new Exception("_sumFunction is null"); - _sumValue = (int)_sumFunction.Call(null, 3, 5); - } - - private static Function _mathMinFunction; - private static void CreateFunctionApply() - { - var math = (JSObject)Runtime.GetGlobalObject("Math"); - if (math == null) - throw new Exception("Runtime.GetGlobalObject(Math) returned null"); - _mathMinFunction = (Function)math.GetObjectProperty("min"); - - } - - internal static int _minValue = 0; - private static void CallFunctionApply() - { - if (_mathMinFunction == null) - throw new Exception("_mathMinFunction is null"); - _minValue = (int)_mathMinFunction.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - } - - internal static Uri _blobURL; - public static void SetBlobUrl(string blobUrl) - { - _blobURL = new Uri(blobUrl); - } - - internal static Uri _blobURI; - public static void SetBlobAsUri(Uri blobUri) - { - _blobURI = blobUri; - } - - internal static uint _uintValue; - private static void InvokeUInt(uint value) - { - _uintValue = value; - } - - internal static TestEnum _enumValue; - private static void SetEnumValue(TestEnum value) - { - _enumValue = value; - } - private static TestEnum GetEnumValue() - { - return _enumValue; - } - - private static UInt64 GetUInt64() - { - return UInt64.MaxValue; - } - - internal static int _functionResultValue; - private static Func CreateFunctionDelegate() - { - return (a, b) => - { - _functionResultValue = a + b; - return _functionResultValue; - }; - } - - internal static int _functionActionResultValue; - internal static int _functionActionResultValueOfAction; - private static Func> CreateFunctionDelegateWithAction() - { - return (a, b) => - { - _functionActionResultValue = a + b; - return (i1, i2) => - { - _functionActionResultValueOfAction = i1 + i2; - }; - }; - } - - internal static int _actionResultValue; - private static Action CreateActionDelegate() - { - return (a1, a2) => - { - _actionResultValue = a1 + a2; - }; - } - - private static bool AreEqual(int a, int b) - { - return a == b; - } - - private static string TestString1(string a) - { - return "Received: " + a; - } - - private static void SetTestString1(string a) - { - _delMethodStringResultValue = a; - } - - // Create a method for a delegate. - public static void DelegateMethod(string message) - { - _delMethodResultValue = message; - } - - delegate void Del(string message); - internal static string _delMethodResultValue; - private static Del CreateDelegateMethod() - { - // Instantiate the delegate. - Del handler = DelegateMethod; - return handler; - } - - delegate string Del2(string message); - internal static string _delMethodStringResultValue; - private static Del2 CreateDelegateMethodReturnString() - { - // Instantiate the delegate. - Del2 handler = TestString1; - return handler; - } - - internal static string _delegateCallResult; - private static Del CreateDelegateFromAnonymousMethod_VoidString() - { - // Instantiate the delegate. - Del handler = delegate(string name) { _delegateCallResult = $"Notification received for: {name}"; }; - return handler; - } - - private static Del CreateDelegateFromLambda_VoidString() - { - // Instantiate the delegate. - Del handler = (string name) => { _delegateCallResult = $"Notification received for: {name}"; }; - return handler; - } - - public static void DelegateMethod_VoidString(string name) => _delegateCallResult = $"Notification received for: {name}"; - - private static Del CreateDelegateFromMethod_VoidString() - { - // Instantiate the delegate. - Del handler = DelegateMethod_VoidString; - return handler; - } - - private static Action CreateActionT_VoidString() - => (string name) => _delegateCallResult = $"Notification received for: {name}"; - - static void Hello(string s) - { - _delegateCallResult += $" Hello, {s}!"; - } - - static void GoodMorning(string s) - { - _delegateCallResult += $" GoodMorning, {s}!"; - } - - delegate void CustomDelStr(string s); - private static CustomDelStr CreateCustomMultiCastDelegate_VoidString() - { - CustomDelStr hiDel, mornDel, multiDel; - hiDel = Hello; - mornDel = GoodMorning; - multiDel = hiDel + mornDel; - - return multiDel; - } - - private static Action CreateMultiCastAction_VoidString() - { - Action hiDel, mornDel, multiDel; - hiDel = Hello; - mornDel = GoodMorning; - multiDel = hiDel + mornDel; - - return multiDel; - } - - internal static JSObject _funcActionBufferObjectResultValue; - internal static int _funcActionBufferResultLengthValue; - - private static Func> CreateFunctionAcceptingUint8Array() - { - return (buffer) => - { - _funcActionBufferObjectResultValue = buffer; - return (i1) => - { - _funcActionBufferResultLengthValue = i1.Length; - }; - }; - } - private static Func> CreateFunctionAcceptingArray() - { - return (buffer) => - { - _funcActionBufferObjectResultValue = buffer; - return (i1) => - { - _funcActionBufferResultLengthValue = i1.Length; - }; - }; - } - - 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 { - FirstValue = 1, - Zero = 0, - Five = 5, - BigValue = 0xFFFFFFFEu - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs deleted file mode 100644 index 39bbf05fef4bdc..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs +++ /dev/null @@ -1,484 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.IO; -using System.Net.Http.Headers; -using System.Net.Http; -using System.Net; -using System.Runtime.InteropServices.JavaScript.Tests; -using System.Threading.Tasks; - -using Xunit; -using Xunit.Abstractions; - -namespace System.Runtime.InteropServices.JavaScript.Http.Tests -{ - public class HttpRequestMessageTest - { - private readonly Version _expectedRequestMessageVersion = HttpVersion.Version11; - private HttpRequestOptionsKey EnableStreamingResponse = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); -#nullable enable - private HttpRequestOptionsKey> FetchOptions = new HttpRequestOptionsKey>("WebAssemblyFetchOptions"); -#nullable disable - - [Fact] - public void Ctor_Default_CorrectDefaults() - { - var rm = new HttpRequestMessage(); - - Assert.Equal(HttpMethod.Get, rm.Method); - Assert.Null(rm.Content); - Assert.Null(rm.RequestUri); - } - - [Fact] - public void Ctor_RelativeStringUri_CorrectValues() - { - var rm = new HttpRequestMessage(HttpMethod.Post, "/relative"); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri("/relative", UriKind.Relative), rm.RequestUri); - } - - [Theory] - [InlineData("http://host/absolute/")] - [InlineData("blob:http://host/absolute/")] - [InlineData("foo://host/absolute")] - public void Ctor_AbsoluteStringUri_CorrectValues(string uri) - { - var rm = new HttpRequestMessage(HttpMethod.Post, uri); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri(uri), rm.RequestUri); - } - - [Fact] - public void Ctor_NullStringUri_Accepted() - { - var rm = new HttpRequestMessage(HttpMethod.Put, (string)null); - - Assert.Null(rm.RequestUri); - Assert.Equal(HttpMethod.Put, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - } - - [Fact] - public void Ctor_RelativeUri_CorrectValues() - { - var uri = new Uri("/relative", UriKind.Relative); - var rm = new HttpRequestMessage(HttpMethod.Post, uri); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(uri, rm.RequestUri); - } - - [Theory] - [InlineData("http://host/absolute/")] - [InlineData("blob:http://host/absolute/")] - [InlineData("foo://host/absolute")] - public void Ctor_AbsoluteUri_CorrectValues(string uriData) - { - var uri = new Uri(uriData); - var rm = new HttpRequestMessage(HttpMethod.Post, uri); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(uri, rm.RequestUri); - } - - [Fact] - public void Ctor_NullUri_Accepted() - { - var rm = new HttpRequestMessage(HttpMethod.Put, (Uri)null); - - Assert.Null(rm.RequestUri); - Assert.Equal(HttpMethod.Put, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - } - - [Theory] - [InlineData("http://example.com")] - [InlineData("blob:http://example.com")] - public void Ctor_NullMethod_ThrowsArgumentNullException(string uriData) - { - Assert.Throws(() => new HttpRequestMessage(null, uriData)); - } - - [Theory] - [InlineData("http://example.com")] - [InlineData("blob:http://example.com")] - public void Dispose_DisposeObject_ContentGetsDisposedAndSettersWillThrowButGettersStillWork(string uriData) - { - var rm = new HttpRequestMessage(HttpMethod.Get, uriData); - var content = new MockContent(); - rm.Content = content; - Assert.False(content.IsDisposed); - - rm.Dispose(); - rm.Dispose(); // Multiple calls don't throw. - - Assert.True(content.IsDisposed); - Assert.Throws(() => { rm.Method = HttpMethod.Put; }); - Assert.Throws(() => { rm.RequestUri = null; }); - Assert.Throws(() => { rm.Version = new Version(1, 0); }); - Assert.Throws(() => { rm.Content = null; }); - - // Property getters should still work after disposing. - Assert.Equal(HttpMethod.Get, rm.Method); - Assert.Equal(new Uri(uriData), rm.RequestUri); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Equal(content, rm.Content); - } - - [Theory] - [InlineData("https://example.com")] - [InlineData("blob:https://example.com")] - public void Properties_SetOptionsAndGetTheirValue_MatchingValues(string uriData) - { - var rm = new HttpRequestMessage(); - - var content = new MockContent(); - var uri = new Uri(uriData); - var version = new Version(1, 0); - var method = new HttpMethod("custom"); - - rm.Content = content; - rm.Method = method; - rm.RequestUri = uri; - rm.Version = version; - - Assert.Equal(content, rm.Content); - Assert.Equal(uri, rm.RequestUri); - Assert.Equal(method, rm.Method); - Assert.Equal(version, rm.Version); - - Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Options); - } - -#nullable enable - [Theory] - [InlineData("https://example.com")] - [InlineData("blob:https://example.com")] - public void Properties_SetOptionsAndGetTheirValue_Set_FetchOptions(string uriData) - { - var rm = new HttpRequestMessage(); - - var content = new MockContent(); - var uri = new Uri(uriData); - var version = new Version(1, 0); - var method = new HttpMethod("custom"); - - rm.Content = content; - rm.Method = method; - rm.RequestUri = uri; - rm.Version = version; - - var fetchme = new Dictionary(); - fetchme.Add("hic", null); - fetchme.Add("sunt", 4444); - fetchme.Add("dracones", new List()); - rm.Options.Set(FetchOptions, fetchme); - - Assert.Equal(content, rm.Content); - Assert.Equal(uri, rm.RequestUri); - Assert.Equal(method, rm.Method); - Assert.Equal(version, rm.Version); - - Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Options); - - rm.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptionsValue); - Assert.NotNull(fetchOptionsValue); - if (fetchOptionsValue != null) - { - foreach (var item in fetchOptionsValue) - { - Assert.True(fetchme.ContainsKey(item.Key)); - } - } - } -#nullable disable - -#nullable enable - [Theory] - [InlineData("https://example.com")] - [InlineData("blob:https://example.com")] - public void Properties_SetOptionsAndGetTheirValue_NotSet_FetchOptions(string uriData) - { - var rm = new HttpRequestMessage(); - - var content = new MockContent(); - var uri = new Uri(uriData); - var version = new Version(1, 0); - var method = new HttpMethod("custom"); - - rm.Content = content; - rm.Method = method; - rm.RequestUri = uri; - rm.Version = version; - - Assert.Equal(content, rm.Content); - Assert.Equal(uri, rm.RequestUri); - Assert.Equal(method, rm.Method); - Assert.Equal(version, rm.Version); - - Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Options); - - rm.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptionsValue); - Assert.Null(fetchOptionsValue); - } -#nullable disable - [Theory] - [InlineData("https://example.com")] - [InlineData("blob:https://example.com")] - public void Properties_SetOptionsAndGetTheirValue_Set_EnableStreamingResponse(string uriData) - { - var rm = new HttpRequestMessage(); - - var content = new MockContent(); - var uri = new Uri(uriData); - var version = new Version(1, 0); - var method = new HttpMethod("custom"); - - rm.Content = content; - rm.Method = method; - rm.RequestUri = uri; - rm.Version = version; - - rm.Options.Set(EnableStreamingResponse, true); - - Assert.Equal(content, rm.Content); - Assert.Equal(uri, rm.RequestUri); - Assert.Equal(method, rm.Method); - Assert.Equal(version, rm.Version); - - Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Options); - - rm.Options.TryGetValue(EnableStreamingResponse, out bool streamingEnabledValue); - Assert.True(streamingEnabledValue); - } - - [Theory] - [InlineData("https://example.com")] - [InlineData("blob:https://example.com")] - public void Properties_SetOptionsAndGetTheirValue_NotSet_EnableStreamingResponse(string uriData) - { - var rm = new HttpRequestMessage(); - - var content = new MockContent(); - var uri = new Uri(uriData); - var version = new Version(1, 0); - var method = new HttpMethod("custom"); - - rm.Content = content; - rm.Method = method; - rm.RequestUri = uri; - rm.Version = version; - - Assert.Equal(content, rm.Content); - Assert.Equal(uri, rm.RequestUri); - Assert.Equal(method, rm.Method); - Assert.Equal(version, rm.Version); - - Assert.NotNull(rm.Headers); - Assert.NotNull(rm.Options); - - rm.Options.TryGetValue(EnableStreamingResponse, out bool streamingEnabledValue); - Assert.False(streamingEnabledValue); - } - - [Fact] - public void Version_SetToNull_ThrowsArgumentNullException() - { - var rm = new HttpRequestMessage(); - Assert.Throws(() => { rm.Version = null; }); - } - - [Fact] - public void Method_SetToNull_ThrowsArgumentNullException() - { - var rm = new HttpRequestMessage(); - Assert.Throws(() => { rm.Method = null; }); - } - - [Fact] - public void ToString_DefaultInstance_DumpAllFields() - { - var rm = new HttpRequestMessage(); - string expected = - "Method: GET, RequestUri: '', Version: " + - _expectedRequestMessageVersion.ToString(2) + - $", Content: , Headers:{Environment.NewLine}{{{Environment.NewLine}}}"; - Assert.Equal(expected, rm.ToString()); - } - - [Theory] - [InlineData("http://a.com/")] - [InlineData("blob:http://a.com/")] - public void ToString_NonDefaultInstanceWithNoCustomHeaders_DumpAllFields(string uriData) - { - var rm = new HttpRequestMessage(); - rm.Method = HttpMethod.Put; - rm.RequestUri = new Uri(uriData); - rm.Version = new Version(1, 0); - rm.Content = new StringContent("content"); - - // Note that there is no Content-Length header: The reason is that the value for Content-Length header - // doesn't get set by StringContent..ctor, but only if someone actually accesses the ContentLength property. - Assert.Equal( - $"Method: PUT, RequestUri: '{uriData}', Version: 1.0, Content: " + typeof(StringContent).ToString() + ", Headers:" + Environment.NewLine + - $"{{{Environment.NewLine}" + - " Content-Type: text/plain; charset=utf-8" + Environment.NewLine + - "}", rm.ToString()); - } - - [Theory] - [InlineData("http://a.com/")] - [InlineData("blob:http://a.com/")] - public void ToString_NonDefaultInstanceWithCustomHeaders_DumpAllFields(string uriData) - { - var rm = new HttpRequestMessage(); - rm.Method = HttpMethod.Put; - rm.RequestUri = new Uri(uriData); - rm.Version = new Version(1, 0); - rm.Content = new StringContent("content"); - rm.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain", 0.2)); - rm.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml", 0.1)); - rm.Headers.Add("Custom-Request-Header", "value1"); - rm.Content.Headers.Add("Custom-Content-Header", "value2"); - - Assert.Equal( - $"Method: PUT, RequestUri: '{uriData}', Version: 1.0, Content: " + typeof(StringContent).ToString() + ", Headers:" + Environment.NewLine + - "{" + Environment.NewLine + - " Accept: text/plain; q=0.2" + Environment.NewLine + - " Accept: text/xml; q=0.1" + Environment.NewLine + - " Custom-Request-Header: value1" + Environment.NewLine + - " Content-Type: text/plain; charset=utf-8" + Environment.NewLine + - " Custom-Content-Header: value2" + Environment.NewLine + - "}", rm.ToString()); - } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupported))] - public async Task BlobUri_Marshal_CorrectValues_Browser() - { - Runtime.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be marshaled as valid URI - App.call_test_method (""InvokeString"", [ url ]); - "); - - var client = new HttpClient (); - Assert.StartsWith ("blob:", HelperMarshal._stringResource); - - HttpRequestMessage rm = new HttpRequestMessage(HttpMethod.Get, new Uri (HelperMarshal._stringResource)); - HttpResponseMessage resp = await client.SendAsync (rm); - Assert.NotNull (resp.Content); - string content = await resp.Content.ReadAsStringAsync(); - Assert.Equal (59, content.Length); - } - - [Fact] - public void BlobStringUri_Marshal_CorrectValues() - { - Runtime.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - // URL.createObjectURL does not work outside of browser but since this was actual - // test code from https://developer.mozilla.org/en-US/docs/Web/API/Blob - // left it in to show what this should do if the test code were to actually run - //return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - return 'blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7'; - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be converted to a valid Uri - // within the method - App.call_test_method (""SetBlobUrl"", [ url ]); - "); - - var rm = new HttpRequestMessage(HttpMethod.Post, HelperMarshal._blobURL); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri("blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7"), rm.RequestUri); - } - - [Fact] - public void BlobUri_Marshal_CorrectValues() - { - Runtime.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - // URL.createObjectURL does not work outside of browser but since this was actual - // test code from https://developer.mozilla.org/en-US/docs/Web/API/Blob - // left it in to show what this should do if the test code were to actually run - //return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - return 'blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7'; - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be marshaled as valid URI - App.call_test_method (""SetBlobAsUri"", [ url ]); - "); - - var rm = new HttpRequestMessage(HttpMethod.Post, HelperMarshal._blobURI); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri("blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7"), rm.RequestUri); - } - - #region Helper methods - - private class MockContent : HttpContent - { - public bool IsDisposed { get; private set; } - - protected override bool TryComputeLength(out long length) - { - throw new NotImplementedException(); - } - -#nullable enable - protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) - { -#nullable disable - throw new NotImplementedException(); - } - - protected override void Dispose(bool disposing) - { - IsDisposed = true; - base.Dispose(disposing); - } - } - - #endregion - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs index c41253f5c8ffba..e35f534f8dac7c 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs @@ -11,204 +11,15 @@ namespace System.Runtime.InteropServices.JavaScript.Tests public static class JavaScriptTests { [Fact] - public static void CoreTypes() + public static void TestLocalsInit() { - var arr1 = new Uint8Array(50); - Assert.Equal(50, arr1.Length); - } - - [Fact] - public static void FunctionSum() - { - // The Difference Between call() and apply() - // The difference is: - // The call() method takes arguments separately. - // The apply() method takes arguments as an array. - var sum = new Function("a", "b", "return a + b"); - Assert.Equal(8, (int)sum.Call(null, 3, 5)); - - Assert.Equal(13, (int)sum.Apply(null, new object[] { 6, 7 })); - } - - [Fact] - public static void FunctionMath() - { - JSObject math = (JSObject)Runtime.GetGlobalObject("Math"); - Assert.True(math != null, "math != null"); - - Function mathMax = (Function)math.GetObjectProperty("max"); - Assert.True(mathMax != null, "math.max != null"); - - var maxValue = (int)mathMax.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - Assert.Equal(7, maxValue); - - maxValue = (int)mathMax.Call(null, 5, 6, 2, 3, 7); - Assert.Equal(7, maxValue); - - Function mathMin = (Function)((JSObject)Runtime.GetGlobalObject("Math")).GetObjectProperty("min"); - Assert.True(mathMin != null, "math.min != null"); - - var minValue = (int)mathMin.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - Assert.Equal(2, minValue); - - minValue = (int)mathMin.Call(null, 5, 6, 2, 3, 7); - Assert.Equal(2, minValue); - } - - [Fact] - [OuterLoop("slow")] - public static async Task BagIterator() - { - await Task.Delay(1); - - var bagFn = new Function(@" - var same = { - x:1 - }; - return Object.entries({ - a:1, - b:'two', - c:{fold:{}}, - d:same, - e:same, - f:same - }); - "); - - for (int attempt = 0; attempt < 100_000; attempt++) + object[] arg = new object[] {"1","2"}; + //Assert.Equal(123456, Runtime.DoSomething("test", arg)); + for(int i = 0; i < 10000; i++) { - try - { - using var bag = (JSObject)bagFn.Call(null); - using var entriesIterator = (JSObject)bag.Invoke("entries"); - - var cnt = entriesIterator.ToEnumerable().Count(); - Assert.Equal(6, cnt); - - // fill GC helps to repro - var x = new byte[100 + attempt / 100]; - if (attempt % 1000 == 0) - { - Runtime.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - GC.Collect(); - } - } - catch (Exception ex) - { - throw new Exception(ex.Message + " At attempt=" + attempt, ex); - } + Console.WriteLine("I " + i); + Assert.Equal(0, Runtime.DoNothing()); } } - - [Fact] - public static async Task Iterator() - { - await Task.Delay(1); - - var makeRangeIterator = new Function("start", "end", "step", @" - let nextIndex = start; - let iterationCount = 0; - - const rangeIterator = { - next: function() { - let result; - if (nextIndex < end) { - result = { value: {}, done: false } - nextIndex += step; - iterationCount++; - return result; - } - return { value: {}, done: true } - } - }; - return rangeIterator; - "); - - const int count = 500; - for (int attempt = 0; attempt < 100; attempt++) - { - int index = 0; - try - { - var entriesIterator = (JSObject)makeRangeIterator.Call(null, 0, count, 1); - Assert.NotNull(entriesIterator); - using (entriesIterator) - { - var enumerable = entriesIterator.ToEnumerable(); - var enumerator = enumerable.GetEnumerator(); - Assert.NotNull(enumerator); - - using (enumerator) - { - while (enumerator.MoveNext()) - { - Assert.NotNull(enumerator.Current); - index++; - } - } - } - Assert.Equal(count, index); - } - catch (Exception ex) - { - throw new Exception($"At attempt={attempt}, index={index}: {ex.Message}", ex); - } - } - } - - public static IEnumerable ToEnumerable(this JSObject iterrator) - { - JSObject nextResult = null; - try - { - nextResult = (JSObject)iterrator.Invoke("next"); - var done = (bool)nextResult.GetObjectProperty("done"); - while (!done) - { - object value = nextResult.GetObjectProperty("value"); - nextResult.Dispose(); - yield return value; - nextResult = (JSObject)iterrator.Invoke("next"); - done = (bool)nextResult.GetObjectProperty("done"); - } - } - finally - { - nextResult?.Dispose(); - } - } - - [Fact] - public static void RoundtripCSDate() - { - var factory = new Function("dummy", @" - return { - dummy:dummy, - }"); - var date = new DateTime(2021, 01, 01, 12, 34, 45); - - var obj = (JSObject)factory.Call(null, date); - var dummy = (DateTime)obj.GetObjectProperty("dummy"); - Assert.Equal(date, dummy); - } - - [Fact] - public static void RoundtripJSDate() - { - var factory = new Function(@" - var dummy = new Date(2021, 00, 01, 12, 34, 45, 567); - return { - dummy:dummy, - check:(value) => { - return value.valueOf()==dummy.valueOf() ? 1 : 0; - }, - }"); - var obj = (JSObject)factory.Call(); - - var date = (DateTime)obj.GetObjectProperty("dummy"); - var check = (int)obj.Invoke("check", date); - Assert.Equal(1, check); - } - } } 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 deleted file mode 100644 index bf76bde3a56b05..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ /dev/null @@ -1,836 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class MarshalTests - { - [Fact] - public static void MarshalPrimitivesToCS() - { - HelperMarshal._i32Value = 0; - Runtime.InvokeJS("App.call_test_method (\"InvokeI32\", [10, 20])"); - Assert.Equal(30, HelperMarshal._i32Value); - - HelperMarshal._f32Value = 0; - Runtime.InvokeJS("App.call_test_method (\"InvokeFloat\", [1.5])"); - Assert.Equal(1.5f, HelperMarshal._f32Value); - - HelperMarshal._f64Value = 0; - Runtime.InvokeJS("App.call_test_method (\"InvokeDouble\", [4.5])"); - Assert.Equal(4.5, HelperMarshal._f64Value); - - HelperMarshal._i64Value = 0; - Runtime.InvokeJS("App.call_test_method (\"InvokeLong\", [99])"); - Assert.Equal(99, HelperMarshal._i64Value); - } - - [Fact] - public static void MarshalArrayBuffer() - { - Runtime.InvokeJS(@" - var buffer = new ArrayBuffer(16); - App.call_test_method (""MarshalArrayBuffer"", [ buffer ]); - "); - Assert.Equal(16, HelperMarshal._byteBuffer.Length); - } - - - - - [Fact] - public static void MarshalStringToCS() - { - HelperMarshal._stringResource = null; - Runtime.InvokeJS("App.call_test_method(\"InvokeString\", [\"hello\"])"); - Assert.Equal("hello", HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalUnicodeStringToCS() - { - HelperMarshal._stringResource = null; - Runtime.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\u0050\u0159\u00ed\u006c\u0069\u0161\u0020\u017e\u006c\u0075\u0165\u006f\u0075\u010d\u006b\u00fd\u0020\u006b\u016f\u0148\u202f\u00fa\u0070\u011b\u006c\u0020\u010f\u00e1\u0062\u0065\u006c\u0073\u006b\u00e9\u0020\u00f3\u0064\u0079\"])"); - Assert.Equal("Got: \u0050\u0159\u00ed\u006c\u0069\u0161\u0020\u017e\u006c\u0075\u0165\u006f\u0075\u010d\u006b\u00fd\u0020\u006b\u016f\u0148\u202f\u00fa\u0070\u011b\u006c\u0020\u010f\u00e1\u0062\u0065\u006c\u0073\u006b\u00e9\u0020\u00f3\u0064\u0079", HelperMarshal._stringResource); - - HelperMarshal._stringResource = null; - Runtime.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\uFEFF\u0000\uFFFE\"])"); - Assert.Equal("Got: \uFEFF\0\uFFFE", HelperMarshal._stringResource); - - HelperMarshal._stringResource = null; - Runtime.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\u02F3o\u0302\u0303\u0308\u0930\u0903\u0951\"])"); - Assert.Equal("Got: \u02F3o\u0302\u0303\u0308\u0930\u0903\u0951", HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalNullStringToCS() - { - HelperMarshal._stringResource = null; - Runtime.InvokeJS("App.call_test_method(\"InvokeString\", [ null ])"); - Assert.Null(HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalStringToJS() - { - HelperMarshal._marshaledString = HelperMarshal._stringResource = null; - Runtime.InvokeJS(@" - var str = App.call_test_method (""InvokeMarshalString""); - App.call_test_method (""InvokeString"", [ str ]); - "); - Assert.NotNull(HelperMarshal._marshaledString); - Assert.Equal(HelperMarshal._marshaledString, HelperMarshal._stringResource); - } - - [Fact] - public static void JSObjectKeepIdentityAcrossCalls() - { - HelperMarshal._object1 = HelperMarshal._object2 = null; - Runtime.InvokeJS(@" - var obj = { foo: 10 }; - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - App.call_test_method (""InvokeObj2"", [ res ]); - "); - - Assert.NotNull(HelperMarshal._object1); - Assert.Same(HelperMarshal._object1, HelperMarshal._object2); - } - - [Fact] - public static void CSObjectKeepIdentityAcrossCalls() - { - HelperMarshal._marshaledObject = HelperMarshal._object1 = HelperMarshal._object2 = null; - Runtime.InvokeJS(@" - var obj = App.call_test_method (""InvokeMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - App.call_test_method (""InvokeObj2"", [ res ]); - "); - - Assert.NotNull(HelperMarshal._object1); - Assert.Same(HelperMarshal._marshaledObject, HelperMarshal._object1); - Assert.Same(HelperMarshal._object1, HelperMarshal._object2); - } - - [Theory] - [InlineData(byte.MinValue)] - [InlineData(byte.MaxValue)] - [InlineData(SByte.MinValue)] - [InlineData(SByte.MaxValue)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxNumberString(object o) - { - HelperMarshal._marshaledObject = o; - HelperMarshal._object1 = HelperMarshal._object2 = null; - var value = Runtime.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj.toString() ]); - "); - - Assert.Equal(o.ToString().ToLower(), HelperMarshal._object1); - } - - [Theory] - [InlineData(byte.MinValue, 0)] - [InlineData(byte.MaxValue, 255)] - [InlineData(SByte.MinValue, -128)] - [InlineData(SByte.MaxValue, 127)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue, 0)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxNumber(object o, object expected = null) - { - HelperMarshal._marshaledObject = o; - HelperMarshal._object1 = HelperMarshal._object2 = null; - Runtime.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(expected ?? o, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxInt() - { - Runtime.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnInt""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(42, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxDouble() - { - Runtime.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnDouble""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(double.Pi, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxLongFail() - { - var ex = Assert.Throws(() => Runtime.InvokeJS(@" - console.log(""the exception in InvokeReturnLong after this is intentional""); - App.call_test_method (""InvokeReturnLong""); - ")); - Assert.Contains("int64 not available", ex.Message); - } - - [Theory] - [InlineData(byte.MinValue, 0)] - [InlineData(byte.MaxValue, 255)] - [InlineData(SByte.MinValue, -128)] - [InlineData(SByte.MaxValue, 127)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue, 0)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxStringNumber(object o, object expected = null) - { - HelperMarshal._marshaledObject = HelperMarshal._object1 = HelperMarshal._object2 = null; - Runtime.InvokeJS(String.Format(@" - var res = App.call_test_method (""InvokeObj1"", [ {0} ]); - ", o)); - - Assert.Equal(expected ?? o, HelperMarshal._object1); - } - - [Fact] - public static void JSInvokeInt() - { - Runtime.InvokeJS(@" - var obj = { - foo: 10, - inc: function() { - var c = this.foo; - ++this.foo; - return c; - }, - add: function(val){ - return this.foo + val; - } - }; - App.call_test_method (""ManipulateObject"", [ obj ]); - "); - Assert.Equal(10, HelperMarshal._valOne); - Assert.Equal(31, HelperMarshal._valTwo); - } - - [Fact] - public static void JSInvokeTypes() - { - Runtime.InvokeJS(@" - var obj = { - return_int: function() { return 100; }, - return_double: function() { return 4.5; }, - return_string: function() { return 'Hic Sunt Dracones'; }, - return_bool: function() { return true; }, - }; - App.call_test_method (""MinipulateObjTypes"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsObjects[0]); - Assert.Equal(4.5, HelperMarshal._jsObjects[1]); - Assert.Equal("Hic Sunt Dracones", HelperMarshal._jsObjects[2]); - Assert.NotEqual("HIC SVNT LEONES", HelperMarshal._jsObjects[2]); - Assert.Equal(true, HelperMarshal._jsObjects[3]); - } - - [Fact] - public static void JSObjectApply() - { - Runtime.InvokeJS(@" - var do_add = function(a, b) { return a + b }; - App.call_test_method (""UseFunction"", [ do_add ]); - "); - Assert.Equal(30, HelperMarshal._jsAddFunctionResult); - } - - [Fact] - public static void JSObjectAsFunction() - { - Runtime.InvokeJS(@" - var do_add = function(a, b) { return a + b }; - App.call_test_method (""UseAsFunction"", [ do_add ]); - "); - Assert.Equal(50, HelperMarshal._jsAddAsFunctionResult); - } - - [Fact] - public static void BindStaticMethod() - { - HelperMarshal._intValue = 0; - Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (200); - "); - - Assert.Equal(200, HelperMarshal._intValue); - } - - [Fact] - public static void BindIntPtrStaticMethod() - { - HelperMarshal._intPtrValue = IntPtr.Zero; - Runtime.InvokeJS(@$" - var invoke_int_ptr = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeIntPtr""); - invoke_int_ptr (42); - "); - Assert.Equal(42, (int)HelperMarshal._intPtrValue); - } - - [Fact] - public static void MarshalIntPtrToJS() - { - HelperMarshal._marshaledIntPtrValue = IntPtr.Zero; - Runtime.InvokeJS(@$" - var invokeMarshalIntPtr = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeMarshalIntPtr""); - var r = invokeMarshalIntPtr (); - - if (r != 42) throw `Invalid int_ptr value`; - "); - Assert.Equal(42, (int)HelperMarshal._marshaledIntPtrValue); - } - - [Fact] - public static void InvokeStaticMethod() - { - HelperMarshal._intValue = 0; - Runtime.InvokeJS(@$" - INTERNAL.call_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt"", [ 300 ]); - "); - - Assert.Equal(300, HelperMarshal._intValue); - } - - [Fact] - public static void ResolveMethod() - { - HelperMarshal._intValue = 0; - Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_method_resolve (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - App.call_test_method (""InvokeInt"", [ invoke_int ]); - "); - - Assert.NotEqual(0, HelperMarshal._intValue); - } - - [Fact] - public static void GetObjectProperties() - { - Runtime.InvokeJS(@" - var obj = {myInt: 100, myDouble: 4.5, myString: ""Hic Sunt Dracones"", myBoolean: true}; - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("Hic Sunt Dracones", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectProperties() - { - Runtime.InvokeJS(@" - var obj = {myInt: 200, myDouble: 0, myString: ""foo"", myBoolean: false}; - App.call_test_method (""PopulateObjectProperties"", [ obj, false ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("qwerty", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectPropertiesIfNotExistsFalse() - { - // This test will not create the properties if they do not already exist - Runtime.InvokeJS(@" - var obj = {myInt: 200}; - App.call_test_method (""PopulateObjectProperties"", [ obj, false ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Null(HelperMarshal._jsProperties[1]); - Assert.Null(HelperMarshal._jsProperties[2]); - Assert.Null(HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectPropertiesIfNotExistsTrue() - { - // This test will set the value of the property if it exists and will create and - // set the value if it does not exists - Runtime.InvokeJS(@" - var obj = {myInt: 200}; - App.call_test_method (""PopulateObjectProperties"", [ obj, true ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("qwerty", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void MarshalTypedArray() - { - Runtime.InvokeJS(@" - var buffer = new ArrayBuffer(16); - var uint8View = new Uint8Array(buffer); - App.call_test_method (""MarshalByteBuffer"", [ uint8View ]); - "); - - Assert.Equal(16, HelperMarshal._byteBuffer.Length); - } - - private static void RunMarshalTypedArrayJS(string type) - { - Runtime.InvokeJS(@" - var obj = { }; - App.call_test_method (""SetTypedArray" + type + @""", [ obj ]); - App.call_test_method (""GetTypedArray" + type + @""", [ obj ]); - "); - } - - [Fact] - public static void MarshalTypedArrayByte() - { - RunMarshalTypedArrayJS("Byte"); - Assert.Equal(17, HelperMarshal._taByte.Length); - Assert.Equal(104, HelperMarshal._taByte[0]); - Assert.Equal(115, HelperMarshal._taByte[HelperMarshal._taByte.Length - 1]); - Assert.Equal("hic sunt dracones", System.Text.Encoding.Default.GetString(HelperMarshal._taByte)); - } - - - - [Fact] - public static void TestFunctionSum() - { - HelperMarshal._sumValue = 0; - Runtime.InvokeJS(@" - App.call_test_method (""CreateFunctionSum"", []); - App.call_test_method (""CallFunctionSum"", []); - "); - Assert.Equal(8, HelperMarshal._sumValue); - } - - [Fact] - public static void TestFunctionApply() - { - HelperMarshal._minValue = 0; - Runtime.InvokeJS(@" - App.call_test_method (""CreateFunctionApply"", []); - App.call_test_method (""CallFunctionApply"", []); - "); - Assert.Equal(2, HelperMarshal._minValue); - } - - [Fact] - public static void BoundStaticMethodMissingArgs() - { - HelperMarshal._intValue = 1; - var ex = Assert.Throws(() => Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (); - ")); - Assert.Contains("Value is not an integer: undefined (undefined)", ex.Message); - Assert.Equal(1, HelperMarshal._intValue); - } - - [Fact] - public static void BoundStaticMethodExtraArgs() - { - HelperMarshal._intValue = 0; - Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (200, 400); - "); - Assert.Equal(200, HelperMarshal._intValue); - } - - [Fact] - public static void RangeCheckInt() - { - HelperMarshal._intValue = 0; - // no numbers bigger than 32 bits - var ex = Assert.Throws(() => Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (Number.MAX_SAFE_INTEGER); - ")); - Assert.Contains("Overflow: value 9007199254740991 is out of -2147483648 2147483647 range", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void IntegerCheckInt() - { - HelperMarshal._intValue = 0; - // no floating point rounding - var ex = Assert.Throws(() => Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (3.14); - ")); - Assert.Contains("Value is not an integer: 3.14 (number)", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void TypeCheckInt() - { - HelperMarshal._intValue = 0; - // no string conversion - var ex = Assert.Throws(() => Runtime.InvokeJS(@$" - var invoke_int = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (""200""); - ")); - Assert.Contains("Value is not an integer: 200 (string)", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void PassUintArgument() - { - HelperMarshal._uintValue = 0; - Runtime.InvokeJS(@$" - var invoke_uint = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeUInt""); - invoke_uint (0xFFFFFFFE); - "); - - Assert.Equal(0xFFFFFFFEu, HelperMarshal._uintValue); - } - - [Fact] - public static void ReturnUintEnum() - { - HelperMarshal._uintValue = 0; - HelperMarshal._enumValue = TestEnum.BigValue; - Runtime.InvokeJS(@$" - var get_value = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}GetEnumValue""); - var e = get_value (); - var invoke_uint = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeUInt""); - invoke_uint (e); - "); - Assert.Equal((uint)TestEnum.BigValue, HelperMarshal._uintValue); - } - - [Fact] - public static void PassUintEnumByValue() - { - HelperMarshal._enumValue = TestEnum.Zero; - Runtime.InvokeJS(@$" - var set_enum = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}SetEnumValue"", ""j""); - set_enum (0xFFFFFFFE); - "); - Assert.Equal(TestEnum.BigValue, HelperMarshal._enumValue); - } - - [Fact] - public static void PassUintEnumByNameIsNotImplemented() - { - HelperMarshal._enumValue = TestEnum.Zero; - var exc = Assert.Throws(() => - Runtime.InvokeJS(@$" - var set_enum = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}SetEnumValue"", ""j""); - set_enum (""BigValue""); - ") - ); - Assert.StartsWith("Error: Expected numeric value for enum argument, got 'BigValue'", exc.Message); - } - - [Fact] - public static void CannotUnboxUint64() - { - var exc = Assert.Throws(() => - Runtime.InvokeJS(@$" - var get_u64 = INTERNAL.mono_bind_static_method (""{HelperMarshal.INTEROP_CLASS}GetUInt64"", """"); - var u64 = get_u64(); - ") - ); - Assert.StartsWith("Error: int64 not available", exc.Message); - } - - [Fact] - public static void BareStringArgumentsAreNotInterned() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var jsLiteral = ""hello world""; - App.call_test_method (""InvokeString"", [ jsLiteral ]); - App.call_test_method (""InvokeString2"", [ jsLiteral ]); - "); - Assert.Equal("hello world", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.False(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void InternedStringSignaturesAreInternedOnJavascriptSide() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var sym = ""interned string""; - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""S""); - "); - Assert.Equal("interned string", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void OnceAJSStringIsInternedItIsAlwaysUsedIfPossible() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var sym = ""interned string 2""; - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal("interned string 2", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void ManuallyInternString() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var sym = INTERNAL.mono_intern_string(""interned string 3""); - App.call_test_method (""InvokeString"", [ sym ], ""s""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal("interned string 3", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void LargeStringsAreNotAutomaticallyLocatedInInternTable() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var s = ""long interned string""; - for (var i = 0; i < 1024; i++) - s += String(i % 10); - var sym = INTERNAL.mono_intern_string(s); - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.False(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void CanInternVeryManyStrings() - { - HelperMarshal._stringResource = null; - Runtime.InvokeJS(@" - for (var i = 0; i < 10240; i++) - INTERNAL.mono_intern_string('s' + i); - App.call_test_method (""InvokeString"", [ 's5000' ], ""S""); - "); - Assert.Equal("s5000", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, string.IsInterned(HelperMarshal._stringResource)); - } - - [Fact] - public static void SymbolsAreMarshaledAsStrings() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Runtime.InvokeJS(@" - var jsLiteral = Symbol(""custom symbol""); - App.call_test_method (""InvokeString"", [ jsLiteral ]); - App.call_test_method (""InvokeString2"", [ jsLiteral ]); - "); - Assert.Equal("custom symbol", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void InternedStringReturnValuesWork() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - var fqn = "[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:StoreArgumentAndReturnLiteral"; - Runtime.InvokeJS( - $"var a = INTERNAL.mono_bind_static_method('{fqn}')('test');\r\n" + - $"var b = INTERNAL.mono_bind_static_method('{fqn}')(a);\r\n" + - "App.call_test_method ('InvokeString2', [ b ]);" - ); - Assert.Equal("s: 1 length: 1", HelperMarshal._stringResource); - Assert.Equal("1", HelperMarshal._stringResource2); - } - - [Fact] - public static void InvokeJSExpression() - { - var result = Runtime.InvokeJS(@"1 + 2"); - Assert.Equal("3", result); - } - - [Fact] - public static void InvokeJSNullExpression() - { - var result = Runtime.InvokeJS(@"null"); - Assert.Null(result); - } - - [Fact] - public static void InvokeJSUndefinedExpression() - { - var result = Runtime.InvokeJS(@"undefined"); - Assert.Null(result); - } - - [Fact] - 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.then(result => { globalThis.__test_promise_resolved = true; " + resolvedBody + " })" + - " .catch(e => { globalThis.__test_promise_failed = true; })" + - " .finally(result => { globalThis.__test_promise_completed = 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."); - } - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs deleted file mode 100644 index d7027fe0b95872..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public class MemoryTests - { - [Theory] - [InlineData(-1L)] - [InlineData(-42L)] - [InlineData(int.MinValue)] - [InlineData(-9007199254740990L)]//MIN_SAFE_INTEGER+1 - [InlineData(-9007199254740991L)]//MIN_SAFE_INTEGER - [InlineData(1L)] - [InlineData(0L)] - [InlineData(42L)] - [InlineData(int.MaxValue)] - [InlineData(0xF_FFFF_FFFFL)] - [InlineData(9007199254740991L)]//MAX_SAFE_INTEGER - public static unsafe void Int52TestOK(long value) - { - long expected = value; - long dummy = 0xA6A6A6A6L; - long actual2 = dummy; - var bagFn = new Function("ptr", "ptr2", @" - const value=globalThis.App.MONO.getI52(ptr); - globalThis.App.MONO.setI52(ptr2, value); - return ''+value;"); - - uint ptr = (uint)Unsafe.AsPointer(ref expected); - uint ptr2 = (uint)Unsafe.AsPointer(ref actual2); - - object actual = (string)bagFn.Call(null, ptr, ptr2); - Assert.Equal(""+ value, actual); - Assert.Equal(value, actual2); - Assert.Equal(0xA6A6A6A6L, dummy); - } - - [Theory] - [InlineData(uint.MinValue)] - [InlineData(1UL)] - [InlineData(0UL)] - [InlineData(42UL)] - [InlineData(uint.MaxValue)] - [InlineData(0xF_FFFF_FFFFUL)] - [InlineData(9007199254740991UL)]//MAX_SAFE_INTEGER - public static unsafe void UInt52TestOK(ulong value) - { - ulong expected = value; - ulong dummy = 0xA6A6A6A6UL; - ulong actual2 = dummy; - var bagFn = new Function("ptr", "ptr2", @" - const value=globalThis.App.MONO.getI52(ptr); - globalThis.App.MONO.setU52(ptr2, value); - return ''+value;"); - - uint ptr = (uint)Unsafe.AsPointer(ref expected); - uint ptr2 = (uint)Unsafe.AsPointer(ref actual2); - - string actual = (string)bagFn.Call(null, ptr, ptr2); - Assert.Equal(""+value, actual); - Assert.Equal(value, actual2); - Assert.Equal(0xA6A6A6A6UL, dummy); - } - - [Fact] - public static unsafe void UInt52TestRandom() - { - for(int i = 0; i < 1000; i++) - { - var value = (ulong)Random.Shared.NextInt64(); - value&= 0x1F_FFFF_FFFF_FFFFUL;// only safe range - UInt52TestOK(value); - } - } - - [Fact] - public static unsafe void Int52TestRandom() - { - for(int i = 0; i < 1000; i++) - { - var value = Random.Shared.NextInt64(-9007199254740991L, 9007199254740991L); - Int52TestOK(value); - } - } - - [Theory] - [InlineData(double.NegativeInfinity)] - [InlineData(double.PositiveInfinity)] - [InlineData(double.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.Pi)] - [InlineData(9007199254740993.0)]//MAX_SAFE_INTEGER +2 - public static unsafe void Int52TestRange(double value) - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.MONO.setI52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Value is not a safe integer", ex.Message); - - double expectedD = value; - uint ptrD = (uint)Unsafe.AsPointer(ref expectedD); - var bagFnD = new Function("ptr", "value", @" - globalThis.App.MONO.getI52(ptr);"); - var exD = Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Value is not a safe integer", ex.Message); - } - - [Theory] - [InlineData(-1.0)] - public static unsafe void UInt52TestRange(double value) - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.MONO.setU52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Can't convert negative Number into UInt64", ex.Message); - - double expectedD = value; - uint ptrD = (uint)Unsafe.AsPointer(ref expectedD); - var bagFnD = new Function("ptr", "value", @" - globalThis.App.MONO.getU52(ptr);"); - var exD = Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Can't convert negative Number into UInt64", ex.Message); - } - - [Fact] - public static unsafe void Int52TestNaN() - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.MONO.setI52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, double.NaN)); - Assert.Contains("Value is not a safe integer: NaN (number)", ex.Message); - } - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs deleted file mode 100644 index c74b84b60fc092..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Runtime.InteropServices.JavaScript; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class ParallelTests - { - // The behavior of APIs like Invoke depends on how many items they are asked to invoke - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2)] - [InlineData(5)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelInvokeActionArray(int count) - { - var actions = new List(); - int sum = 0, expected = 0; - for (int i = 0; i < count; i++) { - int j = i; - actions.Add(() => { - sum += j; - }); - expected += j; - } - - Parallel.Invoke(actions.ToArray()); - Assert.Equal(expected, sum); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelFor(int count) - { - int sum = 0, expected = 0; - for (int i = 0; i < count; i++) - expected += i; - Parallel.For(0, count, (i) => { sum += i; }); - Assert.Equal(expected, sum); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelForEach(int count) - { - int sum = 0, expected = 0; - var items = new List(); - for (int i = 0; i < count; i++) { - items.Add(i); - expected += i; - } - Parallel.ForEach(items, (i) => { sum += i; }); - Assert.Equal(expected, sum); - } - } -} \ No newline at end of file diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TimerTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TimerTests.cs deleted file mode 100644 index 2bf8dee0b82d9d..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TimerTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - // V8's implementation of setTimer ignores delay parameter and always run immediately. So it could not be used to test this. - [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupported))] - public class TimerTests : IAsyncLifetime - { - static JSObject _timersHelper; - static Function _installWrapper; - static Function _getRegisterCount; - static Function _getHitCount; - static Function _cleanupWrapper; - static Function _log; - - public static IEnumerable TestCases() - { - yield return new object[] { new int[0], 0, null, null }; - yield return new object[] { new[] { 10 }, 1, null, null }; - yield return new object[] { new[] { 10, 5 }, 2, null, null }; - yield return new object[] { new[] { 10, 20 }, 1, null, null }; - yield return new object[] { new[] { 800, 600, 400, 200, 100 }, 5, 13, 9 }; - } - - [Theory] - [MemberData(nameof(TestCases))] - public async Task TestTimers(int[] timeouts, int? expectedSetCounter, int? expectedSetCounterAfterCleanUp, int? expectedHitCount) - { - int wasCalled = 0; - Timer[] timers = new Timer[timeouts.Length]; - try - { - _log.Call(_timersHelper, $"Waiting for runtime to settle"); - // the test is quite sensitive to timing and order of execution. Here we are giving time to timers of XHarness and previous tests to finish. - await Task.Delay(2000); - _installWrapper.Call(_timersHelper); - _log.Call(_timersHelper, $"Ready!"); - - for (int i = 0; i < timeouts.Length; i++) - { - int index = i; - _log.Call(_timersHelper, $"Registering {index} delay {timeouts[i]}"); - timers[i] = new Timer((_) => - { - _log.Call(_timersHelper, $"In timer{index}"); - wasCalled++; - }, null, timeouts[i], 0); - } - - var setCounter = (int)_getRegisterCount.Call(_timersHelper); - Assert.True(0 == wasCalled, $"wasCalled: {wasCalled}"); - Assert.True((expectedSetCounter ?? timeouts.Length) == setCounter, $"setCounter: actual {setCounter} expected {expectedSetCounter}"); - - } - finally - { - // the test is quite sensitive to timing and order of execution. - // Here we are giving time to our timers to finish. - var afterLastTimer = timeouts.Length == 0 ? 500 : 500 + timeouts.Max(); - - _log.Call(_timersHelper, "wait for timers to run"); - // this delay is also implemented as timer, so it counts to asserts - await Task.Delay(afterLastTimer); - _log.Call(_timersHelper, "cleanup"); - _cleanupWrapper.Call(_timersHelper); - - Assert.True(timeouts.Length == wasCalled, $"wasCalled: actual {wasCalled} expected {timeouts.Length}"); - - if (expectedSetCounterAfterCleanUp != null) - { - var setCounter = (int)_getRegisterCount.Call(_timersHelper); - Assert.True(expectedSetCounterAfterCleanUp.Value == setCounter, $"setCounter: actual {setCounter} expected {expectedSetCounterAfterCleanUp.Value}"); - } - - if (expectedHitCount != null) - { - var hitCounter = (int)_getHitCount.Call(_timersHelper); - Assert.True(expectedHitCount == hitCounter, $"hitCounter: actual {hitCounter} expected {expectedHitCount}"); - } - - for (int i = 0; i < timeouts.Length; i++) - { - timers[i].Dispose(); - } - } - } - - public async Task InitializeAsync() - { - if (_timersHelper == null) - { - Function helper = new Function(@" - const loadTimersJs = async () => { - await import('./timers.js'); - }; - return loadTimersJs(); - "); - await (Task)helper.Call(_timersHelper); - - _timersHelper = (JSObject)Runtime.GetGlobalObject("timersHelper"); - _installWrapper = (Function)_timersHelper.GetObjectProperty("install"); - _getRegisterCount = (Function)_timersHelper.GetObjectProperty("getRegisterCount"); - _getHitCount = (Function)_timersHelper.GetObjectProperty("getHitCount"); - _cleanupWrapper = (Function)_timersHelper.GetObjectProperty("cleanup"); - _log = (Function)_timersHelper.GetObjectProperty("log"); - } - } - - public Task DisposeAsync() => Task.CompletedTask; - } -} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs deleted file mode 100644 index 9df7fd8719bccf..00000000000000 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class TypedArrayTests - { - private static Function _objectPrototype; - - public static IEnumerable Object_Prototype() - { - _objectPrototype ??= new Function("return Object.prototype.toString;"); - yield return new object[] { _objectPrototype.Call() }; - } - - [Theory] - [MemberData(nameof(Object_Prototype))] - public static void Uint8ArrayFrom(Function objectPrototype) - { - var array = new byte[50]; - Uint8Array from = Uint8Array.From(array); - Assert.Equal(50, from.Length); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(from)); - } - - [Theory] - [MemberData(nameof(Object_Prototype))] - public static void Uint8ArrayFromArrayBuffer(Function objectPrototype) - { - Uint8Array from = new Uint8Array(new ArrayBuffer(50)); - Assert.True(from.Length == 50); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(from)); - } - } -} diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index f82029d12c8f53..422af78bad4bfe 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -73,6 +73,7 @@ const linked_functions = [ "dotnet_browser_can_use_subtle_crypto_impl", "dotnet_browser_simple_digest_hash", "dotnet_browser_sign", + "mono_wasm_do_nothing", ]; // -- this javascript file is evaluated by emcc during compilation! -- diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 2313924d9b9a6e..df9a68de1c5808 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -35,6 +35,7 @@ extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr extern void mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_close_ref (int webSocket_js_handle, int code, MonoString **reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_abort (int webSocket_js_handle, int *is_exception, MonoString **result); +extern void mono_wasm_do_nothing (int *is_exception); void core_initialize_internals () { @@ -56,6 +57,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::WebSocketCloseRef", mono_wasm_web_socket_close_ref); mono_add_internal_call ("Interop/Runtime::WebSocketAbort", mono_wasm_web_socket_abort); mono_add_internal_call ("Interop/Runtime::CancelPromiseRef", mono_wasm_cancel_promise_ref); + mono_add_internal_call ("Interop/Runtime::DoNothing", mono_wasm_do_nothing); } // Int8Array | int8_t | byte or SByte (signed byte) diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index e30e272b786f26..76c54e8db79413 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -110,6 +110,7 @@ const linked_functions = [ "dotnet_browser_can_use_subtle_crypto_impl", "dotnet_browser_simple_digest_hash", "dotnet_browser_sign", + "mono_wasm_do_nothing", ]; // -- this javascript file is evaluated by emcc during compilation! -- diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 099d805edd8ddd..43b94871668eb8 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -48,6 +48,7 @@ import { import { call_static_method, mono_bind_static_method, mono_call_assembly_entry_point, mono_method_resolve, + mono_wasm_do_nothing, mono_wasm_get_by_index_ref, mono_wasm_get_global_object_ref, mono_wasm_get_object_property_ref, mono_wasm_invoke_js, mono_wasm_invoke_js_blazor, @@ -374,7 +375,9 @@ export const __linker_exports: any = { // pal_crypto_webworker.c dotnet_browser_can_use_subtle_crypto_impl, dotnet_browser_simple_digest_hash, - dotnet_browser_sign + dotnet_browser_sign, + + mono_wasm_do_nothing }; const INTERNAL: any = { diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 99a8115e5181f5..0decba16ae628d 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -23,7 +23,7 @@ import { import { conv_string, conv_string_root, js_string_to_mono_string, js_string_to_mono_string_root } from "./strings"; import cwraps from "./cwraps"; import { bindings_lazy_init } from "./startup"; -import { _create_temp_frame, _release_temp_frame } from "./memory"; +import { getI32, _create_temp_frame, _release_temp_frame } from "./memory"; import { VoidPtr, Int32Ptr, EmscriptenModule } from "./types/emscripten"; function _verify_args_for_method_call(args_marshal: string/*ArgsMarshalString*/, args: any) { @@ -262,6 +262,12 @@ export function mono_wasm_invoke_js_with_args_ref(js_handle: JSHandle, method_na } } +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function mono_wasm_do_nothing(is_exception: Int32Ptr): any { + console.log(`mono_wasm_do_nothing ptr: ${is_exception} value: ${getI32(is_exception)}`); +} + + export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoStringRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address);