8000 Add void variants, update tests · dotnet/aspnetcore@ea51c5f · GitHub
[go: up one dir, main page]

Skip to content

Commit ea51c5f

Browse files
committed
Add void variants, update tests
1 parent ba6ec8b commit ea51c5f

File tree

3 files changed

+57
-147
lines changed

3 files changed

+57
-147
lines changed

src/JSInterop/Microsoft.JSInterop/src/JSObjectReferenceExtensions.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,61 @@ public static ValueTask<IJSObjectReference> InvokeNewAsync(this IJSObjectReferen
174174
/// <param name="jsObjectReference">The JavaScript object reference that represents the function to be invoked.</param>
175175
/// <returns>A delegate that can be used to invoke the JavaScript function.</returns>
176176
/// <exception cref="ArgumentNullException">Thrown when <paramref name="jsObjectReference"/> is null.</exception>
177-
public static Func<ValueTask> AsFunction(this IJSObjectReference jsObjectReference)
177+
public static Func<ValueTask> AsVoidFunction(this IJSObjectReference jsObjectReference)
178178
{
179179
ArgumentNullException.ThrowIfNull(jsObjectReference);
180180

181181
return async () => await jsObjectReference.InvokeVoidAsync(string.Empty);
182182
}
183183

184+
/// <summary>
185+
/// Wraps the interop invocation of the JavaScript function referenced by <paramref name="jsObjectReference"/> as a .NET delegate.
186+
/// </summary>
187+
/// <typeparam name="T1">The JSON-serializable type of the first argument.</typeparam>
188+
/// <typeparam name="TResult">The JSON-serializable return type.</typeparam>
189+
/// <param name="jsObjectReference">The JavaScript object reference that represents the function to be invoked.</param>
190+
/// <returns>A delegate that can be used to invoke the JavaScript function.</returns>
191+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="jsObjectReference"/> is null.</exception>
192+
public static Func<T1, ValueTask> AsVoidFunction<T1, [DynamicallyAccessedMembers(JsonSerialized)] TResult>(this IJSObjectReference jsObjectReference)
193+
{
194+
ArgumentNullException.ThrowIfNull(jsObjectReference);
195+
196+
return async (T1 arg1) => await jsObjectReference.InvokeVoidAsync(string.Empty, [arg1]);
197+
}
198+
199+
/// <summary>
200+
/// Wraps the interop invocation of the JavaScript function referenced by <paramref name="jsObjectReference"/> as a .NET delegate.
201+
/// </summary>
202+
/// <typeparam name="T1">The JSON-serializable type of the first argument.</typeparam>
203+
/// <typeparam name="T2">The JSON-serializable type of the second argument.</typeparam>
204+
/// <typeparam name="TResult">The JSON-serializable return type.</typeparam>
205+
/// <param name="jsObjectReference">The JavaScript object reference that represents the function to be invoked.</param>
206+
/// <returns>A delegate that can be used to invoke the JavaScript function.</returns>
207+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="jsObjectReference"/> is null.</exception>
208+
public static Func<T1, T2, ValueTask> AsVoidFunction<T1, T2, [DynamicallyAccessedMembers(JsonSerialized)] TResult>(this IJSObjectReference jsObjectReference)
209+
{
210+
ArgumentNullException.ThrowIfNull(jsObjectReference);
211+
212+
return async (T1 arg1, T2 arg2) => await jsObjectReference.InvokeVoidAsync(string.Empty, [arg1, arg2]);
213+
}
214+
215+
/// <summary>
216+
/// Wraps the interop invocation of the JavaScript function referenced by <paramref name="jsObjectReference"/> as a .NET delegate.
217+
/// </summary>
218+
/// <typeparam name="T1">The JSON-serializable type of the first argument.</typeparam>
219+
/// <typeparam name="T2">The JSON-serializable type of the second argument.</typeparam>
220+
/// <typeparam name="T3">The JSON-serializable type of the third argument.</typeparam>
221+
/// <typeparam name="TResult">The JSON-serializable return type.</typeparam>
222+
/// <param name="jsObjectReference">The JavaScript object reference that represents the function to be invoked.</param>
223+
/// <returns>A delegate that can be used to invoke the JavaScript function.</returns>
224+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="jsObjectReference"/> is null.</exception>
225+
public static Func<T1, T2, T3, ValueTask> AsVoidFunction<T1, T2, T3, [DynamicallyAccessedMembers(JsonSerialized)] TResult>(this IJSObjectReference jsObjectReference)
226+
{
227+
ArgumentNullException.ThrowIfNull(jsObjectReference);
228+
229+
return async (T1 arg1, T2 arg2, T3 arg3) => await jsObjectReference.InvokeVoidAsync(string.Empty, [arg1, arg2, arg3]);
230+
}
231+
184232
/// <summary>
185233
/// Wraps the interop invocation of the JavaScript function referenced by <paramref name="jsObjectReference"/> as a .NET delegate.
186234
/// </summary>

src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ Microsoft.JSInterop.JSRuntime.InvokeNewAsync(string! identifier, object?[]? args
5656
Microsoft.JSInterop.JSRuntime.InvokeNewAsync(string! identifier, System.Threading.CancellationToken cancellationToken, object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
5757
Microsoft.JSInterop.JSRuntime.SetValueAsync<TValue>(string! identifier, TValue value) -> System.Threading.Tasks.ValueTask
5858
Microsoft.JSInterop.JSRuntime.SetValueAsync<TValue>(string! identifier, TValue value, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
59-
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsFunction(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<System.Threading.Tasks.ValueTask>!
6059
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsFunction<T1, T2, T3, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, T2, T3, System.Threading.Tasks.ValueTask<TResult>>!
6160
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsFunction<T1, T2, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, T2, System.Threading.Tasks.ValueTask<TResult>>!
6261
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsFunction<T1, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, System.Threading.Tasks.ValueTask<TResult>>!
6362
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsFunction<TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<System.Threading.Tasks.ValueTask<TResult>>!
63+
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsVoidFunction(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<System.Threading.Tasks.ValueTask>!
64+
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsVoidFunction<T1, T2, T3, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, T2, T3, System.Threading.Tasks.ValueTask>!
65+
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsVoidFunction<T1, T2, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, T2, System.Threading.Tasks.ValueTask>!
66+
static Microsoft.JSInterop.JSObjectReferenceExtensions.AsVoidFunction<T1, TResult>(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference) -> System.Func<T1, System.Threading.Tasks.ValueTask>!
6467
static Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference, string! identifier, params object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
6568
static Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference, string! identifier, System.Threading.CancellationToken cancellationToken, object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
6669
static Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference, string! identifier, System.TimeSpan timeout, object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>

src/JSInterop/Microsoft.JSInterop/test/JSObjectReferenceExtensionsTest.cs

Lines changed: 4 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -14,73 +14,17 @@ namespace Microsoft.JSInterop.Tests;
1414
public class JSObjectReferenceExtensionsTest
1515
{
1616
[Fact]
17-
public void AsAsyncFunction_WithVoidValueTaskFunc_ReturnsFunc()
18-
{
19-
var jsRuntime = new TestJSRuntime();
20-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
21-
22-
// Act
23-
var func = jsObjectReference.AsAsyncFunction<Func<int, ValueTask>>();
24-
25-
// Assert
26-
Assert.NotNull(func);
27-
Assert.IsType<Func<int, ValueTask>>(func);
28-
}
29-
30-
[Fact]
31-
public void AsAsyncFunction_WithVoidTaskFunc_ReturnsFunc()
32-
{
33-
var jsRuntime = new TestJSRuntime();
34-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
35-
36-
// Act
37-
var func = jsObjectReference.AsAsyncFunction<Func<int, Task>>();
38-
39-
// Assert
40-
Assert.NotNull(func);
41-
Assert.IsType<Func<int, Task>>(func);
42-
}
43-
44-
[Fact]
45-
public void AsAsyncFunction_WithValueTaskFunc_ReturnsFunc()
46-
{
47-
var jsRuntime = new TestJSRuntime();
48-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
49-
50-
// Act
51-
var func = jsObjectReference.AsAsyncFunction<Func<int, ValueTask<int>>>();
52-
53-
// Assert
54-
Assert.NotNull(func);
55-
Assert.IsType<Func<int, ValueTask<int>>>(func);
56-
}
57-
58-
[Fact]
59-
public void AsAsyncFunction_WithTaskFunc_ReturnsFunc()
60-
{
61-
var jsRuntime = new TestJSRuntime();
62-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
63-
64-
// Act
65-
var func = jsObjectReference.AsAsyncFunction<Func<int, Task<int>>>();
66-
67-
// Assert
68-
Assert.NotNull(func);
69-
Assert.IsType<Func<int, Task<int>>>(func);
70-
}
71-
72-
[Fact]
73-
public void AsAsyncFunction_WithValueTaskFunc_ReturnsFunc_ThatInvokesInterop()
17+
public void AsFunction_ReturnsFunc_ThatInvokesInterop()
7418
{
7519
// Arrange
76-
var jsRuntime = new TestJSRuntime();
20+
var jsRuntime = new RecordingTestJSRuntime();
7721
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
7822

7923
var bytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(42));
8024
var reader = new Utf8JsonReader(bytes);
8125

8226
// Act
83-
var func = jsObjectReference.AsAsyncFunction<Func<int, ValueTask<int>>>();
27+
var func = jsObjectReference.AsFunction<int, int>();
8428
ValueTask<int> task = func(1);
8529

8630
jsRuntime.EndInvokeJS(
@@ -95,98 +39,13 @@ public void AsAsyncFunction_WithValueTaskFunc_ReturnsFunc_ThatInvokesInterop()
9539
#pragma warning restore xUnit1031 // Do not use blocking task operations in test method
9640
}
9741

98-
[Fact]
99-
public void AsAsyncFunction_WithTaskFunc_ReturnsFunc_ThatInvokesInterop()
100-
{
101-
// Arrange
102-
var jsRuntime = new TestJSRuntime();
103-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
104-
105-
var bytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(42));
106-
var reader = new Utf8JsonReader(bytes);
107-
108-
// Act
109-
var func = jsObjectReference.AsAsyncFunction<Func<int, Task<int>>>();
110-
Task<int> task = func(1);
111-
112-
jsRuntime.EndInvokeJS(
113-
jsRuntime.InvokeCalls[0].AsyncHandle,
114-
/* succeeded: */ true,
115-
ref reader);
116-
117-
// Assert
118-
Assert.True(task.IsCompleted);
119-
#pragma warning disable xUnit1031 // Do not use blocking task operations in test method
120-
Assert.Equal(42, task.Result);
121-
#pragma warning restore xUnit1031 // Do not use blocking task operations in test method
122-
}
123-
124-
[Fact]
125-
public void AsAsyncFunction_WithEventHandlerDelegate_Throws()
126-
{
127-
var jsRuntime = new TestJSRuntime();
128-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
129-
130-
// Act/Assert
131-
Assert.Throws<InvalidOperationException>(jsObjectReference.AsAsyncFunction<EventHandler>);
132-
}
133-
134-
[Fact]
135-
public void AsAsyncFunction_WithActionDelegate_Throws()
136-
{
137-
var jsRuntime = new TestJSRuntime();
138-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
139-
140-
// Act/Assert
141-
Assert.Throws<InvalidOperationException>(jsObjectReference.AsAsyncFunction<Action<int>>);
142-
}
143-
144-
[Fact]
145-
public void AsAsyncFunction_WithFuncWithInvalidReturnType_Throws()
146-
{
147-
var jsRuntime = new TestJSRuntime();
148-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
149-
150-
// Act/Assert
151-
Assert.Throws<InvalidOperationException>(jsObjectReference.AsAsyncFunction<Func<int>>);
152-
}
153-
154-
[Fact]
155-
public void AsAsyncFunction_WithFuncWithTooManyParams_Throws()
156-
{
157-
var jsRuntime = new TestJSRuntime();
158-
var jsObjectReference = new JSObjectReference(jsRuntime, 1);
159-
160-
// Act/Assert
161-
Assert.Throws<InvalidOperationException>(jsObjectReference.AsAsyncFunction<Func<int, int, int, int, int, int, int, int, int, Task>>);
162-
}
163-
164-
class TestJSRuntime : JSInProcessRuntime
42+
class RecordingTestJSRuntime : TestJSRuntime
16543
{
16644
public List<JSInvocationInfo> InvokeCalls { get; set; } = [];
16745

168-
public string? NextResultJson { get; set; }
169-
170-
protected override string? InvokeJS(string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId)
171-
{
172-
throw new NotImplementedException();
173-
}
174-
175-
protected override string? InvokeJS(in JSInvocationInfo invocationInfo)
176-
{
177-
InvokeCalls.Add(invocationInfo);
178-
return NextResultJson;
179-
}
180-
181-
protected override void BeginInvokeJS(long taskId, string identifier, [StringSyntax("Json")] string? argsJson, JSCallResultType resultType, long targetInstanceId)
182-
=> throw new NotImplementedException("This test only covers sync calls");
183-
18446
protected override void BeginInvokeJS(in JSInvocationInfo invocationInfo)
18547
{
18648
InvokeCalls.Add(invocationInfo);
18749
}
188-
189-
protected internal override void EndInvokeDotNet(DotNetInvocationInfo invocationInfo, in DotNetInvocationResult invocationResult)
190-
=> throw new NotImplementedException("This test only covers sync calls");
19150
}
19251
}

0 commit comments

Comments
 (0)
0