Skip to content

Commit

Permalink
Merge branch 'master' into feature/added-patch-verb-to-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
PaddoSwam authored Jul 29, 2018
2 parents 40174e3 + 16e5121 commit 6449690
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 12 deletions.
32 changes: 32 additions & 0 deletions Refit.Tests/FormValueDictionaryTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Xunit;

Expand Down Expand Up @@ -178,6 +179,29 @@ public void SkipsNullValuesFromDictionary()
Assert.Contains("foo", target.Keys);
}


[Fact]
public void SerializesEnumWithEnumMemberAttribute()
{
var source = new Dictionary<string, EnumWithEnumMember>()
{
{ "A", EnumWithEnumMember.A },
{ "B", EnumWithEnumMember.B }
};

var expected = new Dictionary<string, string>
{
{ "A", "A" },
{ "B", "b" }
};


var actual = new FormValueDictionary(source, settings);

Assert.Equal(expected, actual);
}


public class AliasingTestClass
{
[AliasAs("f")]
Expand All @@ -195,5 +219,13 @@ public class AliasingTestClass
[AliasAs("fr")]
public int? Frob { get; set; }
}

public enum EnumWithEnumMember
{
A,

[EnumMember(Value = "b")]
B
}
}
}
37 changes: 33 additions & 4 deletions Refit.Tests/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading;
using Xunit;
using System.Collections;
using System.Runtime.Serialization;

namespace Refit.Tests
{
Expand Down Expand Up @@ -95,7 +96,8 @@ public void TooManyComplexTypesThrows()
{
var input = typeof(IRestMethodInfoTests);

Assert.Throws<ArgumentException>(() => {
Assert.Throws<ArgumentException>(() =>
{
var fixture = new RestMethodInfo(
input,
input.GetMethods().First(x => x.Name == "TooManyComplexTypes"));
Expand Down Expand Up @@ -484,6 +486,9 @@ public interface IDummyHttpApi
[Multipart]
[Post("/foo?&name={name}")]
Task<HttpResponseMessage> PostWithQueryStringParameters(FileInfo source, string name);

[Get("/query")]
Task QueryWithEnum(FooWithEnumMember foo);
}

interface ICancellableMethods
Expand All @@ -495,6 +500,14 @@ interface ICancellableMethods
}


public enum FooWithEnumMember
{
A,

[EnumMember(Value = "b")]
B
}

public class SomeRequestData
{
[AliasAs("rpn")]
Expand Down Expand Up @@ -1197,10 +1210,24 @@ public void QueryStringExcludesPropertiesWithPrivateGetters()
Assert.Equal("/query?FullName=Mickey%20Mouse", uri.PathAndQuery);
}

[Theory]
[InlineData(FooWithEnumMember.A, "/query?foo=A")]
[InlineData(FooWithEnumMember.B, "/query?foo=b")]
public void QueryStringUsesEnumMemberAttribute(FooWithEnumMember queryParameter, string expectedQuery)
{
var fixture = new RequestBuilderImplementation<IDummyHttpApi>();
var factory = fixture.BuildRequestFactoryForMethod("QueryWithEnum");

var output = factory(new object[] { queryParameter });

var uri = new Uri(new Uri("http://api"), output.RequestUri);
Assert.Equal(expectedQuery, uri.PathAndQuery);
}


[Fact]
[UseCulture("es-ES")] // Spain uses a , instead of a .
public void DefaultParmeterFormatterIsInvariant()
public void DefaultParameterFormatterIsInvariant()
{
var settings = new RefitSettings();
var fixture = new RequestBuilderImplementation<IDummyHttpApi>(settings);
Expand Down Expand Up @@ -1234,7 +1261,8 @@ public static Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(th
var testHttpMessageHandler = new TestHttpMessageHandler();


return paramList => {
return paramList =>
{
var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, paramList);
task.Wait();
return testHttpMessageHandler.RequestMessage;
Expand All @@ -1251,7 +1279,8 @@ public static Func<object[], TestHttpMessageHandler> RunRequest(this IRequestBui
testHttpMessageHandler.Content = new StringContent(returnContent);
}

return paramList => {
return paramList =>
{
var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, paramList);
task.Wait();
return testHttpMessageHandler;
Expand Down
41 changes: 33 additions & 8 deletions Refit/RefitSettings.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Newtonsoft.Json;

Expand Down Expand Up @@ -38,32 +40,55 @@ public interface IFormUrlEncodedParameterFormatter

public class DefaultUrlParameterFormatter : IUrlParameterFormatter
{
static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, EnumMemberAttribute>> enumMemberCache
= new ConcurrentDictionary<Type, ConcurrentDictionary<string, EnumMemberAttribute>>();

public virtual string Format(object parameterValue, ParameterInfo parameterInfo)
{
// See if we have a format
var formatString = parameterInfo.GetCustomAttribute<QueryAttribute>(true)?.Format;

EnumMemberAttribute enummember = null;
if (parameterValue != null && parameterInfo.ParameterType.GetTypeInfo().IsEnum)
{
var cached = enumMemberCache.GetOrAdd(parameterInfo.ParameterType, t => new ConcurrentDictionary<string, EnumMemberAttribute>());
enummember = cached.GetOrAdd(parameterValue.ToString(), val => parameterInfo.ParameterType.GetMember(val).First().GetCustomAttribute<EnumMemberAttribute>());
}

return parameterValue == null
? null
: string.Format(CultureInfo.InvariantCulture,
string.IsNullOrWhiteSpace(formatString)
? "{0}"
: $"{{0:{formatString}}}",
parameterValue);
enummember?.Value ?? parameterValue);
}
}

public class DefaultFormUrlEncodedParameterFormatter : IFormUrlEncodedParameterFormatter
{
static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, EnumMemberAttribute>> enumMemberCache
= new ConcurrentDictionary<Type, ConcurrentDictionary<string, EnumMemberAttribute>>();

public virtual string Format(object parameterValue, string formatString)
{
return parameterValue == null
? null
: string.Format(CultureInfo.InvariantCulture,
string.IsNullOrWhiteSpace(formatString)
? "{0}"
: $"{{0:{formatString}}}",
parameterValue);
if (parameterValue == null)
return null;

var parameterType = parameterValue.GetType();

EnumMemberAttribute enummember = null;
if (parameterValue != null && parameterType.GetTypeInfo().IsEnum)
{
var cached = enumMemberCache.GetOrAdd(parameterType, t => new ConcurrentDictionary<string, EnumMemberAttribute>());
enummember = cached.GetOrAdd(parameterValue.ToString(), val => parameterType.GetMember(val).First().GetCustomAttribute<EnumMemberAttribute>());
}

return string.Format(CultureInfo.InvariantCulture,
string.IsNullOrWhiteSpace(formatString)
? "{0}"
: $"{{0:{formatString}}}",
enummember?.Value ?? parameterValue);
}
}
}

0 comments on commit 6449690

Please sign in to comment.