Skip to content

Commit

Permalink
Add runtime tests back
Browse files Browse the repository at this point in the history
  • Loading branch information
brianrourkeboll committed Jun 17, 2023
1 parent 3fea9df commit 2111eb2
Showing 1 changed file with 257 additions and 0 deletions.
257 changes: 257 additions & 0 deletions src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,39 +1420,48 @@ public static IEnumerable<object[]> CustomResults
CustomResult TestAction() => new CustomResult(resultString);
Task<CustomResult> TaskTestAction() => Task.FromResult(new CustomResult(resultString));
ValueTask<CustomResult> ValueTaskTestAction() => ValueTask.FromResult(new CustomResult(resultString));
FSharp.Control.FSharpAsync<CustomResult> FSharpAsyncTestAction() => FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return(new CustomResult(resultString));

static CustomResult StaticTestAction() => new CustomResult("Still not enough tests!");
static Task<CustomResult> StaticTaskTestAction() => Task.FromResult(new CustomResult("Still not enough tests!"));
static ValueTask<CustomResult> StaticValueTaskTestAction() => ValueTask.FromResult(new CustomResult("Still not enough tests!"));
static FSharp.Control.FSharpAsync<CustomResult> StaticFSharpAsyncTestAction() => FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return(new CustomResult("Still not enough tests!"));

// Object return type where the object is IResult
static object StaticResultAsObject() => new CustomResult("Still not enough tests!");

// Task<object> return type
static Task<object> StaticTaskOfIResultAsObject() => Task.FromResult<object>(new CustomResult("Still not enough tests!"));
static ValueTask<object> StaticValueTaskOfIResultAsObject() => ValueTask.FromResult<object>(new CustomResult("Still not enough tests!"));
static FSharp.Control.FSharpAsync<object> StaticFSharpAsyncOfIResultAsObject() => FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return<object>(new CustomResult("Still not enough tests!"));

StructResult TestStructAction() => new StructResult(resultString);
Task<StructResult> TaskTestStructAction() => Task.FromResult(new StructResult(resultString));
ValueTask<StructResult> ValueTaskTestStructAction() => ValueTask.FromResult(new StructResult(resultString));
FSharp.Control.FSharpAsync<StructResult> FSharpAsyncTestStructAction() => FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return(new StructResult(resultString));

return new List<object[]>
{
new object[] { (Func<CustomResult>)TestAction },
new object[] { (Func<Task<CustomResult>>)TaskTestAction},
new object[] { (Func<ValueTask<CustomResult>>)ValueTaskTestAction},
new object[] { (Func<FSharp.Control.FSharpAsync<CustomResult>>)FSharpAsyncTestAction },

new object[] { (Func<CustomResult>)StaticTestAction},
new object[] { (Func<Task<CustomResult>>)StaticTaskTestAction},
new object[] { (Func<ValueTask<CustomResult>>)StaticValueTaskTestAction},
new object[] { (Func<FSharp.Control.FSharpAsync<CustomResult>>)StaticFSharpAsyncTestAction },

new object[] { (Func<object>)StaticResultAsObject},

new object[] { (Func<Task<object>>)StaticTaskOfIResultAsObject},
new object[] { (Func<ValueTask<object>>)StaticValueTaskOfIResultAsObject},
new object[] { (Func<FSharp.Control.FSharpAsync<object>>)StaticFSharpAsyncOfIResultAsObject},

new object[] { (Func<StructResult>)TestStructAction },
new object[] { (Func<Task<StructResult>>)TaskTestStructAction },
new object[] { (Func<ValueTask<StructResult>>)ValueTaskTestStructAction },
new object[] { (Func<FSharp.Control.FSharpAsync<StructResult>>)FSharpAsyncTestStructAction },
};
}
}
Expand Down Expand Up @@ -2218,6 +2227,169 @@ public async Task RequestDelegateFactory_InvokesFilters_OnMethodInfoWithProvided
Assert.Equal("Hello, TestName!", decodedResponseBody);
}

public static object[][] FSharpAsyncOfTMethods
{
get
{
FSharp.Control.FSharpAsync<string> FSharpAsyncOfTMethod()
{
return FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return("foo");
}

FSharp.Control.FSharpAsync<string> FSharpAsyncOfTWithYieldMethod()
{
return FSharp.Control.FSharpAsync.AwaitTask(Yield());

async Task<string> Yield()
{
await Task.Yield();
return "foo";
}
}

FSharp.Control.FSharpAsync<object> FSharpAsyncOfObjectWithYieldMethod()
{
return FSharp.Control.FSharpAsync.AwaitTask(Yield());

async Task<object> Yield()
{
await Task.Yield();
return "foo";
}
}

return new object[][]
{
new object[] { (Func<FSharp.Control.FSharpAsync<string>>)FSharpAsyncOfTMethod },
new object[] { (Func<FSharp.Control.FSharpAsync<string>>)FSharpAsyncOfTWithYieldMethod },
new object[] { (Func<FSharp.Control.FSharpAsync<object>>)FSharpAsyncOfObjectWithYieldMethod }
};
}
}

[Theory]
[MemberData(nameof(FSharpAsyncOfTMethods))]
public async Task CanInvokeFilter_OnFSharpAsyncOfTReturningHandler(Delegate @delegate)
{
// Arrange
var responseBodyStream = new MemoryStream();
var httpContext = CreateHttpContext();
httpContext.Response.Body = responseBodyStream;

// Act
var factoryResult = RequestDelegateFactory.Create(@delegate, new RequestDelegateFactoryOptions()
{
EndpointBuilder = CreateEndpointBuilderFromFilterFactories(new List<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>()
{
(routeHandlerContext, next) => async (context) =>
{
return await next(context);
}
}),
});
var requestDelegate = factoryResult.RequestDelegate;
await requestDelegate(httpContext);

Assert.Equal(200, httpContext.Response.StatusCode);
var decodedResponseBody = Encoding.UTF8.GetString(responseBodyStream.ToArray());
Assert.Equal("foo", decodedResponseBody);
}

public static object[][] VoidReturningMethods
{
get
{
void VoidMethod() { }

ValueTask ValueTaskMethod()
{
return ValueTask.CompletedTask;
}

ValueTask<FSharp.Core.Unit> ValueTaskOfUnitMethod()
{
return ValueTask.FromResult(default(FSharp.Core.Unit)!);
}

Task TaskMethod()
{
return Task.CompletedTask;
}

Task<FSharp.Core.Unit> TaskOfUnitMethod()
{
return Task.FromResult(default(FSharp.Core.Unit)!);
}

FSharp.Control.FSharpAsync<FSharp.Core.Unit> FSharpAsyncOfUnitMethod()
{
return FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return(default(FSharp.Core.Unit)!);
}

async ValueTask ValueTaskWithYieldMethod()
{
await Task.Yield();
}

async Task TaskWithYieldMethod()
{
await Task.Yield();
}

FSharp.Control.FSharpAsync<FSharp.Core.Unit> FSharpAsyncOfUnitWithYieldMethod()
{
return FSharp.Control.FSharpAsync.AwaitTask(Yield());

async Task<FSharp.Core.Unit> Yield()
{
await Task.Yield();
return default!;
}
}

return new object[][]
{
new object[] { (Action)VoidMethod },
new object[] { (Func<ValueTask>)ValueTaskMethod },
new object[] { (Func<ValueTask<FSharp.Core.Unit>>)ValueTaskOfUnitMethod },
new object[] { (Func<Task>)TaskMethod },
new object[] { (Func<Task<FSharp.Core.Unit>>)TaskOfUnitMethod },
new object[] { (Func<FSharp.Control.FSharpAsync<FSharp.Core.Unit>>)FSharpAsyncOfUnitMethod },
new object[] { (Func<ValueTask>)ValueTaskWithYieldMethod },
new object[] { (Func<Task>)TaskWithYieldMethod},
new object[] { (Func<FSharp.Control.FSharpAsync<FSharp.Core.Unit>>)FSharpAsyncOfUnitWithYieldMethod }
};
}
}

[Theory]
[MemberData(nameof(VoidReturningMethods))]
public async Task CanInvokeFilter_OnVoidReturningHandler(Delegate @delegate)
{
// Arrange
var responseBodyStream = new MemoryStream();
var httpContext = CreateHttpContext();
httpContext.Response.Body = responseBodyStream;

// Act
var factoryResult = RequestDelegateFactory.Create(@delegate, new RequestDelegateFactoryOptions()
{
EndpointBuilder = CreateEndpointBuilderFromFilterFactories(new List<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>()
{
(routeHandlerContext, next) => async (context) =>
{
return await next(context);
}
}),
});
var requestDelegate = factoryResult.RequestDelegate;
await requestDelegate(httpContext);

Assert.Equal(200, httpContext.Response.StatusCode);
var decodedResponseBody = Encoding.UTF8.GetString(responseBodyStream.ToArray());
Assert.Equal(String.Empty, decodedResponseBody);
}

[Fact]
public async Task CanInvokeFilter_OnTaskModifyingHttpContext()
{
Expand Down Expand Up @@ -2255,6 +2427,91 @@ async Task HandlerWithTaskAwait(HttpContext c)
Assert.Equal(string.Empty, decodedResponseBody);
}

public static object[][] TasksOfTypesMethods
{
get
{
ValueTask<TodoStruct> ValueTaskOfStructMethod()
{
return ValueTask.FromResult(new TodoStruct { Name = "Test todo" });
}

async ValueTask<TodoStruct> ValueTaskOfStructWithYieldMethod()
{
await Task.Yield();
return new TodoStruct { Name = "Test todo" };
}

Task<TodoStruct> TaskOfStructMethod()
{
return Task.FromResult(new TodoStruct { Name = "Test todo" });
}

async Task<TodoStruct> TaskOfStructWithYieldMethod()
{
await Task.Yield();
return new TodoStruct { Name = "Test todo" };
}

FSharp.Control.FSharpAsync<TodoStruct> FSharpAsyncOfStructMethod()
{
return FSharp.Core.ExtraTopLevelOperators.DefaultAsyncBuilder.Return(new TodoStruct { Name = "Test todo" });
}

FSharp.Control.FSharpAsync<TodoStruct> FSharpAsyncOfStructWithYieldMethod()
{
return FSharp.Control.FSharpAsync.AwaitTask(Yield());

async Task<TodoStruct> Yield()
{
await Task.Yield();
return new TodoStruct { Name = "Test todo" };
}
}

return new object[][]
{
new object[] { (Func<ValueTask<TodoStruct>>)ValueTaskOfStructMethod },
new object[] { (Func<ValueTask<TodoStruct>>)ValueTaskOfStructWithYieldMethod },
new object[] { (Func<Task<TodoStruct>>)TaskOfStructMethod },
new object[] { (Func<Task<TodoStruct>>)TaskOfStructWithYieldMethod },
new object[] { (Func<FSharp.Control.FSharpAsync<TodoStruct>>)FSharpAsyncOfStructMethod },
new object[] { (Func<FSharp.Control.FSharpAsync<TodoStruct>>)FSharpAsyncOfStructWithYieldMethod }
};
}
}

[Theory]
[MemberData(nameof(TasksOfTypesMethods))]
public async Task CanInvokeFilter_OnHandlerReturningTasksOfStruct(Delegate @delegate)
{
// Arrange
var responseBodyStream = new MemoryStream();
var httpContext = CreateHttpContext();
httpContext.Response.Body = responseBodyStream;

// Act
var factoryResult = RequestDelegateFactory.Create(@delegate, new RequestDelegateFactoryOptions()
{
EndpointBuilder = CreateEndpointBuilderFromFilterFactories(new List<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>()
{
(routeHandlerContext, next) => async (context) =>
{
return await next(context);
}
}),
});
var requestDelegate = factoryResult.RequestDelegate;
await requestDelegate(httpContext);

Assert.Equal(200, httpContext.Response.StatusCode);
var deserializedResponseBody = JsonSerializer.Deserialize<TodoStruct>(responseBodyStream.ToArray(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
Assert.Equal("Test todo", deserializedResponseBody.Name);
}

[Fact]
public void Create_DoesNotAddDelegateMethodInfo_AsMetadata()
{
Expand Down

0 comments on commit 2111eb2

Please sign in to comment.