From 04064f983c47d6745f26380c39d333653827155c Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Fri, 15 Dec 2017 19:41:20 +0000 Subject: [PATCH] Add test to more explicitly cover both 'params array' and 'generics'-style interop APIs --- samples/MonoSanity/wwwroot/index.html | 27 +++++++++++++++++++ samples/MonoSanityClient/Examples.cs | 16 ++++++++++- .../Interop/WebAssembly.Runtime.cs | 2 +- .../Tests/MonoSanityTest.cs | 24 +++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/samples/MonoSanity/wwwroot/index.html b/samples/MonoSanity/wwwroot/index.html index 51feee8def..151d945428 100644 --- a/samples/MonoSanity/wwwroot/index.html +++ b/samples/MonoSanity/wwwroot/index.html @@ -45,6 +45,16 @@ +
+ Call JS from .NET (no boxing) +
+ / + = + + +
+
+

Loading...

@@ -91,6 +101,14 @@ el('callJsResult').value = result; }; + el('callJsNoBoxing').onsubmit = function (evt) { + evt.preventDefault(); + var a = parseInt(el('callJsNoBoxingNumberA').value); + var b = parseInt(el('callJsNoBoxingNumberB').value); + var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'CallJsNoBoxing', [a, b]); + el('callJsNoBoxingResult').value = result; + }; + function el(id) { return document.getElementById(id); } @@ -115,6 +133,15 @@ return result === null || result === undefined ? result // Pass through null/undefined so we can verify this is handled upstream : javaScriptStringToDotNetString(result.toString()); + }, + + divideNumbersUnmarshalled: function (a, b) { + // In this example, neither the arguments nor return value are boxed + // -- we expect to receive and return numbers directly + if (b === 0) { + throw new Error('Division by zero'); + } + return a / b; } }; diff --git a/samples/MonoSanityClient/Examples.cs b/samples/MonoSanityClient/Examples.cs index 369c1db873..5a677c97a3 100644 --- a/samples/MonoSanityClient/Examples.cs +++ b/samples/MonoSanityClient/Examples.cs @@ -31,7 +31,8 @@ namespace MonoSanityClient public static string EvaluateJavaScript(string expression) { - var result = Runtime.InvokeJS(out var exceptionMessage, "evaluateJsExpression", expression, null, null); + // For tests that call this method, we'll exercise the 'InvokeJSArray' code path + var result = Runtime.InvokeJSArray(out var exceptionMessage, "evaluateJsExpression", expression, null, null); if (exceptionMessage != null) { return $".NET got exception: {exceptionMessage}"; @@ -39,5 +40,18 @@ namespace MonoSanityClient return $".NET received: {(result ?? "(NULL)")}"; } + + public static string CallJsNoBoxing(int numberA, int numberB) + { + // For tests that call this method, we'll exercise the 'InvokeJS' code path + // since that doesn't box the params + var result = Runtime.InvokeJS(out var exceptionMessage, "divideNumbersUnmarshalled", numberA, numberB, null); + if (exceptionMessage != null) + { + return $".NET got exception: {exceptionMessage}"; + } + + return $".NET received: {result}"; + } } } diff --git a/src/Microsoft.Blazor.Browser/Interop/WebAssembly.Runtime.cs b/src/Microsoft.Blazor.Browser/Interop/WebAssembly.Runtime.cs index 45f4965a56..61fbab3071 100644 --- a/src/Microsoft.Blazor.Browser/Interop/WebAssembly.Runtime.cs +++ b/src/Microsoft.Blazor.Browser/Interop/WebAssembly.Runtime.cs @@ -14,6 +14,6 @@ namespace WebAssembly public static extern TRes InvokeJS(out string exception, string funcName, T0 arg0, T1 arg1, T2 arg2); [MethodImpl(MethodImplOptions.InternalCall)] - public static extern TRes InvokeJSArray(out string exception, string funcName, object[] args); + public static extern TRes InvokeJSArray(out string exception, string funcName, params object[] args); } } diff --git a/test/Microsoft.Blazor.E2ETest/Tests/MonoSanityTest.cs b/test/Microsoft.Blazor.E2ETest/Tests/MonoSanityTest.cs index 2c227d5568..408ea45e94 100644 --- a/test/Microsoft.Blazor.E2ETest/Tests/MonoSanityTest.cs +++ b/test/Microsoft.Blazor.E2ETest/Tests/MonoSanityTest.cs @@ -101,6 +101,30 @@ namespace Microsoft.Blazor.E2ETest.Tests Assert.Equal(".NET received: (NULL)", result); } + [Fact] + public void CanCallJsFunctionsWithoutBoxing() + { + Navigate("/", noReload: true); + + SetValue(Browser, "callJsNoBoxingNumberA", "108"); + SetValue(Browser, "callJsNoBoxingNumberB", "4"); + Browser.FindElement(By.CssSelector("#callJsNoBoxing button")).Click(); + + Assert.Equal(".NET received: 27", GetValue(Browser, "callJsNoBoxingResult")); + } + + [Fact] + public void CanCallJsFunctionsWithoutBoxingAndReceiveException() + { + Navigate("/", noReload: true); + + SetValue(Browser, "callJsNoBoxingNumberA", "1"); + SetValue(Browser, "callJsNoBoxingNumberB", "0"); + Browser.FindElement(By.CssSelector("#callJsNoBoxing button")).Click(); + + Assert.StartsWith(".NET got exception: Division by zero", GetValue(Browser, "callJsNoBoxingResult")); + } + private static string GetValue(IWebDriver webDriver, string elementId) { var element = webDriver.FindElement(By.Id(elementId));