From 42177d47943a28e7cdda0f604ad8bdb6037e4bb7 Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Tue, 22 Oct 2024 23:54:10 +0100 Subject: [PATCH] feat: add generic and enumerable tests --- Refit.Tests/ReflectionTests.cs | 194 ++++++++++++++++++++++++++++----- 1 file changed, 167 insertions(+), 27 deletions(-) diff --git a/Refit.Tests/ReflectionTests.cs b/Refit.Tests/ReflectionTests.cs index 42efd6b39..b0716dbc6 100644 --- a/Refit.Tests/ReflectionTests.cs +++ b/Refit.Tests/ReflectionTests.cs @@ -19,9 +19,21 @@ public interface IBasicApi [Get("/{value}")] Task GetGenericParam(T value); + [Get("/")] + Task GetQuery(string queryKey); + + [Get("/")] + Task GetGenericQuery(T queryKey); + [Get("/")] Task GetPropertyQuery(BaseRecord queryKey); + [Get("/")] + Task GetEnumerableQuery(IEnumerable enums); + + [Get("/")] + Task GetEnumerablePropertyQuery(MyEnumerableParams enums); + [Get("/")] Task GetDictionaryQuery(IDictionary dict); } @@ -32,6 +44,8 @@ public record BaseRecord(string Value); public record MyParams(string PropValue); +public record MyEnumerableParams(int[] Enumerable); + public class TestUrlFormatter : IUrlParameterFormatter { private readonly ICustomAttributeProvider[] expectedAttributeProviders; @@ -44,7 +58,10 @@ public TestUrlFormatter(ICustomAttributeProvider expectedAttributeProvider, Type expectedTypes = [expectedType]; } - public TestUrlFormatter(ICustomAttributeProvider[] expectedAttributeProviders, Type[] expectedTypes) + public TestUrlFormatter( + ICustomAttributeProvider[] expectedAttributeProviders, + Type[] expectedTypes + ) { this.expectedAttributeProviders = expectedAttributeProviders; this.expectedTypes = expectedTypes; @@ -80,8 +97,11 @@ public async Task UrlParameterShouldBeExpectedReflection() var parameterInfo = methodInfo.GetParameters()[0]; var formatter = new TestUrlFormatter(parameterInfo, typeof(string)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetParam("bar"); @@ -99,8 +119,11 @@ public async Task DerivedUrlParameterShouldBeExpectedReflection() var parameterInfo = methodInfo.GetParameters()[0]; var formatter = new TestUrlFormatter(parameterInfo, typeof(BaseRecord)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetDerivedParam(new DerivedRecord("Derived")); @@ -117,8 +140,11 @@ public async Task PropertyParameterShouldBeExpectedReflection() var propertyInfo = typeof(MyParams).GetProperties()[0]; var formatter = new TestUrlFormatter(propertyInfo, typeof(string)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetPropertyParam(new MyParams("propVal")); @@ -137,8 +163,11 @@ public async Task GenericParameterShouldBeExpectedReflection() var parameterInfo = stringMethod.GetParameters()[0]; var formatter = new TestUrlFormatter(parameterInfo, typeof(string)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetGenericParam("genericVal"); @@ -146,24 +175,47 @@ public async Task GenericParameterShouldBeExpectedReflection() } [Fact] - public async Task QueryPropertyParameterShouldBeExpectedReflection() + public async Task QueryParameterShouldBeExpectedReflection() { mockHandler .Expect(HttpMethod.Get, "http://foo/") .WithExactQueryString( - new[] - { - new KeyValuePair("Value", "queryVal"), - } + new[] { new KeyValuePair("queryKey", "queryValue"), } ) + .Respond("application/json", nameof(IBasicApi.GetQuery)); + + var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetQuery))!; + var parameterInfo = methodInfo.GetParameters()[0]; + + var formatter = new TestUrlFormatter(parameterInfo, typeof(string)); + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; + var service = RestService.For("http://foo", settings); + + await service.GetQuery("queryValue"); + formatter.AssertNoOutstandingAssertions(); + } + + [Fact] + public async Task QueryPropertyParameterShouldBeExpectedReflection() + { + mockHandler + .Expect(HttpMethod.Get, "http://foo/") + .WithExactQueryString(new[] { new KeyValuePair("Value", "queryVal"), }) .Respond("application/json", nameof(IBasicApi.GetPropertyQuery)); var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetPropertyQuery))!; var parameterInfo = methodInfo.GetParameters()[0]; var formatter = new TestUrlFormatter(parameterInfo, typeof(BaseRecord)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetPropertyQuery(new BaseRecord("queryVal")); @@ -175,26 +227,103 @@ public async Task DerivedQueryPropertyParameterShouldBeExpectedReflection() { mockHandler .Expect(HttpMethod.Get, "http://foo/") - .WithExactQueryString( - new[] - { - new KeyValuePair("Value", "queryVal"), - } - ) + .WithExactQueryString(new[] { new KeyValuePair("Value", "queryVal"), }) .Respond("application/json", nameof(IBasicApi.GetPropertyQuery)); var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetPropertyQuery))!; var parameterInfo = methodInfo.GetParameters()[0]; var formatter = new TestUrlFormatter(parameterInfo, typeof(BaseRecord)); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); await service.GetPropertyQuery(new DerivedRecord("queryVal")); formatter.AssertNoOutstandingAssertions(); } + [Fact] + public async Task GenericQueryParameterShouldBeExpectedReflection() + { + mockHandler + .Expect(HttpMethod.Get, "http://foo/") + .WithExactQueryString( + new[] { new KeyValuePair("queryKey", "queryValue"), } + ) + .Respond("application/json", nameof(IBasicApi.GetGenericQuery)); + + var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetGenericQuery))!; + var stringMethod = methodInfo.MakeGenericMethod(typeof(string)); + var parameterInfo = stringMethod.GetParameters()[0]; + + var formatter = new TestUrlFormatter(parameterInfo, typeof(string)); + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; + var service = RestService.For("http://foo", settings); + + await service.GetGenericQuery("queryValue"); + formatter.AssertNoOutstandingAssertions(); + } + + [Fact] + public async Task EnumerableQueryParameterShouldBeExpectedReflection() + { + mockHandler + .Expect(HttpMethod.Get, "http://foo/") + .WithExactQueryString(new[] { new KeyValuePair("enums", "k0,k1"), }) + .Respond("application/json", nameof(IBasicApi.GetEnumerableQuery)); + + var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetEnumerableQuery))!; + var parameterInfo = methodInfo.GetParameters()[0]; + + var formatter = new TestUrlFormatter( + [parameterInfo, parameterInfo], + [typeof(IEnumerable), typeof(IEnumerable)] + ); + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; + var service = RestService.For("http://foo", settings); + + await service.GetEnumerableQuery(["k0", "k1"]); + formatter.AssertNoOutstandingAssertions(); + } + + [Fact] + public async Task EnumerablePropertyQueryParameterShouldBeExpectedReflection() + { + mockHandler + .Expect(HttpMethod.Get, "http://foo/") + .WithExactQueryString(new[] { new KeyValuePair("Enumerable", "0,1"), }) + .Respond("application/json", nameof(IBasicApi.GetEnumerablePropertyQuery)); + + var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetEnumerablePropertyQuery))!; + var parameterInfo = methodInfo.GetParameters()[0]; + var propertyInfo = typeof(MyEnumerableParams).GetProperties()[0]; + + var formatter = new TestUrlFormatter( + [propertyInfo, propertyInfo, parameterInfo], + [typeof(int[]), typeof(int[]), typeof(MyEnumerableParams)] + ); + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; + var service = RestService.For("http://foo", settings); + + await service.GetEnumerablePropertyQuery(new MyEnumerableParams([0, 1])); + formatter.AssertNoOutstandingAssertions(); + } + [Fact] public async Task QueryDictionaryParameterShouldBeExpectedReflection() { @@ -212,9 +341,20 @@ public async Task QueryDictionaryParameterShouldBeExpectedReflection() var methodInfo = typeof(IBasicApi).GetMethod(nameof(IBasicApi.GetDictionaryQuery))!; var parameterInfo = methodInfo.GetParameters()[0]; - var formatter = new TestUrlFormatter([typeof(string), typeof(string), parameterInfo, parameterInfo], [typeof(string), typeof(string), typeof(IDictionary),typeof(IDictionary)]); - var settings = new RefitSettings() { HttpMessageHandlerFactory = () => mockHandler }; - settings.UrlParameterFormatter = formatter; + var formatter = new TestUrlFormatter( + [typeof(string), typeof(string), parameterInfo, parameterInfo], + [ + typeof(string), + typeof(string), + typeof(IDictionary), + typeof(IDictionary) + ] + ); + var settings = new RefitSettings + { + HttpMessageHandlerFactory = () => mockHandler, + UrlParameterFormatter = formatter + }; var service = RestService.For("http://foo", settings); var dict = new Dictionary { { "key0", 1 }, { "key1", 2 } };