From ad4b9fd1bd6655231c5a7ca2b3b83536b82eb574 Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Sun, 26 Nov 2023 22:38:28 +0000 Subject: [PATCH] chore: run csharpier --- .../ITypeSymbolExtensions.cs | 17 +- .../InterfaceStubGenerator.cs | 458 +++-- Refit.Benchmarks/EndToEndBenchmark.cs | 150 +- Refit.Benchmarks/IGitHubService.cs | 22 +- .../StaticFileHttpResponseHandler.cs | 21 +- .../HttpClientFactoryExtensions.cs | 126 +- Refit.HttpClientFactory/SettingsFor.cs | 5 +- .../NewtonsoftJsonContentSerializer.cs | 34 +- .../AuthenticatedClientHandlerTests.cs | 147 +- ...rSeparatedPropertyNamesContractResolver.cs | 6 +- Refit.Tests/ExceptionFactoryTests.cs | 28 +- Refit.Tests/FormValueMultimapTests.cs | 106 +- Refit.Tests/GitHubApi.cs | 5 +- Refit.Tests/GlobalSuppressions.cs | 16 +- .../HttpClientFactoryExtensionsTests.cs | 94 +- Refit.Tests/IDefaultInterfaceMethodTests.cs | 24 +- Refit.Tests/InheritedGenericInterfacesApi.cs | 23 +- Refit.Tests/InheritedInterfacesApi.cs | 5 +- .../InheritedInterfacesInSeparateFileApi.cs | 2 +- Refit.Tests/IntegrationTestHelper.cs | 4 +- Refit.Tests/InterfaceStubGenerator.cs | 96 +- Refit.Tests/MethodOverloads.cs | 139 +- Refit.Tests/MultipartTests.cs | 362 ++-- Refit.Tests/NullableReferenceTypes.cs | 1 + Refit.Tests/RequestBuilder.cs | 1760 +++++++++++++---- Refit.Tests/ResponseTests.cs | 167 +- Refit.Tests/RestService.cs | 1233 ++++++------ Refit.Tests/SerializedContentTests.cs | 50 +- Refit.Tests/UseCultureAttribute.cs | 24 +- ...crementalSourceGeneratorVerifier`1+Test.cs | 24 +- ...arpIncrementalSourceGeneratorVerifier`1.cs | 4 +- .../CSharpSourceGeneratorVerifier`1+Test.cs | 24 +- .../CSharpSourceGeneratorVerifier`1.cs | 4 +- Refit.Tests/Verifiers/CSharpVerifierHelper.cs | 9 +- Refit.Tests/XmlContentSerializerTests.cs | 36 +- Refit.Xml/XmlContentSerializer.cs | 98 +- Refit/ApiException.cs | 100 +- Refit/ApiResponse.cs | 49 +- Refit/Attributes.cs | 51 +- Refit/AuthenticatedHttpClientHandler.cs | 10 +- ...PooledBufferWriter.Stream.NETStandard21.cs | 14 +- Refit/Buffers/PooledBufferWriter.Stream.cs | 32 +- Refit/Buffers/PooledBufferWriter.cs | 26 +- Refit/CachedRequestBuilderImplementation.cs | 45 +- Refit/CloseGenericMethodKey.cs | 3 +- Refit/CollectionFormat.cs | 2 +- Refit/FormValueMultimap.cs | 81 +- Refit/HttpContentExtensions.cs | 11 +- Refit/JsonContentSerializer.cs | 10 +- Refit/MultipartItem.cs | 30 +- Refit/NameValueCollection.cs | 1 - Refit/ProblemDetails.cs | 7 +- Refit/Properties/AssemblyInfo.cs | 16 +- Refit/PushStreamContent.cs | 104 +- Refit/RefitSettings.cs | 111 +- Refit/RequestBuilder.cs | 13 +- Refit/RequestBuilderFactory.cs | 8 +- ...tBuilderImplementation.TaskToObservable.cs | 16 +- Refit/RequestBuilderImplementation.cs | 587 ++++-- Refit/RestMethodInfo.cs | 338 +++- Refit/RestMethodParameterInfo.cs | 5 +- Refit/RestService.cs | 36 +- Refit/SystemTextJsonContentSerializer.cs | 60 +- Refit/UniqueName.cs | 10 +- Refit/ValidationApiException.cs | 27 +- .../HttpClientDiagnosticsHandler.cs | 25 +- .../Meow.Common/Responses/SearchResponse.cs | 1 - samples/Meow.Common/Services/CatsService.cs | 5 +- samples/Meow/Program.cs | 9 +- .../ConsoleApplication/Program.cs | 13 +- .../RestApiforTest/Program.cs | 3 +- 71 files changed, 4842 insertions(+), 2341 deletions(-) diff --git a/InterfaceStubGenerator.Shared/ITypeSymbolExtensions.cs b/InterfaceStubGenerator.Shared/ITypeSymbolExtensions.cs index 39ee25ab8..2c48c5ce0 100644 --- a/InterfaceStubGenerator.Shared/ITypeSymbolExtensions.cs +++ b/InterfaceStubGenerator.Shared/ITypeSymbolExtensions.cs @@ -22,24 +22,27 @@ public static IEnumerable GetBaseTypesAndThis(this ITypeSymbol? typ // Determine if "type" inherits from "baseType", ignoring constructed types, optionally including interfaces, // dealing only with original types. public static bool InheritsFromOrEquals( - this ITypeSymbol type, ITypeSymbol baseType, bool includeInterfaces) + this ITypeSymbol type, + ITypeSymbol baseType, + bool includeInterfaces + ) { if (!includeInterfaces) { return InheritsFromOrEquals(type, baseType); } - return type.GetBaseTypesAndThis().Concat(type.AllInterfaces).Any(t => t.Equals(baseType, SymbolEqualityComparer.Default)); + return type.GetBaseTypesAndThis() + .Concat(type.AllInterfaces) + .Any(t => t.Equals(baseType, SymbolEqualityComparer.Default)); } - // Determine if "type" inherits from "baseType", ignoring constructed types and interfaces, dealing // only with original types. - public static bool InheritsFromOrEquals( - this ITypeSymbol type, ITypeSymbol baseType) + public static bool InheritsFromOrEquals(this ITypeSymbol type, ITypeSymbol baseType) { - return type.GetBaseTypesAndThis().Any(t => t.Equals(baseType, SymbolEqualityComparer.Default)); + return type.GetBaseTypesAndThis() + .Any(t => t.Equals(baseType, SymbolEqualityComparer.Default)); } - } } diff --git a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs index 0783f5425..ee9a0c356 100644 --- a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs +++ b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs @@ -24,21 +24,25 @@ public class InterfaceStubGenerator : ISourceGenerator #endif { #pragma warning disable RS2008 // Enable analyzer release tracking - static readonly DiagnosticDescriptor InvalidRefitMember = new( + static readonly DiagnosticDescriptor InvalidRefitMember = + new( "RF001", "Refit types must have Refit HTTP method attributes", "Method {0}.{1} either has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument", "Refit", DiagnosticSeverity.Warning, - true); + true + ); - static readonly DiagnosticDescriptor RefitNotReferenced = new( + static readonly DiagnosticDescriptor RefitNotReferenced = + new( "RF002", "Refit must be referenced", "Refit is not referenced. Add a reference to Refit.", "Refit", DiagnosticSeverity.Error, - true); + true + ); #pragma warning restore RS2008 // Enable analyzer release tracking #if !ROSLYN_4 @@ -48,7 +52,10 @@ public void Execute(GeneratorExecutionContext context) if (context.SyntaxReceiver is not SyntaxReceiver receiver) return; - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.RefitInternalNamespace", out var refitInternalNamespace); + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue( + "build_property.RefitInternalNamespace", + out var refitInternalNamespace + ); GenerateInterfaceStubs( context, @@ -57,9 +64,9 @@ public void Execute(GeneratorExecutionContext context) (CSharpCompilation)context.Compilation, refitInternalNamespace, receiver.CandidateMethods.ToImmutableArray(), - receiver.CandidateInterfaces.ToImmutableArray()); + receiver.CandidateInterfaces.ToImmutableArray() + ); } - #endif public void GenerateInterfaceStubs( @@ -69,41 +76,51 @@ public void GenerateInterfaceStubs( CSharpCompilation compilation, string? refitInternalNamespace, ImmutableArray candidateMethods, - ImmutableArray candidateInterfaces) + ImmutableArray candidateInterfaces + ) { - refitInternalNamespace = $"{refitInternalNamespace ?? string.Empty}RefitInternalGenerated"; + refitInternalNamespace = + $"{refitInternalNamespace ?? string.Empty}RefitInternalGenerated"; // we're going to create a new compilation that contains the attribute. // TODO: we should allow source generators to provide source during initialize, so that this step isn't required. var options = (CSharpParseOptions)compilation.SyntaxTrees[0].Options; - var disposableInterfaceSymbol = compilation.GetTypeByMetadataName("System.IDisposable")!; - var httpMethodBaseAttributeSymbol = compilation.GetTypeByMetadataName("Refit.HttpMethodAttribute"); + var disposableInterfaceSymbol = compilation.GetTypeByMetadataName( + "System.IDisposable" + )!; + var httpMethodBaseAttributeSymbol = compilation.GetTypeByMetadataName( + "Refit.HttpMethodAttribute" + ); - if(httpMethodBaseAttributeSymbol == null) + if (httpMethodBaseAttributeSymbol == null) { reportDiagnostic(context, Diagnostic.Create(RefitNotReferenced, null)); return; } - // Check the candidates and keep the ones we're actually interested in #pragma warning disable RS1024 // Compare symbols correctly - var interfaceToNullableEnabledMap = new Dictionary(SymbolEqualityComparer.Default); + var interfaceToNullableEnabledMap = new Dictionary( + SymbolEqualityComparer.Default + ); #pragma warning restore RS1024 // Compare symbols correctly var methodSymbols = new List(); foreach (var group in candidateMethods.GroupBy(m => m.SyntaxTree)) { - var model = compilation.GetSemanticModel(group.Key); + var model = compilation.GetSemanticModel(group.Key); foreach (var method in group) { // Get the symbol being declared by the method var methodSymbol = model.GetDeclaredSymbol(method); if (IsRefitMethod(methodSymbol, httpMethodBaseAttributeSymbol)) { - var isAnnotated = compilation.Options.NullableContextOptions == NullableContextOptions.Enable || - model.GetNullableContext(method.SpanStart) == NullableContext.Enabled; + var isAnnotated = + compilation.Options.NullableContextOptions + == NullableContextOptions.Enable + || model.GetNullableContext(method.SpanStart) + == NullableContext.Enabled; interfaceToNullableEnabledMap[methodSymbol!.ContainingType] = isAnnotated; methodSymbols.Add(methodSymbol!); @@ -111,12 +128,16 @@ public void GenerateInterfaceStubs( } } - var interfaces = methodSymbols.GroupBy(m => m.ContainingType, SymbolEqualityComparer.Default) - .ToDictionary(g => g.Key, v => v.ToList()); + var interfaces = methodSymbols + .GroupBy( + m => m.ContainingType, + SymbolEqualityComparer.Default + ) + .ToDictionary(g => g.Key, v => v.ToList()); // Look through the candidate interfaces var interfaceSymbols = new List(); - foreach(var group in candidateInterfaces.GroupBy(i => i.SyntaxTree)) + foreach (var group in candidateInterfaces.GroupBy(i => i.SyntaxTree)) { var model = compilation.GetSemanticModel(group.Key); foreach (var iface in group) @@ -137,8 +158,9 @@ public void GenerateInterfaceStubs( { // Add the interface to the generation list with an empty set of methods // The logic already looks for base refit methods - interfaces.Add(ifaceSymbol, new List() ); - var isAnnotated = model.GetNullableContext(iface.SpanStart) == NullableContext.Enabled; + interfaces.Add(ifaceSymbol, new List()); + var isAnnotated = + model.GetNullableContext(iface.SpanStart) == NullableContext.Enabled; interfaceToNullableEnabledMap[ifaceSymbol] = isAnnotated; } @@ -146,14 +168,15 @@ public void GenerateInterfaceStubs( } // Bail out if there aren't any interfaces to generate code for. This may be the case with transitives - if(!interfaces.Any()) return; - + if (!interfaces.Any()) + return; var supportsNullable = options.LanguageVersion >= LanguageVersion.CSharp8; var keyCount = new Dictionary(); - var attributeText = @$" + var attributeText = + @$" #pragma warning disable namespace {refitInternalNamespace} {{ @@ -173,16 +196,24 @@ sealed class PreserveAttribute : global::System.Attribute #pragma warning restore "; - - compilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(attributeText, Encoding.UTF8), options)); + compilation = compilation.AddSyntaxTrees( + CSharpSyntaxTree.ParseText(SourceText.From(attributeText, Encoding.UTF8), options) + ); // add the attribute text - addSource(context, "PreserveAttribute.g.cs", SourceText.From(attributeText, Encoding.UTF8)); + addSource( + context, + "PreserveAttribute.g.cs", + SourceText.From(attributeText, Encoding.UTF8) + ); // get the newly bound attribute - var preserveAttributeSymbol = compilation.GetTypeByMetadataName($"{refitInternalNamespace}.PreserveAttribute")!; + var preserveAttributeSymbol = compilation.GetTypeByMetadataName( + $"{refitInternalNamespace}.PreserveAttribute" + )!; - var generatedClassText = @$" + var generatedClassText = + @$" #pragma warning disable namespace Refit.Implementation {{ @@ -199,11 +230,18 @@ internal static partial class Generated }} #pragma warning restore "; - addSource(context, "Generated.g.cs", SourceText.From(generatedClassText, Encoding.UTF8)); - - compilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(generatedClassText, Encoding.UTF8), options)); - + addSource( + context, + "Generated.g.cs", + SourceText.From(generatedClassText, Encoding.UTF8) + ); + compilation = compilation.AddSyntaxTrees( + CSharpSyntaxTree.ParseText( + SourceText.From(generatedClassText, Encoding.UTF8), + options + ) + ); // group the fields by interface and generate the source foreach (var group in interfaces) @@ -212,55 +250,59 @@ internal static partial class Generated // with a refit attribute on them. Types may contain other members, without the attribute, which we'll // need to check for and error out on - var classSource = ProcessInterface(context, - reportDiagnostic, - group.Key, - group.Value, - preserveAttributeSymbol, - disposableInterfaceSymbol, - httpMethodBaseAttributeSymbol, - supportsNullable, - interfaceToNullableEnabledMap[group.Key]); - + var classSource = ProcessInterface( + context, + reportDiagnostic, + group.Key, + group.Value, + preserveAttributeSymbol, + disposableInterfaceSymbol, + httpMethodBaseAttributeSymbol, + supportsNullable, + interfaceToNullableEnabledMap[group.Key] + ); + var keyName = group.Key.Name; - if(keyCount.TryGetValue(keyName, out var value)) + if (keyCount.TryGetValue(keyName, out var value)) { keyName = $"{keyName}{++value}"; } keyCount[keyName] = value; addSource(context, $"{keyName}.g.cs", SourceText.From(classSource, Encoding.UTF8)); - } - + } } - string ProcessInterface(TContext context, - Action reportDiagnostic, - INamedTypeSymbol interfaceSymbol, - List refitMethods, - ISymbol preserveAttributeSymbol, - ISymbol disposableInterfaceSymbol, - INamedTypeSymbol httpMethodBaseAttributeSymbol, - bool supportsNullable, - bool nullableEnabled) + string ProcessInterface( + TContext context, + Action reportDiagnostic, + INamedTypeSymbol interfaceSymbol, + List refitMethods, + ISymbol preserveAttributeSymbol, + ISymbol disposableInterfaceSymbol, + INamedTypeSymbol httpMethodBaseAttributeSymbol, + bool supportsNullable, + bool nullableEnabled + ) { - // Get the class name with the type parameters, then remove the namespace var className = interfaceSymbol.ToDisplayString(); var lastDot = className.LastIndexOf('.'); - if(lastDot > 0) + if (lastDot > 0) { - className = className.Substring(lastDot+1); + className = className.Substring(lastDot + 1); } var classDeclaration = $"{interfaceSymbol.ContainingType?.Name}{className}"; - // Get the class name itself var classSuffix = $"{interfaceSymbol.ContainingType?.Name}{interfaceSymbol.Name}"; var ns = interfaceSymbol.ContainingNamespace?.ToDisplayString(); // if it's the global namespace, our lookup rules say it should be the same as the class name - if(interfaceSymbol.ContainingNamespace != null && interfaceSymbol.ContainingNamespace.IsGlobalNamespace) + if ( + interfaceSymbol.ContainingNamespace != null + && interfaceSymbol.ContainingNamespace.IsGlobalNamespace + ) { ns = string.Empty; } @@ -272,11 +314,11 @@ string ProcessInterface(TContext context, var source = new StringBuilder(); - if(supportsNullable) + if (supportsNullable) { source.Append("#nullable "); - if(nullableEnabled) + if (nullableEnabled) { source.Append("enable"); } @@ -286,7 +328,8 @@ string ProcessInterface(TContext context, } } - source.Append($@" + source.Append( + $@" #pragma warning disable namespace Refit.Implementation {{ @@ -315,27 +358,46 @@ partial class {ns}{classDeclaration} this.requestBuilder = requestBuilder; }} -"); +" + ); // Get any other methods on the refit interfaces. We'll need to generate something for them and warn - var nonRefitMethods = interfaceSymbol.GetMembers().OfType().Except(refitMethods, SymbolEqualityComparer.Default).Cast().ToList(); + var nonRefitMethods = interfaceSymbol + .GetMembers() + .OfType() + .Except(refitMethods, SymbolEqualityComparer.Default) + .Cast() + .ToList(); // get methods for all inherited - var derivedMethods = interfaceSymbol.AllInterfaces.SelectMany(i => i.GetMembers().OfType()).ToList(); + var derivedMethods = interfaceSymbol.AllInterfaces + .SelectMany(i => i.GetMembers().OfType()) + .ToList(); // Look for disposable - var disposeMethod = derivedMethods.Find(m => m.ContainingType?.Equals(disposableInterfaceSymbol, SymbolEqualityComparer.Default) == true); - if(disposeMethod != null) + var disposeMethod = derivedMethods.Find( + m => + m.ContainingType?.Equals( + disposableInterfaceSymbol, + SymbolEqualityComparer.Default + ) == true + ); + if (disposeMethod != null) { //remove it from the derived methods list so we don't process it with the rest derivedMethods.Remove(disposeMethod); } // Pull out the refit methods from the derived types - var derivedRefitMethods = derivedMethods.Where(m => IsRefitMethod(m, httpMethodBaseAttributeSymbol)).ToList(); - var derivedNonRefitMethods = derivedMethods.Except(derivedMethods, SymbolEqualityComparer.Default).Cast().ToList(); - - // Handle Refit Methods - foreach(var method in refitMethods) + var derivedRefitMethods = derivedMethods + .Where(m => IsRefitMethod(m, httpMethodBaseAttributeSymbol)) + .ToList(); + var derivedNonRefitMethods = derivedMethods + .Except(derivedMethods, SymbolEqualityComparer.Default) + .Cast() + .ToList(); + + // Handle Refit Methods + foreach (var method in refitMethods) { ProcessRefitMethod(source, method, true); } @@ -345,32 +407,35 @@ partial class {ns}{classDeclaration} ProcessRefitMethod(source, method, false); } - // Handle non-refit Methods that aren't static or properties or have a method body foreach (var method in nonRefitMethods.Concat(derivedNonRefitMethods)) { - if (method.IsStatic || - method.MethodKind == MethodKind.PropertyGet || - method.MethodKind == MethodKind.PropertySet || - !method.IsAbstract) // If an interface method has a body, it won't be abstract + if ( + method.IsStatic + || method.MethodKind == MethodKind.PropertyGet + || method.MethodKind == MethodKind.PropertySet + || !method.IsAbstract + ) // If an interface method has a body, it won't be abstract continue; ProcessNonRefitMethod(context, reportDiagnostic, source, method); } // Handle Dispose - if(disposeMethod != null) + if (disposeMethod != null) { ProcessDisposableMethod(source, disposeMethod); - } + } - source.Append(@" + source.Append( + @" } } } #pragma warning restore -"); +" + ); return source.ToString(); } @@ -382,7 +447,9 @@ partial class {ns}{classDeclaration} /// True if directly from the type we're generating for, false for methods found on base interfaces void ProcessRefitMethod(StringBuilder source, IMethodSymbol methodSymbol, bool isTopLevel) { - var returnType = methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + var returnType = methodSymbol.ReturnType.ToDisplayString( + SymbolDisplayFormat.FullyQualifiedFormat + ); var (isAsync, @return, configureAwait) = methodSymbol.ReturnType.MetadataName switch { "Task" => (true, "await (", ").ConfigureAwait(false)"), @@ -394,36 +461,46 @@ void ProcessRefitMethod(StringBuilder source, IMethodSymbol methodSymbol, bool i // Build the list of args for the array var argList = new List(); - foreach(var param in methodSymbol.Parameters) + foreach (var param in methodSymbol.Parameters) { argList.Add($"@{param.MetadataName}"); } - // List of types. + // List of types. var typeList = new List(); - foreach(var param in methodSymbol.Parameters) + foreach (var param in methodSymbol.Parameters) { - typeList.Add($"typeof({param.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)})"); + typeList.Add( + $"typeof({param.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)})" + ); } // List of generic arguments - var genericList = new List(); - foreach(var typeParam in methodSymbol.TypeParameters) + var genericList = new List(); + foreach (var typeParam in methodSymbol.TypeParameters) { - genericList.Add($"typeof({typeParam.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)})"); + genericList.Add( + $"typeof({typeParam.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)})" + ); } - var argumentsArrayString = argList.Count == 0 - ? "global::System.Array.Empty()" - : $"new object[] {{ {string.Join(", ", argList)} }}"; + var argumentsArrayString = + argList.Count == 0 + ? "global::System.Array.Empty()" + : $"new object[] {{ {string.Join(", ", argList)} }}"; - var parameterTypesArrayString = typeList.Count == 0 - ? "global::System.Array.Empty()" - : $"new global::System.Type[] {{ {string.Join(", ", typeList)} }}"; + var parameterTypesArrayString = + typeList.Count == 0 + ? "global::System.Array.Empty()" + : $"new global::System.Type[] {{ {string.Join(", ", typeList)} }}"; - var genericString = genericList.Count > 0 ? $", new global::System.Type[] {{ {string.Join(", ", genericList)} }}" : string.Empty; + var genericString = + genericList.Count > 0 + ? $", new global::System.Type[] {{ {string.Join(", ", genericList)} }}" + : string.Empty; - source.Append(@$" + source.Append( + @$" var ______arguments = {argumentsArrayString}; var ______func = requestBuilder.BuildRestResultFuncForMethod(""{methodSymbol.Name}"", {parameterTypesArrayString}{genericString} ); try @@ -434,7 +511,8 @@ void ProcessRefitMethod(StringBuilder source, IMethodSymbol methodSymbol, bool i {{ throw ex; }} -"); +" + ); WriteMethodClosing(source); } @@ -443,31 +521,44 @@ void ProcessDisposableMethod(StringBuilder source, IMethodSymbol methodSymbol) { WriteMethodOpening(source, methodSymbol, true); - source.Append(@" + source.Append( + @" Client?.Dispose(); -"); +" + ); WriteMethodClosing(source); } - string GenerateConstraints(ImmutableArray typeParameters, bool isOverrideOrExplicitImplementation) + string GenerateConstraints( + ImmutableArray typeParameters, + bool isOverrideOrExplicitImplementation + ) { var source = new StringBuilder(); // Need to loop over the constraints and create them - foreach(var typeParameter in typeParameters) + foreach (var typeParameter in typeParameters) { - WriteConstraitsForTypeParameter(source, typeParameter, isOverrideOrExplicitImplementation); + WriteConstraitsForTypeParameter( + source, + typeParameter, + isOverrideOrExplicitImplementation + ); } return source.ToString(); } - void WriteConstraitsForTypeParameter(StringBuilder source, ITypeParameterSymbol typeParameter, bool isOverrideOrExplicitImplementation) + void WriteConstraitsForTypeParameter( + StringBuilder source, + ITypeParameterSymbol typeParameter, + bool isOverrideOrExplicitImplementation + ) { // Explicit interface implementations and ovverrides can only have class or struct constraints var parameters = new List(); - if(typeParameter.HasReferenceTypeConstraint) + if (typeParameter.HasReferenceTypeConstraint) { parameters.Add("class"); } @@ -487,80 +578,114 @@ void WriteConstraitsForTypeParameter(StringBuilder source, ITypeParameterSymbol { foreach (var typeConstraint in typeParameter.ConstraintTypes) { - parameters.Add(typeConstraint.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); + parameters.Add( + typeConstraint.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + ); } } - + // new constraint has to be last if (typeParameter.HasConstructorConstraint && !isOverrideOrExplicitImplementation) { parameters.Add("new()"); } - if(parameters.Count > 0) + if (parameters.Count > 0) { - source.Append(@$" - where {typeParameter.Name} : {string.Join(", ", parameters)}"); + source.Append( + @$" + where {typeParameter.Name} : {string.Join(", ", parameters)}" + ); } - } - void ProcessNonRefitMethod(TContext context, Action reportDiagnostic, StringBuilder source, IMethodSymbol methodSymbol) + void ProcessNonRefitMethod( + TContext context, + Action reportDiagnostic, + StringBuilder source, + IMethodSymbol methodSymbol + ) { WriteMethodOpening(source, methodSymbol, true); - source.Append(@" + source.Append( + @" throw new global::System.NotImplementedException(""Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument.""); -"); +" + ); WriteMethodClosing(source); - foreach(var location in methodSymbol.Locations) + foreach (var location in methodSymbol.Locations) { - var diagnostic = Diagnostic.Create(InvalidRefitMember, location, methodSymbol.ContainingType.Name, methodSymbol.Name); + var diagnostic = Diagnostic.Create( + InvalidRefitMember, + location, + methodSymbol.ContainingType.Name, + methodSymbol.Name + ); reportDiagnostic(context, diagnostic); - } + } } - void WriteMethodOpening(StringBuilder source, IMethodSymbol methodSymbol, bool isExplicitInterface, bool isAsync = false) + void WriteMethodOpening( + StringBuilder source, + IMethodSymbol methodSymbol, + bool isExplicitInterface, + bool isAsync = false + ) { var visibility = !isExplicitInterface ? "public " : string.Empty; var async = isAsync ? "async " : ""; - source.Append(@$" + source.Append( + @$" /// - {visibility}{async}{methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)} "); + {visibility}{async}{methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)} " + ); - if(isExplicitInterface) + if (isExplicitInterface) { - source.Append(@$"{methodSymbol.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}."); + source.Append( + @$"{methodSymbol.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}." + ); } - source.Append(@$"{methodSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}("); + source.Append( + @$"{methodSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}(" + ); - if(methodSymbol.Parameters.Length > 0) + if (methodSymbol.Parameters.Length > 0) { var list = new List(); - foreach(var param in methodSymbol.Parameters) + foreach (var param in methodSymbol.Parameters) { - var annotation = !param.Type.IsValueType && param.NullableAnnotation == NullableAnnotation.Annotated; + var annotation = + !param.Type.IsValueType + && param.NullableAnnotation == NullableAnnotation.Annotated; - list.Add($@"{param.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}{(annotation ? '?' : string.Empty)} @{param.MetadataName}"); + list.Add( + $@"{param.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}{(annotation ? '?' : string.Empty)} @{param.MetadataName}" + ); } source.Append(string.Join(", ", list)); } - source.Append(@$"){GenerateConstraints(methodSymbol.TypeParameters, isExplicitInterface)} - {{"); + source.Append( + @$"){GenerateConstraints(methodSymbol.TypeParameters, isExplicitInterface)} + {{" + ); } void WriteMethodClosing(StringBuilder source) => source.Append(@" }"); - bool IsRefitMethod(IMethodSymbol? methodSymbol, INamedTypeSymbol httpMethodAttibute) { - return methodSymbol?.GetAttributes().Any(ad => ad.AttributeClass?.InheritsFromOrEquals(httpMethodAttibute) == true) == true; + return methodSymbol + ?.GetAttributes() + .Any(ad => ad.AttributeClass?.InheritsFromOrEquals(httpMethodAttibute) == true) + == true; } #if ROSLYN_4 @@ -569,24 +694,52 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { // We're looking for methods with an attribute that are in an interface var candidateMethodsProvider = context.SyntaxProvider.CreateSyntaxProvider( - (syntax, cancellationToken) => syntax is MethodDeclarationSyntax { Parent: InterfaceDeclarationSyntax, AttributeLists: { Count: > 0 } }, - (context, cancellationToken) => (MethodDeclarationSyntax)context.Node); + (syntax, cancellationToken) => + syntax + is MethodDeclarationSyntax + { + Parent: InterfaceDeclarationSyntax, + AttributeLists: { Count: > 0 } + }, + (context, cancellationToken) => (MethodDeclarationSyntax)context.Node + ); // We also look for interfaces that derive from others, so we can see if any base methods contain // Refit methods var candidateInterfacesProvider = context.SyntaxProvider.CreateSyntaxProvider( - (syntax, cancellationToken) => syntax is InterfaceDeclarationSyntax { BaseList: not null }, - (context, cancellationToken) => (InterfaceDeclarationSyntax)context.Node); + (syntax, cancellationToken) => + syntax is InterfaceDeclarationSyntax { BaseList: not null }, + (context, cancellationToken) => (InterfaceDeclarationSyntax)context.Node + ); var refitInternalNamespace = context.AnalyzerConfigOptionsProvider.Select( - (analyzerConfigOptionsProvider, cancellationToken) => analyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.RefitInternalNamespace", out var refitInternalNamespace) ? refitInternalNamespace : null); - - var inputs = candidateMethodsProvider.Collect() + (analyzerConfigOptionsProvider, cancellationToken) => + analyzerConfigOptionsProvider.GlobalOptions.TryGetValue( + "build_property.RefitInternalNamespace", + out var refitInternalNamespace + ) + ? refitInternalNamespace + : null + ); + + var inputs = candidateMethodsProvider + .Collect() .Combine(candidateInterfacesProvider.Collect()) - .Select((combined, cancellationToken) => (candidateMethods: combined.Left, candidateInterfaces: combined.Right)) + .Select( + (combined, cancellationToken) => + (candidateMethods: combined.Left, candidateInterfaces: combined.Right) + ) .Combine(refitInternalNamespace) .Combine(context.CompilationProvider) - .Select((combined, cancellationToken) => (combined.Left.Left.candidateMethods, combined.Left.Left.candidateInterfaces, refitInternalNamespace: combined.Left.Right, compilation: combined.Right)); + .Select( + (combined, cancellationToken) => + ( + combined.Left.Left.candidateMethods, + combined.Left.Left.candidateInterfaces, + refitInternalNamespace: combined.Left.Right, + compilation: combined.Right + ) + ); context.RegisterSourceOutput( inputs, @@ -595,12 +748,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context) GenerateInterfaceStubs( context, static (context, diagnostic) => context.ReportDiagnostic(diagnostic), - static (context, hintName, sourceText) => context.AddSource(hintName, sourceText), + static (context, hintName, sourceText) => + context.AddSource(hintName, sourceText), (CSharpCompilation)collectedValues.compilation, collectedValues.refitInternalNamespace, collectedValues.candidateMethods, - collectedValues.candidateInterfaces); - }); + collectedValues.candidateInterfaces + ); + } + ); } #else @@ -618,17 +774,19 @@ class SyntaxReceiver : ISyntaxReceiver public void OnVisitSyntaxNode(SyntaxNode syntaxNode) { - // We're looking for methods with an attribute that are in an interfaces - if(syntaxNode is MethodDeclarationSyntax methodDeclarationSyntax && - methodDeclarationSyntax.Parent is InterfaceDeclarationSyntax && - methodDeclarationSyntax.AttributeLists.Count > 0) + // We're looking for methods with an attribute that are in an interfaces + if ( + syntaxNode is MethodDeclarationSyntax methodDeclarationSyntax + && methodDeclarationSyntax.Parent is InterfaceDeclarationSyntax + && methodDeclarationSyntax.AttributeLists.Count > 0 + ) { CandidateMethods.Add(methodDeclarationSyntax); } // We also look for interfaces that derive from others, so we can see if any base methods contain // Refit methods - if(syntaxNode is InterfaceDeclarationSyntax iface && iface.BaseList is not null) + if (syntaxNode is InterfaceDeclarationSyntax iface && iface.BaseList is not null) { CandidateInterfaces.Add(iface); } diff --git a/Refit.Benchmarks/EndToEndBenchmark.cs b/Refit.Benchmarks/EndToEndBenchmark.cs index c25c2a939..f925c0639 100644 --- a/Refit.Benchmarks/EndToEndBenchmark.cs +++ b/Refit.Benchmarks/EndToEndBenchmark.cs @@ -12,16 +12,33 @@ public class EndToEndBenchmark private const string Host = "https://github.com"; private SystemTextJsonContentSerializer systemTextJsonContentSerializer; private NewtonsoftJsonContentSerializer newtonsoftJsonContentSerializer; - private readonly IDictionary> users = new Dictionary>(); - private readonly IDictionary> refitClient = new Dictionary> + private readonly IDictionary> users = + new Dictionary>(); + private readonly IDictionary< + SerializationStrategy, + IDictionary + > refitClient = new Dictionary< + SerializationStrategy, + IDictionary + > { - {SerializationStrategy.SystemTextJson, new Dictionary()}, - {SerializationStrategy.NewtonsoftJson, new Dictionary()} + { + SerializationStrategy.SystemTextJson, + new Dictionary() + }, + { + SerializationStrategy.NewtonsoftJson, + new Dictionary() + } }; - private readonly IDictionary httpMethod = new Dictionary + private readonly IDictionary httpMethod = new Dictionary< + HttpVerb, + HttpMethod + > { - {HttpVerb.Get, HttpMethod.Get}, {HttpVerb.Post, HttpMethod.Post} + { HttpVerb.Get, HttpMethod.Get }, + { HttpVerb.Post, HttpMethod.Post } }; private const int TenUsers = 10; @@ -41,26 +58,57 @@ public enum HttpVerb [GlobalSetup] public Task SetupAsync() { - systemTextJsonContentSerializer = new SystemTextJsonContentSerializer(); - refitClient[SerializationStrategy.SystemTextJson][HttpStatusCode.OK] = RestService.For(Host, new RefitSettings(systemTextJsonContentSerializer) - { - HttpMessageHandlerFactory = () => new StaticFileHttpResponseHandler("system-text-json-10-users.json", HttpStatusCode.OK) - }); - refitClient[SerializationStrategy.SystemTextJson][HttpStatusCode.InternalServerError] = RestService.For(Host, new RefitSettings(systemTextJsonContentSerializer) - { - HttpMessageHandlerFactory = () => new StaticFileHttpResponseHandler("system-text-json-10-users.json", HttpStatusCode.InternalServerError) - }); + refitClient[SerializationStrategy.SystemTextJson][HttpStatusCode.OK] = + RestService.For( + Host, + new RefitSettings(systemTextJsonContentSerializer) + { + HttpMessageHandlerFactory = () => + new StaticFileHttpResponseHandler( + "system-text-json-10-users.json", + HttpStatusCode.OK + ) + } + ); + refitClient[SerializationStrategy.SystemTextJson][HttpStatusCode.InternalServerError] = + RestService.For( + Host, + new RefitSettings(systemTextJsonContentSerializer) + { + HttpMessageHandlerFactory = () => + new StaticFileHttpResponseHandler( + "system-text-json-10-users.json", + HttpStatusCode.InternalServerError + ) + } + ); newtonsoftJsonContentSerializer = new NewtonsoftJsonContentSerializer(); - refitClient[SerializationStrategy.NewtonsoftJson][HttpStatusCode.OK] = RestService.For(Host, new RefitSettings(newtonsoftJsonContentSerializer) - { - HttpMessageHandlerFactory = () => new StaticFileHttpResponseHandler("newtonsoft-json-10-users.json", System.Net.HttpStatusCode.OK) - }); - refitClient[SerializationStrategy.NewtonsoftJson][HttpStatusCode.InternalServerError] = RestService.For(Host, new RefitSettings(newtonsoftJsonContentSerializer) - { - HttpMessageHandlerFactory = () => new StaticFileHttpResponseHandler("newtonsoft-json-10-users.json", System.Net.HttpStatusCode.InternalServerError) - }); + refitClient[SerializationStrategy.NewtonsoftJson][HttpStatusCode.OK] = + RestService.For( + Host, + new RefitSettings(newtonsoftJsonContentSerializer) + { + HttpMessageHandlerFactory = () => + new StaticFileHttpResponseHandler( + "newtonsoft-json-10-users.json", + System.Net.HttpStatusCode.OK + ) + } + ); + refitClient[SerializationStrategy.NewtonsoftJson][HttpStatusCode.InternalServerError] = + RestService.For( + Host, + new RefitSettings(newtonsoftJsonContentSerializer) + { + HttpMessageHandlerFactory = () => + new StaticFileHttpResponseHandler( + "newtonsoft-json-10-users.json", + System.Net.HttpStatusCode.InternalServerError + ) + } + ); users[TenUsers] = autoFixture.CreateMany(TenUsers); @@ -94,7 +142,9 @@ public async Task Task_Async() await refitClient[Serializer][HttpStatusCode].GetUsersTaskAsync(); break; case HttpVerb.Post: - await refitClient[Serializer][HttpStatusCode].PostUsersTaskAsync(users[ModelCount]); + await refitClient[Serializer][HttpStatusCode].PostUsersTaskAsync( + users[ModelCount] + ); break; default: throw new ArgumentOutOfRangeException(nameof(Verb)); @@ -114,9 +164,13 @@ public async Task TaskString_Async() switch (Verb) { case HttpVerb.Get: - return await refitClient[Serializer][HttpStatusCode].GetUsersTaskStringAsync(); + return await refitClient[Serializer][ + HttpStatusCode + ].GetUsersTaskStringAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskStringAsync(users[ModelCount]); + return await refitClient[Serializer][ + HttpStatusCode + ].PostUsersTaskStringAsync(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -137,9 +191,13 @@ public async Task TaskStream_Async() switch (Verb) { case HttpVerb.Get: - return await refitClient[Serializer][HttpStatusCode].GetUsersTaskStreamAsync(); + return await refitClient[Serializer][ + HttpStatusCode + ].GetUsersTaskStreamAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskStreamAsync(users[ModelCount]); + return await refitClient[Serializer][ + HttpStatusCode + ].PostUsersTaskStreamAsync(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -160,9 +218,13 @@ public async Task TaskHttpContent_Async() switch (Verb) { case HttpVerb.Get: - return await refitClient[Serializer][HttpStatusCode].GetUsersTaskHttpContentAsync(); + return await refitClient[Serializer][ + HttpStatusCode + ].GetUsersTaskHttpContentAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskHttpContentAsync(users[ModelCount]); + return await refitClient[Serializer][ + HttpStatusCode + ].PostUsersTaskHttpContentAsync(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -181,9 +243,13 @@ public async Task TaskHttpResponseMessage_Async() switch (Verb) { case HttpVerb.Get: - return await refitClient[Serializer][HttpStatusCode].GetUsersTaskHttpResponseMessageAsync(); + return await refitClient[Serializer][ + HttpStatusCode + ].GetUsersTaskHttpResponseMessageAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskHttpResponseMessageAsync(users[ModelCount]); + return await refitClient[Serializer][ + HttpStatusCode + ].PostUsersTaskHttpResponseMessageAsync(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -195,9 +261,13 @@ public IObservable ObservableHttpResponseMessage() switch (Verb) { case HttpVerb.Get: - return refitClient[Serializer][HttpStatusCode].GetUsersObservableHttpResponseMessage(); + return refitClient[Serializer][ + HttpStatusCode + ].GetUsersObservableHttpResponseMessage(); case HttpVerb.Post: - return refitClient[Serializer][HttpStatusCode].PostUsersObservableHttpResponseMessage(users[ModelCount]); + return refitClient[Serializer][ + HttpStatusCode + ].PostUsersObservableHttpResponseMessage(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -213,7 +283,9 @@ public async Task> TaskT_Async() case HttpVerb.Get: return await refitClient[Serializer][HttpStatusCode].GetUsersTaskTAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskTAsync(users[ModelCount]); + return await refitClient[Serializer][HttpStatusCode].PostUsersTaskTAsync( + users[ModelCount] + ); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } @@ -232,9 +304,13 @@ public async Task>> TaskApiResponseT_Async() switch (Verb) { case HttpVerb.Get: - return await refitClient[Serializer][HttpStatusCode].GetUsersTaskApiResponseTAsync(); + return await refitClient[Serializer][ + HttpStatusCode + ].GetUsersTaskApiResponseTAsync(); case HttpVerb.Post: - return await refitClient[Serializer][HttpStatusCode].PostUsersTaskApiResponseTAsync(users[ModelCount]); + return await refitClient[Serializer][ + HttpStatusCode + ].PostUsersTaskApiResponseTAsync(users[ModelCount]); default: throw new ArgumentOutOfRangeException(nameof(Verb)); } diff --git a/Refit.Benchmarks/IGitHubService.cs b/Refit.Benchmarks/IGitHubService.cs index 18401abf6..50799df78 100644 --- a/Refit.Benchmarks/IGitHubService.cs +++ b/Refit.Benchmarks/IGitHubService.cs @@ -5,50 +5,64 @@ public interface IGitHubService //Task - throws [Get("/users")] public Task GetUsersTaskAsync(); + [Post("/users")] public Task PostUsersTaskAsync([Body] IEnumerable users); //Task - throws [Get("/users")] public Task GetUsersTaskStringAsync(); + [Post("/users")] public Task PostUsersTaskStringAsync([Body] IEnumerable users); //Task - throws [Get("/users")] public Task GetUsersTaskStreamAsync(); + [Post("/users")] public Task PostUsersTaskStreamAsync([Body] IEnumerable users); //Task - throws [Get("/users")] public Task GetUsersTaskHttpContentAsync(); + [Post("/users")] public Task PostUsersTaskHttpContentAsync([Body] IEnumerable users); //Task [Get("/users")] public Task GetUsersTaskHttpResponseMessageAsync(); + [Post("/users")] - public Task PostUsersTaskHttpResponseMessageAsync([Body] IEnumerable users); + public Task PostUsersTaskHttpResponseMessageAsync( + [Body] IEnumerable users + ); //IObservable [Get("/users")] public IObservable GetUsersObservableHttpResponseMessage(); + [Post("/users")] - public IObservable PostUsersObservableHttpResponseMessage([Body] IEnumerable users); + public IObservable PostUsersObservableHttpResponseMessage( + [Body] IEnumerable users + ); //Task<> - throws [Get("/users")] public Task> GetUsersTaskTAsync(); + [Post("/users")] public Task> PostUsersTaskTAsync([Body] IEnumerable users); //Task> [Get("/users")] public Task>> GetUsersTaskApiResponseTAsync(); + [Post("/users")] - public Task>> PostUsersTaskApiResponseTAsync([Body] IEnumerable users); + public Task>> PostUsersTaskApiResponseTAsync( + [Body] IEnumerable users + ); } public class User @@ -61,5 +75,3 @@ public class User public string Url { get; set; } } } - - diff --git a/Refit.Benchmarks/StaticFileHttpResponseHandler.cs b/Refit.Benchmarks/StaticFileHttpResponseHandler.cs index c349598ca..b195741fa 100644 --- a/Refit.Benchmarks/StaticFileHttpResponseHandler.cs +++ b/Refit.Benchmarks/StaticFileHttpResponseHandler.cs @@ -13,17 +13,22 @@ public StaticFileHttpResponseHandler(string fileName, HttpStatusCode responseCod throw new ArgumentNullException(nameof(fileName)); responsePayload = File.ReadAllText(fileName); -; this.responseCode = responseCode; + ; + this.responseCode = responseCode; } - protected override Task SendAsync(HttpRequestMessage request, - CancellationToken cancellationToken) + protected override Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { - return Task.FromResult(new HttpResponseMessage(responseCode) - { - RequestMessage = request, - Content = new StringContent(responsePayload) - }); + return Task.FromResult( + new HttpResponseMessage(responseCode) + { + RequestMessage = request, + Content = new StringContent(responsePayload) + } + ); } } } diff --git a/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs b/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs index 57e857cfa..b4920df5e 100644 --- a/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs +++ b/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs @@ -17,7 +17,11 @@ public static class HttpClientFactoryExtensions /// container /// Optional. Settings to configure the instance with /// - public static IHttpClientBuilder AddRefitClient(this IServiceCollection services, RefitSettings? settings = null) where T : class + public static IHttpClientBuilder AddRefitClient( + this IServiceCollection services, + RefitSettings? settings = null + ) + where T : class { return AddRefitClient(services, _ => settings); } @@ -29,7 +33,11 @@ public static IHttpClientBuilder AddRefitClient(this IServiceCollection servi /// Type of the Refit interface /// Optional. Settings to configure the instance with /// - public static IHttpClientBuilder AddRefitClient(this IServiceCollection services, Type refitInterfaceType, RefitSettings? settings = null) + public static IHttpClientBuilder AddRefitClient( + this IServiceCollection services, + Type refitInterfaceType, + RefitSettings? settings = null + ) { return AddRefitClient(services, refitInterfaceType, _ => settings); } @@ -43,24 +51,42 @@ public static IHttpClientBuilder AddRefitClient(this IServiceCollection services /// Optional. Allows users to change the HttpClient name as provided to IServiceCollection.AddHttpClient. Useful for logging scenarios. /// public static IHttpClientBuilder AddRefitClient( - this IServiceCollection services, - Func? settingsAction, - string? httpClientName = null) where T : class + this IServiceCollection services, + Func? settingsAction, + string? httpClientName = null + ) + where T : class { services.AddSingleton(provider => new SettingsFor(settingsAction?.Invoke(provider))); - services.AddSingleton(provider => RequestBuilder.ForType(provider.GetRequiredService>().Settings)); + services.AddSingleton( + provider => + RequestBuilder.ForType( + provider.GetRequiredService>().Settings + ) + ); return services .AddHttpClient(httpClientName ?? UniqueName.ForType()) .ConfigureHttpMessageHandlerBuilder(builder => { // check to see if user provided custom auth token - if (CreateInnerHandlerIfProvided(builder.Services.GetRequiredService>().Settings) is { } innerHandler) + if ( + CreateInnerHandlerIfProvided( + builder.Services.GetRequiredService>().Settings + ) is + { } innerHandler + ) { builder.PrimaryHandler = innerHandler; } }) - .AddTypedClient((client, serviceProvider) => RestService.For(client, serviceProvider.GetService>()!)); + .AddTypedClient( + (client, serviceProvider) => + RestService.For( + client, + serviceProvider.GetService>()! + ) + ); } /// @@ -72,32 +98,68 @@ public static IHttpClientBuilder AddRefitClient( /// Optional. Allows users to change the HttpClient name as provided to IServiceCollection.AddHttpClient. Useful for logging scenarios. /// public static IHttpClientBuilder AddRefitClient( - this IServiceCollection services, - Type refitInterfaceType, - Func? settingsAction, - string? httpClientName = null) + this IServiceCollection services, + Type refitInterfaceType, + Func? settingsAction, + string? httpClientName = null + ) { var settingsType = typeof(SettingsFor<>).MakeGenericType(refitInterfaceType); var requestBuilderType = typeof(IRequestBuilder<>).MakeGenericType(refitInterfaceType); - services.AddSingleton(settingsType, provider => Activator.CreateInstance(typeof(SettingsFor<>).MakeGenericType(refitInterfaceType)!, settingsAction?.Invoke(provider))!); - services.AddSingleton(requestBuilderType, provider => RequestBuilderGenericForTypeMethod.MakeGenericMethod(refitInterfaceType).Invoke(null, new object?[] { ((ISettingsFor)provider.GetRequiredService(settingsType)).Settings })!); + services.AddSingleton( + settingsType, + provider => + Activator.CreateInstance( + typeof(SettingsFor<>).MakeGenericType(refitInterfaceType)!, + settingsAction?.Invoke(provider) + )! + ); + services.AddSingleton( + requestBuilderType, + provider => + RequestBuilderGenericForTypeMethod + .MakeGenericMethod(refitInterfaceType) + .Invoke( + null, + new object?[] + { + ((ISettingsFor)provider.GetRequiredService(settingsType)).Settings + } + )! + ); return services .AddHttpClient(httpClientName ?? UniqueName.ForType(refitInterfaceType)) .ConfigureHttpMessageHandlerBuilder(builder => { // check to see if user provided custom auth token - if (CreateInnerHandlerIfProvided(((ISettingsFor)builder.Services.GetRequiredService(settingsType)).Settings) is { } innerHandler) + if ( + CreateInnerHandlerIfProvided( + ( + (ISettingsFor)builder.Services.GetRequiredService(settingsType) + ).Settings + ) is + { } innerHandler + ) { builder.PrimaryHandler = innerHandler; } }) - .AddTypedClient(refitInterfaceType, (client, serviceProvider) => RestService.For(refitInterfaceType, client, (IRequestBuilder)serviceProvider.GetRequiredService(requestBuilderType))); + .AddTypedClient( + refitInterfaceType, + (client, serviceProvider) => + RestService.For( + refitInterfaceType, + client, + (IRequestBuilder)serviceProvider.GetRequiredService(requestBuilderType) + ) + ); } - private static readonly MethodInfo RequestBuilderGenericForTypeMethod = typeof(RequestBuilder) - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .Single(z => z.IsGenericMethodDefinition && z.GetParameters().Length == 1); + private static readonly MethodInfo RequestBuilderGenericForTypeMethod = + typeof(RequestBuilder) + .GetMethods(BindingFlags.Public | BindingFlags.Static) + .Single(z => z.IsGenericMethodDefinition && z.GetParameters().Length == 1); static HttpMessageHandler? CreateInnerHandlerIfProvided(RefitSettings? settings) { @@ -111,14 +173,21 @@ public static IHttpClientBuilder AddRefitClient( if (settings.AuthorizationHeaderValueGetter != null) { - innerHandler = new AuthenticatedHttpClientHandler(settings.AuthorizationHeaderValueGetter, innerHandler); + innerHandler = new AuthenticatedHttpClientHandler( + settings.AuthorizationHeaderValueGetter, + innerHandler + ); } } return innerHandler; } - static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder builder, Type type, Func factory) + static IHttpClientBuilder AddTypedClient( + this IHttpClientBuilder builder, + Type type, + Func factory + ) { if (builder == null) { @@ -130,13 +199,16 @@ static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder builder, Type t throw new ArgumentNullException(nameof(factory)); } - builder.Services.AddTransient(type, s => - { - var httpClientFactory = s.GetRequiredService(); - var httpClient = httpClientFactory.CreateClient(builder.Name); + builder.Services.AddTransient( + type, + s => + { + var httpClientFactory = s.GetRequiredService(); + var httpClient = httpClientFactory.CreateClient(builder.Name); - return factory(httpClient, s); - }); + return factory(httpClient, s); + } + ); return builder; } diff --git a/Refit.HttpClientFactory/SettingsFor.cs b/Refit.HttpClientFactory/SettingsFor.cs index cf8e6a4f9..a6f8a948d 100644 --- a/Refit.HttpClientFactory/SettingsFor.cs +++ b/Refit.HttpClientFactory/SettingsFor.cs @@ -2,12 +2,13 @@ { public interface ISettingsFor { - RefitSettings? Settings { get; } + RefitSettings? Settings { get; } } public class SettingsFor : ISettingsFor { public SettingsFor(RefitSettings? settings) => Settings = settings; - public RefitSettings? Settings { get; } + + public RefitSettings? Settings { get; } } } diff --git a/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs b/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs index caa85a567..f881e15e1 100644 --- a/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs +++ b/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs @@ -23,7 +23,8 @@ public sealed class NewtonsoftJsonContentSerializer : IHttpContentSerializer /// /// Creates a new instance /// - public NewtonsoftJsonContentSerializer() : this(null) { } + public NewtonsoftJsonContentSerializer() + : this(null) { } /// /// Creates a new instance with the specified parameters @@ -31,25 +32,37 @@ public NewtonsoftJsonContentSerializer() : this(null) { } /// The serialization settings to use for the current instance public NewtonsoftJsonContentSerializer(JsonSerializerSettings? jsonSerializerSettings) { - this.jsonSerializerSettings = new Lazy(() => jsonSerializerSettings - ?? JsonConvert.DefaultSettings?.Invoke() - ?? new JsonSerializerSettings()); + this.jsonSerializerSettings = new Lazy( + () => + jsonSerializerSettings + ?? JsonConvert.DefaultSettings?.Invoke() + ?? new JsonSerializerSettings() + ); } /// public HttpContent ToHttpContent(T item) { - var content = new StringContent(JsonConvert.SerializeObject(item, jsonSerializerSettings.Value), Encoding.UTF8, "application/json"); + var content = new StringContent( + JsonConvert.SerializeObject(item, jsonSerializerSettings.Value), + Encoding.UTF8, + "application/json" + ); return content; } /// - public async Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) + public async Task FromHttpContentAsync( + HttpContent content, + CancellationToken cancellationToken = default + ) { var serializer = JsonSerializer.Create(jsonSerializerSettings.Value); - using var stream = await content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + using var stream = await content + .ReadAsStreamAsync(cancellationToken) + .ConfigureAwait(false); using var reader = new StreamReader(stream); using var jsonTextReader = new JsonTextReader(reader); @@ -61,9 +74,10 @@ public HttpContent ToHttpContent(T item) if (propertyInfo is null) throw new ArgumentNullException(nameof(propertyInfo)); - return propertyInfo.GetCustomAttributes(true) - .Select(a => a.PropertyName) - .FirstOrDefault(); + return propertyInfo + .GetCustomAttributes(true) + .Select(a => a.PropertyName) + .FirstOrDefault(); } } } diff --git a/Refit.Tests/AuthenticatedClientHandlerTests.cs b/Refit.Tests/AuthenticatedClientHandlerTests.cs index c77ea70d0..1c028ee1c 100644 --- a/Refit.Tests/AuthenticatedClientHandlerTests.cs +++ b/Refit.Tests/AuthenticatedClientHandlerTests.cs @@ -26,16 +26,26 @@ public interface IMyAuthenticatedService Task GetAuthenticatedWithTokenInMethod([Authorize("Bearer")] string token); [Get("/auth")] - Task GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection([Authorize("Bearer")] string token, [HeaderCollection] IDictionary headers); + Task GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection( + [Authorize("Bearer")] string token, + [HeaderCollection] IDictionary headers + ); [Get("/auth")] - Task GetAuthenticatedWithTokenInHeaderCollection([HeaderCollection] IDictionary headers); + Task GetAuthenticatedWithTokenInHeaderCollection( + [HeaderCollection] IDictionary headers + ); [Post("/auth/{id}")] - Task PostAuthenticatedWithTokenInHeaderCollection(int id, SomeRequestData content, [HeaderCollection] IDictionary headers); + Task PostAuthenticatedWithTokenInHeaderCollection( + int id, + SomeRequestData content, + [HeaderCollection] IDictionary headers + ); } - public interface IInheritedAuthenticatedServiceWithHeaders : IAuthenticatedServiceWithHeaders + public interface IInheritedAuthenticatedServiceWithHeaders + : IAuthenticatedServiceWithHeaders { [Get("/get-inherited-thing")] Task GetInheritedThing(); @@ -51,7 +61,9 @@ public interface IAuthenticatedServiceWithHeaders [Fact] public void DefaultHandlerIsHttpClientHandler() { - var handler = new AuthenticatedHttpClientHandler(((_, _) => Task.FromResult(string.Empty))); + var handler = new AuthenticatedHttpClientHandler( + ((_, _) => Task.FromResult(string.Empty)) + ); Assert.IsType(handler.InnerHandler); } @@ -72,9 +84,10 @@ public async void AuthenticatedHandlerIgnoresUnAuth() HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/unauth") - .With(msg => msg.Headers.Authorization == null) - .Respond("text/plain", "Ok"); + handler + .Expect(HttpMethod.Get, "http://api/unauth") + .With(msg => msg.Headers.Authorization == null) + .Respond("text/plain", "Ok"); var fixture = RestService.For("http://api", settings); @@ -95,9 +108,10 @@ public async void AuthenticatedHandlerUsesAuth() HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/auth") - .WithHeaders("Authorization", "Bearer tokenValue") - .Respond("text/plain", "Ok"); + handler + .Expect(HttpMethod.Get, "http://api/auth") + .WithHeaders("Authorization", "Bearer tokenValue") + .Respond("text/plain", "Ok"); var fixture = RestService.For("http://api", settings); @@ -118,7 +132,8 @@ public async void AuthenticatedHandlerWithParamUsesAuth() HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/auth") + handler + .Expect(HttpMethod.Get, "http://api/auth") .WithHeaders("Authorization", "Bearer tokenValue") .Respond("text/plain", "Ok"); @@ -131,17 +146,14 @@ public async void AuthenticatedHandlerWithParamUsesAuth() Assert.Equal("Ok", result); } - [Fact] public async void AuthenticatedHandlerWithTokenInParameterUsesAuth() { var handler = new MockHttpMessageHandler(); - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/auth") + handler + .Expect(HttpMethod.Get, "http://api/auth") .WithHeaders("Authorization", "Bearer tokenValue") .Respond("text/plain", "Ok"); @@ -158,18 +170,16 @@ public async void AuthenticatedHandlerWithTokenInParameterUsesAuth() public async void AuthenticatedHandlerWithTokenInHeaderCollectionUsesAuth() { var handler = new MockHttpMessageHandler(); - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var headers = new Dictionary { - {"User-Agent", "Refit"}, - {"Authorization", "Bearer tokenValue"} + { "User-Agent", "Refit" }, + { "Authorization", "Bearer tokenValue" } }; - handler.Expect(HttpMethod.Get, "http://api/auth") + handler + .Expect(HttpMethod.Get, "http://api/auth") .WithHeaders(headers) .Respond("text/plain", "Ok"); @@ -186,31 +196,32 @@ public async void AuthenticatedHandlerWithTokenInHeaderCollectionUsesAuth() public async void AuthenticatedHandlerWithAuthorizeAttributeAndHeaderCollectionUsesAuth() { var handler = new MockHttpMessageHandler(); - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var expectedHeaders = new Dictionary { - {"Authorization", "Bearer tokenValue"}, - {"User-Agent", "Refit"}, - {"X-Forwarded-For", "Refit"} + { "Authorization", "Bearer tokenValue" }, + { "User-Agent", "Refit" }, + { "X-Forwarded-For", "Refit" } }; var headerCollectionHeaders = new Dictionary { - {"User-Agent", "Refit"}, - {"X-Forwarded-For", "Refit"} + { "User-Agent", "Refit" }, + { "X-Forwarded-For", "Refit" } }; - handler.Expect(HttpMethod.Get, "http://api/auth") + handler + .Expect(HttpMethod.Get, "http://api/auth") .WithHeaders(expectedHeaders) .Respond("text/plain", "Ok"); var fixture = RestService.For("http://api", settings); - var result = await fixture.GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection("tokenValue", headerCollectionHeaders); + var result = await fixture.GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection( + "tokenValue", + headerCollectionHeaders + ); handler.VerifyNoOutstandingExpectation(); @@ -221,32 +232,33 @@ public async void AuthenticatedHandlerWithAuthorizeAttributeAndHeaderCollectionU public async void AuthenticatedHandlerWithDuplicatedAuthorizationHeaderUsesAuth() { var handler = new MockHttpMessageHandler(); - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var expectedHeaders = new Dictionary { - {"Authorization", "Bearer tokenValue2"}, - {"User-Agent", "Refit"}, - {"X-Forwarded-For", "Refit"} + { "Authorization", "Bearer tokenValue2" }, + { "User-Agent", "Refit" }, + { "X-Forwarded-For", "Refit" } }; var headerCollectionHeaders = new Dictionary { - {"Authorization", "Bearer tokenValue2"}, - {"User-Agent", "Refit"}, - {"X-Forwarded-For", "Refit"} + { "Authorization", "Bearer tokenValue2" }, + { "User-Agent", "Refit" }, + { "X-Forwarded-For", "Refit" } }; - handler.Expect(HttpMethod.Get, "http://api/auth") + handler + .Expect(HttpMethod.Get, "http://api/auth") .WithHeaders(expectedHeaders) .Respond("text/plain", "Ok"); var fixture = RestService.For("http://api", settings); - var result = await fixture.GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection("tokenValue", headerCollectionHeaders); + var result = await fixture.GetAuthenticatedWithAuthorizeAttributeAndHeaderCollection( + "tokenValue", + headerCollectionHeaders + ); handler.VerifyNoOutstandingExpectation(); @@ -257,30 +269,29 @@ public async void AuthenticatedHandlerWithDuplicatedAuthorizationHeaderUsesAuth( public async void AuthenticatedHandlerPostTokenInHeaderCollectionUsesAuth() { var handler = new MockHttpMessageHandler(); - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var id = 1; - var someRequestData = new SomeRequestData - { - ReadablePropertyName = 1 - }; + var someRequestData = new SomeRequestData { ReadablePropertyName = 1 }; var headers = new Dictionary { - {"Authorization", "Bearer tokenValue2"}, - {"ThingId", id.ToString()} + { "Authorization", "Bearer tokenValue2" }, + { "ThingId", id.ToString() } }; - handler.Expect(HttpMethod.Post, $"http://api/auth/{id}") + handler + .Expect(HttpMethod.Post, $"http://api/auth/{id}") .WithHeaders(headers) .Respond("text/plain", "Ok"); var fixture = RestService.For("http://api", settings); - var result = await fixture.PostAuthenticatedWithTokenInHeaderCollection(id, someRequestData, headers); + var result = await fixture.PostAuthenticatedWithTokenInHeaderCollection( + id, + someRequestData, + headers + ); handler.VerifyNoOutstandingExpectation(); @@ -297,11 +308,15 @@ public async void AuthentictedMethodFromBaseClassWithHeadersAttributeUsesAuth() HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/get-base-thing") + handler + .Expect(HttpMethod.Get, "http://api/get-base-thing") .WithHeaders("Authorization", "Bearer tokenValue") .Respond("text/plain", "Ok"); - var fixture = RestService.For("http://api", settings); + var fixture = RestService.For( + "http://api", + settings + ); var result = await fixture.GetThingFromBase(); @@ -320,11 +335,15 @@ public async void AuthentictedMethodFromInheritedClassWithHeadersAttributeUsesAu HttpMessageHandlerFactory = () => handler }; - handler.Expect(HttpMethod.Get, "http://api/get-inherited-thing") + handler + .Expect(HttpMethod.Get, "http://api/get-inherited-thing") .WithHeaders("Authorization", "Bearer tokenValue") .Respond("text/plain", "Ok"); - var fixture = RestService.For("http://api", settings); + var fixture = RestService.For( + "http://api", + settings + ); var result = await fixture.GetInheritedThing(); diff --git a/Refit.Tests/DeliminatorSeparatedPropertyNamesContractResolver.cs b/Refit.Tests/DeliminatorSeparatedPropertyNamesContractResolver.cs index bc4007756..76840648b 100644 --- a/Refit.Tests/DeliminatorSeparatedPropertyNamesContractResolver.cs +++ b/Refit.Tests/DeliminatorSeparatedPropertyNamesContractResolver.cs @@ -40,8 +40,10 @@ protected override string ResolvePropertyName(string propertyName) } } - public class SnakeCasePropertyNamesContractResolver : DeliminatorSeparatedPropertyNamesContractResolver + public class SnakeCasePropertyNamesContractResolver + : DeliminatorSeparatedPropertyNamesContractResolver { - public SnakeCasePropertyNamesContractResolver() : base('_') { } + public SnakeCasePropertyNamesContractResolver() + : base('_') { } } } diff --git a/Refit.Tests/ExceptionFactoryTests.cs b/Refit.Tests/ExceptionFactoryTests.cs index d32efe841..6ddb43486 100644 --- a/Refit.Tests/ExceptionFactoryTests.cs +++ b/Refit.Tests/ExceptionFactoryTests.cs @@ -32,8 +32,9 @@ public async Task ProvideFactoryWhichAlwaysReturnsNull_WithResult() ExceptionFactory = _ => Task.FromResult(null) }; - handler.Expect(HttpMethod.Get, "http://api/get-with-result") - .Respond(HttpStatusCode.NotFound, new StringContent("error-result")); + handler + .Expect(HttpMethod.Get, "http://api/get-with-result") + .Respond(HttpStatusCode.NotFound, new StringContent("error-result")); var fixture = RestService.For("http://api", settings); @@ -54,8 +55,9 @@ public async Task ProvideFactoryWhichAlwaysReturnsNull_WithoutResult() ExceptionFactory = _ => Task.FromResult(null) }; - handler.Expect(HttpMethod.Put, "http://api/put-without-result") - .Respond(HttpStatusCode.NotFound); + handler + .Expect(HttpMethod.Put, "http://api/put-without-result") + .Respond(HttpStatusCode.NotFound); var fixture = RestService.For("http://api", settings); @@ -75,12 +77,15 @@ public async Task ProvideFactoryWhichAlwaysReturnsException_WithResult() ExceptionFactory = _ => Task.FromResult(exception) }; - handler.Expect(HttpMethod.Get, "http://api/get-with-result") - .Respond(HttpStatusCode.OK, new StringContent("success-result")); + handler + .Expect(HttpMethod.Get, "http://api/get-with-result") + .Respond(HttpStatusCode.OK, new StringContent("success-result")); var fixture = RestService.For("http://api", settings); - var thrownException = await Assert.ThrowsAsync(() => fixture.GetWithResult()); + var thrownException = await Assert.ThrowsAsync( + () => fixture.GetWithResult() + ); Assert.Equal(exception, thrownException); handler.VerifyNoOutstandingExpectation(); @@ -97,12 +102,15 @@ public async Task ProvideFactoryWhichAlwaysReturnsException_WithoutResult() ExceptionFactory = _ => Task.FromResult(exception) }; - handler.Expect(HttpMethod.Put, "http://api/put-without-result") - .Respond(HttpStatusCode.OK); + handler + .Expect(HttpMethod.Put, "http://api/put-without-result") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://api", settings); - var thrownException = await Assert.ThrowsAsync(() => fixture.PutWithoutResult()); + var thrownException = await Assert.ThrowsAsync( + () => fixture.PutWithoutResult() + ); Assert.Equal(exception, thrownException); handler.VerifyNoOutstandingExpectation(); diff --git a/Refit.Tests/FormValueMultimapTests.cs b/Refit.Tests/FormValueMultimapTests.cs index 7fe865526..7f829b95c 100644 --- a/Refit.Tests/FormValueMultimapTests.cs +++ b/Refit.Tests/FormValueMultimapTests.cs @@ -20,14 +20,10 @@ public void EmptyIfNullPassedIn() Assert.Empty(target); } - [Fact] public void LoadsFromDictionary() { - var source = new Dictionary { - { "foo", "bar" }, - { "xyz", "123" } - }; + var source = new Dictionary { { "foo", "bar" }, { "xyz", "123" } }; var target = new FormValueMultimap(source, settings); @@ -37,16 +33,8 @@ public void LoadsFromDictionary() [Fact] public void LoadsFromObject() { - var source = new ObjectTestClass - { - A = "1", - B = "2" - }; - var expected = new Dictionary - { - { "A", "1" }, - { "B", "2" }, - }; + var source = new ObjectTestClass { A = "1", B = "2" }; + var expected = new Dictionary { { "A", "1" }, { "B", "2" }, }; var actual = new FormValueMultimap(source, settings); @@ -64,13 +52,13 @@ public void LoadFromObjectWithCollections() D = new List { 0.1, 1.0 }, E = new List { true, false } }; - var expected = new List> { + var expected = new List> + { new KeyValuePair("A", "01"), new KeyValuePair("A", "02"), new KeyValuePair("B", "set1,set2"), new KeyValuePair("C", "01 02"), new KeyValuePair("D", "0.10\t1.00"), - // The default behavior is to capitalize booleans. This is not a requirement. new KeyValuePair("E", "True|False") }; @@ -95,11 +83,11 @@ public void DefaultCollectionFormatCanBeSpecifiedInSettings_Multi() C = new HashSet { 1, 2 }, D = new List { 0.1, 1.0 }, E = new List { true, false }, - // Member has no explicit CollectionFormat F = new[] { 1, 2, 3 } }; - var expected = new List> { + var expected = new List> + { new KeyValuePair("A", "01"), new KeyValuePair("A", "02"), new KeyValuePair("B", "set1,set2"), @@ -121,12 +109,12 @@ public void DefaultCollectionFormatCanBeSpecifiedInSettings_Multi() [InlineData(CollectionFormat.Pipes, "1|2|3")] [InlineData(CollectionFormat.Ssv, "1 2 3")] [InlineData(CollectionFormat.Tsv, "1\t2\t3")] - public void DefaultCollectionFormatCanBeSpecifiedInSettings(CollectionFormat format, string expectedFormat) + public void DefaultCollectionFormatCanBeSpecifiedInSettings( + CollectionFormat format, + string expectedFormat + ) { - var settingsWithCollectionFormat = new RefitSettings - { - CollectionFormat = format - }; + var settingsWithCollectionFormat = new RefitSettings { CollectionFormat = format }; var source = new ObjectWithRepeatedFieldsTestClass { // Members have explicit CollectionFormat @@ -135,11 +123,11 @@ public void DefaultCollectionFormatCanBeSpecifiedInSettings(CollectionFormat for C = new HashSet { 1, 2 }, D = new List { 0.1, 1.0 }, E = new List { true, false }, - // Member has no explicit CollectionFormat F = new[] { 1, 2, 3 } }; - var expected = new List> { + var expected = new List> + { new KeyValuePair("A", "01"), new KeyValuePair("A", "02"), new KeyValuePair("B", "set1,set2"), @@ -165,14 +153,19 @@ public class ObjectWithRepeatedFieldsTestClass { [Query(CollectionFormat.Multi, Format = "00")] public IList A { get; set; } + [Query(CollectionFormat.Csv)] public ISet B { get; set; } + [Query(CollectionFormat.Ssv, Format = "00")] public HashSet C { get; set; } + [Query(CollectionFormat.Tsv, Format = "0.00")] public IList D { get; set; } + [Query(CollectionFormat.Pipes)] public IList E { get; set; } + [Query] public int[] F { get; set; } } @@ -180,15 +173,8 @@ public class ObjectWithRepeatedFieldsTestClass [Fact] public void ExcludesPropertiesWithInaccessibleGetters() { - var source = new ClassWithInaccessibleGetters - { - A = "Foo", - B = "Bar" - }; - var expected = new Dictionary - { - { "C", "FooBar" } - }; + var source = new ClassWithInaccessibleGetters { A = "Foo", B = "Bar" }; + var expected = new Dictionary { { "C", "FooBar" } }; var actual = new FormValueMultimap(source, settings); @@ -205,31 +191,19 @@ public class ClassWithInaccessibleGetters [Fact] public void LoadsFromAnonymousType() { - var source = new - { - foo = "bar", - xyz = 123 - }; + var source = new { foo = "bar", xyz = 123 }; - var expected = new Dictionary - { - { "foo", "bar" }, - { "xyz", "123" } - }; + var expected = new Dictionary { { "foo", "bar" }, { "xyz", "123" } }; var actual = new FormValueMultimap(source, settings); - Assert.Equal(expected, actual); } [Fact] public void UsesAliasAsAttribute() { - var source = new AliasingTestClass - { - Foo = "abc" - }; + var source = new AliasingTestClass { Foo = "abc" }; var target = new FormValueMultimap(source, settings); @@ -241,10 +215,7 @@ public void UsesAliasAsAttribute() [Fact] public void UsesJsonPropertyAttribute() { - var source = new AliasingTestClass - { - Bar = "xyz" - }; + var source = new AliasingTestClass { Bar = "xyz" }; var target = new FormValueMultimap(source, settings); @@ -256,10 +227,7 @@ public void UsesJsonPropertyAttribute() [Fact] public void UsesQueryPropertyAttribute() { - var source = new AliasingTestClass - { - Frob = 4 - }; + var source = new AliasingTestClass { Frob = 4 }; var target = new FormValueMultimap(source, settings); @@ -268,14 +236,10 @@ public void UsesQueryPropertyAttribute() Assert.Equal("4.0", target.FirstOrDefault(entry => entry.Key == "prefix-fr").Value); } - [Fact] public void GivesPrecedenceToAliasAs() { - var source = new AliasingTestClass - { - Baz = "123" - }; + var source = new AliasingTestClass { Baz = "123" }; var target = new FormValueMultimap(source, settings); @@ -285,14 +249,10 @@ public void GivesPrecedenceToAliasAs() Assert.Equal("123", target.FirstOrDefault(entry => entry.Key == "a").Value); } - [Fact] public void SkipsNullValuesFromDictionary() { - var source = new Dictionary { - { "foo", "bar" }, - { "xyz", null } - }; + var source = new Dictionary { { "foo", "bar" }, { "xyz", null } }; var target = new FormValueMultimap(source, settings); @@ -300,7 +260,6 @@ public void SkipsNullValuesFromDictionary() Assert.Contains("foo", target.Keys); } - [Fact] public void SerializesEnumWithEnumMemberAttribute() { @@ -310,19 +269,13 @@ public void SerializesEnumWithEnumMemberAttribute() { "B", EnumWithEnumMember.B } }; - var expected = new Dictionary - { - { "A", "A" }, - { "B", "b" } - }; - + var expected = new Dictionary { { "A", "A" }, { "B", "b" } }; var actual = new FormValueMultimap(source, settings); Assert.Equal(expected, actual); } - public class AliasingTestClass { [AliasAs("f")] @@ -337,7 +290,6 @@ public class AliasingTestClass [JsonPropertyName("z")] public string Baz { get; set; } - [Query("-", "prefix", "0.0")] [AliasAs("fr")] public int? Frob { get; set; } diff --git a/Refit.Tests/GitHubApi.cs b/Refit.Tests/GitHubApi.cs index 3e40edf05..60fbbb7a6 100644 --- a/Refit.Tests/GitHubApi.cs +++ b/Refit.Tests/GitHubApi.cs @@ -64,7 +64,10 @@ public interface IGitHubApi IObservable GetUserCamelCase(string userName); [Get("/orgs/{orgname}/members")] - Task> GetOrgMembers(string orgName, CancellationToken cancellationToken = default); + Task> GetOrgMembers( + string orgName, + CancellationToken cancellationToken = default + ); [Get("/search/users")] Task FindUsers(string q); diff --git a/Refit.Tests/GlobalSuppressions.cs b/Refit.Tests/GlobalSuppressions.cs index c44254c46..aaf08cf59 100644 --- a/Refit.Tests/GlobalSuppressions.cs +++ b/Refit.Tests/GlobalSuppressions.cs @@ -5,5 +5,17 @@ using System.Diagnostics.CodeAnalysis; -[assembly: SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "", Scope = "member", Target = "~T:Refit.Tests.RequestBuilderTests")] -[assembly: SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "", Scope = "member", Target = "~T:Refit.Tests.MultipartTests")] +[assembly: SuppressMessage( + "CodeQuality", + "IDE0079:Remove unnecessary suppression", + Justification = "", + Scope = "member", + Target = "~T:Refit.Tests.RequestBuilderTests" +)] +[assembly: SuppressMessage( + "CodeQuality", + "IDE0079:Remove unnecessary suppression", + Justification = "", + Scope = "member", + Target = "~T:Refit.Tests.MultipartTests" +)] diff --git a/Refit.Tests/HttpClientFactoryExtensionsTests.cs b/Refit.Tests/HttpClientFactoryExtensionsTests.cs index 0a3bfd90c..3113e66d5 100644 --- a/Refit.Tests/HttpClientFactoryExtensionsTests.cs +++ b/Refit.Tests/HttpClientFactoryExtensionsTests.cs @@ -1,5 +1,4 @@ - -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options; namespace Refit.Tests { @@ -10,13 +9,9 @@ namespace Refit.Tests public class HttpClientFactoryExtensionsTests { - class User - { - } + class User { } - class Role - { - } + class Role { } [Fact] public void GenericHttpClientsAreAssignedUniqueNames() @@ -34,8 +29,14 @@ public void HttpClientServicesAreAddedCorrectlyGivenGenericArgument() { var serviceCollection = new ServiceCollection(); serviceCollection.AddRefitClient(); - Assert.Contains(serviceCollection, z => z.ServiceType == typeof(SettingsFor)); - Assert.Contains(serviceCollection, z => z.ServiceType == typeof(IRequestBuilder)); + Assert.Contains( + serviceCollection, + z => z.ServiceType == typeof(SettingsFor) + ); + Assert.Contains( + serviceCollection, + z => z.ServiceType == typeof(IRequestBuilder) + ); } [Fact] @@ -43,8 +44,14 @@ public void HttpClientServicesAreAddedCorrectlyGivenTypeArgument() { var serviceCollection = new ServiceCollection(); serviceCollection.AddRefitClient(typeof(IFooWithOtherAttribute)); - Assert.Contains(serviceCollection, z => z.ServiceType == typeof(SettingsFor)); - Assert.Contains(serviceCollection, z => z.ServiceType == typeof(IRequestBuilder)); + Assert.Contains( + serviceCollection, + z => z.ServiceType == typeof(SettingsFor) + ); + Assert.Contains( + serviceCollection, + z => z.ServiceType == typeof(IRequestBuilder) + ); } [Fact] @@ -68,52 +75,87 @@ public void HttpClientReturnsClientGivenTypeArgument() [Fact] public void HttpClientSettingsAreInjectableGivenGenericArgument() { - var serviceCollection = new ServiceCollection() - .Configure(o => o.Serializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions())); - serviceCollection.AddRefitClient(_ => new RefitSettings() {ContentSerializer = _.GetRequiredService>().Value.Serializer}); + var serviceCollection = new ServiceCollection().Configure( + o => o.Serializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions()) + ); + serviceCollection.AddRefitClient( + _ => + new RefitSettings() + { + ContentSerializer = _.GetRequiredService< + IOptions + >().Value.Serializer + } + ); var serviceProvider = serviceCollection.BuildServiceProvider(); Assert.Same( serviceProvider.GetRequiredService>().Value.Serializer, - serviceProvider.GetRequiredService>().Settings!.ContentSerializer + serviceProvider + .GetRequiredService>() + .Settings!.ContentSerializer ); } [Fact] public void HttpClientSettingsAreInjectableGivenTypeArgument() { - var serviceCollection = new ServiceCollection() - .Configure(o => o.Serializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions())); - serviceCollection.AddRefitClient(typeof(IFooWithOtherAttribute), _ => new RefitSettings() {ContentSerializer = _.GetRequiredService>().Value.Serializer}); + var serviceCollection = new ServiceCollection().Configure( + o => o.Serializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions()) + ); + serviceCollection.AddRefitClient( + typeof(IFooWithOtherAttribute), + _ => + new RefitSettings() + { + ContentSerializer = _.GetRequiredService< + IOptions + >().Value.Serializer + } + ); var serviceProvider = serviceCollection.BuildServiceProvider(); Assert.Same( serviceProvider.GetRequiredService>().Value.Serializer, - serviceProvider.GetRequiredService>().Settings!.ContentSerializer + serviceProvider + .GetRequiredService>() + .Settings!.ContentSerializer ); } [Fact] public void HttpClientSettingsCanBeProvidedStaticallyGivenGenericArgument() { - var contentSerializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions()); + var contentSerializer = new SystemTextJsonContentSerializer( + new JsonSerializerOptions() + ); var serviceCollection = new ServiceCollection(); - serviceCollection.AddRefitClient(new RefitSettings() {ContentSerializer = contentSerializer }); + serviceCollection.AddRefitClient( + new RefitSettings() { ContentSerializer = contentSerializer } + ); var serviceProvider = serviceCollection.BuildServiceProvider(); Assert.Same( contentSerializer, - serviceProvider.GetRequiredService>().Settings!.ContentSerializer + serviceProvider + .GetRequiredService>() + .Settings!.ContentSerializer ); } [Fact] public void HttpClientSettingsCanBeProvidedStaticallyGivenTypeArgument() { - var contentSerializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions()); + var contentSerializer = new SystemTextJsonContentSerializer( + new JsonSerializerOptions() + ); var serviceCollection = new ServiceCollection(); - serviceCollection.AddRefitClient(new RefitSettings() {ContentSerializer = contentSerializer }); + serviceCollection.AddRefitClient( + new RefitSettings() { ContentSerializer = contentSerializer } + ); var serviceProvider = serviceCollection.BuildServiceProvider(); Assert.Same( contentSerializer, - serviceProvider.GetRequiredService>().Settings!.ContentSerializer + serviceProvider + .GetRequiredService>() + .Settings!.ContentSerializer ); } diff --git a/Refit.Tests/IDefaultInterfaceMethodTests.cs b/Refit.Tests/IDefaultInterfaceMethodTests.cs index cdfca77f3..25dce0d71 100644 --- a/Refit.Tests/IDefaultInterfaceMethodTests.cs +++ b/Refit.Tests/IDefaultInterfaceMethodTests.cs @@ -45,12 +45,10 @@ public async Task InternalInterfaceMemberTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/") .Respond(HttpStatusCode.OK, "text/html", "OK"); var fixture = RestService.For("https://httpbin.org/", settings); @@ -64,12 +62,10 @@ public async Task DimTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/") .Respond(HttpStatusCode.OK, "text/html", "OK"); var fixture = RestService.For("https://httpbin.org/", settings); @@ -83,12 +79,10 @@ public async Task InternalDimTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/") .Respond(HttpStatusCode.OK, "text/html", "OK"); var fixture = RestService.For("https://httpbin.org/", settings); diff --git a/Refit.Tests/InheritedGenericInterfacesApi.cs b/Refit.Tests/InheritedGenericInterfacesApi.cs index cd9ffdd71..d506d961d 100644 --- a/Refit.Tests/InheritedGenericInterfacesApi.cs +++ b/Refit.Tests/InheritedGenericInterfacesApi.cs @@ -7,9 +7,7 @@ namespace Refit.Tests { - public class DataEntity - { - } + public class DataEntity { } public interface IDataApiA : IDataCrudApi { @@ -23,29 +21,33 @@ public interface IDataApiB : IDataCrudApi Task PingB(); } - public interface IDataCrudApi : IDataCrudApi where T : class + public interface IDataCrudApi : IDataCrudApi + where T : class { [Post("")] Task Copy([Body] T payload); } - public interface IDataCrudApi where T : class + public interface IDataCrudApi + where T : class { [Post("")] Task Create([Body] T payload); [Get("")] - Task> ReadAll() where TFoo : new(); + Task> ReadAll() + where TFoo : new(); [Get("")] - Task> ReadAll() where TFoo : new() - where TBar : struct; + Task> ReadAll() + where TFoo : new() + where TBar : struct; [Get("/{key}")] Task ReadOne(TKey key); [Put("/{key}")] - Task Update(TKey key, [Body]T payload); + Task Update(TKey key, [Body] T payload); [Delete("/{key}")] Task Delete(TKey key); @@ -55,7 +57,6 @@ Task ReadAllClasses() where TFoo : class, new(); } - public class DatasetQueryItem where TResultRow : class, new() { @@ -72,6 +73,6 @@ public interface IDataMosApi { [Get("/datasets/{dataSet}/rows")] Task[]> GetDataSetItems() - where TResulRow : class, new(); + where TResulRow : class, new(); } } diff --git a/Refit.Tests/InheritedInterfacesApi.cs b/Refit.Tests/InheritedInterfacesApi.cs index d8677e32e..5aa5e590c 100644 --- a/Refit.Tests/InheritedInterfacesApi.cs +++ b/Refit.Tests/InheritedInterfacesApi.cs @@ -48,10 +48,7 @@ public interface IAmInterfaceF_RequireUsing Task Get(List guids); } - public interface IContainAandB : IAmInterfaceB, IAmInterfaceA - { - - } + public interface IContainAandB : IAmInterfaceB, IAmInterfaceA { } public interface IAmInterfaceEWithNoRefit { diff --git a/Refit.Tests/InheritedInterfacesInSeparateFileApi.cs b/Refit.Tests/InheritedInterfacesInSeparateFileApi.cs index a086d3647..9a006b559 100644 --- a/Refit.Tests/InheritedInterfacesInSeparateFileApi.cs +++ b/Refit.Tests/InheritedInterfacesInSeparateFileApi.cs @@ -4,7 +4,7 @@ namespace Refit.Tests.SeparateNamespace { - public interface InheritedInterfacesInSeparateFileApi: IAmInterfaceF_RequireUsing + public interface InheritedInterfacesInSeparateFileApi : IAmInterfaceF_RequireUsing { [Get("/get")] Task Get(int i); diff --git a/Refit.Tests/IntegrationTestHelper.cs b/Refit.Tests/IntegrationTestHelper.cs index 1c241a916..d912e9f19 100644 --- a/Refit.Tests/IntegrationTestHelper.cs +++ b/Refit.Tests/IntegrationTestHelper.cs @@ -19,7 +19,9 @@ public static string GetPath(params string[] paths) return (new FileInfo(paths.Aggregate(ret, Path.Combine))).FullName; } - public static string GetIntegrationTestRootDirectory([CallerFilePath] string filePath = default) + public static string GetIntegrationTestRootDirectory( + [CallerFilePath] string filePath = default + ) { // XXX: This is an evil hack, but it's okay for a unit test // We can't use Assembly.Location because unit test runners love diff --git a/Refit.Tests/InterfaceStubGenerator.cs b/Refit.Tests/InterfaceStubGenerator.cs index 274b204ee..b4d12d4e1 100644 --- a/Refit.Tests/InterfaceStubGenerator.cs +++ b/Refit.Tests/InterfaceStubGenerator.cs @@ -24,7 +24,10 @@ public class InterfaceStubGeneratorTests { static readonly MetadataReference RefitAssembly = MetadataReference.CreateFromFile( typeof(GetAttribute).Assembly.Location, - documentation: XmlDocumentationProvider.CreateFromFile(Path.ChangeExtension(typeof(GetAttribute).Assembly.Location, ".xml"))); + documentation: XmlDocumentationProvider.CreateFromFile( + Path.ChangeExtension(typeof(GetAttribute).Assembly.Location, ".xml") + ) + ); static readonly ReferenceAssemblies ReferenceAssemblies; @@ -37,14 +40,17 @@ static InterfaceStubGeneratorTests() #elif NET7_0 ReferenceAssemblies = ReferenceAssemblies.Net.Net70; #else - ReferenceAssemblies = ReferenceAssemblies.Default - .AddPackages(ImmutableArray.Create(new PackageIdentity("System.Text.Json", "7.0.2"))); + ReferenceAssemblies = ReferenceAssemblies.Default.AddPackages( + ImmutableArray.Create(new PackageIdentity("System.Text.Json", "7.0.2")) + ); #endif #if NET461 ReferenceAssemblies = ReferenceAssemblies .AddAssemblies(ImmutableArray.Create("System.Web")) - .AddPackages(ImmutableArray.Create(new PackageIdentity("System.Net.Http", "4.3.4"))); + .AddPackages( + ImmutableArray.Create(new PackageIdentity("System.Net.Http", "4.3.4")) + ); #endif } @@ -55,19 +61,23 @@ public void GenerateInterfaceStubsSmokeTest() var driver = CSharpGeneratorDriver.Create(fixture); - var inputCompilation = CreateCompilation( IntegrationTestHelper.GetPath("RestService.cs"), IntegrationTestHelper.GetPath("GitHubApi.cs"), IntegrationTestHelper.GetPath("InheritedInterfacesApi.cs"), - IntegrationTestHelper.GetPath("InheritedGenericInterfacesApi.cs")); + IntegrationTestHelper.GetPath("InheritedGenericInterfacesApi.cs") + ); var diags = inputCompilation.GetDiagnostics(); // Make sure we don't have any errors Assert.Empty(diags.Where(d => d.Severity == DiagnosticSeverity.Error)); - var rundriver = driver.RunGeneratorsAndUpdateCompilation(inputCompilation, out var outputCompiliation, out var diagnostics); + var rundriver = driver.RunGeneratorsAndUpdateCompilation( + inputCompilation, + out var outputCompiliation, + out var diagnostics + ); var runResult = rundriver.GetRunResult(); @@ -95,37 +105,31 @@ static Compilation CreateCompilation(params string[] sourceFiles) typeof(Attribute) }; - - return CSharpCompilation.Create("compilation", + return CSharpCompilation.Create( + "compilation", sourceFiles.Select(source => CSharpSyntaxTree.ParseText(File.ReadAllText(source))), - keyReferences.Select(t => MetadataReference.CreateFromFile(t.Assembly.Location)), - new CSharpCompilationOptions(OutputKind.ConsoleApplication)); - + keyReferences.Select(t => MetadataReference.CreateFromFile(t.Assembly.Location)), + new CSharpCompilationOptions(OutputKind.ConsoleApplication) + ); } [Fact] public async Task NoRefitInterfacesSmokeTest() { - var input = File.ReadAllText(IntegrationTestHelper.GetPath("IInterfaceWithoutRefit.cs")); + var input = File.ReadAllText( + IntegrationTestHelper.GetPath("IInterfaceWithoutRefit.cs") + ); await new VerifyCS.Test { ReferenceAssemblies = ReferenceAssemblies, - TestState = - { - AdditionalReferences = { RefitAssembly }, - Sources = { input }, - }, + TestState = { AdditionalReferences = { RefitAssembly }, Sources = { input }, }, }.RunAsync(); await new VerifyCSV2.Test { ReferenceAssemblies = ReferenceAssemblies, - TestState = - { - AdditionalReferences = { RefitAssembly }, - Sources = { input }, - }, + TestState = { AdditionalReferences = { RefitAssembly }, Sources = { input }, }, }.RunAsync(); } @@ -134,7 +138,8 @@ public async Task FindInterfacesSmokeTest() { var input = File.ReadAllText(IntegrationTestHelper.GetPath("GitHubApi.cs")); - var output1 = @" + var output1 = + @" #pragma warning disable namespace RefitInternalGenerated { @@ -154,7 +159,8 @@ sealed class PreserveAttribute : global::System.Attribute #pragma warning restore "; - var output1_5 = @" + var output1_5 = + @" #pragma warning disable namespace Refit.Implementation { @@ -172,7 +178,8 @@ internal static partial class Generated #pragma warning restore "; - var output2 = @"#nullable disable + var output2 = + @"#nullable disable #pragma warning disable namespace Refit.Implementation { @@ -598,7 +605,8 @@ public RefitTestsIGitHubApi(global::System.Net.Http.HttpClient client, global::R #pragma warning restore "; - var output3 = @"#nullable disable + var output3 = + @"#nullable disable #pragma warning disable namespace Refit.Implementation { @@ -670,7 +678,8 @@ public RefitTestsIGitHubApiDisposable(global::System.Net.Http.HttpClient client, #pragma warning restore "; - var output4 = @"#nullable disable + var output4 = + @"#nullable disable #pragma warning disable namespace Refit.Implementation { @@ -984,12 +993,14 @@ public RefitTestsTestNestedINestedGitHubApi(global::System.Net.Http.HttpClient c }.RunAsync(); } - [Fact] public async Task GenerateInterfaceStubsWithoutNamespaceSmokeTest() { - var input = File.ReadAllText(IntegrationTestHelper.GetPath("IServiceWithoutNamespace.cs")); - var output1 = @" + var input = File.ReadAllText( + IntegrationTestHelper.GetPath("IServiceWithoutNamespace.cs") + ); + var output1 = + @" #pragma warning disable namespace RefitInternalGenerated { @@ -1008,7 +1019,8 @@ sealed class PreserveAttribute : global::System.Attribute } #pragma warning restore "; - var output1_5 = @" + var output1_5 = + @" #pragma warning disable namespace Refit.Implementation { @@ -1026,7 +1038,8 @@ internal static partial class Generated #pragma warning restore "; - var output2 = @"#nullable disable + var output2 = + @"#nullable disable #pragma warning disable namespace Refit.Implementation { @@ -1150,7 +1163,11 @@ public IServiceWithoutNamespace(global::System.Net.Http.HttpClient client, globa { (typeof(InterfaceStubGeneratorV2), "PreserveAttribute.g.cs", output1), (typeof(InterfaceStubGeneratorV2), "Generated.g.cs", output1_5), - (typeof(InterfaceStubGeneratorV2), "IServiceWithoutNamespace.g.cs", output2), + ( + typeof(InterfaceStubGeneratorV2), + "IServiceWithoutNamespace.g.cs", + output2 + ), }, }, }.RunAsync(); @@ -1186,7 +1203,8 @@ public interface IAmNotARefitInterface Task NotARefitMethod(); } - public interface IBoringCrudApi where T : class + public interface IBoringCrudApi + where T : class { [Post("")] Task Create([Body] T paylod); @@ -1207,12 +1225,14 @@ public interface IBoringCrudApi where T : class public interface INonGenericInterfaceWithGenericMethod { [Post("")] - Task PostMessage([Body] T message) where T : IMessage; + Task PostMessage([Body] T message) + where T : IMessage; [Post("")] - Task PostMessage([Body] T message, U param1, V param2) where T : IMessage where U : T; + Task PostMessage([Body] T message, U param1, V param2) + where T : IMessage + where U : T; } public interface IMessage { } - } diff --git a/Refit.Tests/MethodOverloads.cs b/Refit.Tests/MethodOverloads.cs index f55d8f8a0..589dc8449 100644 --- a/Refit.Tests/MethodOverloads.cs +++ b/Refit.Tests/MethodOverloads.cs @@ -44,24 +44,21 @@ public interface IUseOverloadedGenericMethods Task Get(TInput1 input1, TInput2 input2); } - public class MethodOverladTests { [Fact] public async Task BasicMethodOverloadTest() { - var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/") .Respond(HttpStatusCode.OK, "text/html", "OK"); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/status/403") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/status/403") .Respond(HttpStatusCode.Forbidden); var fixture = RestService.For("https://httpbin.org/", settings); @@ -71,7 +68,6 @@ public async Task BasicMethodOverloadTest() Assert.True(!string.IsNullOrWhiteSpace(plainText)); Assert.Equal(HttpStatusCode.Forbidden, resp.StatusCode); - } [Fact] @@ -79,15 +75,16 @@ public async Task GenericMethodOverloadTest1() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/") .Respond(HttpStatusCode.OK, "text/html", "OK"); - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var plainText = await fixture.Get(); Assert.True(!string.IsNullOrWhiteSpace(plainText)); @@ -98,17 +95,16 @@ public async Task GenericMethodOverloadTest2() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/status/403") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/status/403") .Respond(HttpStatusCode.Forbidden); - - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var resp = await fixture.Get(403); @@ -120,17 +116,17 @@ public async Task GenericMethodOverloadTest3() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .WithQueryString("someVal", "201") - .Respond("application/json", "some-T-value"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .WithQueryString("someVal", "201") + .Respond("application/json", "some-T-value"); - - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var result = await fixture.Get(201); @@ -142,17 +138,21 @@ public async Task GenericMethodOverloadTest4() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .WithHeaders("X-Refit", "99") .WithQueryString("param", "foo") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get\", \"args\": {\"param\": \"foo\"}}"); + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get\", \"args\": {\"param\": \"foo\"}}" + ); - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var result = await fixture.Get("foo", 99); @@ -164,18 +164,21 @@ public async Task GenericMethodOverloadTest5() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; - + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .WithHeaders("X-Refit", "foo") .WithQueryString("param", "99") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get\", \"args\": {\"param\": \"99\"}}"); + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get\", \"args\": {\"param\": \"99\"}}" + ); - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var result = await fixture.Get(99, "foo"); @@ -187,16 +190,17 @@ public async Task GenericMethodOverloadTest6() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .WithQueryString("input", "99") - .Respond("application/json", "generic-output"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .WithQueryString("input", "99") + .Respond("application/json", "generic-output"); - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); var result = await fixture.Get(99); @@ -208,21 +212,19 @@ public async Task GenericMethodOverloadTest7() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .WithQueryString(new Dictionary() - { - { "input1", "str" }, - { "input2", "3" } - }) - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .WithQueryString( + new Dictionary() { { "input1", "str" }, { "input2", "3" } } + ) + .Respond("application/json", "Ok"); - - var fixture = RestService.For>("https://httpbin.org/", settings); + var fixture = RestService.For>( + "https://httpbin.org/", + settings + ); await fixture.Get("str", 3); @@ -230,4 +232,3 @@ public async Task GenericMethodOverloadTest7() } } } - diff --git a/Refit.Tests/MultipartTests.cs b/Refit.Tests/MultipartTests.cs index 897672c50..ce35bebcf 100644 --- a/Refit.Tests/MultipartTests.cs +++ b/Refit.Tests/MultipartTests.cs @@ -31,7 +31,10 @@ public interface IRunscopeApi [Multipart] [Post("/")] - Task UploadStreamPart([Query] ModelObject someQueryParams, StreamPart stream); + Task UploadStreamPart( + [Query] ModelObject someQueryParams, + StreamPart stream + ); [Multipart] [Post("/")] @@ -39,23 +42,35 @@ public interface IRunscopeApi [Multipart] [Post("/")] - Task UploadBytesPart([AliasAs("ByteArrayPartParamAlias")]ByteArrayPart bytes); + Task UploadBytesPart( + [AliasAs("ByteArrayPartParamAlias")] ByteArrayPart bytes + ); [Multipart] [Post("/")] - Task UploadString([AliasAs("SomeStringAlias")]string someString); + Task UploadString([AliasAs("SomeStringAlias")] string someString); [Multipart] [Post("/")] - Task UploadStringWithHeaderAndRequestProperty([Header("Authorization")] string authorization, [Property("SomeProperty")] string someProperty, [AliasAs("SomeStringAlias")]string someString); + Task UploadStringWithHeaderAndRequestProperty( + [Header("Authorization")] string authorization, + [Property("SomeProperty")] string someProperty, + [AliasAs("SomeStringAlias")] string someString + ); [Multipart] [Post("/")] - Task UploadFileInfo(IEnumerable fileInfos, FileInfo anotherFile); + Task UploadFileInfo( + IEnumerable fileInfos, + FileInfo anotherFile + ); [Multipart] [Post("/")] - Task UploadFileInfoPart(IEnumerable fileInfos, FileInfoPart anotherFile); + Task UploadFileInfoPart( + IEnumerable fileInfos, + FileInfoPart anotherFile + ); [Multipart] [Post("/")] @@ -65,15 +80,20 @@ public interface IRunscopeApi [Post("/")] Task UploadJsonObjects(IEnumerable theObjects); - [Multipart] [Post("/")] - Task UploadMixedObjects(IEnumerable theObjects, AnotherModel anotherModel, FileInfo aFile, AnEnum anEnum, string aString, int anInt); + Task UploadMixedObjects( + IEnumerable theObjects, + AnotherModel anotherModel, + FileInfo aFile, + AnEnum anEnum, + string aString, + int anInt + ); [Multipart] [Post("/")] Task UploadHttpContent(HttpContent content); - } public class ModelObject @@ -117,10 +137,7 @@ public async Task MultipartUploadShouldWorkWithStream() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); var fixture = RestService.For(BaseAddress, settings); @@ -147,10 +164,7 @@ public async Task MultipartUploadShouldWorkWithStreamAndCustomBoundary() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using (var stream = GetTestFileStream("Test Files/Test.pdf")) { @@ -159,7 +173,10 @@ public async Task MultipartUploadShouldWorkWithStreamAndCustomBoundary() } var input = typeof(IRunscopeApi); - var methodFixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == "UploadStreamWithCustomBoundary")); + var methodFixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == "UploadStreamWithCustomBoundary") + ); Assert.Equal("-----SomeCustomBoundary", methodFixture.MultipartBoundary); } @@ -183,10 +200,7 @@ public async Task MultipartUploadShouldWorkWithByteArray() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); using var reader = new BinaryReader(stream); @@ -236,14 +250,10 @@ public async Task MultipartUploadShouldWorkWithFileInfo() { Assert.True(StreamsEqual(src, str)); } - } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; try { @@ -254,7 +264,10 @@ public async Task MultipartUploadShouldWorkWithFileInfo() outStream.Close(); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadFileInfo(new[] { new FileInfo(fileName), new FileInfo(fileName) }, new FileInfo(fileName)); + var result = await fixture.UploadFileInfo( + new[] { new FileInfo(fileName), new FileInfo(fileName) }, + new FileInfo(fileName) + ); } finally { @@ -284,11 +297,7 @@ public async Task MultipartUploadShouldWorkWithString() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; - + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var fixture = RestService.For(BaseAddress, settings); var result = await fixture.UploadString(text); @@ -309,7 +318,10 @@ public async Task MultipartUploadShouldWorkWithHeaderAndRequestProperty() #if NET6_0_OR_GREATER Assert.Equal(3, message.Options.Count()); - Assert.Equal(someProperty, ((IDictionary)message.Options)["SomeProperty"]); + Assert.Equal( + someProperty, + ((IDictionary)message.Options)["SomeProperty"] + ); #endif #pragma warning disable CS0618 // Type or member is obsolete @@ -332,14 +344,14 @@ public async Task MultipartUploadShouldWorkWithHeaderAndRequestProperty() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; - + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadStringWithHeaderAndRequestProperty(someHeader,someProperty, text); + var result = await fixture.UploadStringWithHeaderAndRequestProperty( + someHeader, + someProperty, + text + ); } [Fact] @@ -354,7 +366,10 @@ public async Task MultipartUploadShouldWorkWithStreamPart() Assert.Single(parts); Assert.Equal("stream", parts[0].Headers.ContentDisposition.Name); - Assert.Equal("test-streampart.pdf", parts[0].Headers.ContentDisposition.FileName); + Assert.Equal( + "test-streampart.pdf", + parts[0].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[0].Headers.ContentType.MediaType); using var str = await parts[0].ReadAsStreamAsync(); @@ -363,14 +378,13 @@ public async Task MultipartUploadShouldWorkWithStreamPart() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadStreamPart(new StreamPart(stream, "test-streampart.pdf", "application/pdf")); + var result = await fixture.UploadStreamPart( + new StreamPart(stream, "test-streampart.pdf", "application/pdf") + ); } [Fact] @@ -385,7 +399,10 @@ public async Task MultipartUploadShouldWorkWithStreamPartWithNamedMultipart() Assert.Single(parts); Assert.Equal("test-stream", parts[0].Headers.ContentDisposition.Name); - Assert.Equal("test-streampart.pdf", parts[0].Headers.ContentDisposition.FileName); + Assert.Equal( + "test-streampart.pdf", + parts[0].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[0].Headers.ContentType.MediaType); using var str = await parts[0].ReadAsStreamAsync(); @@ -394,14 +411,13 @@ public async Task MultipartUploadShouldWorkWithStreamPartWithNamedMultipart() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadStreamPart(new StreamPart(stream, "test-streampart.pdf", "application/pdf", "test-stream")); + var result = await fixture.UploadStreamPart( + new StreamPart(stream, "test-streampart.pdf", "application/pdf", "test-stream") + ); } [Fact] @@ -420,7 +436,10 @@ public async Task MultipartUploadShouldWorkWithStreamPartAndQuery() Assert.Single(parts); Assert.Equal("stream", parts[0].Headers.ContentDisposition.Name); - Assert.Equal("test-streampart.pdf", parts[0].Headers.ContentDisposition.FileName); + Assert.Equal( + "test-streampart.pdf", + parts[0].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[0].Headers.ContentType.MediaType); using var str = await parts[0].ReadAsStreamAsync(); @@ -429,21 +448,16 @@ public async Task MultipartUploadShouldWorkWithStreamPartAndQuery() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadStreamPart(new ModelObject() - { - Property1 = "test", - Property2 = "test2" - }, new StreamPart(stream, "test-streampart.pdf", "application/pdf")); + var result = await fixture.UploadStreamPart( + new ModelObject() { Property1 = "test", Property2 = "test2" }, + new StreamPart(stream, "test-streampart.pdf", "application/pdf") + ); } - [Fact] public async Task MultipartUploadShouldWorkWithByteArrayPart() { @@ -455,8 +469,14 @@ public async Task MultipartUploadShouldWorkWithByteArrayPart() Assert.Single(parts); - Assert.Equal("ByteArrayPartParamAlias", parts[0].Headers.ContentDisposition.Name); - Assert.Equal("test-bytearraypart.pdf", parts[0].Headers.ContentDisposition.FileName); + Assert.Equal( + "ByteArrayPartParamAlias", + parts[0].Headers.ContentDisposition.Name + ); + Assert.Equal( + "test-bytearraypart.pdf", + parts[0].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[0].Headers.ContentType.MediaType); using var str = await parts[0].ReadAsStreamAsync(); @@ -465,17 +485,16 @@ public async Task MultipartUploadShouldWorkWithByteArrayPart() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; using var stream = GetTestFileStream("Test Files/Test.pdf"); using var reader = new BinaryReader(stream); var bytes = reader.ReadBytes((int)stream.Length); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadBytesPart(new ByteArrayPart(bytes, "test-bytearraypart.pdf", "application/pdf")); + var result = await fixture.UploadBytesPart( + new ByteArrayPart(bytes, "test-bytearraypart.pdf", "application/pdf") + ); } [Fact] @@ -492,7 +511,10 @@ public async Task MultipartUploadShouldWorkWithFileInfoPart() Assert.Equal(3, parts.Count); Assert.Equal("fileInfos", parts[0].Headers.ContentDisposition.Name); - Assert.Equal("test-fileinfopart.pdf", parts[0].Headers.ContentDisposition.FileName); + Assert.Equal( + "test-fileinfopart.pdf", + parts[0].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[0].Headers.ContentType.MediaType); using (var str = await parts[0].ReadAsStreamAsync()) using (var src = GetTestFileStream("Test Files/Test.pdf")) @@ -501,7 +523,10 @@ public async Task MultipartUploadShouldWorkWithFileInfoPart() } Assert.Equal("fileInfos", parts[1].Headers.ContentDisposition.Name); - Assert.Equal("test-fileinfopart2.pdf", parts[1].Headers.ContentDisposition.FileName); + Assert.Equal( + "test-fileinfopart2.pdf", + parts[1].Headers.ContentDisposition.FileName + ); Assert.Null(parts[1].Headers.ContentType); using (var str = await parts[1].ReadAsStreamAsync()) using (var src = GetTestFileStream("Test Files/Test.pdf")) @@ -510,22 +535,20 @@ public async Task MultipartUploadShouldWorkWithFileInfoPart() } Assert.Equal("anotherFile", parts[2].Headers.ContentDisposition.Name); - Assert.Equal("additionalfile.pdf", parts[2].Headers.ContentDisposition.FileName); + Assert.Equal( + "additionalfile.pdf", + parts[2].Headers.ContentDisposition.FileName + ); Assert.Equal("application/pdf", parts[2].Headers.ContentType.MediaType); using (var str = await parts[2].ReadAsStreamAsync()) using (var src = GetTestFileStream("Test Files/Test.pdf")) { Assert.True(StreamsEqual(src, str)); } - } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; - + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; try { @@ -536,11 +559,26 @@ public async Task MultipartUploadShouldWorkWithFileInfoPart() outStream.Close(); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadFileInfoPart(new[] - { - new FileInfoPart(new FileInfo(fileName), "test-fileinfopart.pdf", "application/pdf"), - new FileInfoPart(new FileInfo(fileName), "test-fileinfopart2.pdf", contentType: null) - }, new FileInfoPart(new FileInfo(fileName), fileName: "additionalfile.pdf", contentType: "application/pdf")); + var result = await fixture.UploadFileInfoPart( + new[] + { + new FileInfoPart( + new FileInfo(fileName), + "test-fileinfopart.pdf", + "application/pdf" + ), + new FileInfoPart( + new FileInfo(fileName), + "test-fileinfopart2.pdf", + contentType: null + ) + }, + new FileInfoPart( + new FileInfo(fileName), + fileName: "additionalfile.pdf", + contentType: "application/pdf" + ) + ); } finally { @@ -552,18 +590,22 @@ public async Task MultipartUploadShouldWorkWithFileInfoPart() [InlineData(typeof(NewtonsoftJsonContentSerializer), "application/json")] [InlineData(typeof(SystemTextJsonContentSerializer), "application/json")] [InlineData(typeof(XmlContentSerializer), "application/xml")] - public async Task MultipartUploadShouldWorkWithAnObject(Type contentSerializerType, string mediaType) + public async Task MultipartUploadShouldWorkWithAnObject( + Type contentSerializerType, + string mediaType + ) { - if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer) - { - throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}"); + if ( + Activator.CreateInstance(contentSerializerType) + is not IHttpContentSerializer serializer + ) + { + throw new ArgumentException( + $"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}" + ); } - var model1 = new ModelObject - { - Property1 = "M1.prop1", - Property2 = "M1.prop2" - }; + var model1 = new ModelObject { Property1 = "M1.prop1", Property2 = "M1.prop2" }; var handler = new MockHttpMessageHandler { @@ -576,7 +618,9 @@ public async Task MultipartUploadShouldWorkWithAnObject(Type contentSerializerTy Assert.Equal("theObject", parts[0].Headers.ContentDisposition.Name); Assert.Null(parts[0].Headers.ContentDisposition.FileName); Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType); - var result0 = await serializer.FromHttpContentAsync(parts[0]).ConfigureAwait(false); + var result0 = await serializer + .FromHttpContentAsync(parts[0]) + .ConfigureAwait(false); Assert.Equal(model1.Property1, result0.Property1); Assert.Equal(model1.Property2, result0.Property2); } @@ -596,23 +640,24 @@ public async Task MultipartUploadShouldWorkWithAnObject(Type contentSerializerTy [InlineData(typeof(NewtonsoftJsonContentSerializer), "application/json")] [InlineData(typeof(SystemTextJsonContentSerializer), "application/json")] [InlineData(typeof(XmlContentSerializer), "application/xml")] - public async Task MultipartUploadShouldWorkWithObjects(Type contentSerializerType, string mediaType) + public async Task MultipartUploadShouldWorkWithObjects( + Type contentSerializerType, + string mediaType + ) { - if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer) - { - throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}"); + if ( + Activator.CreateInstance(contentSerializerType) + is not IHttpContentSerializer serializer + ) + { + throw new ArgumentException( + $"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}" + ); } - var model1 = new ModelObject - { - Property1 = "M1.prop1", - Property2 = "M1.prop2" - }; + var model1 = new ModelObject { Property1 = "M1.prop1", Property2 = "M1.prop2" }; - var model2 = new ModelObject - { - Property1 = "M2.prop1" - }; + var model2 = new ModelObject { Property1 = "M2.prop1" }; var handler = new MockHttpMessageHandler { @@ -625,15 +670,18 @@ public async Task MultipartUploadShouldWorkWithObjects(Type contentSerializerTyp Assert.Equal("theObjects", parts[0].Headers.ContentDisposition.Name); Assert.Null(parts[0].Headers.ContentDisposition.FileName); Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType); - var result0 = await serializer.FromHttpContentAsync(parts[0]).ConfigureAwait(false); + var result0 = await serializer + .FromHttpContentAsync(parts[0]) + .ConfigureAwait(false); Assert.Equal(model1.Property1, result0.Property1); Assert.Equal(model1.Property2, result0.Property2); - Assert.Equal("theObjects", parts[1].Headers.ContentDisposition.Name); Assert.Null(parts[1].Headers.ContentDisposition.FileName); Assert.Equal(mediaType, parts[1].Headers.ContentType.MediaType); - var result1 = await serializer.FromHttpContentAsync(parts[1]).ConfigureAwait(false); + var result1 = await serializer + .FromHttpContentAsync(parts[1]) + .ConfigureAwait(false); Assert.Equal(model2.Property1, result1.Property1); Assert.Equal(model2.Property2, result1.Property2); } @@ -655,21 +703,11 @@ public async Task MultipartUploadShouldWorkWithMixedTypes() var fileName = Path.GetTempFileName(); var name = Path.GetFileName(fileName); - var model1 = new ModelObject - { - Property1 = "M1.prop1", - Property2 = "M1.prop2" - }; + var model1 = new ModelObject { Property1 = "M1.prop1", Property2 = "M1.prop2" }; - var model2 = new ModelObject - { - Property1 = "M2.prop1" - }; + var model2 = new ModelObject { Property1 = "M2.prop1" }; - var anotherModel = new AnotherModel - { - Foos = new[] { "bar1", "bar2" } - }; + var anotherModel = new AnotherModel { Foos = new[] { "bar1", "bar2" } }; var handler = new MockHttpMessageHandler { @@ -682,27 +720,31 @@ public async Task MultipartUploadShouldWorkWithMixedTypes() Assert.Equal("theObjects", parts[0].Headers.ContentDisposition.Name); Assert.Null(parts[0].Headers.ContentDisposition.FileName); Assert.Equal("application/json", parts[0].Headers.ContentType.MediaType); - var result0 = JsonConvert.DeserializeObject(await parts[0].ReadAsStringAsync().ConfigureAwait(false)); + var result0 = JsonConvert.DeserializeObject( + await parts[0].ReadAsStringAsync().ConfigureAwait(false) + ); Assert.Equal(model1.Property1, result0.Property1); Assert.Equal(model1.Property2, result0.Property2); - Assert.Equal("theObjects", parts[1].Headers.ContentDisposition.Name); Assert.Null(parts[1].Headers.ContentDisposition.FileName); Assert.Equal("application/json", parts[1].Headers.ContentType.MediaType); - var result1 = JsonConvert.DeserializeObject(await parts[1].ReadAsStringAsync().ConfigureAwait(false)); + var result1 = JsonConvert.DeserializeObject( + await parts[1].ReadAsStringAsync().ConfigureAwait(false) + ); Assert.Equal(model2.Property1, result1.Property1); Assert.Equal(model2.Property2, result1.Property2); Assert.Equal("anotherModel", parts[2].Headers.ContentDisposition.Name); Assert.Null(parts[2].Headers.ContentDisposition.FileName); Assert.Equal("application/json", parts[2].Headers.ContentType.MediaType); - var result2 = JsonConvert.DeserializeObject(await parts[2].ReadAsStringAsync().ConfigureAwait(false)); + var result2 = JsonConvert.DeserializeObject( + await parts[2].ReadAsStringAsync().ConfigureAwait(false) + ); Assert.Equal(2, result2.Foos.Length); Assert.Equal("bar1", result2.Foos[0]); Assert.Equal("bar2", result2.Foos[1]); - Assert.Equal("aFile", parts[3].Headers.ContentDisposition.Name); Assert.Equal(name, parts[3].Headers.ContentDisposition.FileName); Assert.Null(parts[3].Headers.ContentType); @@ -715,7 +757,9 @@ public async Task MultipartUploadShouldWorkWithMixedTypes() Assert.Equal("anEnum", parts[4].Headers.ContentDisposition.Name); Assert.Null(parts[4].Headers.ContentDisposition.FileName); Assert.Equal("application/json", parts[4].Headers.ContentType.MediaType); - var result4 = JsonConvert.DeserializeObject(await parts[4].ReadAsStringAsync().ConfigureAwait(false)); + var result4 = JsonConvert.DeserializeObject( + await parts[4].ReadAsStringAsync().ConfigureAwait(false) + ); Assert.Equal(AnEnum.Val2, result4); Assert.Equal("aString", parts[5].Headers.ContentDisposition.Name); @@ -727,16 +771,14 @@ public async Task MultipartUploadShouldWorkWithMixedTypes() Assert.Equal("anInt", parts[6].Headers.ContentDisposition.Name); Assert.Null(parts[6].Headers.ContentDisposition.FileName); Assert.Equal("application/json", parts[6].Headers.ContentType.MediaType); - var result6 = JsonConvert.DeserializeObject(await parts[6].ReadAsStringAsync().ConfigureAwait(false)); + var result6 = JsonConvert.DeserializeObject( + await parts[6].ReadAsStringAsync().ConfigureAwait(false) + ); Assert.Equal(42, result6); - } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; try { @@ -747,7 +789,14 @@ public async Task MultipartUploadShouldWorkWithMixedTypes() outStream.Close(); var fixture = RestService.For(BaseAddress, settings); - var result = await fixture.UploadMixedObjects(new[] { model1, model2 }, anotherModel, new FileInfo(fileName), AnEnum.Val2, "frob", 42); + var result = await fixture.UploadMixedObjects( + new[] { model1, model2 }, + anotherModel, + new FileInfo(fileName), + AnEnum.Val2, + "frob", + 42 + ); } finally { @@ -781,10 +830,7 @@ public async Task MultipartUploadShouldWorkWithHttpContent() } }; - var settings = new RefitSettings() - { - HttpMessageHandlerFactory = () => handler - }; + var settings = new RefitSettings() { HttpMessageHandlerFactory = () => handler }; var fixture = RestService.For(BaseAddress, settings); var result = await fixture.UploadHttpContent(httpContent); @@ -816,24 +862,32 @@ internal static Stream GetTestFileStream(string relativeFilePath) var assembly = Assembly.GetCallingAssembly(); // compute resource name suffix - var relativeName = "." + relativeFilePath - .Replace('\\', namespaceSeparator) - .Replace('/', namespaceSeparator) - .Replace(' ', '_'); + var relativeName = + "." + + relativeFilePath + .Replace('\\', namespaceSeparator) + .Replace('/', namespaceSeparator) + .Replace(' ', '_'); // get resource stream var fullName = assembly .GetManifestResourceNames() - .FirstOrDefault(name => name.EndsWith(relativeName, StringComparison.InvariantCulture)); + .FirstOrDefault( + name => name.EndsWith(relativeName, StringComparison.InvariantCulture) + ); if (fullName == null) { - throw new Exception($"Unable to find resource for path \"{relativeFilePath}\". Resource with name ending on \"{relativeName}\" was not found in assembly."); + throw new Exception( + $"Unable to find resource for path \"{relativeFilePath}\". Resource with name ending on \"{relativeName}\" was not found in assembly." + ); } var stream = assembly.GetManifestResourceStream(fullName); if (stream == null) { - throw new Exception($"Unable to find resource for path \"{relativeFilePath}\". Resource named \"{fullName}\" was not found in assembly."); + throw new Exception( + $"Unable to find resource for path \"{relativeFilePath}\". Resource named \"{fullName}\" was not found in assembly." + ); } return stream; @@ -841,14 +895,11 @@ internal static Stream GetTestFileStream(string relativeFilePath) static bool StreamsEqual(Stream a, Stream b) { - if (a == null && - b == null) + if (a == null && b == null) return true; - if (a == null || - b == null) + if (a == null || b == null) { - throw new ArgumentNullException( - a == null ? "a" : "b"); + throw new ArgumentNullException(a == null ? "a" : "b"); } if (a.Length < b.Length) @@ -872,7 +923,10 @@ class MockHttpMessageHandler : HttpMessageHandler public Action RequestAsserts { get; set; } public Func Asserts { get; set; } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { RequestAsserts?.Invoke(request); var content = request.Content as MultipartFormDataContent; diff --git a/Refit.Tests/NullableReferenceTypes.cs b/Refit.Tests/NullableReferenceTypes.cs index 347fa667f..8ab2d19a6 100644 --- a/Refit.Tests/NullableReferenceTypes.cs +++ b/Refit.Tests/NullableReferenceTypes.cs @@ -96,5 +96,6 @@ interface ICustomReferenceAndValueParametersService } class CustomReferenceType { } + class CustomValueType { } } diff --git a/Refit.Tests/RequestBuilder.cs b/Refit.Tests/RequestBuilder.cs index e4737a342..88305fce5 100644 --- a/Refit.Tests/RequestBuilder.cs +++ b/Refit.Tests/RequestBuilder.cs @@ -53,138 +53,289 @@ public interface IRestMethodInfoTests Task FetchAnImage(int width, int height); [Get("/foo/bar/{id}")] - IObservable FetchSomeStuffWithBody([AliasAs("id")] int anId, [Body] Dictionary theData); + IObservable FetchSomeStuffWithBody( + [AliasAs("id")] int anId, + [Body] Dictionary theData + ); [Post("/foo/bar/{id}")] - IObservable PostSomeUrlEncodedStuff([AliasAs("id")] int anId, [Body(BodySerializationMethod.UrlEncoded)] Dictionary theData); + IObservable PostSomeUrlEncodedStuff( + [AliasAs("id")] int anId, + [Body(BodySerializationMethod.UrlEncoded)] Dictionary theData + ); [Get("/foo/bar/{id}")] - IObservable FetchSomeStuffWithAuthorizationSchemeSpecified([AliasAs("id")] int anId, [Authorize("Bearer")] string token); + IObservable FetchSomeStuffWithAuthorizationSchemeSpecified( + [AliasAs("id")] int anId, + [Authorize("Bearer")] string token + ); [Get("/foo/bar/{id}")] [Headers("Api-Version: 2", "Accept: application/json")] Task FetchSomeStuffWithHardcodedHeaders(int id); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicHeader(int id, [Header("Authorization")] string authorization); + Task FetchSomeStuffWithDynamicHeader( + int id, + [Header("Authorization")] string authorization + ); [Get("/foo")] - Task FetchSomeStuffWithDynamicHeaderQueryParamAndArrayQueryParam([Header("Authorization")] string authorization, int id, [Query(CollectionFormat.Multi)] string[] someArray, [Property("SomeProperty")] object someValue); + Task FetchSomeStuffWithDynamicHeaderQueryParamAndArrayQueryParam( + [Header("Authorization")] string authorization, + int id, + [Query(CollectionFormat.Multi)] string[] someArray, + [Property("SomeProperty")] object someValue + ); #region [HeaderCollection] interface methods [Get("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task FetchSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task FetchSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithCustomHeaderCollection(int id, [Body] object body, [HeaderCollection] IDictionary headers); + Task PutSomeStuffWithCustomHeaderCollection( + int id, + [Body] object body, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithCustomHeaderCollection(int id, [Body] object body, [HeaderCollection] IDictionary headers); + Task PostSomeStuffWithCustomHeaderCollection( + int id, + [Body] object body, + [HeaderCollection] IDictionary headers + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithCustomHeaderCollection(int id, [Body] object body, [HeaderCollection] IDictionary headers); + Task PatchSomeStuffWithCustomHeaderCollection( + int id, + [Body] object body, + [HeaderCollection] IDictionary headers + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithoutBodyAndCustomHeaderCollection(int id, [HeaderCollection] IDictionary headers); + Task PutSomeStuffWithoutBodyAndCustomHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithoutBodyAndCustomHeaderCollection(int id, [HeaderCollection] IDictionary headers); + Task PostSomeStuffWithoutBodyAndCustomHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithoutBodyAndCustomHeaderCollection(int id, [HeaderCollection] IDictionary headers); + Task PatchSomeStuffWithoutBodyAndCustomHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithInferredBodyAndWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers, object inferredBody); + Task PutSomeStuffWithInferredBodyAndWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers, + object inferredBody + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithInferredBodyAndWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers, object inferredBody); + Task PostSomeStuffWithInferredBodyAndWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers, + object inferredBody + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithInferredBodyAndWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers, object inferredBody); + Task PatchSomeStuffWithInferredBodyAndWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers, + object inferredBody + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicHeaderCollectionAndAuthorize(int id, [Authorize] string value, [HeaderCollection] IDictionary headers); + Task FetchSomeStuffWithDynamicHeaderCollectionAndAuthorize( + int id, + [Authorize] string value, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithDynamicHeaderCollectionAndAuthorize(int id, [Authorize] string value, [HeaderCollection] IDictionary headers); + Task PostSomeStuffWithDynamicHeaderCollectionAndAuthorize( + int id, + [Authorize] string value, + [HeaderCollection] IDictionary headers + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader(int id, [Header("Authorization")] string value, [HeaderCollection] IDictionary headers); + Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader( + int id, + [Header("Authorization")] string value, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithDynamicHeaderCollectionAndDynamicHeader(int id, [Header("Authorization")] string value, [HeaderCollection] IDictionary headers); + Task PostSomeStuffWithDynamicHeaderCollectionAndDynamicHeader( + int id, + [Header("Authorization")] string value, + [HeaderCollection] IDictionary headers + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped(int id, [HeaderCollection] IDictionary headers, [Header("Authorization")] string value); + Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped( + int id, + [HeaderCollection] IDictionary headers, + [Header("Authorization")] string value + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection([Header("X-PathMember")] int id, [HeaderCollection] IDictionary headers); + Task FetchSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection( + [Header("X-PathMember")] int id, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection([Header("X-PathMember")] int id, [HeaderCollection] IDictionary headers); + Task PostSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection( + [Header("X-PathMember")] int id, + [HeaderCollection] IDictionary headers + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithHeaderCollection(int id, [HeaderCollection] IDictionary headers, int baz); + Task FetchSomeStuffWithHeaderCollection( + int id, + [HeaderCollection] IDictionary headers, + int baz + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithHeaderCollection(int id, [HeaderCollection] IDictionary headers, int baz); + Task PostSomeStuffWithHeaderCollection( + int id, + [HeaderCollection] IDictionary headers, + int baz + ); [Get("/foo/bar")] - Task FetchSomeStuffWithDuplicateHeaderCollection([HeaderCollection] IDictionary headers, [HeaderCollection] IDictionary headers2); + Task FetchSomeStuffWithDuplicateHeaderCollection( + [HeaderCollection] IDictionary headers, + [HeaderCollection] IDictionary headers2 + ); [Post("/foo/bar")] - Task PostSomeStuffWithDuplicateHeaderCollection([HeaderCollection] IDictionary headers, [HeaderCollection] IDictionary headers2); + Task PostSomeStuffWithDuplicateHeaderCollection( + [HeaderCollection] IDictionary headers, + [HeaderCollection] IDictionary headers2 + ); [Get("/foo")] - Task FetchSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam([HeaderCollection] IDictionary headers, int id, [Query(CollectionFormat.Multi)] string[] someArray, [Property("SomeProperty")] object someValue); + Task FetchSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam( + [HeaderCollection] IDictionary headers, + int id, + [Query(CollectionFormat.Multi)] string[] someArray, + [Property("SomeProperty")] object someValue + ); [Post("/foo")] - Task PostSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam([HeaderCollection] IDictionary headers, int id, [Query(CollectionFormat.Multi)] string[] someArray, [Property("SomeProperty")] object someValue); + Task PostSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam( + [HeaderCollection] IDictionary headers, + int id, + [Query(CollectionFormat.Multi)] string[] someArray, + [Property("SomeProperty")] object someValue + ); [Get("/foo")] - Task FetchSomeStuffWithHeaderCollectionOfUnsupportedType([HeaderCollection] string headers); + Task FetchSomeStuffWithHeaderCollectionOfUnsupportedType( + [HeaderCollection] string headers + ); [Post("/foo")] - Task PostSomeStuffWithHeaderCollectionOfUnsupportedType([HeaderCollection] string headers); + Task PostSomeStuffWithHeaderCollectionOfUnsupportedType( + [HeaderCollection] string headers + ); #endregion #region [Property] interface methods [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue); + Task FetchSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithDynamicRequestProperty(int id, [Body] object body, [Property("SomeProperty")] object someValue); + Task PostSomeStuffWithDynamicRequestProperty( + int id, + [Body] object body, + [Property("SomeProperty")] object someValue + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithDynamicRequestProperties(int id, [Body] object body, [Property("SomeProperty")] object someValue, [Property("SomeOtherProperty")] object someOtherValue); + Task PostSomeStuffWithDynamicRequestProperties( + int id, + [Body] object body, + [Property("SomeProperty")] object someValue, + [Property("SomeOtherProperty")] object someOtherValue + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithoutBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue); + Task PutSomeStuffWithoutBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithoutBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue); + Task PostSomeStuffWithoutBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithoutBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue); + Task PatchSomeStuffWithoutBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithInferredBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue, object inferredBody); + Task PutSomeStuffWithInferredBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue, + object inferredBody + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithInferredBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue, object inferredBody); + Task PostSomeStuffWithInferredBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue, + object inferredBody + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithInferredBodyAndWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someValue, object inferredBody); + Task PatchSomeStuffWithInferredBodyAndWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someValue, + object inferredBody + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey(int id, [Property("SomeProperty")] object someValue1, [Property("SomeProperty")] object someValue2); + Task FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey( + int id, + [Property("SomeProperty")] object someValue1, + [Property("SomeProperty")] object someValue2 + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestPropertyWithoutKey(int id, [Property] object someValue, [Property("")] object someOtherValue); + Task FetchSomeStuffWithDynamicRequestPropertyWithoutKey( + int id, + [Property] object someValue, + [Property("")] object someOtherValue + ); #endregion @@ -231,7 +382,10 @@ public interface IRestMethodInfoTests Task TooManyComplexTypes(Dictionary theData, Dictionary theData1); [Post("/foo")] - Task ManyComplexTypes(Dictionary theData, [Body] Dictionary theData1); + Task ManyComplexTypes( + Dictionary theData, + [Body] Dictionary theData1 + ); [Post("/foo")] Task PostWithDictionaryQuery([Query] Dictionary theData); @@ -240,22 +394,40 @@ public interface IRestMethodInfoTests Task PostWithComplexTypeQuery([Query] ComplexQueryObject queryParams); [Post("/foo")] - Task ImpliedComplexQueryType(ComplexQueryObject queryParams, [Body] Dictionary theData1); + Task ImpliedComplexQueryType( + ComplexQueryObject queryParams, + [Body] Dictionary theData1 + ); [Get("/api/{id}")] - Task MultipleQueryAttributes(int id, [Query] string text = null, [Query] int? optionalId = null, [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null); + Task MultipleQueryAttributes( + int id, + [Query] string text = null, + [Query] int? optionalId = null, + [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null + ); [Get("/api/{id}")] - Task NullableValues(int id, string text = null, int? optionalId = null, [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null); + Task NullableValues( + int id, + string text = null, + int? optionalId = null, + [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null + ); [Get("/api/{id}")] Task IEnumerableThrowingError([Query(CollectionFormat.Multi)] IEnumerable values); - + [Get("/foo")] List InvalidGenericReturnType(); } - public enum TestEnum { A, B, C } + public enum TestEnum + { + A, + B, + C + } public class ComplexQueryObject { @@ -297,16 +469,23 @@ public void TooManyComplexTypesThrows() { var fixture = new RestMethodInfoInternal( input, - input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.TooManyComplexTypes))); + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.TooManyComplexTypes)) + ); }); - } [Fact] public void ManyComplexTypes() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.ManyComplexTypes))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.ManyComplexTypes)) + ); Assert.Single(fixture.QueryParameterMap); Assert.NotNull(fixture.BodyParameterInfo); @@ -320,7 +499,10 @@ public void ManyComplexTypes() public void DefaultBodyParameterDetected(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Empty(fixture.QueryParameterMap); Assert.NotNull(fixture.BodyParameterInfo); @@ -330,7 +512,12 @@ public void DefaultBodyParameterDetected(string interfaceMethodName) public void DefaultBodyParameterNotDetectedForGet() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.GetWithBodyDetected))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.GetWithBodyDetected)) + ); Assert.Single(fixture.QueryParameterMap); Assert.Null(fixture.BodyParameterInfo); @@ -340,7 +527,12 @@ public void DefaultBodyParameterNotDetectedForGet() public void PostWithDictionaryQueryParameter() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostWithDictionaryQuery))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PostWithDictionaryQuery)) + ); Assert.Single(fixture.QueryParameterMap); Assert.Null(fixture.BodyParameterInfo); @@ -350,7 +542,12 @@ public void PostWithDictionaryQueryParameter() public void PostWithObjectQueryParameterHasSingleQueryParameterValue() { var input = typeof(IRestMethodInfoTests); - var fixtureParams = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostWithComplexTypeQuery))); + var fixtureParams = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PostWithComplexTypeQuery)) + ); Assert.Single(fixtureParams.QueryParameterMap); Assert.Equal("queryParams", fixtureParams.QueryParameterMap[0]); @@ -362,13 +559,11 @@ public void PostWithObjectQueryParameterHasCorrectQuerystring() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.PostWithComplexTypeQuery)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.PostWithComplexTypeQuery) + ); - var param = new ComplexQueryObject - { - TestAlias1 = "one", - TestAlias2 = "two" - }; + var param = new ComplexQueryObject { TestAlias1 = "one", TestAlias2 = "two" }; var output = factory(new object[] { param }); @@ -382,7 +577,9 @@ public void PostWithObjectQueryParameterWithEnumList_Multi() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.PostWithComplexTypeQuery)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.PostWithComplexTypeQuery) + ); var param = new ComplexQueryObject { @@ -391,7 +588,10 @@ public void PostWithObjectQueryParameterWithEnumList_Multi() var output = factory(new object[] { param }); - Assert.Equal("/foo?listOfEnumMulti=A&listOfEnumMulti=B", output.RequestUri.PathAndQuery); + Assert.Equal( + "/foo?listOfEnumMulti=A&listOfEnumMulti=B", + output.RequestUri.PathAndQuery + ); } [Fact] @@ -399,7 +599,9 @@ public void PostWithObjectQueryParameterWithObjectListWithProvidedEnumValues_Mul { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.PostWithComplexTypeQuery)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.PostWithComplexTypeQuery) + ); var param = new ComplexQueryObject { @@ -408,7 +610,10 @@ public void PostWithObjectQueryParameterWithObjectListWithProvidedEnumValues_Mul var output = factory(new object[] { param }); - Assert.Equal("/foo?ObjectCollectionMulti=A&ObjectCollectionMulti=B", output.RequestUri.PathAndQuery); + Assert.Equal( + "/foo?ObjectCollectionMulti=A&ObjectCollectionMulti=B", + output.RequestUri.PathAndQuery + ); } [Fact] @@ -416,7 +621,9 @@ public void PostWithObjectQueryParameterWithEnumList_Csv() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.PostWithComplexTypeQuery)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.PostWithComplexTypeQuery) + ); var param = new ComplexQueryObject { @@ -433,7 +640,9 @@ public void PostWithObjectQueryParameterWithObjectListWithProvidedEnumValues_Csv { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.PostWithComplexTypeQuery)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.PostWithComplexTypeQuery) + ); var param = new ComplexQueryObject { @@ -449,7 +658,9 @@ public void PostWithObjectQueryParameterWithObjectListWithProvidedEnumValues_Csv public void ObjectQueryParameterWithInnerCollectionHasCorrectQuerystring() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.ComplexTypeQueryWithInnerCollection)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.ComplexTypeQueryWithInnerCollection) + ); var param = new ComplexQueryObject { TestCollection = new[] { 1, 2, 3 } }; var output = factory(new object[] { param }); @@ -462,7 +673,12 @@ public void ObjectQueryParameterWithInnerCollectionHasCorrectQuerystring() public void MultipleQueryAttributesWithNulls() { var input = typeof(IRestMethodInfoTests); - var fixtureParams = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.MultipleQueryAttributes))); + var fixtureParams = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.MultipleQueryAttributes)) + ); Assert.Equal(3, fixtureParams.QueryParameterMap.Count); } @@ -475,7 +691,12 @@ public void GarbagePathsShouldThrow() try { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.GarbagePath))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.GarbagePath)) + ); } catch (ArgumentException) { @@ -493,7 +714,16 @@ public void MissingParametersShouldBlowUp() try { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffMissingParameters))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.FetchSomeStuffMissingParameters) + ) + ); } catch (ArgumentException) { @@ -507,18 +737,26 @@ public void MissingParametersShouldBlowUp() public void ParameterMappingSmokeTest() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuff))); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuff)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); Assert.Null(fixture.BodyParameterInfo); } - + [Fact] public void ParameterMappingWithTheSameIdInAFewPlaces() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithTheSameId))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithTheSameId)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -529,19 +767,38 @@ public void ParameterMappingWithTheSameIdInAFewPlaces() public void ParameterMappingWithTheSameIdInTheQueryParameter() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithTheIdInAParameterMultipleTimes))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithTheIdInAParameterMultipleTimes + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); Assert.Null(fixture.BodyParameterInfo); } - [Fact] public void ParameterMappingWithRoundTrippingSmokeTest() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithRoundTrippingParam))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.FetchSomeStuffWithRoundTrippingParam) + ) + ); Assert.Equal("path", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.RoundTripping, fixture.ParameterMap[0].Type); Assert.Equal("id", fixture.ParameterMap[1].Name); @@ -558,8 +815,16 @@ public void ParameterMappingWithNonStringRoundTrippingShouldThrow() { var fixture = new RestMethodInfoInternal( input, - input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithNonStringRoundTrippingParam)) - ); + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithNonStringRoundTrippingParam + ) + ) + ); }); } @@ -567,7 +832,12 @@ public void ParameterMappingWithNonStringRoundTrippingShouldThrow() public void ParameterMappingWithQuerySmokeTest() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithQueryParam))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithQueryParam)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Equal("search", fixture.QueryParameterMap[1]); @@ -578,7 +848,16 @@ public void ParameterMappingWithQuerySmokeTest() public void ParameterMappingWithHardcodedQuerySmokeTest() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithHardcodedQueryParam))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.FetchSomeStuffWithHardcodedQueryParam) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -589,7 +868,12 @@ public void ParameterMappingWithHardcodedQuerySmokeTest() public void AliasMappingShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithAlias))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithAlias)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -600,7 +884,10 @@ public void AliasMappingShouldWork() public void MultipleParametersPerSegmentShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchAnImage))); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchAnImage)) + ); Assert.Equal("width", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Equal("height", fixture.ParameterMap[1].Name); @@ -613,7 +900,12 @@ public void MultipleParametersPerSegmentShouldWork() public void FindTheBodyParameter() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithBody))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithBody)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); @@ -626,7 +918,18 @@ public void FindTheBodyParameter() public void FindTheAuthorizeParameter() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithAuthorizationSchemeSpecified))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithAuthorizationSchemeSpecified + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); @@ -639,7 +942,12 @@ public void FindTheAuthorizeParameter() public void AllowUrlEncodedContent() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostSomeUrlEncodedStuff))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PostSomeUrlEncodedStuff)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); @@ -652,15 +960,30 @@ public void AllowUrlEncodedContent() public void HardcodedHeadersShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithHardcodedHeaders))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.FetchSomeStuffWithHardcodedHeaders) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); Assert.Null(fixture.BodyParameterInfo); - Assert.True(fixture.Headers.ContainsKey("Api-Version"), "Headers include Api-Version header"); + Assert.True( + fixture.Headers.ContainsKey("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("2", fixture.Headers["Api-Version"]); - Assert.True(fixture.Headers.ContainsKey("User-Agent"), "Headers include User-Agent header"); + Assert.True( + fixture.Headers.ContainsKey("User-Agent"), + "Headers include User-Agent header" + ); Assert.Equal("RefitTestClient", fixture.Headers["User-Agent"]); Assert.True(fixture.Headers.ContainsKey("Accept"), "Headers include Accept header"); Assert.Equal("application/json", fixture.Headers["Accept"]); @@ -671,7 +994,14 @@ public void HardcodedHeadersShouldWork() public void DynamicHeadersShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeader))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeader) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -679,7 +1009,10 @@ public void DynamicHeadersShouldWork() Assert.Null(fixture.BodyParameterInfo); Assert.Equal("Authorization", fixture.HeaderParameterMap[1]); - Assert.True(fixture.Headers.ContainsKey("User-Agent"), "Headers include User-Agent header"); + Assert.True( + fixture.Headers.ContainsKey("User-Agent"), + "Headers include User-Agent header" + ); Assert.Equal("RefitTestClient", fixture.Headers["User-Agent"]); Assert.Equal(2, fixture.Headers.Count); } @@ -690,7 +1023,18 @@ public void DynamicHeadersShouldWork() public void DynamicHeaderCollectionShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollection))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollection + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -698,13 +1042,25 @@ public void DynamicHeaderCollectionShouldWork() Assert.Empty(fixture.PropertyParameterMap); Assert.Null(fixture.BodyParameterInfo); - Assert.True(fixture.Headers.ContainsKey("Authorization"), "Headers include Authorization header"); - Assert.Equal("SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", fixture.Headers["Authorization"]); + Assert.True( + fixture.Headers.ContainsKey("Authorization"), + "Headers include Authorization header" + ); + Assert.Equal( + "SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + fixture.Headers["Authorization"] + ); Assert.True(fixture.Headers.ContainsKey("Accept"), "Headers include Accept header"); Assert.Equal("application/json", fixture.Headers["Accept"]); - Assert.True(fixture.Headers.ContainsKey("User-Agent"), "Headers include User-Agent header"); + Assert.True( + fixture.Headers.ContainsKey("User-Agent"), + "Headers include User-Agent header" + ); Assert.Equal("RefitTestClient", fixture.Headers["User-Agent"]); - Assert.True(fixture.Headers.ContainsKey("Api-Version"), "Headers include Api-Version header"); + Assert.True( + fixture.Headers.ContainsKey("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("1", fixture.Headers["Api-Version"]); Assert.Equal(4, fixture.Headers.Count); @@ -719,7 +1075,10 @@ public void DynamicHeaderCollectionShouldWork() public void DynamicHeaderCollectionShouldWorkWithBody(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -735,11 +1094,16 @@ public void DynamicHeaderCollectionShouldWorkWithBody(string interfaceMethodName [Theory] [InlineData(nameof(IRestMethodInfoTests.PutSomeStuffWithoutBodyAndCustomHeaderCollection))] [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithoutBodyAndCustomHeaderCollection))] - [InlineData(nameof(IRestMethodInfoTests.PatchSomeStuffWithoutBodyAndCustomHeaderCollection))] + [InlineData( + nameof(IRestMethodInfoTests.PatchSomeStuffWithoutBodyAndCustomHeaderCollection) + )] public void DynamicHeaderCollectionShouldWorkWithoutBody(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -753,13 +1117,24 @@ public void DynamicHeaderCollectionShouldWorkWithoutBody(string interfaceMethodN } [Theory] - [InlineData(nameof(IRestMethodInfoTests.PutSomeStuffWithInferredBodyAndWithDynamicHeaderCollection))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithInferredBodyAndWithDynamicHeaderCollection))] - [InlineData(nameof(IRestMethodInfoTests.PatchSomeStuffWithInferredBodyAndWithDynamicHeaderCollection))] + [InlineData( + nameof(IRestMethodInfoTests.PutSomeStuffWithInferredBodyAndWithDynamicHeaderCollection) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithInferredBodyAndWithDynamicHeaderCollection) + )] + [InlineData( + nameof( + IRestMethodInfoTests.PatchSomeStuffWithInferredBodyAndWithDynamicHeaderCollection + ) + )] public void DynamicHeaderCollectionShouldWorkWithInferredBody(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -774,12 +1149,19 @@ public void DynamicHeaderCollectionShouldWorkWithInferredBody(string interfaceMe } [Theory] - [InlineData(nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndAuthorize))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicHeaderCollectionAndAuthorize))] + [InlineData( + nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndAuthorize) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicHeaderCollectionAndAuthorize) + )] public void DynamicHeaderCollectionShouldWorkWithAuthorize(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -793,12 +1175,19 @@ public void DynamicHeaderCollectionShouldWorkWithAuthorize(string interfaceMetho } [Theory] - [InlineData(nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicHeaderCollectionAndDynamicHeader))] + [InlineData( + nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicHeaderCollectionAndDynamicHeader) + )] public void DynamicHeaderCollectionShouldWorkWithDynamicHeader(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -812,7 +1201,18 @@ public void DynamicHeaderCollectionShouldWorkWithDynamicHeader(string interfaceM Assert.True(fixture.HeaderCollectionParameterMap.Contains(2)); input = typeof(IRestMethodInfoTests); - fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped))); + fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -827,12 +1227,25 @@ public void DynamicHeaderCollectionShouldWorkWithDynamicHeader(string interfaceM } [Theory] - [InlineData(nameof(IRestMethodInfoTests.FetchSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection))] - public void DynamicHeaderCollectionShouldWorkWithPathMemberDynamicHeader(string interfaceMethodName) + [InlineData( + nameof( + IRestMethodInfoTests.FetchSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection + ) + )] + [InlineData( + nameof( + IRestMethodInfoTests.PostSomeStuffWithPathMemberInCustomHeaderAndDynamicHeaderCollection + ) + )] + public void DynamicHeaderCollectionShouldWorkWithPathMemberDynamicHeader( + string interfaceMethodName + ) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -852,7 +1265,10 @@ public void DynamicHeaderCollectionShouldWorkWithPathMemberDynamicHeader(string public void DynamicHeaderCollectionInMiddleOfParamsShouldWork(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Null(fixture.AuthorizeParameterInfo); @@ -871,16 +1287,33 @@ public void DynamicHeaderCollectionShouldOnlyAllowOne(string interfaceMethodName { var input = typeof(IRestMethodInfoTests); - Assert.Throws(() => new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName))); + Assert.Throws( + () => + new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ) + ); } [Theory] - [InlineData(nameof(IRestMethodInfoTests.FetchSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam))] + [InlineData( + nameof( + IRestMethodInfoTests.FetchSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam + ) + )] + [InlineData( + nameof( + IRestMethodInfoTests.PostSomeStuffWithHeaderCollectionQueryParamAndArrayQueryParam + ) + )] public void DynamicHeaderCollectionShouldWorkWithProperty(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Null(fixture.BodyParameterInfo); Assert.Null(fixture.AuthorizeParameterInfo); @@ -895,12 +1328,24 @@ public void DynamicHeaderCollectionShouldWorkWithProperty(string interfaceMethod } [Theory] - [InlineData(nameof(IRestMethodInfoTests.FetchSomeStuffWithHeaderCollectionOfUnsupportedType))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithHeaderCollectionOfUnsupportedType))] - public void DynamicHeaderCollectionShouldOnlyWorkWithSupportedSemantics(string interfaceMethodName) + [InlineData( + nameof(IRestMethodInfoTests.FetchSomeStuffWithHeaderCollectionOfUnsupportedType) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithHeaderCollectionOfUnsupportedType) + )] + public void DynamicHeaderCollectionShouldOnlyWorkWithSupportedSemantics( + string interfaceMethodName + ) { var input = typeof(IRestMethodInfoTests); - Assert.Throws(() => new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName))); + Assert.Throws( + () => + new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ) + ); } #endregion @@ -911,7 +1356,16 @@ public void DynamicHeaderCollectionShouldOnlyWorkWithSupportedSemantics(string i public void DynamicRequestPropertiesShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestProperty))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestProperty) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -925,7 +1379,16 @@ public void DynamicRequestPropertiesShouldWork() public void DynamicRequestPropertyShouldWorkWithBody() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicRequestProperty))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicRequestProperty) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -941,7 +1404,18 @@ public void DynamicRequestPropertyShouldWorkWithBody() public void DynamicRequestPropertiesShouldWorkWithBody() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostSomeStuffWithDynamicRequestProperties))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.PostSomeStuffWithDynamicRequestProperties + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -954,15 +1428,23 @@ public void DynamicRequestPropertiesShouldWorkWithBody() Assert.Equal("SomeOtherProperty", fixture.PropertyParameterMap[3]); } - [Theory] - [InlineData(nameof(IRestMethodInfoTests.PutSomeStuffWithoutBodyAndWithDynamicRequestProperty))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithoutBodyAndWithDynamicRequestProperty))] - [InlineData(nameof(IRestMethodInfoTests.PatchSomeStuffWithoutBodyAndWithDynamicRequestProperty))] + [InlineData( + nameof(IRestMethodInfoTests.PutSomeStuffWithoutBodyAndWithDynamicRequestProperty) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithoutBodyAndWithDynamicRequestProperty) + )] + [InlineData( + nameof(IRestMethodInfoTests.PatchSomeStuffWithoutBodyAndWithDynamicRequestProperty) + )] public void DynamicRequestPropertyShouldWorkWithoutBody(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -975,13 +1457,22 @@ public void DynamicRequestPropertyShouldWorkWithoutBody(string interfaceMethodNa } [Theory] - [InlineData(nameof(IRestMethodInfoTests.PutSomeStuffWithInferredBodyAndWithDynamicRequestProperty))] - [InlineData(nameof(IRestMethodInfoTests.PostSomeStuffWithInferredBodyAndWithDynamicRequestProperty))] - [InlineData(nameof(IRestMethodInfoTests.PatchSomeStuffWithInferredBodyAndWithDynamicRequestProperty))] + [InlineData( + nameof(IRestMethodInfoTests.PutSomeStuffWithInferredBodyAndWithDynamicRequestProperty) + )] + [InlineData( + nameof(IRestMethodInfoTests.PostSomeStuffWithInferredBodyAndWithDynamicRequestProperty) + )] + [InlineData( + nameof(IRestMethodInfoTests.PatchSomeStuffWithInferredBodyAndWithDynamicRequestProperty) + )] public void DynamicRequestPropertyShouldWorkWithInferredBody(string interfaceMethodName) { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == interfaceMethodName)); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == interfaceMethodName) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -998,7 +1489,18 @@ public void DynamicRequestPropertyShouldWorkWithInferredBody(string interfaceMet public void DynamicRequestPropertiesWithoutKeysShouldDefaultKeyToParameterName() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestPropertyWithoutKey))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestPropertyWithoutKey + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -1013,7 +1515,18 @@ public void DynamicRequestPropertiesWithoutKeysShouldDefaultKeyToParameterName() public void DynamicRequestPropertiesWithDuplicateKeysDontBlowUp() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey + ) + ) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -1030,7 +1543,12 @@ public void DynamicRequestPropertiesWithDuplicateKeysDontBlowUp() public void ValueTypesDontBlowUpBuffered() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.OhYeahValueTypes))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.OhYeahValueTypes)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -1045,7 +1563,12 @@ public void ValueTypesDontBlowUpBuffered() public void ValueTypesDontBlowUpUnBuffered() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.OhYeahValueTypesUnbuffered))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.OhYeahValueTypesUnbuffered)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -1060,7 +1583,12 @@ public void ValueTypesDontBlowUpUnBuffered() public void StreamMethodPullWorks() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PullStreamMethod))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PullStreamMethod)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); Assert.Empty(fixture.QueryParameterMap); @@ -1075,7 +1603,10 @@ public void StreamMethodPullWorks() public void ReturningTaskShouldWork() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.VoidPost))); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.VoidPost)) + ); Assert.Equal("id", fixture.ParameterMap[0].Name); Assert.Equal(ParameterType.Normal, fixture.ParameterMap[0].Type); @@ -1091,7 +1622,12 @@ public void SyncMethodsShouldThrow() try { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.AsyncOnlyBuddy))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.AsyncOnlyBuddy)) + ); } catch (ArgumentException) { @@ -1105,7 +1641,10 @@ public void SyncMethodsShouldThrow() public void UsingThePatchAttributeSetsTheCorrectMethod() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PatchSomething))); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PatchSomething)) + ); Assert.Equal("PATCH", fixture.HttpMethod.Method); } @@ -1114,7 +1653,10 @@ public void UsingThePatchAttributeSetsTheCorrectMethod() public void UsingOptionsAttribute() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IDummyHttpApi.SendOptions))); + var fixture = new RestMethodInfoInternal( + input, + input.GetMethods().First(x => x.Name == nameof(IDummyHttpApi.SendOptions)) + ); Assert.Equal("OPTIONS", fixture.HttpMethod.Method); } @@ -1123,7 +1665,12 @@ public void UsingOptionsAttribute() public void ApiResponseShouldBeSet() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostReturnsApiResponse))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PostReturnsApiResponse)) + ); Assert.True(fixture.IsApiResponse); } @@ -1132,7 +1679,12 @@ public void ApiResponseShouldBeSet() public void ApiResponseShouldNotBeSet() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.PostReturnsNonApiResponse))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First(x => x.Name == nameof(IRestMethodInfoTests.PostReturnsNonApiResponse)) + ); Assert.False(fixture.IsApiResponse); } @@ -1141,20 +1693,40 @@ public void ApiResponseShouldNotBeSet() public void ParameterMappingWithHeaderQueryParamAndQueryArrayParam() { var input = typeof(IRestMethodInfoTests); - var fixture = new RestMethodInfoInternal(input, input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderQueryParamAndArrayQueryParam))); + var fixture = new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => + x.Name + == nameof( + IRestMethodInfoTests.FetchSomeStuffWithDynamicHeaderQueryParamAndArrayQueryParam + ) + ) + ); Assert.Equal("GET", fixture.HttpMethod.Method); Assert.Equal(2, fixture.QueryParameterMap.Count); Assert.Single(fixture.HeaderParameterMap); Assert.Single(fixture.PropertyParameterMap); } - + [Fact] public void GenericReturnTypeIsNotTaskOrObservableShouldThrow() { var input = typeof(IRestMethodInfoTests); - Assert.Throws(() => new RestMethodInfoInternal(input, - input.GetMethods().First(x => x.Name == nameof(IRestMethodInfoTests.InvalidGenericReturnType)))); + Assert.Throws( + () => + new RestMethodInfoInternal( + input, + input + .GetMethods() + .First( + x => x.Name == nameof(IRestMethodInfoTests.InvalidGenericReturnType) + ) + ) + ); } } @@ -1174,7 +1746,10 @@ public interface IDummyHttpApi Task FetchSomeStuffWithHardcodedQueryParameter(int id); [Get("/foo/bar/{id}?baz=bamf")] - Task FetchSomeStuffWithHardcodedAndOtherQueryParameters(int id, [AliasAs("search_for")] string searchQuery); + Task FetchSomeStuffWithHardcodedAndOtherQueryParameters( + int id, + [AliasAs("search_for")] string searchQuery + ); [Get("/{id}/{width}x{height}/foo")] Task FetchSomethingWithMultipleParametersPerSegment(int id, int width, int height); @@ -1203,65 +1778,136 @@ public interface IDummyHttpApi [Get("/foo/bar/{id}")] [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==")] - Task FetchSomeStuffWithDynamicHeader(int id, [Header("Authorization")] string authorization); + Task FetchSomeStuffWithDynamicHeader( + int id, + [Header("Authorization")] string authorization + ); [Get("/foo/bar/{id}")] Task FetchSomeStuffWithCustomHeader(int id, [Header("X-Emoji")] string custom); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithPathMemberInCustomHeader([Header("X-PathMember")] int id, [Header("X-Emoji")] string custom); + Task FetchSomeStuffWithPathMemberInCustomHeader( + [Header("X-PathMember")] int id, + [Header("X-Emoji")] string custom + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithCustomHeader(int id, [Body] object body, [Header("X-Emoji")] string emoji); + Task PostSomeStuffWithCustomHeader( + int id, + [Body] object body, + [Header("X-Emoji")] string emoji + ); [Get("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task FetchSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task FetchSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Delete("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task DeleteSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task DeleteSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Put("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task PutSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task PutSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Post("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task PostSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task PostSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Patch("/foo/bar/{id}")] - [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", "Accept: application/json")] - Task PatchSomeStuffWithDynamicHeaderCollection(int id, [HeaderCollection] IDictionary headers); + [Headers( + "Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + "Accept: application/json" + )] + Task PatchSomeStuffWithDynamicHeaderCollection( + int id, + [HeaderCollection] IDictionary headers + ); [Get("/foo/bar/{id}")] [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==")] - Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader(int id, [Header("Authorization")] string value, [HeaderCollection] IDictionary headers); + Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader( + int id, + [Header("Authorization")] string value, + [HeaderCollection] IDictionary headers + ); [Get("/foo/bar/{id}")] [Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==")] - Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped(int id, [HeaderCollection] IDictionary headers, [Header("Authorization")] string value); + Task FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped( + int id, + [HeaderCollection] IDictionary headers, + [Header("Authorization")] string value + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someProperty); + Task FetchSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someProperty + ); [Delete("/foo/bar/{id}")] - Task DeleteSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someProperty); + Task DeleteSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someProperty + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someProperty); + Task PutSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someProperty + ); [Post("/foo/bar/{id}")] - Task PostSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someProperty); + Task PostSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someProperty + ); [Patch("/foo/bar/{id}")] - Task PatchSomeStuffWithDynamicRequestProperty(int id, [Property("SomeProperty")] object someProperty); + Task PatchSomeStuffWithDynamicRequestProperty( + int id, + [Property("SomeProperty")] object someProperty + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey(int id, [Property("SomeProperty")] object someValue1, [Property("SomeProperty")] object someValue2); + Task FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey( + int id, + [Property("SomeProperty")] object someValue1, + [Property("SomeProperty")] object someValue2 + ); [Get("/foo/bar/{id}")] - Task FetchSomeStuffWithDynamicRequestPropertyWithoutKey(int id, [Property] object someValue, [Property("")] object someOtherValue); + Task FetchSomeStuffWithDynamicRequestPropertyWithoutKey( + int id, + [Property] object someValue, + [Property("")] object someOtherValue + ); [Get("/string")] Task FetchSomeStuffWithoutFullPath(); @@ -1270,24 +1916,42 @@ public interface IDummyHttpApi Task FetchSomeStuffWithVoid(); [Get("/void/{id}/path")] - Task FetchSomeStuffWithVoidAndQueryAlias(string id, [AliasAs("a")] string valueA, [AliasAs("b")] string valueB); + Task FetchSomeStuffWithVoidAndQueryAlias( + string id, + [AliasAs("a")] string valueA, + [AliasAs("b")] string valueB + ); [Get("/foo")] Task FetchSomeStuffWithNonFormattableQueryParams(bool b, char c); [Post("/foo/bar/{id}")] - Task PostSomeUrlEncodedStuff(int id, [Body(BodySerializationMethod.UrlEncoded)] object content); + Task PostSomeUrlEncodedStuff( + int id, + [Body(BodySerializationMethod.UrlEncoded)] object content + ); [Post("/foo/bar/{id}")] - Task PostSomeAliasedUrlEncodedStuff(int id, [Body(BodySerializationMethod.UrlEncoded)] SomeRequestData content); + Task PostSomeAliasedUrlEncodedStuff( + int id, + [Body(BodySerializationMethod.UrlEncoded)] SomeRequestData content + ); string SomeOtherMethod(); [Put("/foo/bar/{id}")] - Task PutSomeContentWithAuthorization(int id, [Body] object content, [Header("Authorization")] string authorization); + Task PutSomeContentWithAuthorization( + int id, + [Body] object content, + [Header("Authorization")] string authorization + ); [Put("/foo/bar/{id}")] - Task PutSomeStuffWithDynamicContentType(int id, [Body] string content, [Header("Content-Type")] string contentType); + Task PutSomeStuffWithDynamicContentType( + int id, + [Body] string content, + [Header("Content-Type")] string contentType + ); [Post("/foo/bar/{id}")] Task PostAValueType(int id, [Body] Guid? content); @@ -1304,7 +1968,6 @@ public interface IDummyHttpApi [Get("/query")] Task QueryWithEnumerable(IEnumerable numbers); - [Get("/query")] Task QueryWithArray(int[] numbers); @@ -1333,25 +1996,37 @@ public interface IDummyHttpApi Task QueryWithDictionaryWithEnumKey([Query] IDictionary query); [Get("/foo")] - Task QueryWithDictionaryWithPrefix([Query(".", "dictionary")] IDictionary query); + Task QueryWithDictionaryWithPrefix( + [Query(".", "dictionary")] IDictionary query + ); [Get("/foo")] Task QueryWithDictionaryWithNumericKey([Query] IDictionary query); [Get("/query")] - Task QueryWithEnumerableFormattedAsMulti([Query(CollectionFormat.Multi)] IEnumerable lines); + Task QueryWithEnumerableFormattedAsMulti( + [Query(CollectionFormat.Multi)] IEnumerable lines + ); [Get("/query")] - Task QueryWithEnumerableFormattedAsCsv([Query(CollectionFormat.Csv)] IEnumerable lines); + Task QueryWithEnumerableFormattedAsCsv( + [Query(CollectionFormat.Csv)] IEnumerable lines + ); [Get("/query")] - Task QueryWithEnumerableFormattedAsSsv([Query(CollectionFormat.Ssv)] IEnumerable lines); + Task QueryWithEnumerableFormattedAsSsv( + [Query(CollectionFormat.Ssv)] IEnumerable lines + ); [Get("/query")] - Task QueryWithEnumerableFormattedAsTsv([Query(CollectionFormat.Tsv)] IEnumerable lines); + Task QueryWithEnumerableFormattedAsTsv( + [Query(CollectionFormat.Tsv)] IEnumerable lines + ); [Get("/query")] - Task QueryWithEnumerableFormattedAsPipes([Query(CollectionFormat.Pipes)] IEnumerable lines); + Task QueryWithEnumerableFormattedAsPipes( + [Query(CollectionFormat.Pipes)] IEnumerable lines + ); [Get("/query")] Task QueryWithObjectWithPrivateGetters(Person person); @@ -1367,7 +2042,12 @@ public interface IDummyHttpApi Task QueryWithTypeWithEnum(TypeFooWithEnumMember foo); [Get("/api/{id}")] - Task QueryWithOptionalParameters(int id, [Query] string text = null, [Query] int? optionalId = null, [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null); + Task QueryWithOptionalParameters( + int id, + [Query] string text = null, + [Query] int? optionalId = null, + [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null + ); [Delete("/api/bar")] Task ClearWithEnumMember([Query] FooWithEnumMember foo); @@ -1381,13 +2061,14 @@ public interface IDummyHttpApi [Multipart] [Post("/companies/{companyId}/{path}")] - Task> UploadFile(int companyId, - string path, - [AliasAs("file")] StreamPart stream, - [Header("Authorization")] string authorization, - bool overwrite = false, - [AliasAs("fileMetadata")] string metadata = null); - + Task> UploadFile( + int companyId, + string path, + [AliasAs("file")] StreamPart stream, + [Header("Authorization")] string authorization, + bool overwrite = false, + [AliasAs("fileMetadata")] string metadata = null + ); [Post("/foo")] Task PostWithComplexTypeQuery([Query] ComplexQueryObject queryParams); @@ -1396,11 +2077,22 @@ Task> UploadFile(int companyId, Task ComplexTypeQueryWithInnerCollection([Query] ComplexQueryObject queryParams); [Get("/api/{obj.someProperty}")] - Task QueryWithOptionalParametersPathBoundObject(PathBoundObject obj, [Query] string text = null, [Query] int? optionalId = null, [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null); + Task QueryWithOptionalParametersPathBoundObject( + PathBoundObject obj, + [Query] string text = null, + [Query] int? optionalId = null, + [Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null + ); [Headers("Accept:application/json", "X-API-V: 125")] [Get("/api/someModule/deviceList?controlId={control_id}")] - Task QueryWithHeadersBeforeData([Header("Authorization")] string authorization, [Header("X-Lng")] string twoLetterLang, string search, [AliasAs("control_id")] string controlId, string secret); + Task QueryWithHeadersBeforeData( + [Header("Authorization")] string authorization, + [Header("X-Lng")] string twoLetterLang, + string search, + [AliasAs("control_id")] string controlId, + string secret + ); [Get("/query")] [QueryUriFormat(UriFormat.Unescaped)] @@ -1418,6 +2110,7 @@ interface ICancellableMethods { [Get("/foo")] Task GetWithCancellation(CancellationToken token = default); + [Get("/foo")] Task GetWithCancellationAndReturn(CancellationToken token = default); } @@ -1464,12 +2157,17 @@ public TestHttpMessageHandler(string content = "test") ContentFactory = () => Content; } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { RequestMessage = request; if (request.Content != null) { - SendContent = await request.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + SendContent = await request.Content + .ReadAsStringAsync(cancellationToken) + .ConfigureAwait(false); } CancellationToken = cancellationToken; @@ -1497,7 +2195,11 @@ public string Format(object value, ICustomAttributeProvider attributeProvider, T // Converts enums to ints and adds a suffix to strings to test that both dictionary keys and values are formatted. public class TestEnumUrlParameterFormatter : DefaultUrlParameterFormatter { - public override string Format(object parameterValue, ICustomAttributeProvider attributeProvider, Type type) + public override string Format( + object parameterValue, + ICustomAttributeProvider attributeProvider, + Type type + ) { if (parameterValue is TestEnum enumValue) { @@ -1518,7 +2220,11 @@ public override string Format(object parameterValue, ICustomAttributeProvider at public class TestEnumerableUrlParameterFormatter : DefaultUrlParameterFormatter { - public override string Format(object parameterValue, ICustomAttributeProvider attributeProvider, Type type) + public override string Format( + object parameterValue, + ICustomAttributeProvider attributeProvider, + Type type + ) { if (parameterValue is IEnumerable enu) { @@ -1526,7 +2232,10 @@ public override string Format(object parameterValue, ICustomAttributeProvider at } if (parameterValue is IEnumerable en) { - return string.Join(",", en.Cast().Select(o => base.Format(o, attributeProvider, type))); + return string.Join( + ",", + en.Cast().Select(o => base.Format(o, attributeProvider, type)) + ); } return base.Format(parameterValue, attributeProvider, type); @@ -1535,7 +2244,6 @@ public override string Format(object parameterValue, ICustomAttributeProvider at public class RequestBuilderTests { - [Fact] public void MethodsShouldBeCancellableDefault() { @@ -1587,7 +2295,15 @@ public void HttpContentAsApiResponseTest() var mpc = new MultipartContent("foosubtype"); - var task = (Task>)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { mpc }); + var task = + (Task>) + factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/") + }, + new object[] { mpc } + ); task.Wait(); Assert.NotNull(task.Result.Headers); @@ -1611,7 +2327,15 @@ public void HttpContentTest() var mpc = new MultipartContent("foosubtype"); - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { mpc }); + var task = + (Task) + factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/") + }, + new object[] { mpc } + ); task.Wait(); Assert.Equal(testHttpMessageHandler.RequestMessage.Content, mpc); @@ -1633,7 +2357,15 @@ public void StreamResponseAsApiResponseTest() writer.Flush(); streamResponse.Seek(0L, SeekOrigin.Begin); - var task = (Task>)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { "test-file" }); + var task = + (Task>) + factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/") + }, + new object[] { "test-file" } + ); task.Wait(); Assert.NotNull(task.Result.Headers); @@ -1661,7 +2393,15 @@ public void StreamResponseTest() writer.Flush(); streamResponse.Seek(0L, SeekOrigin.Begin); - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { "test-file" }); + var task = + (Task) + factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/") + }, + new object[] { "test-file" } + ); task.Wait(); using var reader = new StreamReader(task.Result); @@ -1671,15 +2411,9 @@ public void StreamResponseTest() [Fact] public void MethodsThatDontHaveAnHttpMethodShouldFail() { - var failureMethods = new[] { - "SomeOtherMethod", - "weofjwoeijfwe", - null, - }; + var failureMethods = new[] { "SomeOtherMethod", "weofjwoeijfwe", null, }; - var successMethods = new[] { - "FetchSomeStuff", - }; + var successMethods = new[] { "FetchSomeStuff", }; foreach (var v in failureMethods) { @@ -1719,7 +2453,9 @@ public void MethodsThatDontHaveAnHttpMethodShouldFail() public void HardcodedQueryParamShouldBeInUrl() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithHardcodedQueryParameter"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithHardcodedQueryParameter" + ); var output = factory(new object[] { 6 }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1730,7 +2466,9 @@ public void HardcodedQueryParamShouldBeInUrl() public void ParameterizedQueryParamsShouldBeInUrl() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithHardcodedAndOtherQueryParameters"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithHardcodedAndOtherQueryParameters" + ); var output = factory(new object[] { 6, "foo" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1741,7 +2479,9 @@ public void ParameterizedQueryParamsShouldBeInUrl() public void ParameterizedValuesShouldBeInUrlMoreThanOnce() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.SomeApiThatUsesParameterMoreThanOnceInTheUrl)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.SomeApiThatUsesParameterMoreThanOnceInTheUrl) + ); var output = factory(new object[] { 6 }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1753,11 +2493,16 @@ public void ParameterizedValuesShouldBeInUrlMoreThanOnce() [InlineData("aaa/bbb/ccc", "/foo/bar/aaa/bbb/ccc/1")] [InlineData("aaa", "/foo/bar/aaa/1")] [InlineData("aa a/bb-b", "/foo/bar/aa%20a/bb-b/1")] - public void RoundTrippingParameterizedQueryParamsShouldBeInUrl(string path, string expectedQuery) + public void RoundTrippingParameterizedQueryParamsShouldBeInUrl( + string path, + string expectedQuery + ) { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithRoundTrippingParam"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithRoundTrippingParam" + ); var output = factory(new object[] { path, 1 }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1769,7 +2514,9 @@ public void ParameterizedNullQueryParamsShouldBeBlankInUrl() { var fixture = new RequestBuilderImplementation(); var factory = fixture.BuildRequestFactoryForMethod("PostWithQueryStringParameters"); - var output = factory(new object[] { new FileInfo(typeof(RequestBuilderTests).Assembly.Location), null }); + var output = factory( + new object[] { new FileInfo(typeof(RequestBuilderTests).Assembly.Location), null } + ); var uri = new Uri(new Uri("http://api"), output.RequestUri); Assert.Equal("/foo?name=", uri.PathAndQuery); @@ -1779,7 +2526,9 @@ public void ParameterizedNullQueryParamsShouldBeBlankInUrl() public void ParametersShouldBePutAsExplicitQueryString() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithExplicitParameters)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithExplicitParameters) + ); var output = factory(new object[] { "value1", "value2" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1802,7 +2551,9 @@ public void QueryParamShouldFormat() public void ParameterizedQueryParamsShouldBeInUrlAndValuesEncoded() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithHardcodedAndOtherQueryParameters"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithHardcodedAndOtherQueryParameters" + ); var output = factory(new object[] { 6, "push!=pull&push" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1814,31 +2565,43 @@ public void ParameterizedQueryParamsShouldBeInUrlAndValuesEncoded() public void ParameterizedQueryParamsShouldBeInUrlAndValuesEncodedWhenMixedReplacementAndQuery() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithVoidAndQueryAlias"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithVoidAndQueryAlias" + ); var output = factory(new object[] { "6 & 7/8", "test@example.com", "push!=pull" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal("/void/6%20%26%207%2F8/path?a=test%40example.com&b=push%21%3Dpull", uri.PathAndQuery); + Assert.Equal( + "/void/6%20%26%207%2F8/path?a=test%40example.com&b=push%21%3Dpull", + uri.PathAndQuery + ); } [Fact] public void QueryParamWithPathDelimiterShouldBeEncoded() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithVoidAndQueryAlias"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithVoidAndQueryAlias" + ); var output = factory(new object[] { "6/6", "test@example.com", "push!=pull" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal("/void/6%2F6/path?a=test%40example.com&b=push%21%3Dpull", uri.PathAndQuery); + Assert.Equal( + "/void/6%2F6/path?a=test%40example.com&b=push%21%3Dpull", + uri.PathAndQuery + ); } [Fact] public void ParameterizedQueryParamsShouldBeInUrlAndValuesEncodedWhenMixedReplacementAndQueryBadId() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithVoidAndQueryAlias"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithVoidAndQueryAlias" + ); var output = factory(new object[] { "6", "test@example.com", "push!=pull" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1850,7 +2613,9 @@ public void ParameterizedQueryParamsShouldBeInUrlAndValuesEncodedWhenMixedReplac public void NonFormattableQueryParamsShouldBeIncluded() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithNonFormattableQueryParams"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithNonFormattableQueryParams" + ); var output = factory(new object[] { true, 'x' }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1862,7 +2627,9 @@ public void NonFormattableQueryParamsShouldBeIncluded() public void MultipleParametersInTheSameSegmentAreGeneratedProperly() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomethingWithMultipleParametersPerSegment"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomethingWithMultipleParametersPerSegment" + ); var output = factory(new object[] { 6, 1024, 768 }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -1874,12 +2641,17 @@ public void HardcodedHeadersShouldBeInHeaders() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithHardcodedHeaders)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithHardcodedHeaders) + ); var output = factory(new object[] { 6 }); Assert.True(output.Headers.Contains("User-Agent"), "Headers include User-Agent header"); Assert.Equal("RefitTestClient", output.Headers.UserAgent.ToString()); - Assert.True(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.True( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("2", output.Headers.GetValues("Api-Version").Single()); Assert.True(output.Headers.Contains("Accept"), "Headers include Accept header"); Assert.Equal("application/json", output.Headers.Accept.ToString()); @@ -1889,24 +2661,35 @@ public void HardcodedHeadersShouldBeInHeaders() public void EmptyHardcodedHeadersShouldBeInHeaders() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithEmptyHardcodedHeader"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithEmptyHardcodedHeader" + ); var output = factory(new object[] { 6 }); Assert.True(output.Headers.Contains("User-Agent"), "Headers include User-Agent header"); Assert.Equal("RefitTestClient", output.Headers.UserAgent.ToString()); - Assert.True(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.True( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("", output.Headers.GetValues("Api-Version").Single()); } + [Fact] public void NullHardcodedHeadersShouldNotBeInHeaders() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithNullHardcodedHeader"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithNullHardcodedHeader" + ); var output = factory(new object[] { 6 }); Assert.True(output.Headers.Contains("User-Agent"), "Headers include User-Agent header"); Assert.Equal("RefitTestClient", output.Headers.UserAgent.ToString()); - Assert.False(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.False( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); } [Fact] @@ -1916,7 +2699,15 @@ public void ReadStringContentWithMetadata() var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStringWithMetadata"); var testHttpMessageHandler = new TestHttpMessageHandler(); - var task = (Task>)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { 42 }); + var task = + (Task>) + factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/") + }, + new object[] { 42 } + ); task.Wait(); Assert.NotNull(task.Result.Headers); @@ -1932,10 +2723,15 @@ public void ReadStringContentWithMetadata() public void ContentHeadersCanBeHardcoded() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("PostSomeStuffWithHardCodedContentTypeHeader"); + var factory = fixture.BuildRequestFactoryForMethod( + "PostSomeStuffWithHardCodedContentTypeHeader" + ); var output = factory(new object[] { 6, "stuff" }); - Assert.True(output.Content.Headers.Contains("Content-Type"), "Content headers include Content-Type header"); + Assert.True( + output.Content.Headers.Contains("Content-Type"), + "Content headers include Content-Type header" + ); Assert.Equal("literally/anything", output.Content.Headers.ContentType.ToString()); } @@ -1946,7 +2742,7 @@ public void DynamicHeaderShouldBeInHeaders() var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithDynamicHeader"); var output = factory(new object[] { 6, "Basic RnVjayB5ZWFoOmhlYWRlcnMh" }); - Assert.NotNull(output.Headers.Authorization);//, "Headers include Authorization header"); + Assert.NotNull(output.Headers.Authorization); //, "Headers include Authorization header"); Assert.Equal("RnVjayB5ZWFoOmhlYWRlcnMh", output.Headers.Authorization.Parameter); } @@ -1979,17 +2775,22 @@ public void NullDynamicHeaderShouldNotBeInHeaders() var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithDynamicHeader"); var output = factory(new object[] { 6, null }); - Assert.Null(output.Headers.Authorization);//, "Headers include Authorization header"); + Assert.Null(output.Headers.Authorization); //, "Headers include Authorization header"); } [Fact] public void PathMemberAsCustomDynamicHeaderShouldBeInHeaders() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithPathMemberInCustomHeader"); + var factory = fixture.BuildRequestFactoryForMethod( + "FetchSomeStuffWithPathMemberInCustomHeader" + ); var output = factory(new object[] { 6, ":joy_cat:" }); - Assert.True(output.Headers.Contains("X-PathMember"), "Headers include X-PathMember header"); + Assert.True( + output.Headers.Contains("X-PathMember"), + "Headers include X-PathMember header" + ); Assert.Equal("6", output.Headers.GetValues("X-PathMember").First()); } @@ -2000,10 +2801,19 @@ public void AddCustomHeadersToRequestHeadersOnly() var factory = fixture.BuildRequestFactoryForMethod("PostSomeStuffWithCustomHeader"); var output = factory(new object[] { 6, new { Foo = "bar" }, ":smile_cat:" }); - Assert.True(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.True( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); Assert.True(output.Headers.Contains("X-Emoji"), "Headers include X-Emoji header"); - Assert.False(output.Content.Headers.Contains("Api-Version"), "Content headers include Api-Version header"); - Assert.False(output.Content.Headers.Contains("X-Emoji"), "Content headers include X-Emoji header"); + Assert.False( + output.Content.Headers.Contains("Api-Version"), + "Content headers include Api-Version header" + ); + Assert.False( + output.Content.Headers.Contains("X-Emoji"), + "Content headers include X-Emoji header" + ); } [Theory] @@ -2016,8 +2826,8 @@ public void HeaderCollectionShouldBeInHeaders(string interfaceMethodName) { var headerCollection = new Dictionary { - {"key1", "val1"}, - {"key2", "val2"} + { "key1", "val1" }, + { "key2", "val2" } }; var fixture = new RequestBuilderImplementation(); @@ -2026,11 +2836,20 @@ public void HeaderCollectionShouldBeInHeaders(string interfaceMethodName) Assert.True(output.Headers.Contains("User-Agent"), "Headers include User-Agent header"); Assert.Equal("RefitTestClient", output.Headers.GetValues("User-Agent").First()); - Assert.True(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.True( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("1", output.Headers.GetValues("Api-Version").First()); - Assert.True(output.Headers.Contains("Authorization"), "Headers include Authorization header"); - Assert.Equal("SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", output.Headers.GetValues("Authorization").First()); + Assert.True( + output.Headers.Contains("Authorization"), + "Headers include Authorization header" + ); + Assert.Equal( + "SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + output.Headers.GetValues("Authorization").First() + ); Assert.True(output.Headers.Contains("Accept"), "Headers include Accept header"); Assert.Equal("application/json", output.Headers.GetValues("Accept").First()); @@ -2046,21 +2865,33 @@ public void LastWriteWinsWhenHeaderCollectionAndDynamicHeader() var authHeader = "LetMeIn"; var headerCollection = new Dictionary { - {"Authorization", "OpenSesame"} + { "Authorization", "OpenSesame" } }; var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeader) + ); var output = factory(new object[] { 6, authHeader, headerCollection }); - Assert.True(output.Headers.Contains("Authorization"), "Headers include Authorization header"); + Assert.True( + output.Headers.Contains("Authorization"), + "Headers include Authorization header" + ); Assert.Equal("OpenSesame", output.Headers.GetValues("Authorization").First()); fixture = new RequestBuilderImplementation(); - factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped)); + factory = fixture.BuildRequestFactoryForMethod( + nameof( + IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollectionAndDynamicHeaderOrderFlipped + ) + ); output = factory(new object[] { 6, headerCollection, authHeader }); - Assert.True(output.Headers.Contains("Authorization"), "Headers include Authorization header"); + Assert.True( + output.Headers.Contains("Authorization"), + "Headers include Authorization header" + ); Assert.Equal(authHeader, output.Headers.GetValues("Authorization").First()); } @@ -2078,11 +2909,20 @@ public void NullHeaderCollectionDoesntBlowUp(string interfaceMethodName) Assert.True(output.Headers.Contains("User-Agent"), "Headers include User-Agent header"); Assert.Equal("RefitTestClient", output.Headers.GetValues("User-Agent").First()); - Assert.True(output.Headers.Contains("Api-Version"), "Headers include Api-Version header"); + Assert.True( + output.Headers.Contains("Api-Version"), + "Headers include Api-Version header" + ); Assert.Equal("1", output.Headers.GetValues("Api-Version").First()); - Assert.True(output.Headers.Contains("Authorization"), "Headers include Authorization header"); - Assert.Equal("SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", output.Headers.GetValues("Authorization").First()); + Assert.True( + output.Headers.Contains("Authorization"), + "Headers include Authorization header" + ); + Assert.Equal( + "SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==", + output.Headers.GetValues("Authorization").First() + ); Assert.True(output.Headers.Contains("Accept"), "Headers include Accept header"); Assert.Equal("application/json", output.Headers.GetValues("Accept").First()); } @@ -2092,17 +2932,25 @@ public void HeaderCollectionCanUnsetHeaders() { var headerCollection = new Dictionary { - {"Authorization", ""}, - {"Api-Version", null} + { "Authorization", "" }, + { "Api-Version", null } }; var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollection)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithDynamicHeaderCollection) + ); var output = factory(new object[] { 6, headerCollection }); - Assert.True(!output.Headers.Contains("Api-Version"), "Headers does not include Api-Version header"); + Assert.True( + !output.Headers.Contains("Api-Version"), + "Headers does not include Api-Version header" + ); - Assert.True(output.Headers.Contains("Authorization"), "Headers include Authorization header"); + Assert.True( + output.Headers.Contains("Authorization"), + "Headers include Authorization header" + ); Assert.Equal("", output.Headers.GetValues("Authorization").First()); } @@ -2121,15 +2969,18 @@ public void DynamicRequestPropertiesShouldBeInProperties(string interfaceMethodN #if NET6_0_OR_GREATER Assert.NotEmpty(output.Options); - Assert.Equal(someProperty, ((IDictionary)output.Options)["SomeProperty"]); + Assert.Equal( + someProperty, + ((IDictionary)output.Options)["SomeProperty"] + ); #endif #pragma warning disable CS0618 // Type or member is obsolete Assert.NotEmpty(output.Properties); Assert.Equal(someProperty, output.Properties["SomeProperty"]); #pragma warning restore CS0618 // Type or member is obsolete - } + [Fact] public void OptionsFromSettingsShouldBeInProperties() { @@ -2137,23 +2988,35 @@ public void OptionsFromSettingsShouldBeInProperties() string valueProp1 = "TestValue"; const string nameProp2 = "UnitTest.Property2"; object valueProp2 = new List() { "123", "345" }; - var fixture = new RequestBuilderImplementation(new RefitSettings() - { - HttpRequestMessageOptions = new Dictionary() + var fixture = new RequestBuilderImplementation( + new RefitSettings() { - [nameProp1] = valueProp1, - [nameProp2] = valueProp2, - }, - }); + HttpRequestMessageOptions = new Dictionary() + { + [nameProp1] = valueProp1, + [nameProp2] = valueProp2, + }, + } + ); var factory = fixture.BuildRequestFactoryForMethod(nameof(IContainAandB.Ping)); var output = factory(Array.Empty()); #if NET6_0_OR_GREATER Assert.NotEmpty(output.Options); - Assert.True(output.Options.TryGetValue(new HttpRequestOptionsKey(nameProp1), out var resultValueProp1)); + Assert.True( + output.Options.TryGetValue( + new HttpRequestOptionsKey(nameProp1), + out var resultValueProp1 + ) + ); Assert.Equal(valueProp1, resultValueProp1); - Assert.True(output.Options.TryGetValue(new HttpRequestOptionsKey>(nameProp2), out var resultValueProp2)); + Assert.True( + output.Options.TryGetValue( + new HttpRequestOptionsKey>(nameProp2), + out var resultValueProp2 + ) + ); Assert.Equal(valueProp2, resultValueProp2); #else Assert.NotEmpty(output.Properties); @@ -2161,7 +3024,7 @@ public void OptionsFromSettingsShouldBeInProperties() Assert.IsType(resultValueProp1); Assert.Equal(valueProp1, (string)resultValueProp1); - Assert.True(output.Properties.TryGetValue(nameProp2, out var resultValueProp2)); + Assert.True(output.Properties.TryGetValue(nameProp2, out var resultValueProp2)); Assert.IsType>(resultValueProp2); Assert.Equal(valueProp2, (List)resultValueProp2); #endif @@ -2176,9 +3039,11 @@ public void InterfaceTypeShouldBeInProperties() #pragma warning disable CS0618 // Type or member is obsolete Assert.NotEmpty(output.Properties); - Assert.Equal(typeof(IContainAandB), output.Properties[HttpRequestMessageOptions.InterfaceType]); + Assert.Equal( + typeof(IContainAandB), + output.Properties[HttpRequestMessageOptions.InterfaceType] + ); #pragma warning restore CS0618 // Type or member is obsolete - } [Fact] @@ -2191,10 +3056,22 @@ public void RestMethodInfoShouldBeInProperties() #if NET6_0_OR_GREATER Assert.NotEmpty(output.Options); - Assert.True(output.Options.TryGetValue(new HttpRequestOptionsKey(HttpRequestMessageOptions.RestMethodInfo), out var restMethodInfo)); + Assert.True( + output.Options.TryGetValue( + new HttpRequestOptionsKey( + HttpRequestMessageOptions.RestMethodInfo + ), + out var restMethodInfo + ) + ); #else Assert.NotEmpty(output.Properties); - Assert.True(output.Properties.TryGetValue(HttpRequestMessageOptions.RestMethodInfo, out var restMethodInfoObj)); + Assert.True( + output.Properties.TryGetValue( + HttpRequestMessageOptions.RestMethodInfo, + out var restMethodInfoObj + ) + ); Assert.IsType(restMethodInfoObj); var restMethodInfo = restMethodInfoObj as RestMethodInfo; #endif @@ -2207,13 +3084,18 @@ public void DynamicRequestPropertiesWithDefaultKeysShouldBeInProperties() var someProperty = new object(); var someOtherProperty = new object(); var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithDynamicRequestPropertyWithoutKey)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithDynamicRequestPropertyWithoutKey) + ); var output = factory(new object[] { 6, someProperty, someOtherProperty }); #if NET6_0_OR_GREATER Assert.NotEmpty(output.Options); Assert.Equal(someProperty, ((IDictionary)output.Options)["someValue"]); - Assert.Equal(someOtherProperty, ((IDictionary)output.Options)["someOtherValue"]); + Assert.Equal( + someOtherProperty, + ((IDictionary)output.Options)["someOtherValue"] + ); #endif #pragma warning disable CS0618 // Type or member is obsolete @@ -2229,13 +3111,17 @@ public void DynamicRequestPropertiesWithDuplicateKeyShouldOverwritePreviousPrope var someProperty = new object(); var someOtherProperty = new object(); var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithDynamicRequestPropertyWithDuplicateKey) + ); var output = factory(new object[] { 6, someProperty, someOtherProperty }); - #if NET6_0_OR_GREATER Assert.Equal(3, output.Options.Count()); - Assert.Equal(someOtherProperty, ((IDictionary)output.Options)["SomeProperty"]); + Assert.Equal( + someOtherProperty, + ((IDictionary)output.Options)["SomeProperty"] + ); #endif #pragma warning disable CS0618 // Type or member is obsolete @@ -2251,10 +3137,19 @@ public void HttpClientShouldPrefixedAbsolutePathToTheRequestUri() var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithoutFullPath"); var testHttpMessageHandler = new TestHttpMessageHandler(); - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, Array.Empty()); + var task = (Task)factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/foo/bar") + }, + Array.Empty() + ); task.Wait(); - Assert.Equal("http://api/foo/bar/string", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); + Assert.Equal( + "http://api/foo/bar/string", + testHttpMessageHandler.RequestMessage.RequestUri.ToString() + ); } [Fact] @@ -2264,10 +3159,19 @@ public void HttpClientForVoidMethodShouldPrefixedAbsolutePathToTheRequestUri() var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithVoid"); var testHttpMessageHandler = new TestHttpMessageHandler(); - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, Array.Empty()); + var task = (Task)factory( + new HttpClient(testHttpMessageHandler) + { + BaseAddress = new Uri("http://api/foo/bar") + }, + Array.Empty() + ); task.Wait(); - Assert.Equal("http://api/foo/bar/void", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); + Assert.Equal( + "http://api/foo/bar/void", + testHttpMessageHandler.RequestMessage.RequestUri.ToString() + ); } [Fact] @@ -2277,10 +3181,16 @@ public void HttpClientShouldNotPrefixEmptyAbsolutePathToTheRequestUri() var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuff"); var testHttpMessageHandler = new TestHttpMessageHandler(); - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { 42 }); + var task = (Task)factory( + new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, + new object[] { 42 } + ); task.Wait(); - Assert.Equal("http://api/foo/bar/42", testHttpMessageHandler.RequestMessage.RequestUri.ToString()); + Assert.Equal( + "http://api/foo/bar/42", + testHttpMessageHandler.RequestMessage.RequestUri.ToString() + ); } [Fact] @@ -2288,9 +3198,11 @@ public void DontBlowUpWithDynamicAuthorizationHeaderAndContent() { var fixture = new RequestBuilderImplementation(); var factory = fixture.BuildRequestFactoryForMethod("PutSomeContentWithAuthorization"); - var output = factory(new object[] { 7, new { Octocat = "Dunetocat" }, "Basic RnVjayB5ZWFoOmhlYWRlcnMh" }); + var output = factory( + new object[] { 7, new { Octocat = "Dunetocat" }, "Basic RnVjayB5ZWFoOmhlYWRlcnMh" } + ); - Assert.NotNull(output.Headers.Authorization);//, "Headers include Authorization header"); + Assert.NotNull(output.Headers.Authorization); //, "Headers include Authorization header"); Assert.Equal("RnVjayB5ZWFoOmhlYWRlcnMh", output.Headers.Authorization.Parameter); } @@ -2298,12 +3210,16 @@ public void DontBlowUpWithDynamicAuthorizationHeaderAndContent() public void SuchFlexibleContentTypeWow() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("PutSomeStuffWithDynamicContentType"); - var output = factory(new object[] { 7, "such \"refit\" is \"amaze\" wow", "text/dson" }); + var factory = fixture.BuildRequestFactoryForMethod( + "PutSomeStuffWithDynamicContentType" + ); + var output = factory( + new object[] { 7, "such \"refit\" is \"amaze\" wow", "text/dson" } + ); - Assert.NotNull(output.Content);//, "Request has content"); - Assert.NotNull(output.Content.Headers.ContentType);//, "Headers include Content-Type header"); - Assert.Equal("text/dson", output.Content.Headers.ContentType.MediaType);//, "Content-Type header has the expected value"); + Assert.NotNull(output.Content); //, "Request has content"); + Assert.NotNull(output.Content.Headers.ContentType); //, "Headers include Content-Type header"); + Assert.Equal("text/dson", output.Content.Headers.ContentType.MediaType); //, "Content-Type header has the expected value"); } [Fact] @@ -2312,14 +3228,17 @@ public void BodyContentGetsUrlEncoded() var fixture = new RequestBuilderImplementation(); var factory = fixture.RunRequest("PostSomeUrlEncodedStuff"); var output = factory( - new object[] { + new object[] + { 6, - new { + new + { Foo = "Something", Bar = 100, Baz = "" // explicitly use blank to preserve value that would be stripped if null } - }); + } + ); Assert.Equal("Foo=Something&Bar=100&Baz=", output.SendContent); } @@ -2330,14 +3249,12 @@ public void FormFieldGetsAliased() var fixture = new RequestBuilderImplementation(); var factory = fixture.RunRequest("PostSomeAliasedUrlEncodedStuff"); var output = factory( - new object[] { + new object[] + { 6, - new SomeRequestData { - ReadablePropertyName = 99 - } - }); - - + new SomeRequestData { ReadablePropertyName = 99 } + } + ); Assert.Equal("rpn=99", output.SendContent); } @@ -2345,7 +3262,10 @@ public void FormFieldGetsAliased() [Fact] public void CustomParmeterFormatter() { - var settings = new RefitSettings { UrlParameterFormatter = new TestUrlParameterFormatter("custom-parameter") }; + var settings = new RefitSettings + { + UrlParameterFormatter = new TestUrlParameterFormatter("custom-parameter") + }; var fixture = new RequestBuilderImplementation(settings); var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuff"); @@ -2358,7 +3278,10 @@ public void CustomParmeterFormatter() [Fact] public void QueryStringWithEnumerablesCanBeFormatted() { - var settings = new RefitSettings { UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() }; + var settings = new RefitSettings + { + UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() + }; var fixture = new RequestBuilderImplementation(settings); var factory = fixture.BuildRequestFactoryForMethod("QueryWithEnumerable"); @@ -2371,7 +3294,10 @@ public void QueryStringWithEnumerablesCanBeFormatted() [Fact] public void QueryStringWithArrayCanBeFormatted() { - var settings = new RefitSettings { UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() }; + var settings = new RefitSettings + { + UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() + }; var fixture = new RequestBuilderImplementation(settings); var factory = fixture.BuildRequestFactoryForMethod("QueryWithArray"); @@ -2408,10 +3334,9 @@ public void QueryStringWithArrayCanBeFormattedByAttributeWithMultiple() [Fact] public void QueryStringWithArrayCanBeFormattedByDefaultSetting() { - var fixture = new RequestBuilderImplementation(new RefitSettings - { - CollectionFormat = CollectionFormat.Multi - }); + var fixture = new RequestBuilderImplementation( + new RefitSettings { CollectionFormat = CollectionFormat.Multi } + ); var factory = fixture.BuildRequestFactoryForMethod("QueryWithArray"); var output = factory(new object[] { new[] { 1, 2, 3 } }); @@ -2422,10 +3347,9 @@ public void QueryStringWithArrayCanBeFormattedByDefaultSetting() [Fact] public void DefaultCollectionFormatCanBeOverridenByQueryAttribute() { - var fixture = new RequestBuilderImplementation(new RefitSettings - { - CollectionFormat = CollectionFormat.Multi - }); + var fixture = new RequestBuilderImplementation( + new RefitSettings { CollectionFormat = CollectionFormat.Multi } + ); var factory = fixture.BuildRequestFactoryForMethod("QueryWithArrayFormattedAsCsv"); var output = factory(new object[] { new[] { 1, 2, 3 } }); @@ -2438,7 +3362,9 @@ public void RequestWithParameterInMultiplePlaces() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithTheSameId)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithTheSameId) + ); var output = factory(new object[] { "theId" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -2455,14 +3381,15 @@ public void RequestWithParameterInAQueryParameterMultipleTimes() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.FetchSomeStuffWithTheIdInAParameterMultipleTimes)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.FetchSomeStuffWithTheIdInAParameterMultipleTimes) + ); var output = factory(new object[] { "theId" }); var uri = new Uri(new Uri("http://api"), output.RequestUri); Assert.Equal("/foo/bar?param=first%20theId%20and%20second%20theId", uri.PathAndQuery); } - [Theory] [InlineData("QueryWithArrayFormattedAsMulti", "/query?numbers=1&numbers=2&numbers=3")] [InlineData("QueryWithArrayFormattedAsCsv", "/query?numbers=1%2C2%2C3")] @@ -2483,28 +3410,34 @@ public void QueryStringWithArrayFormatted(string apiMethodName, string expectedQ [Fact] public void QueryStringWithArrayFormattedAsSsvAndItemsFormattedIndividually() { - var settings = new RefitSettings { UrlParameterFormatter = new TestUrlParameterFormatter("custom-parameter") }; + var settings = new RefitSettings + { + UrlParameterFormatter = new TestUrlParameterFormatter("custom-parameter") + }; var fixture = new RequestBuilderImplementation(settings); var factory = fixture.BuildRequestFactoryForMethod("QueryWithArrayFormattedAsSsv"); var output = factory(new object[] { new int[] { 1, 2, 3 } }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal("/query?numbers=custom-parameter%20custom-parameter%20custom-parameter", uri.PathAndQuery); + Assert.Equal( + "/query?numbers=custom-parameter%20custom-parameter%20custom-parameter", + uri.PathAndQuery + ); } [Fact] public void QueryStringWithEnumerablesCanBeFormattedEnumerable() { - var settings = new RefitSettings { UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() }; + var settings = new RefitSettings + { + UrlParameterFormatter = new TestEnumerableUrlParameterFormatter() + }; var fixture = new RequestBuilderImplementation(settings); var factory = fixture.BuildRequestFactoryForMethod("QueryWithEnumerable"); - var list = new List - { - 1, 2, 3 - }; + var list = new List { 1, 2, 3 }; var output = factory(new object[] { list }); @@ -2513,7 +3446,10 @@ public void QueryStringWithEnumerablesCanBeFormattedEnumerable() } [Theory] - [InlineData("QueryWithEnumerableFormattedAsMulti", "/query?lines=first&lines=second&lines=third")] + [InlineData( + "QueryWithEnumerableFormattedAsMulti", + "/query?lines=first&lines=second&lines=third" + )] [InlineData("QueryWithEnumerableFormattedAsCsv", "/query?lines=first%2Csecond%2Cthird")] [InlineData("QueryWithEnumerableFormattedAsSsv", "/query?lines=first%20second%20third")] [InlineData("QueryWithEnumerableFormattedAsTsv", "/query?lines=first%09second%09third")] @@ -2524,12 +3460,7 @@ public void QueryStringWithEnumerableFormatted(string apiMethodName, string expe var factory = fixture.BuildRequestFactoryForMethod(apiMethodName); - var lines = new List - { - "first", - "second", - "third" - }; + var lines = new List { "first", "second", "third" }; var output = factory(new object[] { lines }); @@ -2544,11 +3475,7 @@ public void QueryStringExcludesPropertiesWithPrivateGetters() var factory = fixture.BuildRequestFactoryForMethod("QueryWithObjectWithPrivateGetters"); - var person = new Person - { - FirstName = "Mickey", - LastName = "Mouse" - }; + var person = new Person { FirstName = "Mickey", LastName = "Mouse" }; var output = factory(new object[] { person }); @@ -2559,7 +3486,10 @@ public void QueryStringExcludesPropertiesWithPrivateGetters() [Theory] [InlineData(FooWithEnumMember.A, "/query?foo=A")] [InlineData(FooWithEnumMember.B, "/query?foo=b")] - public void QueryStringUsesEnumMemberAttribute(FooWithEnumMember queryParameter, string expectedQuery) + public void QueryStringUsesEnumMemberAttribute( + FooWithEnumMember queryParameter, + string expectedQuery + ) { var fixture = new RequestBuilderImplementation(); var factory = fixture.BuildRequestFactoryForMethod("QueryWithEnum"); @@ -2573,12 +3503,17 @@ public void QueryStringUsesEnumMemberAttribute(FooWithEnumMember queryParameter, [Theory] [InlineData(FooWithEnumMember.A, "/query?foo=A")] [InlineData(FooWithEnumMember.B, "/query?foo=b")] - public void QueryStringUsesEnumMemberAttributeInTypeWithEnum(FooWithEnumMember queryParameter, string expectedQuery) + public void QueryStringUsesEnumMemberAttributeInTypeWithEnum( + FooWithEnumMember queryParameter, + string expectedQuery + ) { var fixture = new RequestBuilderImplementation(); var factory = fixture.BuildRequestFactoryForMethod("QueryWithTypeWithEnum"); - var output = factory(new object[] { new TypeFooWithEnumMember { Foo = queryParameter } }); + var output = factory( + new object[] { new TypeFooWithEnumMember { Foo = queryParameter } } + ); var uri = new Uri(new Uri("http://api"), output.RequestUri); Assert.Equal(expectedQuery, uri.PathAndQuery); @@ -2613,14 +3548,23 @@ public void TestNullableQueryStringParamsWithANull(string expectedQuery) public void TestNullableQueryStringParamsWithANullAndPathBoundObject(string expectedQuery) { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod("QueryWithOptionalParametersPathBoundObject"); - var output = factory(new object[] { new PathBoundObject() { SomeProperty = 123, SomeProperty2 = "test" }, "title", null, new string[] { "A", "B" } }); + var factory = fixture.BuildRequestFactoryForMethod( + "QueryWithOptionalParametersPathBoundObject" + ); + var output = factory( + new object[] + { + new PathBoundObject() { SomeProperty = 123, SomeProperty2 = "test" }, + "title", + null, + new string[] { "A", "B" } + } + ); 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 DefaultParameterFormatterIsInvariant() @@ -2695,7 +3639,9 @@ public void MultipartPostWithAliasAndHeader() public void PostBlobByteWithAlias() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.Blob_Post_Byte)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.Blob_Post_Byte) + ); var bytes = new byte[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; @@ -2712,7 +3658,9 @@ public void PostBlobByteWithAlias() public void QueryWithAliasAndHeadersWorks() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithHeadersBeforeData)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithHeadersBeforeData) + ); var authHeader = "theAuth"; var langHeader = "LnG"; @@ -2720,13 +3668,16 @@ public void QueryWithAliasAndHeadersWorks() var controlIdParam = "theControlId"; var secretValue = "theSecret"; - - - var output = factory(new object[] { authHeader, langHeader, searchParam, controlIdParam, secretValue }); + var output = factory( + new object[] { authHeader, langHeader, searchParam, controlIdParam, secretValue } + ); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal($"/api/someModule/deviceList?controlId={controlIdParam}&search={searchParam}&secret={secretValue}", uri.PathAndQuery); + Assert.Equal( + $"/api/someModule/deviceList?controlId={controlIdParam}&search={searchParam}&secret={secretValue}", + uri.PathAndQuery + ); Assert.Equal(langHeader, output.Headers.GetValues("X-LnG").FirstOrDefault()); Assert.Equal(authHeader, output.Headers.Authorization?.Scheme); } @@ -2735,7 +3686,11 @@ class RequestBuilderMock : IRequestBuilder { public int CallCount { get; private set; } - public Func BuildRestResultFuncForMethod(string methodName, Type[] parameterTypes = null, Type[] genericArgumentTypes = null) + public Func BuildRestResultFuncForMethod( + string methodName, + Type[] parameterTypes = null, + Type[] genericArgumentTypes = null + ) { CallCount++; return null; @@ -2748,10 +3703,24 @@ public void CachedRequestBuilderCallInternalBuilderForParametersWithSameNamesBut var internalBuilder = new RequestBuilderMock(); var cachedBuilder = new CachedRequestBuilderImplementation(internalBuilder); - cachedBuilder.BuildRestResultFuncForMethod("TestMethodName", new[] { typeof(CollisionA.SomeType) }); - cachedBuilder.BuildRestResultFuncForMethod("TestMethodName", new[] { typeof(CollisionB.SomeType) }); - cachedBuilder.BuildRestResultFuncForMethod("TestMethodName", null, new[] { typeof(CollisionA.SomeType) }); - cachedBuilder.BuildRestResultFuncForMethod("TestMethodName", null, new[] { typeof(CollisionB.SomeType) }); + cachedBuilder.BuildRestResultFuncForMethod( + "TestMethodName", + new[] { typeof(CollisionA.SomeType) } + ); + cachedBuilder.BuildRestResultFuncForMethod( + "TestMethodName", + new[] { typeof(CollisionB.SomeType) } + ); + cachedBuilder.BuildRestResultFuncForMethod( + "TestMethodName", + null, + new[] { typeof(CollisionA.SomeType) } + ); + cachedBuilder.BuildRestResultFuncForMethod( + "TestMethodName", + null, + new[] { typeof(CollisionB.SomeType) } + ); Assert.Equal(4, internalBuilder.CallCount); } @@ -2760,7 +3729,9 @@ public void CachedRequestBuilderCallInternalBuilderForParametersWithSameNamesBut public void DictionaryQueryWithEnumKeyProducesCorrectQueryString() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithDictionaryWithEnumKey)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithDictionaryWithEnumKey) + ); var dict = new Dictionary { @@ -2778,7 +3749,9 @@ public void DictionaryQueryWithEnumKeyProducesCorrectQueryString() public void DictionaryQueryWithPrefix() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithDictionaryWithPrefix)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithDictionaryWithPrefix) + ); var dict = new Dictionary { @@ -2796,13 +3769,11 @@ public void DictionaryQueryWithPrefix() public void DictionaryQueryWithNumericKeyProducesCorrectQueryString() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithDictionaryWithNumericKey)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithDictionaryWithNumericKey) + ); - var dict = new Dictionary - { - { 1, "value1" }, - { 2, "value2" }, - }; + var dict = new Dictionary { { 1, "value1" }, { 2, "value2" }, }; var output = factory(new object[] { dict }); var uri = new Uri(new Uri("http://api"), output.RequestUri); @@ -2817,7 +3788,9 @@ public void DictionaryQueryWithCustomFormatterProducesCorrectQueryString() var refitSettings = new RefitSettings { UrlParameterFormatter = urlParameterFormatter }; var fixture = new RequestBuilderImplementation(refitSettings); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.QueryWithDictionaryWithEnumKey)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.QueryWithDictionaryWithEnumKey) + ); var dict = new Dictionary { @@ -2828,14 +3801,19 @@ public void DictionaryQueryWithCustomFormatterProducesCorrectQueryString() var output = factory(new object[] { dict }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal($"/foo?{(int)TestEnum.A}=value1{TestEnumUrlParameterFormatter.StringParameterSuffix}&{(int)TestEnum.B}=value2{TestEnumUrlParameterFormatter.StringParameterSuffix}", uri.PathAndQuery); + Assert.Equal( + $"/foo?{(int)TestEnum.A}=value1{TestEnumUrlParameterFormatter.StringParameterSuffix}&{(int)TestEnum.B}=value2{TestEnumUrlParameterFormatter.StringParameterSuffix}", + uri.PathAndQuery + ); } [Fact] public void ComplexQueryObjectWithAliasedDictionaryProducesCorrectQueryString() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary) + ); var complexQuery = new ComplexQueryObject { @@ -2849,14 +3827,19 @@ public void ComplexQueryObjectWithAliasedDictionaryProducesCorrectQueryString() var output = factory(new object[] { complexQuery }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal("/foo?test-dictionary-alias.A=value1&test-dictionary-alias.B=value2", uri.PathAndQuery); + Assert.Equal( + "/foo?test-dictionary-alias.A=value1&test-dictionary-alias.B=value2", + uri.PathAndQuery + ); } [Fact] public void ComplexQueryObjectWithDictionaryProducesCorrectQueryString() { var fixture = new RequestBuilderImplementation(); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary) + ); var complexQuery = new ComplexQueryObject { @@ -2879,7 +3862,9 @@ public void ComplexQueryObjectWithDictionaryAndCustomFormatterProducesCorrectQue var urlParameterFormatter = new TestEnumUrlParameterFormatter(); var refitSettings = new RefitSettings { UrlParameterFormatter = urlParameterFormatter }; var fixture = new RequestBuilderImplementation(refitSettings); - var factory = fixture.BuildRequestFactoryForMethod(nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary)); + var factory = fixture.BuildRequestFactoryForMethod( + nameof(IDummyHttpApi.ComplexQueryObjectWithDictionary) + ); var complexQuery = new ComplexQueryObject { @@ -2893,28 +3878,41 @@ public void ComplexQueryObjectWithDictionaryAndCustomFormatterProducesCorrectQue var output = factory(new object[] { complexQuery }); var uri = new Uri(new Uri("http://api"), output.RequestUri); - Assert.Equal($"/foo?TestDictionary.{(int)TestEnum.A}=value1{TestEnumUrlParameterFormatter.StringParameterSuffix}&TestDictionary.{(int)TestEnum.B}=value2{TestEnumUrlParameterFormatter.StringParameterSuffix}", uri.PathAndQuery); + Assert.Equal( + $"/foo?TestDictionary.{(int)TestEnum.A}=value1{TestEnumUrlParameterFormatter.StringParameterSuffix}&TestDictionary.{(int)TestEnum.B}=value2{TestEnumUrlParameterFormatter.StringParameterSuffix}", + uri.PathAndQuery + ); } } static class RequestBuilderTestExtensions { - public static Func BuildRequestFactoryForMethod(this IRequestBuilder builder, string methodName, string baseAddress = "http://api/") + public static Func BuildRequestFactoryForMethod( + this IRequestBuilder builder, + string methodName, + string baseAddress = "http://api/" + ) { var factory = builder.BuildRestResultFuncForMethod(methodName); var testHttpMessageHandler = new TestHttpMessageHandler(); - return paramList => { - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri(baseAddress) }, paramList); + var task = (Task)factory( + new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri(baseAddress) }, + paramList + ); task.Wait(); return testHttpMessageHandler.RequestMessage; }; } - - public static Func RunRequest(this IRequestBuilder builder, string methodName, string returnContent = null, string baseAddress = "http://api/") + public static Func RunRequest( + this IRequestBuilder builder, + string methodName, + string returnContent = null, + string baseAddress = "http://api/" + ) { var factory = builder.BuildRestResultFuncForMethod(methodName); var testHttpMessageHandler = new TestHttpMessageHandler(); @@ -2925,15 +3923,15 @@ public static Func RunRequest(this IRequestBui return paramList => { - var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri(baseAddress) }, paramList); + var task = (Task)factory( + new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri(baseAddress) }, + paramList + ); try { task.Wait(); } - catch (AggregateException e) when (e.InnerException is TaskCanceledException) - { - - } + catch (AggregateException e) when (e.InnerException is TaskCanceledException) { } return testHttpMessageHandler; }; diff --git a/Refit.Tests/ResponseTests.cs b/Refit.Tests/ResponseTests.cs index 73798fe54..687cf6c0d 100644 --- a/Refit.Tests/ResponseTests.cs +++ b/Refit.Tests/ResponseTests.cs @@ -32,14 +32,12 @@ public class ResponseTests { readonly MockHttpMessageHandler mockHandler; readonly IMyAliasService fixture; + public ResponseTests() { mockHandler = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHandler - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHandler }; fixture = RestService.For("http://api", settings); } @@ -59,8 +57,12 @@ public interface IMyAliasService [Fact] public async Task JsonPropertyCanBeUsedToAliasFieldNamesInResponses() { - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") - .Respond("application/json", "{\"FIELD_WE_SHOULD_SHORTEN_WITH_ALIAS_AS\": \"Hello\", \"FIELD_WE_SHOULD_SHORTEN_WITH_JSON_PROPERTY\": \"World\"}"); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") + .Respond( + "application/json", + "{\"FIELD_WE_SHOULD_SHORTEN_WITH_ALIAS_AS\": \"Hello\", \"FIELD_WE_SHOULD_SHORTEN_WITH_JSON_PROPERTY\": \"World\"}" + ); var result = await fixture.GetTestObject(); @@ -74,9 +76,12 @@ public async Task JsonPropertyCanBeUsedToAliasFieldNamesInResponses() [Fact] public async Task AliasAsCannotBeUsedToAliasFieldNamesInResponses() { - - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") - .Respond("application/json", "{\"FIELD_WE_SHOULD_SHORTEN_WITH_ALIAS_AS\": \"Hello\", \"FIELD_WE_SHOULD_SHORTEN_WITH_JSON_PROPERTY\": \"World\"}"); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") + .Respond( + "application/json", + "{\"FIELD_WE_SHOULD_SHORTEN_WITH_ALIAS_AS\": \"Hello\", \"FIELD_WE_SHOULD_SHORTEN_WITH_JSON_PROPERTY\": \"World\"}" + ); var result = await fixture.GetTestObject(); @@ -92,7 +97,11 @@ public async Task ThrowsValidationException() var expectedContent = new ProblemDetails { Detail = "detail", - Errors = { { "Field1", new string[] { "Problem1" } }, { "Field2", new string[] { "Problem2" } } }, + Errors = + { + { "Field1", new string[] { "Problem1" } }, + { "Field2", new string[] { "Problem2" } } + }, Instance = "instance", Status = 1, Title = "title", @@ -102,11 +111,15 @@ public async Task ThrowsValidationException() { Content = new StringContent(JsonConvert.SerializeObject(expectedContent)) }; - expectedResponse.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") + expectedResponse.Content.Headers.ContentType = + new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => fixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => fixture.GetTestObject() + ); Assert.NotNull(actualException.Content); Assert.Equal("detail", actualException.Content.Detail); Assert.Equal("Problem1", actualException.Content.Errors["Field1"][0]); @@ -116,7 +129,7 @@ public async Task ThrowsValidationException() Assert.Equal("title", actualException.Content.Title); Assert.Equal("type", actualException.Content.Type); } - + /// /// Test to verify if EnsureSuccessStatusCodeAsync throws a ValidationApiException for a Bad Request in terms of RFC 7807 /// @@ -126,7 +139,11 @@ public async Task When_BadRequest_EnsureSuccessStatusCodeAsync_ThrowsValidationE var expectedContent = new ProblemDetails { Detail = "detail", - Errors = { { "Field1", new string[] { "Problem1" } }, { "Field2", new string[] { "Problem2" } } }, + Errors = + { + { "Field1", new string[] { "Problem1" } }, + { "Field2", new string[] { "Problem2" } } + }, Instance = "instance", Status = 1, Title = "title", @@ -138,12 +155,16 @@ public async Task When_BadRequest_EnsureSuccessStatusCodeAsync_ThrowsValidationE Content = new StringContent(JsonConvert.SerializeObject(expectedContent)) }; - expectedResponse.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); - mockHandler.Expect(HttpMethod.Get, "http://api/GetApiResponseTestObject") + expectedResponse.Content.Headers.ContentType = + new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); + mockHandler + .Expect(HttpMethod.Get, "http://api/GetApiResponseTestObject") .Respond(req => expectedResponse); using var response = await fixture.GetApiResponseTestObject(); - var actualException = await Assert.ThrowsAsync(() => response.EnsureSuccessStatusCodeAsync()); + var actualException = await Assert.ThrowsAsync( + () => response.EnsureSuccessStatusCodeAsync() + ); Assert.NotNull(actualException.Content); Assert.Equal("detail", actualException.Content.Detail); @@ -174,14 +195,19 @@ public async Task WhenProblemDetailsResponseContainsExtensions_ShouldHydrateExte Content = new StringContent(JsonConvert.SerializeObject(expectedContent)) }; - expectedResponse.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") + expectedResponse.Content.Headers.ContentType = + new System.Net.Http.Headers.MediaTypeHeaderValue("application/problem+json"); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") .Respond(req => expectedResponse); - mockHandler.Expect(HttpMethod.Get, "http://api/soloyolo") + mockHandler + .Expect(HttpMethod.Get, "http://api/soloyolo") .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => fixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => fixture.GetTestObject() + ); Assert.NotNull(actualException.Content); Assert.Equal("detail", actualException.Content.Detail); Assert.Equal("instance", actualException.Content.Instance); @@ -189,9 +215,25 @@ public async Task WhenProblemDetailsResponseContainsExtensions_ShouldHydrateExte Assert.Equal("title", actualException.Content.Title); Assert.Equal("type", actualException.Content.Type); - Assert.Collection(actualException.Content.Extensions, - kvp => Assert.Equal(new KeyValuePair(nameof(expectedContent.Foo), expectedContent.Foo), kvp), - kvp => Assert.Equal(new KeyValuePair(nameof(expectedContent.Baz), expectedContent.Baz), kvp)); + Assert.Collection( + actualException.Content.Extensions, + kvp => + Assert.Equal( + new KeyValuePair( + nameof(expectedContent.Foo), + expectedContent.Foo + ), + kvp + ), + kvp => + Assert.Equal( + new KeyValuePair( + nameof(expectedContent.Baz), + expectedContent.Baz + ), + kvp + ) + ); } [Fact] @@ -199,7 +241,9 @@ public async Task WithNonSeekableStream_UsingSystemTextJsonContentSerializer() { var model = new TestAliasObject { - ShortNameForAlias = nameof(WithNonSeekableStream_UsingSystemTextJsonContentSerializer), + ShortNameForAlias = nameof( + WithNonSeekableStream_UsingSystemTextJsonContentSerializer + ), ShortNameForJsonProperty = nameof(TestAliasObject) }; @@ -230,7 +274,10 @@ public async Task WithNonSeekableStream_UsingSystemTextJsonContentSerializer() { Headers = { - ContentType = new MediaTypeHeaderValue("application/json") { CharSet = Encoding.UTF8.WebName } + ContentType = new MediaTypeHeaderValue("application/json") + { + CharSet = Encoding.UTF8.WebName + } } }; @@ -239,17 +286,24 @@ public async Task WithNonSeekableStream_UsingSystemTextJsonContentSerializer() Content = httpContent }; - expectedResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + expectedResponse.Content.Headers.ContentType = new MediaTypeHeaderValue( + "application/json" + ); expectedResponse.StatusCode = HttpStatusCode.OK; - localHandler.Expect(HttpMethod.Get, "http://api/aliasTest").Respond(req => expectedResponse); + localHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") + .Respond(req => expectedResponse); var localFixture = RestService.For("http://api", settings); var result = await localFixture.GetTestObject(); Assert.NotNull(result); - Assert.Equal(nameof(WithNonSeekableStream_UsingSystemTextJsonContentSerializer), result.ShortNameForAlias); + Assert.Equal( + nameof(WithNonSeekableStream_UsingSystemTextJsonContentSerializer), + result.ShortNameForAlias + ); Assert.Equal(nameof(TestAliasObject), result.ShortNameForJsonProperty); } @@ -262,10 +316,13 @@ public async Task BadRequestWithEmptyContent_ShouldReturnApiException() }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => fixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => fixture.GetTestObject() + ); Assert.NotNull(actualException.Content); Assert.Equal("Hello world", actualException.Content); @@ -280,7 +337,8 @@ public async Task BadRequestWithEmptyContent_ShouldReturnApiResponse() }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") + mockHandler + .Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") .Respond(req => expectedResponse); var apiResponse = await fixture.GetApiResponseTestObject(); @@ -300,7 +358,8 @@ public async Task BadRequestWithStringContent_ShouldReturnIApiResponse() }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetIApiResponse)}") + mockHandler + .Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetIApiResponse)}") .Respond(req => expectedResponse); var apiResponse = await fixture.GetIApiResponse(); @@ -327,16 +386,20 @@ public async Task ValidationApiException_HydratesBaseContent() { Content = new StringContent(expectedContent) }; - expectedResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/problem+json"); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") + expectedResponse.Content.Headers.ContentType = new MediaTypeHeaderValue( + "application/problem+json" + ); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => fixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => fixture.GetTestObject() + ); var actualBaseException = actualException as ApiException; Assert.Equal(expectedContent, actualBaseException.Content); } - [Fact] public async Task WithHtmlResponse_ShouldReturnApiException() { @@ -347,10 +410,13 @@ public async Task WithHtmlResponse_ShouldReturnApiException() }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") - .Respond(req => expectedResponse); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") + .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => fixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => fixture.GetTestObject() + ); Assert.IsType(actualException.InnerException); Assert.NotNull(actualException.Content); @@ -367,7 +433,8 @@ public async Task WithHtmlResponse_ShouldReturnApiResponse() }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") + mockHandler + .Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") .Respond(req => expectedResponse); var apiResponse = await fixture.GetApiResponseTestObject(); @@ -396,17 +463,19 @@ public async Task WithNonJsonResponseUsingNewtonsoftJsonContentSerializer_Should }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, "http://api/aliasTest") - .Respond(req => expectedResponse); + mockHandler + .Expect(HttpMethod.Get, "http://api/aliasTest") + .Respond(req => expectedResponse); - var actualException = await Assert.ThrowsAsync(() => newtonSoftFixture.GetTestObject()); + var actualException = await Assert.ThrowsAsync( + () => newtonSoftFixture.GetTestObject() + ); Assert.IsType(actualException.InnerException); Assert.NotNull(actualException.Content); Assert.Equal(nonJsonResponse, actualException.Content); } - [Fact] public async Task WithNonJsonResponseUsingNewtonsoftJsonContentSerializer_ShouldReturnApiResponse() { @@ -425,7 +494,8 @@ public async Task WithNonJsonResponseUsingNewtonsoftJsonContentSerializer_Should }; expectedResponse.Content.Headers.Clear(); - mockHandler.Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") + mockHandler + .Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetApiResponseTestObject)}") .Respond(req => expectedResponse); var apiResponse = await newtonSoftFixture.GetApiResponseTestObject(); @@ -441,6 +511,7 @@ public sealed class ThrowOnGetLengthMemoryStream : MemoryStream { public bool CanGetLength { get; set; } - public override long Length => CanGetLength ? base.Length : throw new NotSupportedException(); + public override long Length => + CanGetLength ? base.Length : throw new NotSupportedException(); } } diff --git a/Refit.Tests/RestService.cs b/Refit.Tests/RestService.cs index 849ab4e2d..ec7090165 100644 --- a/Refit.Tests/RestService.cs +++ b/Refit.Tests/RestService.cs @@ -100,17 +100,24 @@ public interface IApiBindPathToObject Task GetFoos2(List values); [Post("/foos/{request.someProperty}/bar/{request.someProperty2}")] - Task PostFooBar(PathBoundObject request, [Body]object someObject); + Task PostFooBar(PathBoundObject request, [Body] object someObject); [Get("/foos/{request.someProperty}/bar/{request.someProperty2}")] Task GetFooBars(PathBoundObjectWithQuery request); [Post("/foos/{request.someProperty}/bar/{request.someProperty2}")] - Task PostFooBar(PathBoundObject request, [Query] ModelObject someQueryParams); + Task PostFooBar( + PathBoundObject request, + [Query] ModelObject someQueryParams + ); [Multipart] [Post("/foos/{request.someProperty}/bar/{request.someProperty2}")] - Task PostFooBarStreamPart(PathBoundObject request, [Query] ModelObject someQueryParams, StreamPart stream); + Task PostFooBarStreamPart( + PathBoundObject request, + [Query] ModelObject someQueryParams, + StreamPart stream + ); [Multipart] [Post("/foos/{request.someProperty}/bar/{request.someProperty2}")] @@ -118,7 +125,10 @@ public interface IApiBindPathToObject [Multipart] [Post("/foos/{request.someProperty}/bar/{request.someProperty2}")] - Task PostFooBarStreamPart(PathBoundObjectWithQuery request, StreamPart stream); + Task PostFooBarStreamPart( + PathBoundObjectWithQuery request, + StreamPart stream + ); } public class PathBoundList @@ -129,7 +139,6 @@ public class PathBoundList public class PathBoundDerivedObject : PathBoundObject { public string SomeProperty3 { get; set; } - } public class PathBoundObject @@ -137,7 +146,6 @@ public class PathBoundObject public int SomeProperty { get; set; } public string SomeProperty2 { get; set; } - } public class PathBoundObjectWithQuery @@ -148,12 +156,10 @@ public class PathBoundObjectWithQuery [Query] public string SomeQuery { get; set; } - } public class PathBoundObjectWithQueryFormat { - [Query(Format = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'")] public DateTime SomeQueryWithFormat { get; set; } } @@ -199,18 +205,16 @@ public interface IHttpBinApi Task Get(TParam param, [Header("X-Refit")] THeader header); [Get("/get?hardcoded=true")] - Task GetQuery([Query("_")]TParam param); + Task GetQuery([Query("_")] TParam param); [Post("/post?hardcoded=true")] - Task PostQuery([Query("_")]TParam param); + Task PostQuery([Query("_")] TParam param); [Get("")] - Task GetQueryWithIncludeParameterName([Query(".", "search")]TParam param); + Task GetQueryWithIncludeParameterName([Query(".", "search")] TParam param); [Get("/get?hardcoded=true")] - Task GetQuery1([Query("_")]TParam param); - - + Task GetQuery1([Query("_")] TParam param); } public interface IBrokenWebApi @@ -288,22 +292,18 @@ public void CanCreateInstanceUsingStaticMethod() { var instance = IRefitInterfaceWithStaticMethod.Create(); - Assert.NotNull(instance); } #endif - [Fact] public async Task CanAddContentHeadersToPostWithoutBody() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://foo/nobody") + mockHttp + .Expect(HttpMethod.Post, "http://foo/nobody") // The content length header is set automatically by the HttpContent instance, // so checking the header as a string doesn't work .With(r => r.Content?.Headers.ContentLength == 0) @@ -323,14 +323,12 @@ public async Task CanAddContentHeadersToPostWithoutBody() public async Task GetWithNoParametersTest() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/someendpoint") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/someendpoint") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); await fixture.Get(); @@ -341,15 +339,12 @@ public async Task GetWithNoParametersTest() public async Task BaseAddressFromHttpClientMatchesTest() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/someendpoint") - .WithExactQueryString("") - .Respond("application/json", "Ok"); - + mockHttp + .Expect(HttpMethod.Get, "http://foo/someendpoint") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var client = new HttpClient(mockHttp) - { - BaseAddress = new Uri("http://foo") - }; + var client = new HttpClient(mockHttp) { BaseAddress = new Uri("http://foo") }; var fixture = RestService.For(client); @@ -361,15 +356,12 @@ public async Task BaseAddressFromHttpClientMatchesTest() public async Task BaseAddressWithTrailingSlashFromHttpClientMatchesTest() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/someendpoint") - .WithExactQueryString("") - .Respond("application/json", "Ok"); - + mockHttp + .Expect(HttpMethod.Get, "http://foo/someendpoint") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var client = new HttpClient(mockHttp) - { - BaseAddress = new Uri("http://foo/") - }; + var client = new HttpClient(mockHttp) { BaseAddress = new Uri("http://foo/") }; var fixture = RestService.For(client); @@ -381,17 +373,15 @@ public async Task BaseAddressWithTrailingSlashFromHttpClientMatchesTest() public async Task BaseAddressWithTrailingSlashCalledBeforeFromHttpClientMatchesTest() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/someendpoint") - .WithExactQueryString("") - .Respond("application/json", "Ok"); - + mockHttp + .Expect(HttpMethod.Get, "http://foo/someendpoint") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var client = new HttpClient(mockHttp) - { - BaseAddress = new Uri("http://foo/") - }; + var client = new HttpClient(mockHttp) { BaseAddress = new Uri("http://foo/") }; - await client.GetAsync("/firstRequest"); ; + await client.GetAsync("/firstRequest"); + ; var fixture = RestService.For(client); @@ -403,14 +393,12 @@ public async Task BaseAddressWithTrailingSlashCalledBeforeFromHttpClientMatchesT public async Task GetWithNoParametersTestTrailingSlashInBase() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/someendpoint") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/someendpoint") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo/", settings); await fixture.Get(); @@ -421,21 +409,17 @@ public async Task GetWithNoParametersTestTrailingSlashInBase() public async Task GetWithPathBoundObject() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFooBars(new PathBoundObject() - { - SomeProperty = 1, - SomeProperty2 = "barNone" - }); + await fixture.GetFooBars( + new PathBoundObject() { SomeProperty = 1, SomeProperty2 = "barNone" } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -443,21 +427,17 @@ await fixture.GetFooBars(new PathBoundObject() public async Task GetWithPathBoundObjectDifferentCasing() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFooBarsWithDifferentCasing(new PathBoundObject() - { - SomeProperty = 1, - SomeProperty2 = "barNone" - }); + await fixture.GetFooBarsWithDifferentCasing( + new PathBoundObject() { SomeProperty = 1, SomeProperty2 = "barNone" } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -465,21 +445,18 @@ await fixture.GetFooBarsWithDifferentCasing(new PathBoundObject() public async Task GetWithPathBoundObjectAndParameter() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/myId/22/bar/bart") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/myId/22/bar/bart") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetBarsByFoo("myId", new PathBoundObject() - { - SomeProperty = 22, - SomeProperty2 = "bart" - }); + await fixture.GetBarsByFoo( + "myId", + new PathBoundObject() { SomeProperty = 22, SomeProperty2 = "bart" } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -487,21 +464,20 @@ public async Task GetWithPathBoundObjectAndParameter() public async Task GetWithPathBoundObjectAndParameterParameterPrecedence() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/chooseMe/bar/barNone") - .WithExactQueryString(new[] { new KeyValuePair("SomeProperty", "1") }) - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/chooseMe/bar/barNone") + .WithExactQueryString( + new[] { new KeyValuePair("SomeProperty", "1") } + ) + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFooBars(new PathBoundObject() - { - SomeProperty = 1, - SomeProperty2 = "barNone" - }, "chooseMe"); + await fixture.GetFooBars( + new PathBoundObject() { SomeProperty = 1, SomeProperty2 = "barNone" }, + "chooseMe" + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -509,22 +485,24 @@ await fixture.GetFooBars(new PathBoundObject() public async Task GetWithPathBoundDerivedObject() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/1/bar/test") - .WithExactQueryString(new[] { new KeyValuePair("SomeProperty2", "barNone") }) - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/1/bar/test") + .WithExactQueryString( + new[] { new KeyValuePair("SomeProperty2", "barNone") } + ) + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFooBarsDerived(new PathBoundDerivedObject() - { - SomeProperty = 1, - SomeProperty2 = "barNone", - SomeProperty3 = "test" - }); + await fixture.GetFooBarsDerived( + new PathBoundDerivedObject() + { + SomeProperty = 1, + SomeProperty2 = "barNone", + SomeProperty3 = "test" + } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -532,21 +510,19 @@ await fixture.GetFooBarsDerived(new PathBoundDerivedObject() public async Task GetWithPathBoundObjectAndQueryParameter() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/22/bar") - .WithExactQueryString(new[] { new KeyValuePair("SomeProperty2", "bart") }) - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/22/bar") + .WithExactQueryString( + new[] { new KeyValuePair("SomeProperty2", "bart") } + ) + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetBarsByFoo(new PathBoundObject() - { - SomeProperty = 22, - SomeProperty2 = "bart" - }); + await fixture.GetBarsByFoo( + new PathBoundObject() { SomeProperty = 22, SomeProperty2 = "bart" } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -554,20 +530,17 @@ await fixture.GetBarsByFoo(new PathBoundObject() public async Task PostFooBarPathBoundObject() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Post, "http://foo/foos/22/bar/bart") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Post, "http://foo/foos/22/bar/bart") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.PostFooBar(new PathBoundObject() - { - SomeProperty = 22, - SomeProperty2 = "bart" - }, new { }); + await fixture.PostFooBar( + new PathBoundObject() { SomeProperty = 22, SomeProperty2 = "bart" }, + new { } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -575,8 +548,9 @@ await fixture.PostFooBar(new PathBoundObject() public async Task PathBoundObjectsRespectFormatter() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/22%2C23") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/22%2C23") + .Respond("application/json", "Ok"); var settings = new RefitSettings { @@ -585,10 +559,12 @@ public async Task PathBoundObjectsRespectFormatter() }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFoos(new PathBoundList() - { - Values = new List() { 22, 23 } - }); + await fixture.GetFoos( + new PathBoundList() + { + Values = new List() { 22, 23 } + } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -596,22 +572,22 @@ await fixture.GetFoos(new PathBoundList() public async Task GetWithPathBoundObjectAndQuery() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") - .WithExactQueryString("SomeQuery=test") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foos/1/bar/barNone") + .WithExactQueryString("SomeQuery=test") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetFooBars(new PathBoundObjectWithQuery() - { - SomeProperty = 1, - SomeProperty2 = "barNone", - SomeQuery = "test" - }); + await fixture.GetFooBars( + new PathBoundObjectWithQuery() + { + SomeProperty = 1, + SomeProperty2 = "barNone", + SomeQuery = "test" + } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -619,20 +595,20 @@ await fixture.GetFooBars(new PathBoundObjectWithQuery() public async Task GetWithPathBoundObjectAndQueryWithFormat() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Get, "http://foo/foo") - .WithExactQueryString("SomeQueryWithFormat=2020-03-05T13:55:00Z") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/foo") + .WithExactQueryString("SomeQueryWithFormat=2020-03-05T13:55:00Z") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.GetBarsWithCustomQueryFormat(new PathBoundObjectWithQueryFormat - { - SomeQueryWithFormat = new DateTime(2020, 03, 05, 13, 55, 00) - }); + await fixture.GetBarsWithCustomQueryFormat( + new PathBoundObjectWithQueryFormat + { + SomeQueryWithFormat = new DateTime(2020, 03, 05, 13, 55, 00) + } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -641,25 +617,18 @@ await fixture.GetBarsWithCustomQueryFormat(new PathBoundObjectWithQueryFormat public async Task GetWithPathBoundObjectAndQueryObject() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Post, "http://foo/foos/1/bar/barNone") - .WithExactQueryString("Property1=test&Property2=test2") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Post, "http://foo/foos/1/bar/barNone") + .WithExactQueryString("Property1=test&Property2=test2") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); - await fixture.PostFooBar(new PathBoundObject() - { - SomeProperty = 1, - SomeProperty2 = "barNone" - }, new ModelObject() - { - Property1 = "test", - Property2 = "test2" - }); + await fixture.PostFooBar( + new PathBoundObject() { SomeProperty = 1, SomeProperty2 = "barNone" }, + new ModelObject() { Property1 = "test", Property2 = "test2" } + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -667,22 +636,19 @@ await fixture.PostFooBar(new PathBoundObject() public async Task PostFooBarPathMultipart() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") - .WithExactQueryString("") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") + .WithExactQueryString("") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); using var stream = GetTestFileStream("Test Files/Test.pdf"); - await fixture.PostFooBarStreamPart(new PathBoundObject() - { - SomeProperty = 22, - SomeProperty2 = "bar" - }, new StreamPart(stream, "Test.pdf", "application/pdf")); + await fixture.PostFooBarStreamPart( + new PathBoundObject() { SomeProperty = 22, SomeProperty2 = "bar" }, + new StreamPart(stream, "Test.pdf", "application/pdf") + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -690,23 +656,24 @@ await fixture.PostFooBarStreamPart(new PathBoundObject() public async Task PostFooBarPathQueryMultipart() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") - .WithExactQueryString("SomeQuery=test") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") + .WithExactQueryString("SomeQuery=test") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); using var stream = GetTestFileStream("Test Files/Test.pdf"); - await fixture.PostFooBarStreamPart(new PathBoundObjectWithQuery() - { - SomeProperty = 22, - SomeProperty2 = "bar", - SomeQuery = "test" - }, new StreamPart(stream, "Test.pdf", "application/pdf")); + await fixture.PostFooBarStreamPart( + new PathBoundObjectWithQuery() + { + SomeProperty = 22, + SomeProperty2 = "bar", + SomeQuery = "test" + }, + new StreamPart(stream, "Test.pdf", "application/pdf") + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -714,26 +681,20 @@ await fixture.PostFooBarStreamPart(new PathBoundObjectWithQuery() public async Task PostFooBarPathQueryObjectMultipart() { var mockHttp = new MockHttpMessageHandler(); - mockHttp.Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") - .WithExactQueryString("Property1=test&Property2=test2") - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Post, "http://foo/foos/22/bar/bar") + .WithExactQueryString("Property1=test&Property2=test2") + .Respond("application/json", "Ok"); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://foo", settings); using var stream = GetTestFileStream("Test Files/Test.pdf"); - await fixture.PostFooBarStreamPart(new PathBoundObject - { - SomeProperty = 22, - SomeProperty2 = "bar" - }, new ModelObject() - { - Property1 = "test", - Property2 = "test2" - }, new StreamPart(stream, "Test.pdf", "application/pdf")); + await fixture.PostFooBarStreamPart( + new PathBoundObject { SomeProperty = 22, SomeProperty2 = "bar" }, + new ModelObject() { Property1 = "test", Property2 = "test2" }, + new StreamPart(stream, "Test.pdf", "application/pdf") + ); mockHttp.VerifyNoOutstandingExpectation(); } @@ -741,12 +702,10 @@ await fixture.PostFooBarStreamPart(new PathBoundObject public async Task DoesntAddAutoAddContentToGetRequest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "http://foo/nobody") + mockHttp + .Expect(HttpMethod.Get, "http://foo/nobody") // We can't add HttpContent to a GET request, // because HttpClient doesn't allow it and it will // blow up at runtime @@ -764,12 +723,10 @@ public async Task DoesntAddAutoAddContentToGetRequest() public async Task DoesntAddAutoAddContentToHeadRequest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Head, "http://foo/nobody") + mockHttp + .Expect(HttpMethod.Head, "http://foo/nobody") // We can't add HttpContent to a HEAD request, // because HttpClient doesn't allow it and it will // blow up at runtime @@ -787,26 +744,22 @@ public async Task DoesntAddAutoAddContentToHeadRequest() public async Task GetWithDecimal() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "http://foo/withDecimal") - .WithExactQueryString(new[] { new KeyValuePair("value", "3.456") }) - .Respond("application/json", "Ok"); + mockHttp + .Expect(HttpMethod.Get, "http://foo/withDecimal") + .WithExactQueryString(new[] { new KeyValuePair("value", "3.456") }) + .Respond("application/json", "Ok"); var fixture = RestService.For("http://foo", settings); const decimal val = 3.456M; - var result = await fixture.GetWithDecimal(val); mockHttp.VerifyNoOutstandingExpectation(); } - [Fact] public async Task HitTheGitHubUserApiAsApiResponse() { @@ -815,17 +768,28 @@ public async Task HitTheGitHubUserApiAsApiResponse() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; var responseMessage = new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, - Content = new StringContent("{ 'login':'octocat', 'avatar_url':'http://foo/bar' }", System.Text.Encoding.UTF8, "application/json"), + Content = new StringContent( + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }", + System.Text.Encoding.UTF8, + "application/json" + ), }; responseMessage.Headers.Add("Cookie", "Value"); - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/users/octocat").Respond(req => responseMessage); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond(req => responseMessage); var fixture = RestService.For("https://api.github.com", settings); @@ -851,11 +815,17 @@ public async Task HitTheNonExistentApiAsApiResponse() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") - .Respond(HttpStatusCode.NotFound); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") + .Respond(HttpStatusCode.NotFound); var fixture = RestService.For("https://api.github.com", settings); @@ -878,11 +848,17 @@ public async Task HitTheNonExistentApi() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") - .Respond(HttpStatusCode.NotFound); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") + .Respond(HttpStatusCode.NotFound); var fixture = RestService.For("https://api.github.com", settings); @@ -906,21 +882,33 @@ public async Task HitTheGitHubUserApiAsObservableApiResponse() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; var responseMessage = new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, - Content = new StringContent("{ 'login':'octocat', 'avatar_url':'http://foo/bar' }", System.Text.Encoding.UTF8, "application/json"), + Content = new StringContent( + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }", + System.Text.Encoding.UTF8, + "application/json" + ), }; responseMessage.Headers.Add("Cookie", "Value"); - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/users/octocat").Respond(req => responseMessage); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond(req => responseMessage); var fixture = RestService.For("https://api.github.com", settings); - var result = await fixture.GetUserObservableWithMetadata("octocat") + var result = await fixture + .GetUserObservableWithMetadata("octocat") .Timeout(TimeSpan.FromSeconds(10)); Assert.True(result.Headers.Any()); @@ -943,12 +931,20 @@ public async Task HitTheGitHubUserApi() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/users/octocat") - .Respond("application/json", "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }"); - + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond( + "application/json", + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }" + ); var fixture = RestService.For("https://api.github.com", settings); @@ -968,11 +964,20 @@ public async Task HitWithCamelCaseParameter() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/users/octocat") - .Respond("application/json", "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }"); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond( + "application/json", + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }" + ); var fixture = RestService.For("https://api.github.com", settings); @@ -992,12 +997,20 @@ public async Task HitTheGitHubOrgMembersApi() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") - .Respond("application/json", "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]"); - + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") + .Respond( + "application/json", + "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]" + ); var fixture = RestService.For("https://api.github.com", settings); @@ -1017,14 +1030,26 @@ public async Task HitTheGitHubOrgMembersApiInParallel() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") - .Respond("application/json", "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]"); - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") - .Respond("application/json", "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]"); - + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") + .Respond( + "application/json", + "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]" + ); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/orgs/github/members") + .Respond( + "application/json", + "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]" + ); var fixture = RestService.For("https://api.github.com", settings); @@ -1050,33 +1075,42 @@ public async Task RequestCanceledBeforeResponseRead() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; var cts = new CancellationTokenSource(); - mockHttp.When(HttpMethod.Get, "https://api.github.com/orgs/github/members") - .Respond(req => - { - // Cancel the request - cts.Cancel(); - - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StringContent("[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]", Encoding.UTF8, "application/json") - }; - }); + mockHttp + .When(HttpMethod.Get, "https://api.github.com/orgs/github/members") + .Respond(req => + { + // Cancel the request + cts.Cancel(); + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent( + "[{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]", + Encoding.UTF8, + "application/json" + ) + }; + }); var fixture = RestService.For("https://api.github.com", settings); - - var result = await Assert.ThrowsAsync(async () => await fixture.GetOrgMembers("github", cts.Token)); + var result = await Assert.ThrowsAsync( + async () => await fixture.GetOrgMembers("github", cts.Token) + ); AssertFirstLineContains(nameof(IGitHubApi.GetOrgMembers), result.StackTrace); } - [Fact] public async Task HitTheGitHubUserSearchApi() { @@ -1085,12 +1119,21 @@ public async Task HitTheGitHubUserSearchApi() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/search/users") - .WithQueryString("q", "tom repos:>42 followers:>1000") - .Respond("application/json", "{ 'total_count': 1, 'items': [{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]}"); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/search/users") + .WithQueryString("q", "tom repos:>42 followers:>1000") + .Respond( + "application/json", + "{ 'total_count': 1, 'items': [{ 'login':'octocat', 'avatar_url':'http://foo/bar', 'type':'User'}]}" + ); var fixture = RestService.For("https://api.github.com", settings); @@ -1109,16 +1152,25 @@ public async Task HitTheGitHubUserApiAsObservable() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Get, "https://api.github.com/users/octocat") - .Respond("application/json", "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }"); + mockHttp + .Expect(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond( + "application/json", + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }" + ); var fixture = RestService.For("https://api.github.com", settings); - - var result = await fixture.GetUserObservable("octocat") + var result = await fixture + .GetUserObservable("octocat") .Timeout(TimeSpan.FromSeconds(10)); Assert.Equal("octocat", result.Login); @@ -1135,16 +1187,24 @@ public async Task HitTheGitHubUserApiAsObservableAndSubscribeAfterTheFact() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.When(HttpMethod.Get, "https://api.github.com/users/octocat") - .Respond("application/json", "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }"); + mockHttp + .When(HttpMethod.Get, "https://api.github.com/users/octocat") + .Respond( + "application/json", + "{ 'login':'octocat', 'avatar_url':'http://foo/bar' }" + ); var fixture = RestService.For("https://api.github.com", settings); - var obs = fixture.GetUserObservable("octocat") - .Timeout(TimeSpan.FromSeconds(10)); + var obs = fixture.GetUserObservable("octocat").Timeout(TimeSpan.FromSeconds(10)); // NB: We're gonna await twice, so that the 2nd await is definitely // after the result has completed. @@ -1159,7 +1219,6 @@ public async Task TwoSubscriptionsResultInTwoRequests() { var input = new TestHttpMessageHandler { - // we need to use a factory here to ensure each request gets its own httpcontent instance ContentFactory = () => new StringContent("test") }; @@ -1169,8 +1228,7 @@ public async Task TwoSubscriptionsResultInTwoRequests() Assert.Equal(0, input.MessagesSent); - var obs = fixture.GetIndexObservable() - .Timeout(TimeSpan.FromSeconds(10)); + var obs = fixture.GetIndexObservable().Timeout(TimeSpan.FromSeconds(10)); var result1 = await obs; Assert.Equal(1, input.MessagesSent); @@ -1191,12 +1249,15 @@ public async Task ShouldRetHttpResponseMessage() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.When(HttpMethod.Get, "https://api.github.com/") - .Respond(HttpStatusCode.OK); - + mockHttp.When(HttpMethod.Get, "https://api.github.com/").Respond(HttpStatusCode.OK); var fixture = RestService.For("https://api.github.com", settings); var result = await fixture.GetIndex(); @@ -1213,14 +1274,20 @@ public async Task ShouldRetHttpResponseMessageWithNestedInterface() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.When(HttpMethod.Get, "https://api.github.com/") - .Respond(HttpStatusCode.OK); - + mockHttp.When(HttpMethod.Get, "https://api.github.com/").Respond(HttpStatusCode.OK); - var fixture = RestService.For("https://api.github.com", settings); + var fixture = RestService.For( + "https://api.github.com", + settings + ); var result = await fixture.GetIndex(); Assert.NotNull(result); @@ -1232,15 +1299,14 @@ public async Task HitTheNpmJs() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; - - mockHttp.Expect(HttpMethod.Get, "https://registry.npmjs.org/congruence") - .Respond("application/json", "{ \"_id\":\"congruence\", \"_rev\":\"rev\" , \"name\":\"name\"}"); - + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; + mockHttp + .Expect(HttpMethod.Get, "https://registry.npmjs.org/congruence") + .Respond( + "application/json", + "{ \"_id\":\"congruence\", \"_rev\":\"rev\" , \"name\":\"name\"}" + ); var fixture = RestService.For("https://registry.npmjs.org", settings); var result = await fixture.GetCongruence(); @@ -1255,17 +1321,14 @@ public async Task PostToRequestBin() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); - await fixture.Post(); mockHttp.VerifyNoOutstandingExpectation(); @@ -1276,18 +1339,15 @@ public async Task PostStringDefaultToRequestBin() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/foo") - .WithContent("raw string") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/foo") + .WithContent("raw string") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); - await fixture.PostRawStringDefault("raw string"); mockHttp.VerifyNoOutstandingExpectation(); @@ -1298,19 +1358,16 @@ public async Task PostStringJsonToRequestBin() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/foo") - .WithContent("\"json string\"") - .WithHeaders("Content-Type", "application/json; charset=utf-8") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/foo") + .WithContent("\"json string\"") + .WithHeaders("Content-Type", "application/json; charset=utf-8") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); - await fixture.PostRawStringJson("json string"); mockHttp.VerifyNoOutstandingExpectation(); @@ -1321,19 +1378,16 @@ public async Task PostStringUrlToRequestBin() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/foo") - .WithContent("url%26string") - .WithHeaders("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/foo") + .WithContent("url%26string") + .WithHeaders("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); - await fixture.PostRawStringUrlEncoded("url&string"); mockHttp.VerifyNoOutstandingExpectation(); @@ -1344,25 +1398,23 @@ public async Task PostToRequestBinWithGenerics() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); - await fixture.PostGeneric(5); mockHttp.VerifyNoOutstandingExpectation(); mockHttp.ResetExpectations(); - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/1h3a5jm1") + .Respond(HttpStatusCode.OK); await fixture.PostGeneric("4"); @@ -1374,10 +1426,7 @@ public async Task PostWithVoidReturnBufferedBodyExpectContentLengthHeader() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var postBody = new Dictionary { @@ -1385,7 +1434,8 @@ public async Task PostWithVoidReturnBufferedBodyExpectContentLengthHeader() { "once", "told me" } }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/foo") + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/foo") .With(request => request.Content?.Headers.ContentLength > 0) .Respond(HttpStatusCode.OK); @@ -1401,10 +1451,7 @@ public async Task PostWithNonVoidReturnBufferedBodyExpectContentLengthHeader() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var postBody = new Dictionary { @@ -1413,7 +1460,8 @@ public async Task PostWithNonVoidReturnBufferedBodyExpectContentLengthHeader() }; const string expectedResponse = "some response"; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/foo") + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/foo") .With(request => request.Content?.Headers.ContentLength > 0) .Respond("text/plain", expectedResponse); @@ -1431,15 +1479,13 @@ public async Task UseMethodWithArgumentsParameter() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("http://httpbin.org/", settings); - mockHttp.Expect(HttpMethod.Get, "http://httpbin.org/foo/something") - .Respond(HttpStatusCode.OK); + mockHttp + .Expect(HttpMethod.Get, "http://httpbin.org/foo/something") + .Respond(HttpStatusCode.OK); await fixture.SomeApiThatUsesVariableNameFromCodeGen("something"); @@ -1454,11 +1500,21 @@ public async Task CanGetDataOutOfErrorResponses() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.When(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") - .Respond(HttpStatusCode.NotFound, "application/json", "{'message': 'Not Found', 'documentation_url': 'http://foo/bar'}"); + mockHttp + .When(HttpMethod.Get, "https://api.github.com/give-me-some-404-action") + .Respond( + HttpStatusCode.NotFound, + "application/json", + "{'message': 'Not Found', 'documentation_url': 'http://foo/bar'}" + ); var fixture = RestService.For("https://api.github.com", settings); try @@ -1492,19 +1548,26 @@ public async Task CanSerializeBigData() BigData = Enumerable.Range(0, 800000).Select(x => (byte)(x % 256)).ToArray() }; - mockHttp.Expect(HttpMethod.Post, "http://httpbin.org/big") - .With(m => + mockHttp + .Expect(HttpMethod.Post, "http://httpbin.org/big") + .With(m => + { + async Task T() { - async Task T() - { - using var s = await m.Content.ReadAsStreamAsync(); - var it = await System.Text.Json.JsonSerializer.DeserializeAsync(s, new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase }); - return it.BigData.SequenceEqual(bigObject.BigData); - } - - return T().Result; - }) - .Respond(HttpStatusCode.OK); + using var s = await m.Content.ReadAsStreamAsync(); + var it = await System.Text.Json.JsonSerializer.DeserializeAsync( + s, + new System.Text.Json.JsonSerializerOptions + { + PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase + } + ); + return it.BigData.SequenceEqual(bigObject.BigData); + } + + return T().Result; + }) + .Respond(HttpStatusCode.OK); var fixture = RestService.For("http://httpbin.org/", settings); @@ -1521,17 +1584,27 @@ public async Task ErrorsFromApiReturnErrorContent() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Post, "https://api.github.com/users") - .Respond(HttpStatusCode.BadRequest, "application/json", "{ 'errors': [ 'error1', 'message' ]}"); - + mockHttp + .Expect(HttpMethod.Post, "https://api.github.com/users") + .Respond( + HttpStatusCode.BadRequest, + "application/json", + "{ 'errors': [ 'error1', 'message' ]}" + ); var fixture = RestService.For("https://api.github.com", settings); - - var result = await Assert.ThrowsAsync(async () => await fixture.CreateUser(new User { Name = "foo" })); + var result = await Assert.ThrowsAsync( + async () => await fixture.CreateUser(new User { Name = "foo" }) + ); AssertFirstLineContains(nameof(IGitHubApi.CreateUser), result.StackTrace); @@ -1543,7 +1616,6 @@ public async Task ErrorsFromApiReturnErrorContent() mockHttp.VerifyNoOutstandingExpectation(); } - [Fact] public async Task ErrorsFromApiReturnErrorContentWhenApiResponse() { @@ -1552,16 +1624,24 @@ public async Task ErrorsFromApiReturnErrorContentWhenApiResponse() var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, - ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings() { ContractResolver = new SnakeCasePropertyNamesContractResolver() }) + ContentSerializer = new NewtonsoftJsonContentSerializer( + new JsonSerializerSettings() + { + ContractResolver = new SnakeCasePropertyNamesContractResolver() + } + ) }; - mockHttp.Expect(HttpMethod.Post, "https://api.github.com/users") - .Respond(HttpStatusCode.BadRequest, "application/json", "{ 'errors': [ 'error1', 'message' ]}"); - + mockHttp + .Expect(HttpMethod.Post, "https://api.github.com/users") + .Respond( + HttpStatusCode.BadRequest, + "application/json", + "{ 'errors': [ 'error1', 'message' ]}" + ); var fixture = RestService.For("https://api.github.com", settings); - using var response = await fixture.CreateUserWithMetadata(new User { Name = "foo" }); Assert.False(response.IsSuccessStatusCode); Assert.NotNull(response.Error); @@ -1606,19 +1686,21 @@ public async Task GenericsWork() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; - - mockHttp.Expect(HttpMethod.Get, "http://httpbin.org/get") - .WithHeaders("X-Refit", "99") - .WithQueryString("param", "foo") - .Respond("application/json", "{\"url\": \"http://httpbin.org/get?param=foo\", \"args\": {\"param\": \"foo\"}, \"headers\":{\"X-Refit\":\"99\"}}"); - + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; + mockHttp + .Expect(HttpMethod.Get, "http://httpbin.org/get") + .WithHeaders("X-Refit", "99") + .WithQueryString("param", "foo") + .Respond( + "application/json", + "{\"url\": \"http://httpbin.org/get?param=foo\", \"args\": {\"param\": \"foo\"}, \"headers\":{\"X-Refit\":\"99\"}}" + ); - var fixture = RestService.For>("http://httpbin.org/get", settings); + var fixture = RestService.For>( + "http://httpbin.org/get", + settings + ); var result = await fixture.Get("foo", 99); @@ -1634,7 +1716,9 @@ public async Task ValueTypesArentValidButTheyWorkAnyway() { var handler = new TestHttpMessageHandler("true"); - var fixture = RestService.For(new HttpClient(handler) { BaseAddress = new Uri("http://nowhere.com") }); + var fixture = RestService.For( + new HttpClient(handler) { BaseAddress = new Uri("http://nowhere.com") } + ); var result = await fixture.PostAValue("Does this work?"); @@ -1649,7 +1733,9 @@ public async void MissingBaseUrlThrowsArgumentException() var fixture = RestService.For(client); // We should get an InvalidOperationException if we call a method without a base address set - var result = await Assert.ThrowsAsync(async () => await fixture.GetUser(null)); + var result = await Assert.ThrowsAsync( + async () => await fixture.GetUser(null) + ); AssertFirstLineContains(nameof(IGitHubApi.GetUser), result.StackTrace); } @@ -1659,22 +1745,22 @@ public async Task SimpleDynamicQueryparametersTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .WithHeaders("X-Refit", "99") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get?FirstName=John&LastName=Rambo\", \"args\": {\"FirstName\": \"John\", \"lName\": \"Rambo\"}}"); + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get?FirstName=John&LastName=Rambo\", \"args\": {\"FirstName\": \"John\", \"lName\": \"Rambo\"}}" + ); - var myParams = new MySimpleQueryParams - { - FirstName = "John", - LastName = "Rambo" - }; + var myParams = new MySimpleQueryParams { FirstName = "John", LastName = "Rambo" }; - var fixture = RestService.For>("https://httpbin.org/get", settings); + var fixture = RestService.For>( + "https://httpbin.org/get", + settings + ); var resp = await fixture.Get(myParams, 99); @@ -1687,19 +1773,16 @@ public async Task ComplexDynamicQueryparametersTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get?hardcoded=true&FirstName=John&LastName=Rambo&Addr_Zip=9999&Addr_Street=HomeStreet 99&MetaData_Age=99&MetaData_Initials=JR&MetaData_Birthday=10%2F31%2F1918 4%3A21%3A16 PM&Other=12345&Other=10%2F31%2F2017 4%3A21%3A17 PM&Other=696e8653-6671-4484-a65f-9485af95fd3a\", \"args\": { \"Addr_Street\": \"HomeStreet 99\", \"Addr_Zip\": \"9999\", \"FirstName\": \"John\", \"LastName\": \"Rambo\", \"MetaData_Age\": \"99\", \"MetaData_Birthday\": \"10/31/1981 4:32:59 PM\", \"MetaData_Initials\": \"JR\", \"Other\": [\"12345\",\"10/31/2017 4:32:59 PM\",\"60282dd2-f79a-4400-be01-bcb0e86e7bc6\"], \"hardcoded\": \"true\"}}"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get?hardcoded=true&FirstName=John&LastName=Rambo&Addr_Zip=9999&Addr_Street=HomeStreet 99&MetaData_Age=99&MetaData_Initials=JR&MetaData_Birthday=10%2F31%2F1918 4%3A21%3A16 PM&Other=12345&Other=10%2F31%2F2017 4%3A21%3A17 PM&Other=696e8653-6671-4484-a65f-9485af95fd3a\", \"args\": { \"Addr_Street\": \"HomeStreet 99\", \"Addr_Zip\": \"9999\", \"FirstName\": \"John\", \"LastName\": \"Rambo\", \"MetaData_Age\": \"99\", \"MetaData_Birthday\": \"10/31/1981 4:32:59 PM\", \"MetaData_Initials\": \"JR\", \"Other\": [\"12345\",\"10/31/2017 4:32:59 PM\",\"60282dd2-f79a-4400-be01-bcb0e86e7bc6\"], \"hardcoded\": \"true\"}}" + ); - var myParams = new MyComplexQueryParams - { - FirstName = "John", - LastName = "Rambo" - }; + var myParams = new MyComplexQueryParams { FirstName = "John", LastName = "Rambo" }; myParams.Address.Postcode = 9999; myParams.Address.Street = "HomeStreet 99"; @@ -1711,8 +1794,10 @@ public async Task ComplexDynamicQueryparametersTest() myParams.Other.Add(new DateTime(2017, 10, 31, 16, 24, 59)); myParams.Other.Add(new Guid("60282dd2-f79a-4400-be01-bcb0e86e7bc6")); - - var fixture = RestService.For>("https://httpbin.org", settings); + var fixture = RestService.For>( + "https://httpbin.org", + settings + ); var resp = await fixture.GetQuery(myParams); @@ -1726,19 +1811,16 @@ public async Task ComplexPostDynamicQueryparametersTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "https://httpbin.org/post") - .Respond("application/json", "{\"url\": \"https://httpbin.org/post?hardcoded=true&FirstName=John&LastName=Rambo&Addr_Zip=9999&Addr_Street=HomeStreet 99&MetaData_Age=99&MetaData_Initials=JR&MetaData_Birthday=10%2F31%2F1918 4%3A21%3A16 PM&Other=12345&Other=10%2F31%2F2017 4%3A21%3A17 PM&Other=696e8653-6671-4484-a65f-9485af95fd3a\", \"args\": { \"Addr_Street\": \"HomeStreet 99\", \"Addr_Zip\": \"9999\", \"FirstName\": \"John\", \"LastName\": \"Rambo\", \"MetaData_Age\": \"99\", \"MetaData_Birthday\": \"10/31/1981 4:32:59 PM\", \"MetaData_Initials\": \"JR\", \"Other\": [\"12345\",\"10/31/2017 4:32:59 PM\",\"60282dd2-f79a-4400-be01-bcb0e86e7bc6\"], \"hardcoded\": \"true\"}}"); + mockHttp + .Expect(HttpMethod.Post, "https://httpbin.org/post") + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/post?hardcoded=true&FirstName=John&LastName=Rambo&Addr_Zip=9999&Addr_Street=HomeStreet 99&MetaData_Age=99&MetaData_Initials=JR&MetaData_Birthday=10%2F31%2F1918 4%3A21%3A16 PM&Other=12345&Other=10%2F31%2F2017 4%3A21%3A17 PM&Other=696e8653-6671-4484-a65f-9485af95fd3a\", \"args\": { \"Addr_Street\": \"HomeStreet 99\", \"Addr_Zip\": \"9999\", \"FirstName\": \"John\", \"LastName\": \"Rambo\", \"MetaData_Age\": \"99\", \"MetaData_Birthday\": \"10/31/1981 4:32:59 PM\", \"MetaData_Initials\": \"JR\", \"Other\": [\"12345\",\"10/31/2017 4:32:59 PM\",\"60282dd2-f79a-4400-be01-bcb0e86e7bc6\"], \"hardcoded\": \"true\"}}" + ); - var myParams = new MyComplexQueryParams - { - FirstName = "John", - LastName = "Rambo" - }; + var myParams = new MyComplexQueryParams { FirstName = "John", LastName = "Rambo" }; myParams.Address.Postcode = 9999; myParams.Address.Street = "HomeStreet 99"; @@ -1750,8 +1832,10 @@ public async Task ComplexPostDynamicQueryparametersTest() myParams.Other.Add(new DateTime(2017, 10, 31, 16, 24, 59)); myParams.Other.Add(new Guid("60282dd2-f79a-4400-be01-bcb0e86e7bc6")); - - var fixture = RestService.For>("https://httpbin.org", settings); + var fixture = RestService.For>( + "https://httpbin.org", + settings + ); var resp = await fixture.PostQuery(myParams); @@ -1765,27 +1849,24 @@ public async Task GenericMethodTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; const string response = "4"; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", response); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond("application/json", response); var myParams = new Dictionary { ["FirstName"] = "John", ["LastName"] = "Rambo", - ["Address"] = new - { - Zip = 9999, - Street = "HomeStreet 99" - } + ["Address"] = new { Zip = 9999, Street = "HomeStreet 99" } }; - var fixture = RestService.For, int>>("https://httpbin.org", settings); + var fixture = RestService.For, int>>( + "https://httpbin.org", + settings + ); // Use the generic to get it as an ApiResponse of string var resp = await fixture.GetQuery1>(myParams); @@ -1793,8 +1874,9 @@ public async Task GenericMethodTest() mockHttp.VerifyNoOutstandingExpectation(); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", response); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond("application/json", response); // Get as string var resp1 = await fixture.GetQuery1(myParams); @@ -1803,9 +1885,9 @@ public async Task GenericMethodTest() mockHttp.VerifyNoOutstandingExpectation(); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", response); - + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond("application/json", response); var resp2 = await fixture.GetQuery1(myParams); Assert.Equal(4, resp2); @@ -1818,92 +1900,97 @@ public async Task InheritedMethodTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("https://httpbin.org", settings); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get").Respond("application/json", nameof(IAmInterfaceA.Ping)); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond("application/json", nameof(IAmInterfaceA.Ping)); var resp = await fixture.Ping(); Assert.Equal(nameof(IAmInterfaceA.Ping), resp); mockHttp.VerifyNoOutstandingExpectation(); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .Respond("application/json", nameof(IAmInterfaceB.Pong)); resp = await fixture.Pong(); Assert.Equal(nameof(IAmInterfaceB.Pong), resp); mockHttp.VerifyNoOutstandingExpectation(); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .Respond("application/json", nameof(IAmInterfaceC.Pang)); resp = await fixture.Pang(); Assert.Equal(nameof(IAmInterfaceC.Pang), resp); mockHttp.VerifyNoOutstandingExpectation(); } - [Fact] public async Task InheritedInterfaceWithOnlyBaseMethodsTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; var fixture = RestService.For("https://httpbin.org", settings); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get").Respond("application/json", nameof(IAmInterfaceA.Ping)); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond("application/json", nameof(IAmInterfaceA.Ping)); var resp = await fixture.Ping(); Assert.Equal(nameof(IAmInterfaceA.Ping), resp); mockHttp.VerifyNoOutstandingExpectation(); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") .Respond("application/json", nameof(IAmInterfaceB.Pong)); resp = await fixture.Pong(); Assert.Equal(nameof(IAmInterfaceB.Pong), resp); mockHttp.VerifyNoOutstandingExpectation(); } - [Fact] public async Task InheritedInterfaceWithoutRefitInBaseMethodsTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - var fixture = RestService.For("https://httpbin.org", settings); + var fixture = RestService.For( + "https://httpbin.org", + settings + ); - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/doSomething") - .WithQueryString("parameter", "4") - .Respond("application/json", nameof(IImplementTheInterfaceAndUseRefit.DoSomething)); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/doSomething") + .WithQueryString("parameter", "4") + .Respond("application/json", nameof(IImplementTheInterfaceAndUseRefit.DoSomething)); await fixture.DoSomething(4); mockHttp.VerifyNoOutstandingExpectation(); - - - - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/DoSomethingElse") - .Respond("application/json", nameof(IImplementTheInterfaceAndUseRefit.DoSomethingElse)); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/DoSomethingElse") + .Respond( + "application/json", + nameof(IImplementTheInterfaceAndUseRefit.DoSomethingElse) + ); await fixture.DoSomethingElse(); mockHttp.VerifyNoOutstandingExpectation(); - - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/DoSomethingElse") - .Respond("application/json", nameof(IImplementTheInterfaceAndUseRefit.DoSomethingElse)); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/DoSomethingElse") + .Respond( + "application/json", + nameof(IImplementTheInterfaceAndUseRefit.DoSomethingElse) + ); await ((IAmInterfaceEWithNoRefit)fixture).DoSomethingElse(); mockHttp.VerifyNoOutstandingExpectation(); - - Assert.Throws(() => RestService.For>("https://httpbin.org")); + Assert.Throws( + () => RestService.For>("https://httpbin.org") + ); } [Fact] @@ -1911,26 +1998,26 @@ public async Task DictionaryDynamicQueryparametersTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get?hardcoded=true&FirstName=John&LastName=Rambo&Address_Zip=9999&Address_Street=HomeStreet 99\", \"args\": {\"Address_Street\": \"HomeStreet 99\",\"Address_Zip\": \"9999\",\"FirstName\": \"John\",\"LastName\": \"Rambo\",\"hardcoded\": \"true\"}}"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get?hardcoded=true&FirstName=John&LastName=Rambo&Address_Zip=9999&Address_Street=HomeStreet 99\", \"args\": {\"Address_Street\": \"HomeStreet 99\",\"Address_Zip\": \"9999\",\"FirstName\": \"John\",\"LastName\": \"Rambo\",\"hardcoded\": \"true\"}}" + ); var myParams = new Dictionary { ["FirstName"] = "John", ["LastName"] = "Rambo", - ["Address"] = new - { - Zip = 9999, - Street = "HomeStreet 99" - } + ["Address"] = new { Zip = 9999, Street = "HomeStreet 99" } }; - var fixture = RestService.For, int>>("https://httpbin.org", settings); + var fixture = RestService.For, int>>( + "https://httpbin.org", + settings + ); var resp = await fixture.GetQuery(myParams); @@ -1944,23 +2031,23 @@ public async Task ComplexDynamicQueryparametersTestWithIncludeParameterName() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "https://httpbin.org/get") - .Respond("application/json", "{\"url\": \"https://httpbin.org/get?search.FirstName=John&search.LastName=Rambo&search.Addr.Zip=9999&search.Addr.Street=HomeStreet 99\", \"args\": {\"search.Addr.Street\": \"HomeStreet 99\",\"search.Addr.Zip\": \"9999\",\"search.FirstName\": \"John\",\"search.LastName\": \"Rambo\"}}"); + mockHttp + .Expect(HttpMethod.Get, "https://httpbin.org/get") + .Respond( + "application/json", + "{\"url\": \"https://httpbin.org/get?search.FirstName=John&search.LastName=Rambo&search.Addr.Zip=9999&search.Addr.Street=HomeStreet 99\", \"args\": {\"search.Addr.Street\": \"HomeStreet 99\",\"search.Addr.Zip\": \"9999\",\"search.FirstName\": \"John\",\"search.LastName\": \"Rambo\"}}" + ); - var myParams = new MyComplexQueryParams - { - FirstName = "John", - LastName = "Rambo" - }; + var myParams = new MyComplexQueryParams { FirstName = "John", LastName = "Rambo" }; myParams.Address.Postcode = 9999; myParams.Address.Street = "HomeStreet 99"; - var fixture = RestService.For>("https://httpbin.org/get", settings); + var fixture = RestService.For>( + "https://httpbin.org/get", + settings + ); var resp = await fixture.GetQueryWithIncludeParameterName(myParams); @@ -1973,12 +2060,10 @@ public async Task ComplexDynamicQueryparametersTestWithIncludeParameterName() public async Task ServiceOutsideNamespaceGetRequest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Get, "http://foo/") + mockHttp + .Expect(HttpMethod.Get, "http://foo/") // We can't add HttpContent to a GET request, // because HttpClient doesn't allow it and it will // blow up at runtime @@ -1996,13 +2081,9 @@ public async Task ServiceOutsideNamespaceGetRequest() public async Task ServiceOutsideNamespacePostRequest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; - mockHttp.Expect(HttpMethod.Post, "http://foo/") - .Respond("application/json", "Ok"); + mockHttp.Expect(HttpMethod.Post, "http://foo/").Respond("application/json", "Ok"); var fixture = RestService.For("http://foo", settings); @@ -2025,10 +2106,17 @@ public async Task CanSerializeContentAsXml() mockHttp .Expect(HttpMethod.Post, "/users") .WithHeaders("Content-Type:application/xml; charset=utf-8") - .Respond(req => new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StringContent("Created", Encoding.UTF8, "application/xml") - }); + .Respond( + req => + new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent( + "Created", + Encoding.UTF8, + "application/xml" + ) + } + ); var fixture = RestService.For("https://api.github.com", settings); @@ -2104,7 +2192,9 @@ public void NonGenericCreate() var expectedBaseAddress = "http://example.com/api"; var inputBaseAddress = "http://example.com/api/"; - var fixture = RestService.For(typeof(ITrimTrailingForwardSlashApi), inputBaseAddress) as ITrimTrailingForwardSlashApi; + var fixture = + RestService.For(typeof(ITrimTrailingForwardSlashApi), inputBaseAddress) + as ITrimTrailingForwardSlashApi; Assert.Equal(fixture.Client.BaseAddress.AbsoluteUri, expectedBaseAddress); } @@ -2114,15 +2204,11 @@ public async Task TypeCollisionTest() { var mockHttp = new MockHttpMessageHandler(); - var settings = new RefitSettings - { - HttpMessageHandlerFactory = () => mockHttp, - }; + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, }; const string Url = "https://httpbin.org/get"; - mockHttp.Expect(HttpMethod.Get, Url) - .Respond("application/json", "{ }"); + mockHttp.Expect(HttpMethod.Get, Url).Respond("application/json", "{ }"); var fixtureA = RestService.For(Url); @@ -2136,9 +2222,6 @@ public async Task TypeCollisionTest() Assert.IsType(respB); } - - - internal static Stream GetTestFileStream(string relativeFilePath) { const char namespaceSeparator = '.'; @@ -2147,24 +2230,32 @@ internal static Stream GetTestFileStream(string relativeFilePath) var assembly = Assembly.GetCallingAssembly(); // compute resource name suffix - var relativeName = "." + relativeFilePath - .Replace('\\', namespaceSeparator) - .Replace('/', namespaceSeparator) - .Replace(' ', '_'); + var relativeName = + "." + + relativeFilePath + .Replace('\\', namespaceSeparator) + .Replace('/', namespaceSeparator) + .Replace(' ', '_'); // get resource stream var fullName = assembly .GetManifestResourceNames() - .FirstOrDefault(name => name.EndsWith(relativeName, StringComparison.InvariantCulture)); + .FirstOrDefault( + name => name.EndsWith(relativeName, StringComparison.InvariantCulture) + ); if (fullName == null) { - throw new Exception($"Unable to find resource for path \"{relativeFilePath}\". Resource with name ending on \"{relativeName}\" was not found in assembly."); + throw new Exception( + $"Unable to find resource for path \"{relativeFilePath}\". Resource with name ending on \"{relativeName}\" was not found in assembly." + ); } var stream = assembly.GetManifestResourceStream(fullName); if (stream == null) { - throw new Exception($"Unable to find resource for path \"{relativeFilePath}\". Resource named \"{fullName}\" was not found in assembly."); + throw new Exception( + $"Unable to find resource for path \"{relativeFilePath}\". Resource named \"{fullName}\" was not found in assembly." + ); } return stream; diff --git a/Refit.Tests/SerializedContentTests.cs b/Refit.Tests/SerializedContentTests.cs index 15c354400..7dbc1c065 100644 --- a/Refit.Tests/SerializedContentTests.cs +++ b/Refit.Tests/SerializedContentTests.cs @@ -17,14 +17,20 @@ public class SerializedContentTests [InlineData(typeof(XmlContentSerializer))] public async Task WhenARequestRequiresABodyThenItDoesNotDeadlock(Type contentSerializerType) { - if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer) + if ( + Activator.CreateInstance(contentSerializerType) + is not IHttpContentSerializer serializer + ) { - throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}"); + throw new ArgumentException( + $"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}" + ); } var handler = new MockPushStreamContentHttpMessageHandler { - Asserts = async content => new StringContent(await content.ReadAsStringAsync().ConfigureAwait(false)) + Asserts = async content => + new StringContent(await content.ReadAsStringAsync().ConfigureAwait(false)) }; var settings = new RefitSettings(serializer) @@ -34,7 +40,8 @@ public async Task WhenARequestRequiresABodyThenItDoesNotDeadlock(Type contentSer var fixture = RestService.For(BaseAddress, settings); - var fixtureTask = await RunTaskWithATimeLimit(fixture.CreateUser(new User())).ConfigureAwait(false); + var fixtureTask = await RunTaskWithATimeLimit(fixture.CreateUser(new User())) + .ConfigureAwait(false); Assert.True(fixtureTask.IsCompleted); Assert.Equal(TaskStatus.RanToCompletion, fixtureTask.Status); } @@ -45,9 +52,14 @@ public async Task WhenARequestRequiresABodyThenItDoesNotDeadlock(Type contentSer [InlineData(typeof(XmlContentSerializer))] public async Task WhenARequestRequiresABodyThenItIsSerialized(Type contentSerializerType) { - if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer) + if ( + Activator.CreateInstance(contentSerializerType) + is not IHttpContentSerializer serializer + ) { - throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}"); + throw new ArgumentException( + $"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}" + ); } var model = new User @@ -61,8 +73,12 @@ public async Task WhenARequestRequiresABodyThenItIsSerialized(Type contentSerial { Asserts = async content => { - var stringContent = new StringContent(await content.ReadAsStringAsync().ConfigureAwait(false)); - var user = await serializer.FromHttpContentAsync(content).ConfigureAwait(false); + var stringContent = new StringContent( + await content.ReadAsStringAsync().ConfigureAwait(false) + ); + var user = await serializer + .FromHttpContentAsync(content) + .ConfigureAwait(false); Assert.NotSame(model, user); Assert.Equal(model.Name, user.Name); Assert.Equal(model.CreatedAt, user.CreatedAt); @@ -80,7 +96,8 @@ public async Task WhenARequestRequiresABodyThenItIsSerialized(Type contentSerial var fixture = RestService.For(BaseAddress, settings); - var fixtureTask = await RunTaskWithATimeLimit(fixture.CreateUser(model)).ConfigureAwait(false); + var fixtureTask = await RunTaskWithATimeLimit(fixture.CreateUser(model)) + .ConfigureAwait(false); Assert.True(fixtureTask.IsCompleted); } @@ -113,7 +130,10 @@ class MockPushStreamContentHttpMessageHandler : HttpMessageHandler { public Func> Asserts { get; set; } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { var content = request.Content as PushStreamContent; Assert.IsType(content); @@ -130,14 +150,16 @@ public async Task StreamDeserialization_UsingSystemTextJsonContentSerializer() { var model = new TestAliasObject { - ShortNameForAlias = nameof(StreamDeserialization_UsingSystemTextJsonContentSerializer), + ShortNameForAlias = nameof( + StreamDeserialization_UsingSystemTextJsonContentSerializer + ), ShortNameForJsonProperty = nameof(TestAliasObject) }; var serializer = new SystemTextJsonContentSerializer(); var json = serializer.ToHttpContent(model); - + var result = await serializer.FromHttpContentAsync(json); Assert.NotNull(result); @@ -150,7 +172,9 @@ public void StreamDeserialization_UsingSystemTextJsonContentSerializer_SetsCorre { var model = new TestAliasObject { - ShortNameForAlias = nameof(StreamDeserialization_UsingSystemTextJsonContentSerializer), + ShortNameForAlias = nameof( + StreamDeserialization_UsingSystemTextJsonContentSerializer + ), ShortNameForJsonProperty = nameof(TestAliasObject) }; diff --git a/Refit.Tests/UseCultureAttribute.cs b/Refit.Tests/UseCultureAttribute.cs index 5d3a4cb81..d45fd0f31 100644 --- a/Refit.Tests/UseCultureAttribute.cs +++ b/Refit.Tests/UseCultureAttribute.cs @@ -8,13 +8,16 @@ namespace Refit.Tests { - /// /// Apply this attribute to your test method to replace the /// and /// with another culture. /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = false, + Inherited = true + )] public class UseCultureAttribute : BeforeAfterTestAttribute { readonly Lazy culture; @@ -23,7 +26,6 @@ public class UseCultureAttribute : BeforeAfterTestAttribute CultureInfo originalCulture; CultureInfo originalUICulture; - /// /// Replaces the culture and UI culture of the current thread with /// @@ -36,8 +38,7 @@ public class UseCultureAttribute : BeforeAfterTestAttribute /// /// public UseCultureAttribute(string culture) - : this(culture, culture) - { } + : this(culture, culture) { } /// /// Replaces the culture and UI culture of the current thread with @@ -54,12 +55,18 @@ public UseCultureAttribute(string culture, string uiCulture) /// /// Gets the culture. /// - public CultureInfo Culture { get { return culture.Value; } } + public CultureInfo Culture + { + get { return culture.Value; } + } /// /// Gets the UI culture. /// - public CultureInfo UICulture { get { return uiCulture.Value; } } + public CultureInfo UICulture + { + get { return uiCulture.Value; } + } /// /// Stores the current @@ -72,7 +79,6 @@ public override void Before(MethodInfo methodUnderTest) originalCulture = CultureInfo.CurrentCulture; originalUICulture = CultureInfo.CurrentUICulture; - CultureInfo.CurrentCulture = Culture; CultureInfo.CurrentUICulture = UICulture; } @@ -88,6 +94,4 @@ public override void After(MethodInfo methodUnderTest) CultureInfo.CurrentUICulture = originalUICulture; } } - - } diff --git a/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1+Test.cs b/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1+Test.cs index 2781f056d..be8adea56 100644 --- a/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1+Test.cs +++ b/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1+Test.cs @@ -15,15 +15,23 @@ public class Test : CSharpSourceGeneratorTest - { - var compilationOptions = solution.GetProject(projectId).CompilationOptions; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); + SolutionTransforms.Add( + (solution, projectId) => + { + var compilationOptions = solution.GetProject(projectId).CompilationOptions; + compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( + compilationOptions.SpecificDiagnosticOptions.SetItems( + CSharpVerifierHelper.NullableWarnings + ) + ); + solution = solution.WithProjectCompilationOptions( + projectId, + compilationOptions + ); - return solution; - }); + return solution; + } + ); } /// diff --git a/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1.cs b/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1.cs index 9aa951242..068ecffde 100644 --- a/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1.cs +++ b/Refit.Tests/Verifiers/CSharpIncrementalSourceGeneratorVerifier`1.cs @@ -3,7 +3,5 @@ namespace Refit.Tests { public static partial class CSharpIncrementalSourceGeneratorVerifier - where TIncrementalGenerator : IIncrementalGenerator, new() - { - } + where TIncrementalGenerator : IIncrementalGenerator, new() { } } diff --git a/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1+Test.cs b/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1+Test.cs index e8bcbf254..0f1d672b2 100644 --- a/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1+Test.cs +++ b/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1+Test.cs @@ -13,15 +13,23 @@ public class Test : CSharpSourceGeneratorTest { public Test() { - SolutionTransforms.Add((solution, projectId) => - { - var compilationOptions = solution.GetProject(projectId).CompilationOptions; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( - compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); - solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); + SolutionTransforms.Add( + (solution, projectId) => + { + var compilationOptions = solution.GetProject(projectId).CompilationOptions; + compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( + compilationOptions.SpecificDiagnosticOptions.SetItems( + CSharpVerifierHelper.NullableWarnings + ) + ); + solution = solution.WithProjectCompilationOptions( + projectId, + compilationOptions + ); - return solution; - }); + return solution; + } + ); } } } diff --git a/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1.cs b/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1.cs index 121ae4d6f..3921a9722 100644 --- a/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1.cs +++ b/Refit.Tests/Verifiers/CSharpSourceGeneratorVerifier`1.cs @@ -3,7 +3,5 @@ namespace Refit.Tests { public static partial class CSharpSourceGeneratorVerifier - where TSourceGenerator : ISourceGenerator, new() - { - } + where TSourceGenerator : ISourceGenerator, new() { } } diff --git a/Refit.Tests/Verifiers/CSharpVerifierHelper.cs b/Refit.Tests/Verifiers/CSharpVerifierHelper.cs index bb92f669b..5b0e3a1fa 100644 --- a/Refit.Tests/Verifiers/CSharpVerifierHelper.cs +++ b/Refit.Tests/Verifiers/CSharpVerifierHelper.cs @@ -15,12 +15,17 @@ static class CSharpVerifierHelper /// related to nullability mapped to , which is then used to enable all /// of these warnings for default validation during analyzer and code fix tests. /// - internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler(); + internal static ImmutableDictionary NullableWarnings { get; } = + GetNullableWarningsFromCompiler(); static ImmutableDictionary GetNullableWarningsFromCompiler() { string[] args = { "/warnaserror:nullable" }; - var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); + var commandLineArguments = CSharpCommandLineParser.Default.Parse( + args, + baseDirectory: Environment.CurrentDirectory, + sdkDirectory: Environment.CurrentDirectory + ); return commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; } } diff --git a/Refit.Tests/XmlContentSerializerTests.cs b/Refit.Tests/XmlContentSerializerTests.cs index b1c49f69a..6cc40a7c8 100644 --- a/Refit.Tests/XmlContentSerializerTests.cs +++ b/Refit.Tests/XmlContentSerializerTests.cs @@ -42,8 +42,16 @@ public async Task ShouldSerializeToXml() var document = new XmlDocument(); document.LoadXml(await content.ReadAsStringAsync()); - var root = document[nameof(Dto)] ?? throw new NullReferenceException("Root element was not found"); - Assert.Equal(dto.CreatedOn, XmlConvert.ToDateTime(root[nameof(Dto.CreatedOn)].InnerText, XmlDateTimeSerializationMode.Utc)); + var root = + document[nameof(Dto)] + ?? throw new NullReferenceException("Root element was not found"); + Assert.Equal( + dto.CreatedOn, + XmlConvert.ToDateTime( + root[nameof(Dto.CreatedOn)].InnerText, + XmlDateTimeSerializationMode.Utc + ) + ); Assert.Equal(dto.Identifier, root[nameof(Dto.Identifier)].InnerText); Assert.Equal(dto.Name, root[nameof(Dto.Name)].InnerText); } @@ -55,7 +63,10 @@ public async Task ShouldSerializeToXmlUsingAttributeOverrides() var dto = BuildDto(); var serializerSettings = new XmlContentSerializerSettings(); - var attributes = new XmlAttributes { XmlRoot = new XmlRootAttribute(overridenRootElementName) }; + var attributes = new XmlAttributes + { + XmlRoot = new XmlRootAttribute(overridenRootElementName) + }; serializerSettings.XmlAttributeOverrides.Add(dto.GetType(), attributes); var sut = new XmlContentSerializer(serializerSettings); @@ -72,7 +83,10 @@ public async Task ShouldSerializeToXmlUsingNamespaceOverrides() const string prefix = "google"; var dto = BuildDto(); - var serializerSettings = new XmlContentSerializerSettings { XmlNamespaces = new XmlSerializerNamespaces() }; + var serializerSettings = new XmlContentSerializerSettings + { + XmlNamespaces = new XmlSerializerNamespaces() + }; serializerSettings.XmlNamespaces.Add(prefix, "https://google.com"); var sut = new XmlContentSerializer(serializerSettings); @@ -86,10 +100,15 @@ public async Task ShouldSerializeToXmlUsingNamespaceOverrides() [Fact] public async Task ShouldDeserializeFromXmlAsync() { - var serializerSettings = new XmlContentSerializerSettings { XmlNamespaces = new XmlSerializerNamespaces() }; + var serializerSettings = new XmlContentSerializerSettings + { + XmlNamespaces = new XmlSerializerNamespaces() + }; var sut = new XmlContentSerializer(serializerSettings); - var dto = await sut.FromHttpContentAsync(new StringContent("123")); + var dto = await sut.FromHttpContentAsync( + new StringContent("123") + ); Assert.Equal("123", dto.Identifier); } @@ -102,10 +121,7 @@ public async Task XmlEncodingShouldMatchWriterSettingAsync() { XmlReaderWriterSettings = new XmlReaderWriterSettings() { - WriterSettings = new XmlWriterSettings() - { - Encoding = encoding - } + WriterSettings = new XmlWriterSettings() { Encoding = encoding } } }; var sut = new XmlContentSerializer(serializerSettings); diff --git a/Refit.Xml/XmlContentSerializer.cs b/Refit.Xml/XmlContentSerializer.cs index 31e6d954d..ad15ca6c2 100644 --- a/Refit.Xml/XmlContentSerializer.cs +++ b/Refit.Xml/XmlContentSerializer.cs @@ -20,9 +20,8 @@ public class XmlContentSerializer : IHttpContentSerializer readonly XmlContentSerializerSettings settings; readonly ConcurrentDictionary serializerCache = new(); - public XmlContentSerializer() : this(new XmlContentSerializerSettings()) - { - } + public XmlContentSerializer() + : this(new XmlContentSerializerSettings()) { } public XmlContentSerializer(XmlContentSerializerSettings settings) { @@ -38,13 +37,21 @@ public XmlContentSerializer(XmlContentSerializerSettings settings) /// public HttpContent ToHttpContent(T item) { - if (item is null) throw new ArgumentNullException(nameof(item)); + if (item is null) + throw new ArgumentNullException(nameof(item)); - var xmlSerializer = serializerCache.GetOrAdd(item.GetType(), t => new XmlSerializer(t, settings.XmlAttributeOverrides)); + var xmlSerializer = serializerCache.GetOrAdd( + item.GetType(), + t => new XmlSerializer(t, settings.XmlAttributeOverrides) + ); using var stream = new MemoryStream(); - using var writer = XmlWriter.Create(stream, settings.XmlReaderWriterSettings.WriterSettings); - var encoding = settings.XmlReaderWriterSettings.WriterSettings?.Encoding ?? Encoding.Unicode; + using var writer = XmlWriter.Create( + stream, + settings.XmlReaderWriterSettings.WriterSettings + ); + var encoding = + settings.XmlReaderWriterSettings.WriterSettings?.Encoding ?? Encoding.Unicode; xmlSerializer.Serialize(writer, item, settings.XmlNamespaces); var str = encoding.GetString(stream.ToArray()); var content = new StringContent(str, encoding, "application/xml"); @@ -58,19 +65,31 @@ public HttpContent ToHttpContent(T item) /// HttpContent object with Xml content to deserialize. /// CancellationToken to abort the deserialization. /// The deserialized object of type . - public async Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) + public async Task FromHttpContentAsync( + HttpContent content, + CancellationToken cancellationToken = default + ) { - var xmlSerializer = serializerCache.GetOrAdd(typeof(T), t => new XmlSerializer( - t, - settings.XmlAttributeOverrides, - Array.Empty(), - null, - settings.XmlDefaultNamespace)); - - - using var input = new StringReader(await content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false)); - - using var reader = XmlReader.Create(input, settings.XmlReaderWriterSettings.ReaderSettings); + var xmlSerializer = serializerCache.GetOrAdd( + typeof(T), + t => + new XmlSerializer( + t, + settings.XmlAttributeOverrides, + Array.Empty(), + null, + settings.XmlDefaultNamespace + ) + ); + + using var input = new StringReader( + await content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false) + ); + + using var reader = XmlReader.Create( + input, + settings.XmlReaderWriterSettings.ReaderSettings + ); return (T?)xmlSerializer.Deserialize(reader); } @@ -80,13 +99,14 @@ public HttpContent ToHttpContent(T item) if (propertyInfo is null) throw new ArgumentNullException(nameof(propertyInfo)); - return propertyInfo.GetCustomAttributes(true) - .Select(a => a.ElementName) - .FirstOrDefault() - ?? - propertyInfo.GetCustomAttributes(true) - .Select(a => a.AttributeName) - .FirstOrDefault(); + return propertyInfo + .GetCustomAttributes(true) + .Select(a => a.ElementName) + .FirstOrDefault() + ?? propertyInfo + .GetCustomAttributes(true) + .Select(a => a.AttributeName) + .FirstOrDefault(); } } @@ -95,20 +115,20 @@ public class XmlReaderWriterSettings XmlReaderSettings readerSettings; XmlWriterSettings writerSettings; - public XmlReaderWriterSettings() : this(new XmlReaderSettings(), new XmlWriterSettings()) - { - } + public XmlReaderWriterSettings() + : this(new XmlReaderSettings(), new XmlWriterSettings()) { } - public XmlReaderWriterSettings(XmlReaderSettings readerSettings) : this(readerSettings, new XmlWriterSettings()) - { - } + public XmlReaderWriterSettings(XmlReaderSettings readerSettings) + : this(readerSettings, new XmlWriterSettings()) { } - public XmlReaderWriterSettings(XmlWriterSettings writerSettings) : this(new XmlReaderSettings(), writerSettings) - { - } + public XmlReaderWriterSettings(XmlWriterSettings writerSettings) + : this(new XmlReaderSettings(), writerSettings) { } #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public XmlReaderWriterSettings(XmlReaderSettings readerSettings, XmlWriterSettings writerSettings) + public XmlReaderWriterSettings( + XmlReaderSettings readerSettings, + XmlWriterSettings writerSettings + ) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { ReaderSettings = readerSettings; @@ -154,10 +174,8 @@ public XmlContentSerializerSettings() XmlDefaultNamespace = null; XmlReaderWriterSettings = new XmlReaderWriterSettings(); XmlNamespaces = new XmlSerializerNamespaces( - new[] - { - new XmlQualifiedName(string.Empty, string.Empty), - }); + new[] { new XmlQualifiedName(string.Empty, string.Empty), } + ); XmlAttributeOverrides = new XmlAttributeOverrides(); } diff --git a/Refit/ApiException.cs b/Refit/ApiException.cs index 00ee9d390..51f9d5dfb 100644 --- a/Refit/ApiException.cs +++ b/Refit/ApiException.cs @@ -60,13 +60,40 @@ public class ApiException : Exception /// public RefitSettings RefitSettings { get; } - protected ApiException(HttpRequestMessage message, HttpMethod httpMethod, string? content, HttpStatusCode statusCode, string? reasonPhrase, HttpResponseHeaders headers, RefitSettings refitSettings, Exception? innerException = null) : - this(CreateMessage(statusCode, reasonPhrase), message, httpMethod, content, statusCode, reasonPhrase, headers, refitSettings, innerException) - { - } - - protected ApiException(string exceptionMessage, HttpRequestMessage message, HttpMethod httpMethod, string? content, HttpStatusCode statusCode, string? reasonPhrase, HttpResponseHeaders headers, RefitSettings refitSettings, Exception? innerException = null) : - base(exceptionMessage, innerException) + protected ApiException( + HttpRequestMessage message, + HttpMethod httpMethod, + string? content, + HttpStatusCode statusCode, + string? reasonPhrase, + HttpResponseHeaders headers, + RefitSettings refitSettings, + Exception? innerException = null + ) + : this( + CreateMessage(statusCode, reasonPhrase), + message, + httpMethod, + content, + statusCode, + reasonPhrase, + headers, + refitSettings, + innerException + ) { } + + protected ApiException( + string exceptionMessage, + HttpRequestMessage message, + HttpMethod httpMethod, + string? content, + HttpStatusCode statusCode, + string? reasonPhrase, + HttpResponseHeaders headers, + RefitSettings refitSettings, + Exception? innerException = null + ) + : base(exceptionMessage, innerException) { RequestMessage = message; HttpMethod = httpMethod; @@ -82,9 +109,12 @@ protected ApiException(string exceptionMessage, HttpRequestMessage message, Http /// /// Type to deserialize the content to /// The response content deserialized as - public async Task GetContentAsAsync() => HasContent ? - await RefitSettings.ContentSerializer.FromHttpContentAsync(new StringContent(Content!)).ConfigureAwait(false) : - default; + public async Task GetContentAsAsync() => + HasContent + ? await RefitSettings.ContentSerializer + .FromHttpContentAsync(new StringContent(Content!)) + .ConfigureAwait(false) + : default; /// /// Create an instance of . @@ -96,11 +126,24 @@ await RefitSettings.ContentSerializer.FromHttpContentAsync(new StringContent( /// Add an inner exception to the . /// A newly created . #pragma warning disable VSTHRD200 // Use "Async" suffix for async methods - public static Task Create(HttpRequestMessage message, HttpMethod httpMethod, HttpResponseMessage response, RefitSettings refitSettings, Exception? innerException = null) + public static Task Create( + HttpRequestMessage message, + HttpMethod httpMethod, + HttpResponseMessage response, + RefitSettings refitSettings, + Exception? innerException = null + ) #pragma warning restore VSTHRD200 // Use "Async" suffix for async methods { var exceptionMessage = CreateMessage(response.StatusCode, response.ReasonPhrase); - return Create(exceptionMessage, message, httpMethod, response, refitSettings, innerException); + return Create( + exceptionMessage, + message, + httpMethod, + response, + refitSettings, + innerException + ); } /// @@ -114,10 +157,27 @@ public static Task Create(HttpRequestMessage message, HttpMethod h /// Add an inner exception to the . /// A newly created . #pragma warning disable VSTHRD200 // Use "Async" suffix for async methods - public static async Task Create(string exceptionMessage, HttpRequestMessage message, HttpMethod httpMethod, HttpResponseMessage response, RefitSettings refitSettings, Exception? innerException = null) + public static async Task Create( + string exceptionMessage, + HttpRequestMessage message, + HttpMethod httpMethod, + HttpResponseMessage response, + RefitSettings refitSettings, + Exception? innerException = null + ) #pragma warning restore VSTHRD200 // Use "Async" suffix for async methods { - var exception = new ApiException(exceptionMessage, message, httpMethod, null, response.StatusCode, response.ReasonPhrase, response.Headers, refitSettings, innerException); + var exception = new ApiException( + exceptionMessage, + message, + httpMethod, + null, + response.StatusCode, + response.ReasonPhrase, + response.Headers, + refitSettings, + innerException + ); if (response.Content == null) { @@ -130,17 +190,21 @@ public static async Task Create(string exceptionMessage, HttpReque var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); exception.Content = content; - if (response.Content.Headers?.ContentType?.MediaType?.Equals("application/problem+json") ?? false) + if ( + response.Content.Headers?.ContentType?.MediaType?.Equals( + "application/problem+json" + ) ?? false + ) { - exception = ValidationApiException.Create(exception); + exception = ValidationApiException.Create(exception); } response.Content.Dispose(); } catch { - // NB: We're already handling an exception at this point, - // so we want to make sure we don't throw another one + // NB: We're already handling an exception at this point, + // so we want to make sure we don't throw another one // that hides the real error. } diff --git a/Refit/ApiResponse.cs b/Refit/ApiResponse.cs index 823a150b1..cf1ff9d46 100644 --- a/Refit/ApiResponse.cs +++ b/Refit/ApiResponse.cs @@ -7,9 +7,21 @@ namespace Refit { static class ApiResponse { - internal static T Create(HttpResponseMessage resp, object? content, RefitSettings settings, ApiException? error = null) + internal static T Create( + HttpResponseMessage resp, + object? content, + RefitSettings settings, + ApiException? error = null + ) { - return (T)Activator.CreateInstance(typeof(ApiResponse), resp, content, settings, error)!; + return (T) + Activator.CreateInstance( + typeof(ApiResponse), + resp, + content, + settings, + error + )!; } } @@ -30,7 +42,12 @@ public sealed class ApiResponse : IApiResponse /// Refit settings used to send the request. /// The ApiException, if the request failed. /// - public ApiResponse(HttpResponseMessage response, T? content, RefitSettings settings, ApiException? error = null) + public ApiResponse( + HttpResponseMessage response, + T? content, + RefitSettings settings, + ApiException? error = null + ) { this.response = response ?? throw new ArgumentNullException(nameof(response)); Error = error; @@ -47,11 +64,11 @@ public ApiResponse(HttpResponseMessage response, T? content, RefitSettings setti /// Refit settings used to send the request. /// public RefitSettings Settings { get; } - + public HttpResponseHeaders Headers => response.Headers; - + public HttpContentHeaders? ContentHeaders => response.Content?.Headers; - + #if NET6_0_OR_GREATER [MemberNotNullWhen(true, nameof(Content))] [MemberNotNullWhen(true, nameof(ContentHeaders))] @@ -60,15 +77,14 @@ public ApiResponse(HttpResponseMessage response, T? content, RefitSettings setti public bool IsSuccessStatusCode => response.IsSuccessStatusCode; public string? ReasonPhrase => response.ReasonPhrase; - + public HttpRequestMessage? RequestMessage => response.RequestMessage; - + public HttpStatusCode StatusCode => response.StatusCode; - + public Version Version => response.Version; - - public ApiException? Error { get; private set; } + public ApiException? Error { get; private set; } public void Dispose() { @@ -84,7 +100,16 @@ public async Task> EnsureSuccessStatusCodeAsync() { if (!IsSuccessStatusCode) { - var exception = Error ?? await ApiException.Create(response.RequestMessage!, response.RequestMessage!.Method, response, Settings).ConfigureAwait(false); + var exception = + Error + ?? await ApiException + .Create( + response.RequestMessage!, + response.RequestMessage!.Method, + response, + Settings + ) + .ConfigureAwait(false); Dispose(); diff --git a/Refit/Attributes.cs b/Refit/Attributes.cs index 3aa29a567..7e6e0b995 100644 --- a/Refit/Attributes.cs +++ b/Refit/Attributes.cs @@ -11,11 +11,7 @@ public HttpMethodAttribute(string path) public abstract HttpMethod Method { get; } - public virtual string Path - { - get; - protected set; - } + public virtual string Path { get; protected set; } } /// @@ -24,7 +20,8 @@ public virtual string Path [AttributeUsage(AttributeTargets.Method)] public class GetAttribute : HttpMethodAttribute { - public GetAttribute(string path) : base(path) { } + public GetAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -38,7 +35,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class PostAttribute : HttpMethodAttribute { - public PostAttribute(string path) : base(path) { } + public PostAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -52,7 +50,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class PutAttribute : HttpMethodAttribute { - public PutAttribute(string path) : base(path) { } + public PutAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -66,7 +65,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class DeleteAttribute : HttpMethodAttribute { - public DeleteAttribute(string path) : base(path) { } + public DeleteAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -80,7 +80,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class PatchAttribute : HttpMethodAttribute { - public PatchAttribute(string path) : base(path) { } + public PatchAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -94,7 +95,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class OptionsAttribute : HttpMethodAttribute { - public OptionsAttribute(string path) : base(path) { } + public OptionsAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -108,7 +110,8 @@ public override HttpMethod Method [AttributeUsage(AttributeTargets.Method)] public class HeadAttribute : HttpMethodAttribute { - public HeadAttribute(string path) : base(path) { } + public HeadAttribute(string path) + : base(path) { } public override HttpMethod Method { @@ -131,7 +134,6 @@ public MultipartAttribute(string boundaryText = "----MyGreatBoundary") { BoundaryText = boundaryText; } - } /// @@ -175,10 +177,8 @@ public enum BodySerializationMethod [AttributeUsage(AttributeTargets.Parameter)] public class BodyAttribute : Attribute { - public BodyAttribute() - { + public BodyAttribute() { } - } public BodyAttribute(bool buffered) { Buffered = buffered; @@ -190,15 +190,16 @@ public BodyAttribute(BodySerializationMethod serializationMethod, bool buffered) Buffered = buffered; } - public BodyAttribute(BodySerializationMethod serializationMethod = BodySerializationMethod.Default) + public BodyAttribute( + BodySerializationMethod serializationMethod = BodySerializationMethod.Default + ) { SerializationMethod = serializationMethod; } - - public bool? Buffered { get; set; } - public BodySerializationMethod SerializationMethod { get; protected set; } = BodySerializationMethod.Default; + public BodySerializationMethod SerializationMethod { get; protected set; } = + BodySerializationMethod.Default; } /// @@ -216,7 +217,10 @@ public AliasAsAttribute(string name) } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] - [Obsolete("Use Refit.StreamPart, Refit.ByteArrayPart, Refit.FileInfoPart or if necessary, inherit from Refit.MultipartItem", false)] + [Obsolete( + "Use Refit.StreamPart, Refit.ByteArrayPart, Refit.FileInfoPart or if necessary, inherit from Refit.MultipartItem", + false + )] public class AttachmentNameAttribute : Attribute { public AttachmentNameAttribute(string name) @@ -231,10 +235,7 @@ public AttachmentNameAttribute(string name) /// Allows you to provide a Dictionary of headers to be added to the request. /// [AttributeUsage(AttributeTargets.Parameter)] - public class HeaderCollectionAttribute : Attribute - { - - } + public class HeaderCollectionAttribute : Attribute { } /// /// Add multiple headers to the request. diff --git a/Refit/AuthenticatedHttpClientHandler.cs b/Refit/AuthenticatedHttpClientHandler.cs index 84f45d67a..9401a2eb0 100644 --- a/Refit/AuthenticatedHttpClientHandler.cs +++ b/Refit/AuthenticatedHttpClientHandler.cs @@ -7,13 +7,19 @@ class AuthenticatedHttpClientHandler : DelegatingHandler { readonly Func> getToken; - public AuthenticatedHttpClientHandler(Func> getToken, HttpMessageHandler? innerHandler = null) + public AuthenticatedHttpClientHandler( + Func> getToken, + HttpMessageHandler? innerHandler = null + ) : base(innerHandler ?? new HttpClientHandler()) { this.getToken = getToken ?? throw new ArgumentNullException(nameof(getToken)); } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { // See if the request has an authorize header var auth = request.Headers.Authorization; diff --git a/Refit/Buffers/PooledBufferWriter.Stream.NETStandard21.cs b/Refit/Buffers/PooledBufferWriter.Stream.NETStandard21.cs index 370df4654..90ace7c05 100644 --- a/Refit/Buffers/PooledBufferWriter.Stream.NETStandard21.cs +++ b/Refit/Buffers/PooledBufferWriter.Stream.NETStandard21.cs @@ -16,7 +16,8 @@ private sealed partial class PooledMemoryStream : Stream /// public Task CopyToInternalAsync(Stream destination, CancellationToken cancellationToken) { - if (pooledBuffer is null) ThrowObjectDisposedException(); + if (pooledBuffer is null) + ThrowObjectDisposedException(); var bytesAvailable = length - position; @@ -28,7 +29,10 @@ public Task CopyToInternalAsync(Stream destination, CancellationToken cancellati } /// - public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + public override ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) { if (cancellationToken.IsCancellationRequested) { @@ -54,9 +58,11 @@ public override ValueTask ReadAsync(Memory buffer, CancellationToken /// public override int Read(Span buffer) { - if (pooledBuffer is null) ThrowObjectDisposedException(); + if (pooledBuffer is null) + ThrowObjectDisposedException(); - if (position >= length) return 0; + if (position >= length) + return 0; var bytesAvailable = length - position; diff --git a/Refit/Buffers/PooledBufferWriter.Stream.cs b/Refit/Buffers/PooledBufferWriter.Stream.cs index 4d1e2c493..78aa91d89 100644 --- a/Refit/Buffers/PooledBufferWriter.Stream.cs +++ b/Refit/Buffers/PooledBufferWriter.Stream.cs @@ -60,7 +60,6 @@ public override long Position { get => position; set => ThrowNotSupportedException(); - } /// @@ -78,7 +77,11 @@ public override Task FlushAsync(CancellationToken cancellationToken) } /// - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + public override Task CopyToAsync( + Stream destination, + int bufferSize, + CancellationToken cancellationToken + ) { if (cancellationToken.IsCancellationRequested) { @@ -107,10 +110,14 @@ public override Task CopyToAsync(Stream destination, int bufferSize, Cancellatio /// public override int Read(byte[] buffer, int offset, int count) { - if (offset < 0) ThrowArgumentOutOfRangeExceptionForNegativeOffset(); - if (count < 0) ThrowArgumentOutOfRangeExceptionForNegativeCount(); - if (offset + count > buffer.Length) ThrowArgumentOutOfRangeExceptionForEndOfStreamReached(); - if (pooledBuffer is null) ThrowObjectDisposedException(); + if (offset < 0) + ThrowArgumentOutOfRangeExceptionForNegativeOffset(); + if (count < 0) + ThrowArgumentOutOfRangeExceptionForNegativeCount(); + if (offset + count > buffer.Length) + ThrowArgumentOutOfRangeExceptionForEndOfStreamReached(); + if (pooledBuffer is null) + ThrowObjectDisposedException(); var destination = buffer.AsSpan(offset, count); var source = pooledBuffer.AsSpan(0, length).Slice(position); @@ -134,7 +141,12 @@ public override int Read(byte[] buffer, int offset, int count) } /// - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + public override Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) { if (cancellationToken.IsCancellationRequested) { @@ -160,7 +172,8 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel /// public override int ReadByte() { - if (pooledBuffer is null) ThrowObjectDisposedException(); + if (pooledBuffer is null) + ThrowObjectDisposedException(); if (position >= pooledBuffer!.Length) { @@ -193,7 +206,8 @@ public override void Write(byte[] buffer, int offset, int count) /// protected override void Dispose(bool disposing) { - if (pooledBuffer == null) return; + if (pooledBuffer == null) + return; GC.SuppressFinalize(this); diff --git a/Refit/Buffers/PooledBufferWriter.cs b/Refit/Buffers/PooledBufferWriter.cs index 4ed0ee614..a2325efe8 100644 --- a/Refit/Buffers/PooledBufferWriter.cs +++ b/Refit/Buffers/PooledBufferWriter.cs @@ -35,8 +35,10 @@ public PooledBufferWriter() /// public void Advance(int count) { - if (count < 0) ThrowArgumentOutOfRangeExceptionForNegativeCount(); - if (position > buffer.Length - count) ThrowArgumentOutOfRangeExceptionForAdvancedTooFar(); + if (count < 0) + ThrowArgumentOutOfRangeExceptionForNegativeCount(); + if (position > buffer.Length - count) + ThrowArgumentOutOfRangeExceptionForAdvancedTooFar(); position += count; } @@ -62,20 +64,21 @@ public Span GetSpan(int sizeHint = 0) /// /// The size in bytes of the new data to insert into the buffer [MethodImpl(MethodImplOptions.AggressiveInlining)] -void EnsureFreeCapacity(int count) + void EnsureFreeCapacity(int count) { - if (count < 0) ThrowArgumentOutOfRangeExceptionForNegativeCount(); + if (count < 0) + ThrowArgumentOutOfRangeExceptionForNegativeCount(); - if (count == 0) count = 1; + if (count == 0) + count = 1; - int - currentLength = buffer.Length, + int currentLength = buffer.Length, freeCapacity = currentLength - position; - if (count <= freeCapacity) return; + if (count <= freeCapacity) + return; - int - growBy = Math.Max(count, currentLength), + int growBy = Math.Max(count, currentLength), newSize = checked(currentLength + growBy); var rent = ArrayPool.Shared.Rent(newSize); @@ -90,7 +93,8 @@ void EnsureFreeCapacity(int count) /// public void Dispose() { - if (buffer.Length == 0) return; + if (buffer.Length == 0) + return; ArrayPool.Shared.Return(buffer); } diff --git a/Refit/CachedRequestBuilderImplementation.cs b/Refit/CachedRequestBuilderImplementation.cs index 67271526b..951b08d9e 100644 --- a/Refit/CachedRequestBuilderImplementation.cs +++ b/Refit/CachedRequestBuilderImplementation.cs @@ -3,32 +3,57 @@ namespace Refit { - class CachedRequestBuilderImplementation : CachedRequestBuilderImplementation, IRequestBuilder + class CachedRequestBuilderImplementation + : CachedRequestBuilderImplementation, + IRequestBuilder { - public CachedRequestBuilderImplementation(IRequestBuilder innerBuilder) : base(innerBuilder) - { - } + public CachedRequestBuilderImplementation(IRequestBuilder innerBuilder) + : base(innerBuilder) { } } class CachedRequestBuilderImplementation : IRequestBuilder { public CachedRequestBuilderImplementation(IRequestBuilder innerBuilder) { - this.innerBuilder = innerBuilder ?? throw new ArgumentNullException(nameof(innerBuilder)); + this.innerBuilder = + innerBuilder ?? throw new ArgumentNullException(nameof(innerBuilder)); } readonly IRequestBuilder innerBuilder; - readonly ConcurrentDictionary> methodDictionary = new(); + readonly ConcurrentDictionary< + string, + Func + > methodDictionary = new(); - public Func BuildRestResultFuncForMethod(string methodName, Type[]? parameterTypes = null, Type[]? genericArgumentTypes = null) + public Func BuildRestResultFuncForMethod( + string methodName, + Type[]? parameterTypes = null, + Type[]? genericArgumentTypes = null + ) { - var cacheKey = GetCacheKey(methodName, parameterTypes ?? Array.Empty(), genericArgumentTypes ?? Array.Empty()); - var func = methodDictionary.GetOrAdd(cacheKey, _ => innerBuilder.BuildRestResultFuncForMethod(methodName, parameterTypes, genericArgumentTypes)); + var cacheKey = GetCacheKey( + methodName, + parameterTypes ?? Array.Empty(), + genericArgumentTypes ?? Array.Empty() + ); + var func = methodDictionary.GetOrAdd( + cacheKey, + _ => + innerBuilder.BuildRestResultFuncForMethod( + methodName, + parameterTypes, + genericArgumentTypes + ) + ); return func; } - static string GetCacheKey(string methodName, Type[] parameterTypes, Type[] genericArgumentTypes) + static string GetCacheKey( + string methodName, + Type[] parameterTypes, + Type[] genericArgumentTypes + ) { var genericDefinition = GetGenericString(genericArgumentTypes); var argumentString = GetArgumentString(parameterTypes); diff --git a/Refit/CloseGenericMethodKey.cs b/Refit/CloseGenericMethodKey.cs index e7684941f..d9560140f 100644 --- a/Refit/CloseGenericMethodKey.cs +++ b/Refit/CloseGenericMethodKey.cs @@ -13,7 +13,8 @@ internal CloseGenericMethodKey(MethodInfo openMethodInfo, Type[] types) public MethodInfo OpenMethodInfo { get; } public Type[] Types { get; } - public bool Equals(CloseGenericMethodKey other) => OpenMethodInfo == other.OpenMethodInfo && Types.SequenceEqual(other.Types); + public bool Equals(CloseGenericMethodKey other) => + OpenMethodInfo == other.OpenMethodInfo && Types.SequenceEqual(other.Types); public override bool Equals(object? obj) { diff --git a/Refit/CollectionFormat.cs b/Refit/CollectionFormat.cs index 244f02d33..30968a7fe 100644 --- a/Refit/CollectionFormat.cs +++ b/Refit/CollectionFormat.cs @@ -1,7 +1,7 @@ namespace Refit { /// - /// Collection format defined in https://swagger.io/docs/specification/2-0/describing-parameters/ + /// Collection format defined in https://swagger.io/docs/specification/2-0/describing-parameters/ /// public enum CollectionFormat { diff --git a/Refit/FormValueMultimap.cs b/Refit/FormValueMultimap.cs index ab9ead272..86f29f435 100644 --- a/Refit/FormValueMultimap.cs +++ b/Refit/FormValueMultimap.cs @@ -13,7 +13,8 @@ class FormValueMultimap : IEnumerable> { static readonly Dictionary PropertyCache = new(); - readonly IList> formEntries = new List>(); + readonly IList> formEntries = + new List>(); readonly IHttpContentSerializer contentSerializer; @@ -23,7 +24,8 @@ public FormValueMultimap(object source, RefitSettings settings) throw new ArgumentNullException(nameof(settings)); contentSerializer = settings.ContentSerializer; - if (source == null) return; + if (source == null) + return; if (source is IDictionary dictionary) { @@ -32,7 +34,10 @@ public FormValueMultimap(object source, RefitSettings settings) var value = dictionary[key]; if (value != null) { - Add(key.ToString(), settings.FormUrlEncodedParameterFormatter.Format(value, null)); + Add( + key.ToString(), + settings.FormUrlEncodedParameterFormatter.Format(value, null) + ); } } @@ -60,16 +65,23 @@ public FormValueMultimap(object source, RefitSettings settings) if (value is IEnumerable enumerable) { - var collectionFormat = attrib != null && attrib.IsCollectionFormatSpecified - ? attrib.CollectionFormat - : settings.CollectionFormat; + var collectionFormat = + attrib != null && attrib.IsCollectionFormatSpecified + ? attrib.CollectionFormat + : settings.CollectionFormat; switch (collectionFormat) { case CollectionFormat.Multi: foreach (var item in enumerable) { - Add(fieldName, settings.FormUrlEncodedParameterFormatter.Format(item, attrib?.Format)); + Add( + fieldName, + settings.FormUrlEncodedParameterFormatter.Format( + item, + attrib?.Format + ) + ); } break; case CollectionFormat.Csv: @@ -86,19 +98,36 @@ public FormValueMultimap(object source, RefitSettings settings) var formattedValues = enumerable .Cast() - .Select(v => settings.FormUrlEncodedParameterFormatter.Format(v, attrib?.Format)); + .Select( + v => + settings.FormUrlEncodedParameterFormatter.Format( + v, + attrib?.Format + ) + ); Add(fieldName, string.Join(delimiter, formattedValues)); break; default: - Add(fieldName, settings.FormUrlEncodedParameterFormatter.Format(value, attrib?.Format)); + Add( + fieldName, + settings.FormUrlEncodedParameterFormatter.Format( + value, + attrib?.Format + ) + ); break; } } else { - Add(fieldName, settings.FormUrlEncodedParameterFormatter.Format(value, attrib?.Format)); + Add( + fieldName, + settings.FormUrlEncodedParameterFormatter.Format( + value, + attrib?.Format + ) + ); } - } } } @@ -116,15 +145,23 @@ void Add(string? key, string? value) string GetFieldNameForProperty(PropertyInfo propertyInfo) { - var name = propertyInfo.GetCustomAttributes(true) - .Select(a => a.Name) - .FirstOrDefault() - ?? contentSerializer.GetFieldNameForProperty(propertyInfo) - ?? propertyInfo.Name; - - var qattrib = propertyInfo.GetCustomAttributes(true) - .Select(attr => !string.IsNullOrWhiteSpace(attr.Prefix) ? $"{attr.Prefix}{attr.Delimiter}{name}" : name) - .FirstOrDefault(); + var name = + propertyInfo + .GetCustomAttributes(true) + .Select(a => a.Name) + .FirstOrDefault() + ?? contentSerializer.GetFieldNameForProperty(propertyInfo) + ?? propertyInfo.Name; + + var qattrib = propertyInfo + .GetCustomAttributes(true) + .Select( + attr => + !string.IsNullOrWhiteSpace(attr.Prefix) + ? $"{attr.Prefix}{attr.Delimiter}{name}" + : name + ) + .FirstOrDefault(); return qattrib ?? name; } @@ -132,8 +169,8 @@ string GetFieldNameForProperty(PropertyInfo propertyInfo) static PropertyInfo[] GetProperties(Type type) { return type.GetProperties(BindingFlags.Instance | BindingFlags.Public) - .Where(p => p.CanRead && p.GetMethod?.IsPublic == true) - .ToArray(); + .Where(p => p.CanRead && p.GetMethod?.IsPublic == true) + .ToArray(); } public IEnumerator> GetEnumerator() diff --git a/Refit/HttpContentExtensions.cs b/Refit/HttpContentExtensions.cs index 9ea7668ae..6f55afaaa 100644 --- a/Refit/HttpContentExtensions.cs +++ b/Refit/HttpContentExtensions.cs @@ -7,13 +7,18 @@ static class HttpContentExtensions { #pragma warning disable IDE0079 // Remove unnecessary suppression #pragma warning disable IDE0060 // Remove unused parameter - public static Task ReadAsStreamAsync(this HttpContent httpContent, CancellationToken cancellationToken) - + public static Task ReadAsStreamAsync( + this HttpContent httpContent, + CancellationToken cancellationToken + ) { return httpContent.ReadAsStreamAsync(); } - public static Task ReadAsStringAsync(this HttpContent httpContent, CancellationToken cancellationToken) + public static Task ReadAsStringAsync( + this HttpContent httpContent, + CancellationToken cancellationToken + ) { return httpContent.ReadAsStringAsync(); } diff --git a/Refit/JsonContentSerializer.cs b/Refit/JsonContentSerializer.cs index e6b14d876..420f99ac2 100644 --- a/Refit/JsonContentSerializer.cs +++ b/Refit/JsonContentSerializer.cs @@ -3,7 +3,10 @@ namespace Refit { - [Obsolete("Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", true)] + [Obsolete( + "Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", + true + )] public class JsonContentSerializer : IHttpContentSerializer { public HttpContent ToHttpContent(T item) @@ -11,7 +14,10 @@ public HttpContent ToHttpContent(T item) throw new NotImplementedException(); } - public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) + public Task FromHttpContentAsync( + HttpContent content, + CancellationToken cancellationToken = default + ) { throw new NotImplementedException(); } diff --git a/Refit/MultipartItem.cs b/Refit/MultipartItem.cs index 4ee80a94d..fef54f019 100644 --- a/Refit/MultipartItem.cs +++ b/Refit/MultipartItem.cs @@ -11,7 +11,8 @@ public MultipartItem(string fileName, string? contentType) ContentType = contentType; } - public MultipartItem(string fileName, string? contentType, string? name) : this(fileName, contentType) + public MultipartItem(string fileName, string? contentType, string? name) + : this(fileName, contentType) { Name = name; } @@ -41,8 +42,13 @@ public HttpContent ToContent() /// public class StreamPart : MultipartItem { - public StreamPart(Stream value, string fileName, string? contentType = null, string? name = null) : - base(fileName, contentType, name) + public StreamPart( + Stream value, + string fileName, + string? contentType = null, + string? name = null + ) + : base(fileName, contentType, name) { Value = value ?? throw new ArgumentNullException(nameof(value)); } @@ -60,8 +66,13 @@ protected override HttpContent CreateContent() /// public class ByteArrayPart : MultipartItem { - public ByteArrayPart(byte[] value, string fileName, string? contentType = null, string? name = null) : - base(fileName, contentType, name) + public ByteArrayPart( + byte[] value, + string fileName, + string? contentType = null, + string? name = null + ) + : base(fileName, contentType, name) { Value = value ?? throw new ArgumentNullException(nameof(value)); } @@ -79,8 +90,13 @@ protected override HttpContent CreateContent() /// public class FileInfoPart : MultipartItem { - public FileInfoPart(FileInfo value, string fileName, string? contentType = null, string? name = null) : - base(fileName, contentType, name) + public FileInfoPart( + FileInfo value, + string fileName, + string? contentType = null, + string? name = null + ) + : base(fileName, contentType, name) { Value = value ?? throw new ArgumentNullException(nameof(value)); } diff --git a/Refit/NameValueCollection.cs b/Refit/NameValueCollection.cs index 0a1ba6c30..e313b184b 100644 --- a/Refit/NameValueCollection.cs +++ b/Refit/NameValueCollection.cs @@ -3,6 +3,5 @@ class NameValueCollection : Dictionary { public string[] AllKeys => Keys.ToArray(); - } } diff --git a/Refit/ProblemDetails.cs b/Refit/ProblemDetails.cs index abff7a871..526d49f27 100644 --- a/Refit/ProblemDetails.cs +++ b/Refit/ProblemDetails.cs @@ -10,13 +10,15 @@ public class ProblemDetails /// /// Collection of resulting errors for the request. /// - public Dictionary Errors { get; set; } = new Dictionary(); + public Dictionary Errors { get; set; } = + new Dictionary(); /// /// Collection of ProblemDetails extensions /// [JsonExtensionData] - public IDictionary Extensions { get; set; } = new Dictionary(StringComparer.Ordinal); + public IDictionary Extensions { get; set; } = + new Dictionary(StringComparer.Ordinal); /// /// A URI reference that identifies the problem type. @@ -43,5 +45,4 @@ public class ProblemDetails /// public string? Instance { get; set; } } - } diff --git a/Refit/Properties/AssemblyInfo.cs b/Refit/Properties/AssemblyInfo.cs index b1b7307fd..538a3f6a8 100644 --- a/Refit/Properties/AssemblyInfo.cs +++ b/Refit/Properties/AssemblyInfo.cs @@ -1,6 +1,14 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("Refit.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed")] -[assembly: InternalsVisibleTo("Refit.HttpClientFactory, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed")] -[assembly: InternalsVisibleTo("Refit.Newtonsoft.Json, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed")] -[assembly: InternalsVisibleTo("Refit.Xml, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed")] +[assembly: InternalsVisibleTo( + "Refit.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed" +)] +[assembly: InternalsVisibleTo( + "Refit.HttpClientFactory, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed" +)] +[assembly: InternalsVisibleTo( + "Refit.Newtonsoft.Json, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed" +)] +[assembly: InternalsVisibleTo( + "Refit.Xml, PublicKey=00240000048000009400000006020000002400005253413100040000010001009dc017250415a0d51fddb74de84257c388028f04893673ca5c8f9e7145aea2b11443cb49dd79386d2255179a79ec516466b621f77e43386e711b775f77bb0e4b217f8c208c054e5f515ae33ee76bac1b56cdc20e1c151cf026a9b7f8362f1963825e546e16b360dfc63fe670403c9d6152c24491dd5dfb9ff68fe102ef3e1aed" +)] diff --git a/Refit/PushStreamContent.cs b/Refit/PushStreamContent.cs index 59335cf50..8b58db275 100644 --- a/Refit/PushStreamContent.cs +++ b/Refit/PushStreamContent.cs @@ -27,7 +27,7 @@ namespace System.Net.Http { /// /// Provides an implementation that exposes an output - /// which can be written to directly. The ability to push data to the output stream differs from the + /// which can be written to directly. The ability to push data to the output stream differs from the /// where data is pulled and not pushed. /// // https://github.com/ASP-NET-MVC/aspnetwebstack/blob/d5188c8a75b5b26b09ab89bedfd7ee635ae2ff17/src/System.Net.Http.Formatting/PushStreamContent.cs @@ -39,61 +39,67 @@ class PushStreamContent : HttpContent /// /// Initializes a new instance of the class. The /// action is called when an output stream - /// has become available allowing the action to write to it directly. When the - /// stream is closed, it will signal to the content that is has completed and the + /// has become available allowing the action to write to it directly. When the + /// stream is closed, it will signal to the content that is has completed and the /// HTTP request or response will be completed. /// /// The action to call when an output stream is available. public PushStreamContent(Action onStreamAvailable) - : this(Taskify(onStreamAvailable), (MediaTypeHeaderValue?)null) - { - } + : this(Taskify(onStreamAvailable), (MediaTypeHeaderValue?)null) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The action to call when an output stream is available. The stream is automatically /// closed when the return task is completed. - public PushStreamContent(Func onStreamAvailable) - : this(onStreamAvailable, (MediaTypeHeaderValue?)null) - { - } + public PushStreamContent( + Func onStreamAvailable + ) + : this(onStreamAvailable, (MediaTypeHeaderValue?)null) { } /// /// Initializes a new instance of the class with the given media type. /// - public PushStreamContent(Action onStreamAvailable, string mediaType) - : this(Taskify(onStreamAvailable), new MediaTypeHeaderValue(mediaType)) - { - } + public PushStreamContent( + Action onStreamAvailable, + string mediaType + ) + : this(Taskify(onStreamAvailable), new MediaTypeHeaderValue(mediaType)) { } /// /// Initializes a new instance of the class with the given media type. /// - public PushStreamContent(Func onStreamAvailable, string mediaType) - : this(onStreamAvailable, new MediaTypeHeaderValue(mediaType)) - { - } + public PushStreamContent( + Func onStreamAvailable, + string mediaType + ) + : this(onStreamAvailable, new MediaTypeHeaderValue(mediaType)) { } /// /// Initializes a new instance of the class with the given . /// - public PushStreamContent(Action onStreamAvailable, MediaTypeHeaderValue? mediaType) - : this(Taskify(onStreamAvailable), mediaType) - { - } + public PushStreamContent( + Action onStreamAvailable, + MediaTypeHeaderValue? mediaType + ) + : this(Taskify(onStreamAvailable), mediaType) { } /// /// Initializes a new instance of the class with the given . /// - public PushStreamContent(Func onStreamAvailable, MediaTypeHeaderValue? mediaType) + public PushStreamContent( + Func onStreamAvailable, + MediaTypeHeaderValue? mediaType + ) { - this.onStreamAvailable = onStreamAvailable ?? throw new ArgumentNullException(nameof(onStreamAvailable)); + this.onStreamAvailable = + onStreamAvailable ?? throw new ArgumentNullException(nameof(onStreamAvailable)); Headers.ContentType = mediaType ?? new MediaTypeHeaderValue("application/octet-stream"); } static Func Taskify( - Action onStreamAvailable) + Action onStreamAvailable + ) { if (onStreamAvailable == null) { @@ -112,19 +118,20 @@ public PushStreamContent(Func onSt /// Used as the T in a "conversion" of a Task into a Task{T} /// // https://github.com/ASP-NET-MVC/aspnetwebstack/blob/5118a14040b13f95bf778d1fc4522eb4ea2eef18/src/Common/TaskHelpers.cs#L65 - struct AsyncVoid - { - } + struct AsyncVoid { } /// - /// When this method is called, it calls the action provided in the constructor with the output - /// stream to write to. Once the action has completed its work it closes the stream which will + /// When this method is called, it calls the action provided in the constructor with the output + /// stream to write to. Once the action has completed its work it closes the stream which will /// close this content instance and complete the HTTP request or response. /// /// The to which to write. /// The associated . - /// A instance that is asynchronously serializing the object's content. - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context) + /// A instance that is asynchronously serializing the object's content. + protected override async Task SerializeToStreamAsync( + Stream stream, + TransportContext? context + ) { var serializeToStreamTask = new TaskCompletionSource(); @@ -151,11 +158,16 @@ internal class CompleteTaskOnCloseStream : DelegatingStream { readonly TaskCompletionSource serializeToStreamTask; - public CompleteTaskOnCloseStream(Stream innerStream, TaskCompletionSource serializeToStreamTask) + public CompleteTaskOnCloseStream( + Stream innerStream, + TaskCompletionSource serializeToStreamTask + ) : base(innerStream) { Contract.Assert(serializeToStreamTask != null); - this.serializeToStreamTask = serializeToStreamTask ?? throw new ArgumentNullException(nameof(serializeToStreamTask)); + this.serializeToStreamTask = + serializeToStreamTask + ?? throw new ArgumentNullException(nameof(serializeToStreamTask)); } protected override void Dispose(bool disposing) @@ -168,7 +180,7 @@ protected override void Dispose(bool disposing) } /// - /// Stream that delegates to inner stream. + /// Stream that delegates to inner stream. /// This is taken from System.Net.Http /// // https://github.com/ASP-NET-MVC/aspnetwebstack/blob/d5188c8a75b5b26b09ab89bedfd7ee635ae2ff17/src/System.Net.Http.Formatting/Internal/DelegatingStream.cs @@ -244,7 +256,12 @@ public override int Read(byte[] buffer, int offset, int count) return InnerStream.Read(buffer, offset, count); } - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + public override Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) { return InnerStream.ReadAsync(buffer, offset, count, cancellationToken); } @@ -259,7 +276,11 @@ public override void Flush() InnerStream.Flush(); } - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + public override Task CopyToAsync( + Stream destination, + int bufferSize, + CancellationToken cancellationToken + ) { return InnerStream.CopyToAsync(destination, bufferSize, cancellationToken); } @@ -279,7 +300,12 @@ public override void Write(byte[] buffer, int offset, int count) InnerStream.Write(buffer, offset, count); } - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + public override Task WriteAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) { return InnerStream.WriteAsync(buffer, offset, count, cancellationToken); } diff --git a/Refit/RefitSettings.cs b/Refit/RefitSettings.cs index ddb50e2e2..1e91f91fd 100644 --- a/Refit/RefitSettings.cs +++ b/Refit/RefitSettings.cs @@ -31,18 +31,29 @@ public RefitSettings() public RefitSettings( IHttpContentSerializer contentSerializer, IUrlParameterFormatter? urlParameterFormatter = null, - IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter = null) + IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter = null + ) { - ContentSerializer = contentSerializer ?? throw new ArgumentNullException(nameof(contentSerializer), "The content serializer can't be null"); + ContentSerializer = + contentSerializer + ?? throw new ArgumentNullException( + nameof(contentSerializer), + "The content serializer can't be null" + ); UrlParameterFormatter = urlParameterFormatter ?? new DefaultUrlParameterFormatter(); - FormUrlEncodedParameterFormatter = formUrlEncodedParameterFormatter ?? new DefaultFormUrlEncodedParameterFormatter(); + FormUrlEncodedParameterFormatter = + formUrlEncodedParameterFormatter ?? new DefaultFormUrlEncodedParameterFormatter(); ExceptionFactory = new DefaultApiExceptionFactory(this).CreateAsync; } /// /// Supply a function to provide the Authorization header. Does not work if you supply an HttpClient instance. /// - public Func>? AuthorizationHeaderValueGetter { get; set; } + public Func< + HttpRequestMessage, + CancellationToken, + Task + >? AuthorizationHeaderValueGetter { get; set; } /// /// Supply a custom inner HttpMessageHandler. Does not work if you supply an HttpClient instance. @@ -73,7 +84,8 @@ public RefitSettings( /// /// Sets the default collection format to use. (defaults to ) /// - public CollectionFormat CollectionFormat { get; set; } = CollectionFormat.RefitParameterFormatter; + public CollectionFormat CollectionFormat { get; set; } = + CollectionFormat.RefitParameterFormatter; /// /// Sets the default behavior when sending a request's body content. (defaults to false, request body is not streamed to the server) @@ -106,7 +118,10 @@ public interface IHttpContentSerializer /// HttpContent object to deserialize. /// CancellationToken to abort the deserialization. /// The deserialized object of type . - Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default); + Task FromHttpContentAsync( + HttpContent content, + CancellationToken cancellationToken = default + ); /// /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands @@ -137,17 +152,26 @@ public interface IFormUrlEncodedParameterFormatter /// public class DefaultUrlParameterFormatter : IUrlParameterFormatter { - static readonly ConcurrentDictionary> EnumMemberCache = new(); - - public virtual string? Format(object? parameterValue, ICustomAttributeProvider attributeProvider, Type type) + static readonly ConcurrentDictionary< + Type, + ConcurrentDictionary + > EnumMemberCache = new(); + + public virtual string? Format( + object? parameterValue, + ICustomAttributeProvider attributeProvider, + Type type + ) { if (attributeProvider is null) throw new ArgumentNullException(nameof(attributeProvider)); // See if we have a format - var formatString = attributeProvider.GetCustomAttributes(typeof(QueryAttribute), true) + var formatString = attributeProvider + .GetCustomAttributes(typeof(QueryAttribute), true) .OfType() - .FirstOrDefault()?.Format; + .FirstOrDefault() + ?.Format; EnumMemberAttribute? enummember = null; if (parameterValue != null) @@ -155,18 +179,28 @@ public class DefaultUrlParameterFormatter : IUrlParameterFormatter var parameterType = parameterValue.GetType(); if (parameterType.IsEnum) { - var cached = EnumMemberCache.GetOrAdd(parameterType, t => new ConcurrentDictionary()); - enummember = cached.GetOrAdd(parameterValue.ToString()!, val => parameterType.GetMember(val).First().GetCustomAttribute()); + var cached = EnumMemberCache.GetOrAdd( + parameterType, + t => new ConcurrentDictionary() + ); + enummember = cached.GetOrAdd( + parameterValue.ToString()!, + val => + parameterType + .GetMember(val) + .First() + .GetCustomAttribute() + ); } } return parameterValue == null - ? null - : string.Format(CultureInfo.InvariantCulture, - string.IsNullOrWhiteSpace(formatString) - ? "{0}" - : $"{{0:{formatString}}}", - enummember?.Value ?? parameterValue); + ? null + : string.Format( + CultureInfo.InvariantCulture, + string.IsNullOrWhiteSpace(formatString) ? "{0}" : $"{{0:{formatString}}}", + enummember?.Value ?? parameterValue + ); } } @@ -175,8 +209,10 @@ public class DefaultUrlParameterFormatter : IUrlParameterFormatter /// public class DefaultFormUrlEncodedParameterFormatter : IFormUrlEncodedParameterFormatter { - static readonly ConcurrentDictionary> EnumMemberCache - = new(); + static readonly ConcurrentDictionary< + Type, + ConcurrentDictionary + > EnumMemberCache = new(); public virtual string? Format(object? parameterValue, string? formatString) { @@ -188,15 +224,25 @@ public class DefaultFormUrlEncodedParameterFormatter : IFormUrlEncodedParameterF EnumMemberAttribute? enummember = null; if (parameterType.GetTypeInfo().IsEnum) { - var cached = EnumMemberCache.GetOrAdd(parameterType, t => new ConcurrentDictionary()); - enummember = cached.GetOrAdd(parameterValue.ToString()!, val => parameterType.GetMember(val).First().GetCustomAttribute()); + var cached = EnumMemberCache.GetOrAdd( + parameterType, + t => new ConcurrentDictionary() + ); + enummember = cached.GetOrAdd( + parameterValue.ToString()!, + val => + parameterType + .GetMember(val) + .First() + .GetCustomAttribute() + ); } - return string.Format(CultureInfo.InvariantCulture, - string.IsNullOrWhiteSpace(formatString) - ? "{0}" - : $"{{0:{formatString}}}", - enummember?.Value ?? parameterValue); + return string.Format( + CultureInfo.InvariantCulture, + string.IsNullOrWhiteSpace(formatString) ? "{0}" : $"{{0:{formatString}}}", + enummember?.Value ?? parameterValue + ); } } @@ -226,12 +272,17 @@ public DefaultApiExceptionFactory(RefitSettings refitSettings) } } - static async Task CreateExceptionAsync(HttpResponseMessage responseMessage, RefitSettings refitSettings) + static async Task CreateExceptionAsync( + HttpResponseMessage responseMessage, + RefitSettings refitSettings + ) { var requestMessage = responseMessage.RequestMessage!; var method = requestMessage.Method; - return await ApiException.Create(requestMessage, method, responseMessage, refitSettings).ConfigureAwait(false); + return await ApiException + .Create(requestMessage, method, responseMessage, refitSettings) + .ConfigureAwait(false); } } } diff --git a/Refit/RequestBuilder.cs b/Refit/RequestBuilder.cs index d0939c539..d543269ea 100644 --- a/Refit/RequestBuilder.cs +++ b/Refit/RequestBuilder.cs @@ -4,16 +4,19 @@ namespace Refit { public interface IRequestBuilder { - Func BuildRestResultFuncForMethod(string methodName, Type[]? parameterTypes = null, Type[]? genericArgumentTypes = null); + Func BuildRestResultFuncForMethod( + string methodName, + Type[]? parameterTypes = null, + Type[]? genericArgumentTypes = null + ); } - public interface IRequestBuilder : IRequestBuilder - { - } + public interface IRequestBuilder : IRequestBuilder { } public static class RequestBuilder { - static readonly IRequestBuilderFactory PlatformRequestBuilderFactory = new RequestBuilderFactory(); + static readonly IRequestBuilderFactory PlatformRequestBuilderFactory = + new RequestBuilderFactory(); public static IRequestBuilder ForType(RefitSettings? settings) { diff --git a/Refit/RequestBuilderFactory.cs b/Refit/RequestBuilderFactory.cs index 48f7e34ef..1cdb2484d 100644 --- a/Refit/RequestBuilderFactory.cs +++ b/Refit/RequestBuilderFactory.cs @@ -10,12 +10,16 @@ class RequestBuilderFactory : IRequestBuilderFactory { public IRequestBuilder Create(RefitSettings? settings = null) { - return new CachedRequestBuilderImplementation(new RequestBuilderImplementation(settings)); + return new CachedRequestBuilderImplementation( + new RequestBuilderImplementation(settings) + ); } public IRequestBuilder Create(Type refitInterfaceType, RefitSettings? settings = null) { - return new CachedRequestBuilderImplementation(new RequestBuilderImplementation(refitInterfaceType, settings)); + return new CachedRequestBuilderImplementation( + new RequestBuilderImplementation(refitInterfaceType, settings) + ); } } } diff --git a/Refit/RequestBuilderImplementation.TaskToObservable.cs b/Refit/RequestBuilderImplementation.TaskToObservable.cs index ccda8603f..cd0951588 100644 --- a/Refit/RequestBuilderImplementation.TaskToObservable.cs +++ b/Refit/RequestBuilderImplementation.TaskToObservable.cs @@ -15,13 +15,17 @@ public IDisposable Subscribe(IObserver observer) { var cts = new CancellationTokenSource(); #pragma warning disable VSTHRD110 // Observe result of async calls - taskFactory(cts.Token).ContinueWith(t => - { - if (cts.IsCancellationRequested) return; + taskFactory(cts.Token) + .ContinueWith( + t => + { + if (cts.IsCancellationRequested) + return; - ToObservableDone(t, observer); - }, - TaskScheduler.Default); + ToObservableDone(t, observer); + }, + TaskScheduler.Default + ); #pragma warning restore VSTHRD110 // Observe result of async calls diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index 1023a1d36..3ce8e3b6f 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -10,9 +10,8 @@ namespace Refit { class RequestBuilderImplementation : RequestBuilderImplementation, IRequestBuilder { - public RequestBuilderImplementation(RefitSettings? refitSettings = null) : base(typeof(TApi), refitSettings) - { - } + public RequestBuilderImplementation(RefitSettings? refitSettings = null) + : base(typeof(TApi), refitSettings) { } } partial class RequestBuilderImplementation : IRequestBuilder @@ -23,18 +22,25 @@ partial class RequestBuilderImplementation : IRequestBuilder HttpMethod.Head }; readonly Dictionary> interfaceHttpMethods; - readonly ConcurrentDictionary interfaceGenericHttpMethods; + readonly ConcurrentDictionary< + CloseGenericMethodKey, + RestMethodInfoInternal + > interfaceGenericHttpMethods; readonly IHttpContentSerializer serializer; readonly RefitSettings settings; public Type TargetType { get; } - public RequestBuilderImplementation(Type refitInterfaceType, RefitSettings? refitSettings = null) + public RequestBuilderImplementation( + Type refitInterfaceType, + RefitSettings? refitSettings = null + ) { var targetInterfaceInheritedInterfaces = refitInterfaceType.GetInterfaces(); settings = refitSettings ?? new RefitSettings(); serializer = settings.ContentSerializer; - interfaceGenericHttpMethods = new ConcurrentDictionary(); + interfaceGenericHttpMethods = + new ConcurrentDictionary(); if (refitInterfaceType == null || !refitInterfaceType.GetTypeInfo().IsInterface) { @@ -54,7 +60,10 @@ public RequestBuilderImplementation(Type refitInterfaceType, RefitSettings? refi interfaceHttpMethods = dict; } - void AddInterfaceHttpMethods(Type interfaceType, Dictionary> methods) + void AddInterfaceHttpMethods( + Type interfaceType, + Dictionary> methods + ) { // Consider public (the implicit visibility) and non-public abstract members of the interfaceType var methodInfos = interfaceType @@ -78,7 +87,11 @@ void AddInterfaceHttpMethods(Type interfaceType, Dictionary 1) { - throw new ArgumentException($"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined"); + throw new ArgumentException( + $"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined" + ); } return CloseGenericMethodIfNeeded(httpMethods[0], genericArgumentTypes); } var isGeneric = genericArgumentTypes?.Length > 0; - var possibleMethodsList = httpMethods.Where(method => method.MethodInfo.GetParameters().Length == parameterTypes.Length); + var possibleMethodsList = httpMethods.Where( + method => method.MethodInfo.GetParameters().Length == parameterTypes.Length + ); // If it's a generic method, add that filter if (isGeneric) - possibleMethodsList = possibleMethodsList.Where(method => method.MethodInfo.IsGenericMethod && method.MethodInfo.GetGenericArguments().Length == genericArgumentTypes!.Length); + possibleMethodsList = possibleMethodsList.Where( + method => + method.MethodInfo.IsGenericMethod + && method.MethodInfo.GetGenericArguments().Length + == genericArgumentTypes!.Length + ); else // exclude generic methods - possibleMethodsList = possibleMethodsList.Where(method => !method.MethodInfo.IsGenericMethod); + possibleMethodsList = possibleMethodsList.Where( + method => !method.MethodInfo.IsGenericMethod + ); var possibleMethods = possibleMethodsList.ToList(); @@ -109,9 +133,10 @@ RestMethodInfoInternal FindMatchingRestMethodInfo(string key, Type[]? parameterT var parameterTypesArray = parameterTypes.ToArray(); foreach (var method in possibleMethods) { - var match = method.MethodInfo.GetParameters() - .Select(p => p.ParameterType) - .SequenceEqual(parameterTypesArray); + var match = method.MethodInfo + .GetParameters() + .Select(p => p.ParameterType) + .SequenceEqual(parameterTypesArray); if (match) { return CloseGenericMethodIfNeeded(method, genericArgumentTypes); @@ -122,29 +147,50 @@ RestMethodInfoInternal FindMatchingRestMethodInfo(string key, Type[]? parameterT } else { - throw new ArgumentException("Method must be defined and have an HTTP Method attribute"); + throw new ArgumentException( + "Method must be defined and have an HTTP Method attribute" + ); } - } - RestMethodInfoInternal CloseGenericMethodIfNeeded(RestMethodInfoInternal restMethodInfo, Type[]? genericArgumentTypes) + RestMethodInfoInternal CloseGenericMethodIfNeeded( + RestMethodInfoInternal restMethodInfo, + Type[]? genericArgumentTypes + ) { if (genericArgumentTypes != null) { - return interfaceGenericHttpMethods.GetOrAdd(new CloseGenericMethodKey(restMethodInfo.MethodInfo, genericArgumentTypes), - _ => new RestMethodInfoInternal(restMethodInfo.Type, restMethodInfo.MethodInfo.MakeGenericMethod(genericArgumentTypes), restMethodInfo.RefitSettings)); + return interfaceGenericHttpMethods.GetOrAdd( + new CloseGenericMethodKey(restMethodInfo.MethodInfo, genericArgumentTypes), + _ => + new RestMethodInfoInternal( + restMethodInfo.Type, + restMethodInfo.MethodInfo.MakeGenericMethod(genericArgumentTypes), + restMethodInfo.RefitSettings + ) + ); } return restMethodInfo; } - public Func BuildRestResultFuncForMethod(string methodName, Type[]? parameterTypes = null, Type[]? genericArgumentTypes = null) + public Func BuildRestResultFuncForMethod( + string methodName, + Type[]? parameterTypes = null, + Type[]? genericArgumentTypes = null + ) { if (!interfaceHttpMethods.ContainsKey(methodName)) { - throw new ArgumentException("Method must be defined and have an HTTP Method attribute"); + throw new ArgumentException( + "Method must be defined and have an HTTP Method attribute" + ); } - var restMethod = FindMatchingRestMethodInfo(methodName, parameterTypes, genericArgumentTypes); + var restMethod = FindMatchingRestMethodInfo( + methodName, + parameterTypes, + genericArgumentTypes + ); if (restMethod.ReturnType == typeof(Task)) { return BuildVoidTaskFuncForMethod(restMethod); @@ -156,22 +202,44 @@ RestMethodInfoInternal CloseGenericMethodIfNeeded(RestMethodInfoInternal restMet // difficult to upcast Task to an arbitrary T, especially // if you need to AOT everything, so we need to reflectively // invoke buildTaskFuncForMethod. - var taskFuncMi = typeof(RequestBuilderImplementation).GetMethod(nameof(BuildTaskFuncForMethod), BindingFlags.NonPublic | BindingFlags.Instance); - var taskFunc = (MulticastDelegate?)(taskFuncMi!.MakeGenericMethod(restMethod.ReturnResultType, restMethod.DeserializedResultType)).Invoke(this, new[] { restMethod }); + var taskFuncMi = typeof(RequestBuilderImplementation).GetMethod( + nameof(BuildTaskFuncForMethod), + BindingFlags.NonPublic | BindingFlags.Instance + ); + var taskFunc = (MulticastDelegate?) + ( + taskFuncMi!.MakeGenericMethod( + restMethod.ReturnResultType, + restMethod.DeserializedResultType + ) + ).Invoke(this, new[] { restMethod }); return (client, args) => taskFunc!.DynamicInvoke(client, args); } // Same deal - var rxFuncMi = typeof(RequestBuilderImplementation).GetMethod(nameof(BuildRxFuncForMethod), BindingFlags.NonPublic | BindingFlags.Instance); - var rxFunc = (MulticastDelegate?)(rxFuncMi!.MakeGenericMethod(restMethod.ReturnResultType, restMethod.DeserializedResultType)).Invoke(this, new[] { restMethod }); + var rxFuncMi = typeof(RequestBuilderImplementation).GetMethod( + nameof(BuildRxFuncForMethod), + BindingFlags.NonPublic | BindingFlags.Instance + ); + var rxFunc = (MulticastDelegate?) + ( + rxFuncMi!.MakeGenericMethod( + restMethod.ReturnResultType, + restMethod.DeserializedResultType + ) + ).Invoke(this, new[] { restMethod }); return (client, args) => rxFunc!.DynamicInvoke(client, args); } - void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName, string parameterName, object itemValue) + void AddMultipartItem( + MultipartFormDataContent multiPartContent, + string fileName, + string parameterName, + object itemValue + ) { - if (itemValue is HttpContent content) { multiPartContent.Add(content); @@ -180,7 +248,11 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName if (itemValue is MultipartItem multipartItem) { var httpContent = multipartItem.ToContent(); - multiPartContent.Add(httpContent, multipartItem.Name ?? parameterName, string.IsNullOrEmpty(multipartItem.FileName) ? fileName : multipartItem.FileName); + multiPartContent.Add( + httpContent, + multipartItem.Name ?? parameterName, + string.IsNullOrEmpty(multipartItem.FileName) ? fileName : multipartItem.FileName + ); return; } @@ -215,7 +287,10 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName Exception e; try { - multiPartContent.Add(settings.ContentSerializer.ToHttpContent(itemValue), parameterName); + multiPartContent.Add( + settings.ContentSerializer.ToHttpContent(itemValue), + parameterName + ); return; } catch (Exception ex) @@ -224,17 +299,30 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName e = ex; } - throw new ArgumentException($"Unexpected parameter type in a Multipart request. Parameter {fileName} is of type {itemValue.GetType().Name}, whereas allowed types are String, Stream, FileInfo, Byte array and anything that's JSON serializable", nameof(itemValue), e); + throw new ArgumentException( + $"Unexpected parameter type in a Multipart request. Parameter {fileName} is of type {itemValue.GetType().Name}, whereas allowed types are String, Stream, FileInfo, Byte array and anything that's JSON serializable", + nameof(itemValue), + e + ); } - Func> BuildCancellableTaskFuncForMethod(RestMethodInfoInternal restMethod) + Func> BuildCancellableTaskFuncForMethod< + T, + TBody + >(RestMethodInfoInternal restMethod) { return async (client, ct, paramList) => { if (client.BaseAddress == null) - throw new InvalidOperationException("BaseAddress must be set on the HttpClient instance"); - - var factory = BuildRequestFactoryForMethod(restMethod, client.BaseAddress.AbsolutePath, restMethod.CancellationToken != null); + throw new InvalidOperationException( + "BaseAddress must be set on the HttpClient instance" + ); + + var factory = BuildRequestFactoryForMethod( + restMethod, + client.BaseAddress.AbsolutePath, + restMethod.CancellationToken != null + ); var rq = factory(paramList); HttpResponseMessage? resp = null; HttpContent? content = null; @@ -246,7 +334,9 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName { await rq.Content!.LoadIntoBufferAsync().ConfigureAwait(false); } - resp = await client.SendAsync(rq, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false); + resp = await client + .SendAsync(rq, HttpCompletionOption.ResponseHeadersRead, ct) + .ConfigureAwait(false); content = resp.Content ?? new StringContent(string.Empty); Exception? e = null; disposeResponse = restMethod.ShouldDisposeResponse; @@ -263,17 +353,31 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName try { // Only attempt to deserialize content if no error present for backward-compatibility - body = e == null - ? await DeserializeContentAsync(resp, content, ct).ConfigureAwait(false) - : default; + body = + e == null + ? await DeserializeContentAsync(resp, content, ct) + .ConfigureAwait(false) + : default; } catch (Exception ex) { //if an error occured while attempting to deserialize return the wrapped ApiException - e = await ApiException.Create("An error occured deserializing the response.", resp.RequestMessage!, resp.RequestMessage!.Method, resp, settings, ex); + e = await ApiException.Create( + "An error occured deserializing the response.", + resp.RequestMessage!, + resp.RequestMessage!.Method, + resp, + settings, + ex + ); } - return ApiResponse.Create(resp, body, settings, e as ApiException); + return ApiResponse.Create( + resp, + body, + settings, + e as ApiException + ); } else if (e != null) { @@ -284,11 +388,19 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName { try { - return await DeserializeContentAsync(resp, content, ct).ConfigureAwait(false); + return await DeserializeContentAsync(resp, content, ct) + .ConfigureAwait(false); } catch (Exception ex) { - throw await ApiException.Create("An error occured deserializing the response.", resp.RequestMessage!, resp.RequestMessage!.Method, resp, settings, ex); + throw await ApiException.Create( + "An error occured deserializing the response.", + resp.RequestMessage!, + resp.RequestMessage!.Method, + resp, + settings, + ex + ); } } } @@ -306,7 +418,11 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName }; } - async Task DeserializeContentAsync(HttpResponseMessage resp, HttpContent content, CancellationToken cancellationToken) + async Task DeserializeContentAsync( + HttpResponseMessage resp, + HttpContent content, + CancellationToken cancellationToken + ) { T? result; if (typeof(T) == typeof(HttpResponseMessage)) @@ -322,24 +438,33 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName } else if (typeof(T) == typeof(Stream)) { - var stream = (object)await content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + var stream = (object) + await content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); result = (T)stream; } else if (typeof(T) == typeof(string)) { - using var stream = await content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + using var stream = await content + .ReadAsStreamAsync(cancellationToken) + .ConfigureAwait(false); using var reader = new StreamReader(stream); var str = (object)await reader.ReadToEndAsync().ConfigureAwait(false); result = (T)str; } else { - result = await serializer.FromHttpContentAsync(content, cancellationToken).ConfigureAwait(false); + result = await serializer + .FromHttpContentAsync(content, cancellationToken) + .ConfigureAwait(false); } return result; } - List> BuildQueryMap(object? @object, string? delimiter = null, RestMethodParameterInfo? parameterInfo = null) + List> BuildQueryMap( + object? @object, + string? delimiter = null, + RestMethodParameterInfo? parameterInfo = null + ) { if (@object is IDictionary idictionary) { @@ -348,9 +473,12 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName var kvps = new List>(); - if (@object is null) return kvps; + if (@object is null) + return kvps; - var props = @object.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) + var props = @object + .GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.CanRead && p.GetMethod?.IsPublic == true); foreach (var propertyInfo in props) @@ -364,7 +492,11 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName //if we have a parameter info lets check it to make sure it isn't bound to the path if (parameterInfo.IsObjectPropertyParameter) { - if (parameterInfo.ParameterProperties.Any(x => x.PropertyInfo == propertyInfo)) + if ( + parameterInfo.ParameterProperties.Any( + x => x.PropertyInfo == propertyInfo + ) + ) { continue; } @@ -377,18 +509,27 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName if (aliasAttribute != null) key = aliasAttribute.Name; - // Look to see if the property has a Query attribute, and if so, format it accordingly var queryAttribute = propertyInfo.GetCustomAttribute(); if (queryAttribute != null && queryAttribute.Format != null) { - obj = settings.FormUrlEncodedParameterFormatter.Format(obj, queryAttribute.Format); + obj = settings.FormUrlEncodedParameterFormatter.Format( + obj, + queryAttribute.Format + ); } // If obj is IEnumerable - format it accounting for Query attribute and CollectionFormat if (obj is not string && obj is IEnumerable ienu && obj is not IDictionary) { - foreach (var value in ParseEnumerableQueryParameterValue(ienu, propertyInfo, propertyInfo.PropertyType, queryAttribute)) + foreach ( + var value in ParseEnumerableQueryParameterValue( + ienu, + propertyInfo, + propertyInfo.PropertyType, + queryAttribute + ) + ) { kvps.Add(new KeyValuePair(key, value)); } @@ -407,7 +548,12 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName case IDictionary idict: foreach (var keyValuePair in BuildQueryMap(idict, delimiter)) { - kvps.Add(new KeyValuePair($"{key}{delimiter}{keyValuePair.Key}", keyValuePair.Value)); + kvps.Add( + new KeyValuePair( + $"{key}{delimiter}{keyValuePair.Key}", + keyValuePair.Value + ) + ); } break; @@ -415,7 +561,12 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName default: foreach (var keyValuePair in BuildQueryMap(obj, delimiter)) { - kvps.Add(new KeyValuePair($"{key}{delimiter}{keyValuePair.Key}", keyValuePair.Value)); + kvps.Add( + new KeyValuePair( + $"{key}{delimiter}{keyValuePair.Key}", + keyValuePair.Value + ) + ); } break; @@ -425,7 +576,10 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName return kvps; } - List> BuildQueryMap(IDictionary dictionary, string? delimiter = null) + List> BuildQueryMap( + IDictionary dictionary, + string? delimiter = null + ) { var kvps = new List>(); @@ -438,7 +592,7 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName var keyType = key.GetType(); var formattedKey = settings.UrlParameterFormatter.Format(key, keyType, keyType); - if(string.IsNullOrWhiteSpace(formattedKey)) // blank keys can't be put in the query string + if (string.IsNullOrWhiteSpace(formattedKey)) // blank keys can't be put in the query string { continue; } @@ -451,7 +605,12 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName { foreach (var keyValuePair in BuildQueryMap(obj, delimiter)) { - kvps.Add(new KeyValuePair($"{formattedKey}{delimiter}{keyValuePair.Key}", keyValuePair.Value)); + kvps.Add( + new KeyValuePair( + $"{formattedKey}{delimiter}{keyValuePair.Key}", + keyValuePair.Value + ) + ); } } } @@ -459,20 +618,23 @@ void AddMultipartItem(MultipartFormDataContent multiPartContent, string fileName return kvps; } - Func BuildRequestFactoryForMethod(RestMethodInfoInternal restMethod, string basePath, bool paramsContainsCancellationToken) + Func BuildRequestFactoryForMethod( + RestMethodInfoInternal restMethod, + string basePath, + bool paramsContainsCancellationToken + ) { return paramList => { // make sure we strip out any cancellation tokens if (paramsContainsCancellationToken) { - paramList = paramList.Where(o => o == null || o.GetType() != typeof(CancellationToken)).ToArray(); + paramList = paramList + .Where(o => o == null || o.GetType() != typeof(CancellationToken)) + .ToArray(); } - var ret = new HttpRequestMessage - { - Method = restMethod.HttpMethod - }; + var ret = new HttpRequestMessage { Method = restMethod.HttpMethod }; // set up multipart content MultipartFormDataContent? multiPartContent = null; @@ -482,7 +644,8 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn ret.Content = multiPartContent; } - var urlTarget = (basePath == "/" ? string.Empty : basePath) + restMethod.RelativePath; + var urlTarget = + (basePath == "/" ? string.Empty : basePath) + restMethod.RelativePath; var queryParamsToAdd = new List>(); var headersToAdd = new Dictionary(restMethod.Headers); var propertiesToAdd = new Dictionary(); @@ -504,11 +667,16 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn var propertyObject = propertyInfo.PropertyInfo.GetValue(param); urlTarget = Regex.Replace( urlTarget, - "{" + propertyInfo.Name + "}", - Uri.EscapeDataString(settings.UrlParameterFormatter.Format(propertyObject, - propertyInfo.PropertyInfo, - propertyInfo.PropertyInfo.PropertyType) ?? string.Empty), - RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + "{" + propertyInfo.Name + "}", + Uri.EscapeDataString( + settings.UrlParameterFormatter.Format( + propertyObject, + propertyInfo.PropertyInfo, + propertyInfo.PropertyInfo.PropertyType + ) ?? string.Empty + ), + RegexOptions.IgnoreCase | RegexOptions.CultureInvariant + ); } //don't continue here as we want it to fall through so any parameters on this object not bound here get passed as query parameters } @@ -522,34 +690,48 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn var paramValue = (string)param; replacement = string.Join( "/", - paramValue.Split('/') - .Select(s => - Uri.EscapeDataString( - settings.UrlParameterFormatter.Format(s, restMethod.ParameterInfoMap[i], restMethod.ParameterInfoMap[i].ParameterType) ?? string.Empty - ) + paramValue + .Split('/') + .Select( + s => + Uri.EscapeDataString( + settings.UrlParameterFormatter.Format( + s, + restMethod.ParameterInfoMap[i], + restMethod.ParameterInfoMap[i].ParameterType + ) ?? string.Empty + ) ) ); } else { pattern = "{" + restMethod.ParameterMap[i].Name + "}"; - replacement = Uri.EscapeDataString(settings.UrlParameterFormatter - .Format(param, restMethod.ParameterInfoMap[i], restMethod.ParameterInfoMap[i].ParameterType) ?? string.Empty); + replacement = Uri.EscapeDataString( + settings.UrlParameterFormatter.Format( + param, + restMethod.ParameterInfoMap[i], + restMethod.ParameterInfoMap[i].ParameterType + ) ?? string.Empty + ); } urlTarget = Regex.Replace( urlTarget, pattern, replacement, - RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + RegexOptions.IgnoreCase | RegexOptions.CultureInvariant + ); isParameterMappedToRequest = true; - } } // if marked as body, add to content - if (restMethod.BodyParameterInfo != null && restMethod.BodyParameterInfo.Item3 == i) + if ( + restMethod.BodyParameterInfo != null + && restMethod.BodyParameterInfo.Item3 == i + ) { if (param is HttpContent httpContentParam) { @@ -560,8 +742,10 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn ret.Content = new StreamContent(streamParam); } // Default sends raw strings - else if (restMethod.BodyParameterInfo.Item1 == BodySerializationMethod.Default && - param is string stringParam) + else if ( + restMethod.BodyParameterInfo.Item1 == BodySerializationMethod.Default + && param is string stringParam + ) { ret.Content = new StringContent(stringParam); } @@ -570,7 +754,16 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn switch (restMethod.BodyParameterInfo.Item1) { case BodySerializationMethod.UrlEncoded: - ret.Content = param is string str ? (HttpContent)new StringContent(Uri.EscapeDataString(str), Encoding.UTF8, "application/x-www-form-urlencoded") : new FormUrlEncodedContent(new FormValueMultimap(param, settings)); + ret.Content = param is string str + ? (HttpContent) + new StringContent( + Uri.EscapeDataString(str), + Encoding.UTF8, + "application/x-www-form-urlencoded" + ) + : new FormUrlEncodedContent( + new FormValueMultimap(param, settings) + ); break; case BodySerializationMethod.Default: #pragma warning disable CS0618 // Type or member is obsolete @@ -588,9 +781,13 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn { using (stream) { - await content.CopyToAsync(stream).ConfigureAwait(false); + await content + .CopyToAsync(stream) + .ConfigureAwait(false); } - }, content.Headers.ContentType); + }, + content.Headers.ContentType + ); break; case true: ret.Content = content; @@ -614,7 +811,9 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn //if header collection, add to request headers if (restMethod.HeaderCollectionParameterMap.Contains(i)) { - var headerCollection = param as IDictionary ?? new Dictionary(); + var headerCollection = + param as IDictionary + ?? new Dictionary(); foreach (var header in headerCollection) { @@ -625,9 +824,13 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn } //if authorize, add to request headers with scheme - if (restMethod.AuthorizeParameterInfo != null && restMethod.AuthorizeParameterInfo.Item2 == i) + if ( + restMethod.AuthorizeParameterInfo != null + && restMethod.AuthorizeParameterInfo.Item2 == i + ) { - headersToAdd["Authorization"] = $"{restMethod.AuthorizeParameterInfo.Item1} {param}"; + headersToAdd["Authorization"] = + $"{restMethod.AuthorizeParameterInfo.Item1} {param}"; isParameterMappedToRequest = true; } @@ -639,28 +842,49 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn } // ignore nulls and already processed parameters - if (isParameterMappedToRequest || param == null) continue; + if (isParameterMappedToRequest || param == null) + continue; // for anything that fell through to here, if this is not a multipart method add the parameter to the query string // or if is an object bound to the path add any non-path bound properties to query string // or if it's an object with a query attribute - var queryAttribute = restMethod.ParameterInfoMap[i].GetCustomAttribute(); - if (!restMethod.IsMultipart || - restMethod.ParameterMap.ContainsKey(i) && restMethod.ParameterMap[i].IsObjectPropertyParameter || - queryAttribute != null + var queryAttribute = restMethod.ParameterInfoMap[ + i + ].GetCustomAttribute(); + if ( + !restMethod.IsMultipart + || restMethod.ParameterMap.ContainsKey(i) + && restMethod.ParameterMap[i].IsObjectPropertyParameter + || queryAttribute != null ) { var attr = queryAttribute ?? new QueryAttribute(); if (DoNotConvertToQueryMap(param)) { - queryParamsToAdd.AddRange(ParseQueryParameter(param, restMethod.ParameterInfoMap[i], restMethod.QueryParameterMap[i], attr)); + queryParamsToAdd.AddRange( + ParseQueryParameter( + param, + restMethod.ParameterInfoMap[i], + restMethod.QueryParameterMap[i], + attr + ) + ); } else { foreach (var kvp in BuildQueryMap(param, attr.Delimiter, parameterInfo)) { - var path = !string.IsNullOrWhiteSpace(attr.Prefix) ? $"{attr.Prefix}{attr.Delimiter}{kvp.Key}" : kvp.Key; - queryParamsToAdd.AddRange(ParseQueryParameter(kvp.Value, restMethod.ParameterInfoMap[i], path, attr)); + var path = !string.IsNullOrWhiteSpace(attr.Prefix) + ? $"{attr.Prefix}{attr.Delimiter}{kvp.Key}" + : kvp.Key; + queryParamsToAdd.AddRange( + ParseQueryParameter( + kvp.Value, + restMethod.ParameterInfoMap[i], + path, + attr + ) + ); } } @@ -720,7 +944,7 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn // Add RefitSetting.HttpRequestMessageOptions to the HttpRequestMessage if (this.settings.HttpRequestMessageOptions != null) { - foreach(var p in this.settings.HttpRequestMessageOptions) + foreach (var p in this.settings.HttpRequestMessageOptions) { #if NET6_0_OR_GREATER ret.Options.Set(new HttpRequestOptionsKey(p.Key), p.Value); @@ -733,7 +957,10 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn foreach (var property in propertiesToAdd) { #if NET6_0_OR_GREATER - ret.Options.Set(new HttpRequestOptionsKey(property.Key), property.Value); + ret.Options.Set( + new HttpRequestOptionsKey(property.Key), + property.Value + ); #else ret.Properties[property.Key] = property.Value; #endif @@ -741,11 +968,20 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn // Always add the top-level type of the interface to the properties #if NET6_0_OR_GREATER - ret.Options.Set(new HttpRequestOptionsKey(HttpRequestMessageOptions.InterfaceType), TargetType); - ret.Options.Set(new HttpRequestOptionsKey(HttpRequestMessageOptions.RestMethodInfo), restMethod.ToRestMethodInfo()); + ret.Options.Set( + new HttpRequestOptionsKey(HttpRequestMessageOptions.InterfaceType), + TargetType + ); + ret.Options.Set( + new HttpRequestOptionsKey( + HttpRequestMessageOptions.RestMethodInfo + ), + restMethod.ToRestMethodInfo() + ); #else ret.Properties[HttpRequestMessageOptions.InterfaceType] = TargetType; - ret.Properties[HttpRequestMessageOptions.RestMethodInfo] = restMethod.ToRestMethodInfo(); + ret.Properties[HttpRequestMessageOptions.RestMethodInfo] = + restMethod.ToRestMethodInfo(); #endif // NB: The URI methods in .NET are dumb. Also, we do this @@ -757,14 +993,23 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn { if (!string.IsNullOrWhiteSpace(key)) { - queryParamsToAdd.Insert(0, new KeyValuePair(key, query[key])); + queryParamsToAdd.Insert( + 0, + new KeyValuePair(key, query[key]) + ); } } if (queryParamsToAdd.Any()) { - var pairs = queryParamsToAdd.Where(x => x.Key != null && x.Value != null) - .Select(x => Uri.EscapeDataString(x.Key) + "=" + Uri.EscapeDataString(x.Value ?? string.Empty)); + var pairs = queryParamsToAdd + .Where(x => x.Key != null && x.Value != null) + .Select( + x => + Uri.EscapeDataString(x.Key) + + "=" + + Uri.EscapeDataString(x.Value ?? string.Empty) + ); uri.Query = string.Join("&", pairs); } else @@ -772,53 +1017,98 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn uri.Query = null; } - var uriFormat = restMethod.MethodInfo.GetCustomAttribute()?.UriFormat ?? UriFormat.UriEscaped; - ret.RequestUri = new Uri(uri.Uri.GetComponents(UriComponents.PathAndQuery, uriFormat), UriKind.Relative); + var uriFormat = + restMethod.MethodInfo.GetCustomAttribute()?.UriFormat + ?? UriFormat.UriEscaped; + ret.RequestUri = new Uri( + uri.Uri.GetComponents(UriComponents.PathAndQuery, uriFormat), + UriKind.Relative + ); return ret; }; } - IEnumerable> ParseQueryParameter(object? param, ParameterInfo parameterInfo, string queryPath, QueryAttribute queryAttribute) + IEnumerable> ParseQueryParameter( + object? param, + ParameterInfo parameterInfo, + string queryPath, + QueryAttribute queryAttribute + ) { if (param is not string && param is IEnumerable paramValues) { - foreach (var value in ParseEnumerableQueryParameterValue(paramValues, parameterInfo, parameterInfo.ParameterType, queryAttribute)) + foreach ( + var value in ParseEnumerableQueryParameterValue( + paramValues, + parameterInfo, + parameterInfo.ParameterType, + queryAttribute + ) + ) { yield return new KeyValuePair(queryPath, value); } } else { - yield return new KeyValuePair(queryPath, settings.UrlParameterFormatter.Format(param, parameterInfo, parameterInfo.ParameterType)); + yield return new KeyValuePair( + queryPath, + settings.UrlParameterFormatter.Format( + param, + parameterInfo, + parameterInfo.ParameterType + ) + ); } } - IEnumerable ParseEnumerableQueryParameterValue(IEnumerable paramValues, ICustomAttributeProvider customAttributeProvider, Type type, QueryAttribute? queryAttribute) + IEnumerable ParseEnumerableQueryParameterValue( + IEnumerable paramValues, + ICustomAttributeProvider customAttributeProvider, + Type type, + QueryAttribute? queryAttribute + ) { - var collectionFormat = queryAttribute != null && queryAttribute.IsCollectionFormatSpecified - ? queryAttribute.CollectionFormat - : settings.CollectionFormat; + var collectionFormat = + queryAttribute != null && queryAttribute.IsCollectionFormatSpecified + ? queryAttribute.CollectionFormat + : settings.CollectionFormat; switch (collectionFormat) { case CollectionFormat.Multi: foreach (var paramValue in paramValues) { - yield return settings.UrlParameterFormatter.Format(paramValue, customAttributeProvider, type); + yield return settings.UrlParameterFormatter.Format( + paramValue, + customAttributeProvider, + type + ); } break; default: - var delimiter = collectionFormat == CollectionFormat.Ssv ? " " - : collectionFormat == CollectionFormat.Tsv ? "\t" - : collectionFormat == CollectionFormat.Pipes ? "|" - : ","; + var delimiter = + collectionFormat == CollectionFormat.Ssv + ? " " + : collectionFormat == CollectionFormat.Tsv + ? "\t" + : collectionFormat == CollectionFormat.Pipes + ? "|" + : ","; // Missing a "default" clause was preventing the collection from serializing at all, as it was hitting "continue" thus causing an off-by-one error var formattedValues = paramValues .Cast() - .Select(v => settings.UrlParameterFormatter.Format(v, customAttributeProvider, type)); + .Select( + v => + settings.UrlParameterFormatter.Format( + v, + customAttributeProvider, + type + ) + ); yield return string.Join(delimiter, formattedValues); @@ -826,7 +1116,9 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn } } - Func> BuildRxFuncForMethod(RestMethodInfoInternal restMethod) + Func> BuildRxFuncForMethod( + RestMethodInfoInternal restMethod + ) { var taskFunc = BuildCancellableTaskFuncForMethod(restMethod); @@ -848,7 +1140,9 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn }; } - Func> BuildTaskFuncForMethod(RestMethodInfoInternal restMethod) + Func> BuildTaskFuncForMethod( + RestMethodInfoInternal restMethod + ) { var ret = BuildCancellableTaskFuncForMethod(restMethod); @@ -856,21 +1150,33 @@ Func BuildRequestFactoryForMethod(RestMethodInfoIn { if (restMethod.CancellationToken != null) { - return ret(client, paramList.OfType().FirstOrDefault(), paramList); + return ret( + client, + paramList.OfType().FirstOrDefault(), + paramList + ); } return ret(client, CancellationToken.None, paramList); }; } - Func BuildVoidTaskFuncForMethod(RestMethodInfoInternal restMethod) + Func BuildVoidTaskFuncForMethod( + RestMethodInfoInternal restMethod + ) { return async (client, paramList) => { if (client.BaseAddress == null) - throw new InvalidOperationException("BaseAddress must be set on the HttpClient instance"); - - var factory = BuildRequestFactoryForMethod(restMethod, client.BaseAddress.AbsolutePath, restMethod.CancellationToken != null); + throw new InvalidOperationException( + "BaseAddress must be set on the HttpClient instance" + ); + + var factory = BuildRequestFactoryForMethod( + restMethod, + client.BaseAddress.AbsolutePath, + restMethod.CancellationToken != null + ); var rq = factory(paramList); var ct = CancellationToken.None; @@ -895,7 +1201,10 @@ Func BuildVoidTaskFuncForMethod(RestMethodInfoIntern }; } - private static bool IsBodyBuffered(RestMethodInfoInternal restMethod, HttpRequestMessage? request) + private static bool IsBodyBuffered( + RestMethodInfoInternal restMethod, + HttpRequestMessage? request + ) { return (restMethod.BodyParameterInfo?.Item2 ?? false) && (request?.Content != null); } @@ -907,11 +1216,12 @@ static bool DoNotConvertToQueryMap(object? value) var type = value.GetType(); - bool ShouldReturn() => type == typeof(string) || - type == typeof(bool) || - type == typeof(char) || - typeof(IFormattable).IsAssignableFrom(type) || - type == typeof(Uri); + bool ShouldReturn() => + type == typeof(string) + || type == typeof(bool) + || type == typeof(char) + || typeof(IFormattable).IsAssignableFrom(type) + || type == typeof(Uri); // Bail out early & match string if (ShouldReturn()) @@ -923,14 +1233,14 @@ bool ShouldReturn() => type == typeof(string) || var ienu = typeof(IEnumerable<>); // We don't want to enumerate to get the type, so we'll just look for IEnumerable var intType = type.GetInterfaces() - .FirstOrDefault(i => i.GetTypeInfo().IsGenericType && - i.GetGenericTypeDefinition() == ienu); + .FirstOrDefault( + i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == ienu + ); if (intType != null) { type = intType.GetGenericArguments()[0]; } - } return ShouldReturn(); @@ -955,7 +1265,8 @@ static void SetHeader(HttpRequestMessage request, string name, string? value) request.Content.Headers.Remove(name); } - if (value == null) return; + if (value == null) + return; var added = request.Headers.TryAddWithoutValidation(name, value); diff --git a/Refit/RestMethodInfo.cs b/Refit/RestMethodInfo.cs index f7ec90c68..2403de863 100644 --- a/Refit/RestMethodInfo.cs +++ b/Refit/RestMethodInfo.cs @@ -13,7 +13,13 @@ internal static class IsExternalInit { } namespace Refit { - public record RestMethodInfo(string Name, Type HostingType, MethodInfo MethodInfo, string RelativePath, Type ReturnType); + public record RestMethodInfo( + string Name, + Type HostingType, + MethodInfo MethodInfo, + string RelativePath, + Type ReturnType + ); [DebuggerDisplay("{MethodInfo}")] internal class RestMethodInfoInternal @@ -47,7 +53,11 @@ internal class RestMethodInfoInternal static readonly HttpMethod PatchMethod = new("PATCH"); #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public RestMethodInfoInternal(Type targetInterface, MethodInfo methodInfo, RefitSettings? refitSettings = null) + public RestMethodInfoInternal( + Type targetInterface, + MethodInfo methodInfo, + RefitSettings? refitSettings = null + ) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { RefitSettings = refitSettings ?? new RefitSettings(); @@ -55,25 +65,27 @@ public RestMethodInfoInternal(Type targetInterface, MethodInfo methodInfo, Refit Name = methodInfo.Name; MethodInfo = methodInfo ?? throw new ArgumentNullException(nameof(methodInfo)); - var hma = methodInfo.GetCustomAttributes(true) - .OfType() - .First(); + var hma = methodInfo.GetCustomAttributes(true).OfType().First(); HttpMethod = hma.Method; RelativePath = hma.Path; - IsMultipart = methodInfo.GetCustomAttributes(true) - .OfType() - .Any(); + IsMultipart = methodInfo.GetCustomAttributes(true).OfType().Any(); - MultipartBoundary = IsMultipart ? methodInfo.GetCustomAttribute(true)?.BoundaryText ?? new MultipartAttribute().BoundaryText : string.Empty; + MultipartBoundary = IsMultipart + ? methodInfo.GetCustomAttribute(true)?.BoundaryText + ?? new MultipartAttribute().BoundaryText + : string.Empty; VerifyUrlPathIsSane(RelativePath); DetermineReturnTypeInfo(methodInfo); DetermineIfResponseMustBeDisposed(); // Exclude cancellation token parameters from this list - var parameterList = methodInfo.GetParameters().Where(p => p.ParameterType != typeof(CancellationToken)).ToList(); + var parameterList = methodInfo + .GetParameters() + .Where(p => p.ParameterType != typeof(CancellationToken)) + .ToList(); ParameterInfoMap = parameterList .Select((parameter, index) => new { index, parameter }) .ToDictionary(x => x.index, x => x.parameter); @@ -92,7 +104,12 @@ public RestMethodInfoInternal(Type targetInterface, MethodInfo methodInfo, Refit { for (var i = 0; i < parameterList.Count; i++) { - if (ParameterMap.ContainsKey(i) || HeaderParameterMap.ContainsKey(i) || PropertyParameterMap.ContainsKey(i) || HeaderCollectionParameterMap.Contains(i)) + if ( + ParameterMap.ContainsKey(i) + || HeaderParameterMap.ContainsKey(i) + || PropertyParameterMap.ContainsKey(i) + || HeaderCollectionParameterMap.Contains(i) + ) { continue; } @@ -101,19 +118,24 @@ public RestMethodInfoInternal(Type targetInterface, MethodInfo methodInfo, Refit if (attachmentName == null) continue; - AttachmentNameMap[i] = Tuple.Create(attachmentName, GetUrlNameForParameter(parameterList[i])); + AttachmentNameMap[i] = Tuple.Create( + attachmentName, + GetUrlNameForParameter(parameterList[i]) + ); } } QueryParameterMap = new Dictionary(); for (var i = 0; i < parameterList.Count; i++) { - if (ParameterMap.ContainsKey(i) || - HeaderParameterMap.ContainsKey(i) || - PropertyParameterMap.ContainsKey(i) || - HeaderCollectionParameterMap.Contains(i) || - (BodyParameterInfo != null && BodyParameterInfo.Item3 == i) || - (AuthorizeParameterInfo != null && AuthorizeParameterInfo.Item2 == i)) + if ( + ParameterMap.ContainsKey(i) + || HeaderParameterMap.ContainsKey(i) + || PropertyParameterMap.ContainsKey(i) + || HeaderCollectionParameterMap.Contains(i) + || (BodyParameterInfo != null && BodyParameterInfo.Item3 == i) + || (AuthorizeParameterInfo != null && AuthorizeParameterInfo.Item2 == i) + ) { continue; } @@ -121,18 +143,26 @@ public RestMethodInfoInternal(Type targetInterface, MethodInfo methodInfo, Refit QueryParameterMap.Add(i, GetUrlNameForParameter(parameterList[i])); } - var ctParams = methodInfo.GetParameters().Where(p => p.ParameterType == typeof(CancellationToken)).ToList(); + var ctParams = methodInfo + .GetParameters() + .Where(p => p.ParameterType == typeof(CancellationToken)) + .ToList(); if (ctParams.Count > 1) { - throw new ArgumentException($"Argument list to method \"{methodInfo.Name}\" can only contain a single CancellationToken"); + throw new ArgumentException( + $"Argument list to method \"{methodInfo.Name}\" can only contain a single CancellationToken" + ); } CancellationToken = ctParams.FirstOrDefault(); - IsApiResponse = ReturnResultType!.GetTypeInfo().IsGenericType && - (ReturnResultType!.GetGenericTypeDefinition() == typeof(ApiResponse<>) - || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>)) - || ReturnResultType == typeof(IApiResponse); + IsApiResponse = + ReturnResultType!.GetTypeInfo().IsGenericType + && ( + ReturnResultType!.GetGenericTypeDefinition() == typeof(ApiResponse<>) + || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>) + ) + || ReturnResultType == typeof(IApiResponse); } private ISet BuildHeaderCollectionParameterMap(List parameterList) @@ -142,7 +172,8 @@ private ISet BuildHeaderCollectionParameterMap(List paramete for (var i = 0; i < parameterList.Count; i++) { var param = parameterList[i]; - var headerCollection = param.GetCustomAttributes(true) + var headerCollection = param + .GetCustomAttributes(true) .OfType() .FirstOrDefault(); @@ -155,18 +186,23 @@ private ISet BuildHeaderCollectionParameterMap(List paramete } else { - throw new ArgumentException($"HeaderCollection parameter of type {param.ParameterType.Name} is not assignable from IDictionary"); + throw new ArgumentException( + $"HeaderCollection parameter of type {param.ParameterType.Name} is not assignable from IDictionary" + ); } } } if (headerCollectionMap.Count > 1) - throw new ArgumentException("Only one parameter can be a HeaderCollection parameter"); + throw new ArgumentException( + "Only one parameter can be a HeaderCollection parameter" + ); return headerCollectionMap; } - public RestMethodInfo ToRestMethodInfo() => new RestMethodInfo(Name, Type, MethodInfo, RelativePath, ReturnType); + public RestMethodInfo ToRestMethodInfo() => + new RestMethodInfo(Name, Type, MethodInfo, RelativePath, ReturnType); static Dictionary BuildRequestPropertyMap(List parameterList) { @@ -175,16 +211,18 @@ static Dictionary BuildRequestPropertyMap(List param for (var i = 0; i < parameterList.Count; i++) { var param = parameterList[i]; - var propertyAttribute = param.GetCustomAttributes(true) + var propertyAttribute = param + .GetCustomAttributes(true) .OfType() .FirstOrDefault(); if (propertyAttribute != null) { - var propertyKey = !string.IsNullOrEmpty(propertyAttribute.Key) ? propertyAttribute.Key : param.Name!; + var propertyKey = !string.IsNullOrEmpty(propertyAttribute.Key) + ? propertyAttribute.Key + : param.Name!; propertyMap[i] = propertyKey!; } - } return propertyMap; @@ -194,7 +232,8 @@ static PropertyInfo[] GetParameterProperties(ParameterInfo parameter) { return parameter.ParameterType .GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.CanRead && p.GetMethod?.IsPublic == true).ToArray(); + .Where(p => p.CanRead && p.GetMethod?.IsPublic == true) + .ToArray(); } static void VerifyUrlPathIsSane(string relativePath) @@ -203,26 +242,38 @@ static void VerifyUrlPathIsSane(string relativePath) return; if (!relativePath.StartsWith("/")) - throw new ArgumentException($"URL path {relativePath} must start with '/' and be of the form '/foo/bar/baz'"); + throw new ArgumentException( + $"URL path {relativePath} must start with '/' and be of the form '/foo/bar/baz'" + ); } - static Dictionary BuildParameterMap(string relativePath, List parameterInfo) + static Dictionary BuildParameterMap( + string relativePath, + List parameterInfo + ) { var ret = new Dictionary(); // This section handles pattern matching in the URL. We also need it to add parameter key/values for any attribute with a [Query] - var parameterizedParts = relativePath.Split('/', '?') + var parameterizedParts = relativePath + .Split('/', '?') .SelectMany(x => ParameterRegex.Matches(x).Cast()) .ToList(); if (parameterizedParts.Count > 0) { - var paramValidationDict = parameterInfo.ToDictionary(k => GetUrlNameForParameter(k).ToLowerInvariant(), v => v); + var paramValidationDict = parameterInfo.ToDictionary( + k => GetUrlNameForParameter(k).ToLowerInvariant(), + v => v + ); //if the param is an lets make a dictionary for all it's potential parameters - var objectParamValidationDict = parameterInfo.Where(x => x.ParameterType.GetTypeInfo().IsClass) - .SelectMany(x => GetParameterProperties(x).Select(p => Tuple.Create(x, p))) - .GroupBy(i => $"{i.Item1.Name}.{GetUrlNameForProperty(i.Item2)}".ToLowerInvariant()) - .ToDictionary(k => k.Key, v => v.First()); + var objectParamValidationDict = parameterInfo + .Where(x => x.ParameterType.GetTypeInfo().IsClass) + .SelectMany(x => GetParameterProperties(x).Select(p => Tuple.Create(x, p))) + .GroupBy( + i => $"{i.Item1.Name}.{GetUrlNameForProperty(i.Item2)}".ToLowerInvariant() + ) + .ToDictionary(k => k.Key, v => v.First()); foreach (var match in parameterizedParts) { var rawName = match.Groups[1].Value.ToLowerInvariant(); @@ -242,12 +293,25 @@ static Dictionary BuildParameterMap(string relativ var paramType = paramValidationDict[name].ParameterType; if (isRoundTripping && paramType != typeof(string)) { - throw new ArgumentException($"URL {relativePath} has round-tripping parameter {rawName}, but the type of matched method parameter is {paramType.FullName}. It must be a string."); + throw new ArgumentException( + $"URL {relativePath} has round-tripping parameter {rawName}, but the type of matched method parameter is {paramType.FullName}. It must be a string." + ); } - var parameterType = isRoundTripping ? ParameterType.RoundTripping : ParameterType.Normal; - var restMethodParameterInfo = new RestMethodParameterInfo(name, paramValidationDict[name]) { Type = parameterType }; + var parameterType = isRoundTripping + ? ParameterType.RoundTripping + : ParameterType.Normal; + var restMethodParameterInfo = new RestMethodParameterInfo( + name, + paramValidationDict[name] + ) + { + Type = parameterType + }; #if NETSTANDARD2_1 || NET6_0_OR_GREATER - ret.TryAdd(parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo), restMethodParameterInfo); + ret.TryAdd( + parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo), + restMethodParameterInfo + ); #else var idx = parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo); if (!ret.ContainsKey(idx)) @@ -266,21 +330,33 @@ static Dictionary BuildParameterMap(string relativ { if (!ret[parameterIndex].IsObjectPropertyParameter) { - throw new ArgumentException($"Parameter {property.Item1.Name} matches both a parameter and nested parameter on a parameter object"); + throw new ArgumentException( + $"Parameter {property.Item1.Name} matches both a parameter and nested parameter on a parameter object" + ); } //we already have this parameter. add the additional property - ret[parameterIndex].ParameterProperties.Add(new RestMethodParameterProperty(name, property.Item2)); + ret[parameterIndex].ParameterProperties.Add( + new RestMethodParameterProperty(name, property.Item2) + ); } else { - var restMethodParameterInfo = new RestMethodParameterInfo(true, property.Item1); - restMethodParameterInfo.ParameterProperties.Add(new RestMethodParameterProperty(name, property.Item2)); + var restMethodParameterInfo = new RestMethodParameterInfo( + true, + property.Item1 + ); + restMethodParameterInfo.ParameterProperties.Add( + new RestMethodParameterProperty(name, property.Item2) + ); #if NETSTANDARD2_1 || NET6_0_OR_GREATER - ret.TryAdd(parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo), restMethodParameterInfo); + ret.TryAdd( + parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo), + restMethodParameterInfo + ); #else // Do the contains check var idx = parameterInfo.IndexOf(restMethodParameterInfo.ParameterInfo); - if(!ret.ContainsKey(idx)) + if (!ret.ContainsKey(idx)) { ret.Add(idx, restMethodParameterInfo); } @@ -289,9 +365,10 @@ static Dictionary BuildParameterMap(string relativ } else { - throw new ArgumentException($"URL {relativePath} has parameter {rawName}, but no method parameter matches"); + throw new ArgumentException( + $"URL {relativePath} has parameter {rawName}, but no method parameter matches" + ); } - } } return ret; @@ -299,7 +376,8 @@ static Dictionary BuildParameterMap(string relativ static string GetUrlNameForParameter(ParameterInfo paramInfo) { - var aliasAttr = paramInfo.GetCustomAttributes(true) + var aliasAttr = paramInfo + .GetCustomAttributes(true) .OfType() .FirstOrDefault(); return aliasAttr != null ? aliasAttr.Name : paramInfo.Name!; @@ -307,7 +385,8 @@ static string GetUrlNameForParameter(ParameterInfo paramInfo) static string GetUrlNameForProperty(PropertyInfo propInfo) { - var aliasAttr = propInfo.GetCustomAttributes(true) + var aliasAttr = propInfo + .GetCustomAttributes(true) .OfType() .FirstOrDefault(); return aliasAttr != null ? aliasAttr.Name : propInfo.Name; @@ -316,24 +395,38 @@ static string GetUrlNameForProperty(PropertyInfo propInfo) static string GetAttachmentNameForParameter(ParameterInfo paramInfo) { #pragma warning disable CS0618 // Type or member is obsolete - var nameAttr = paramInfo.GetCustomAttributes(true) + var nameAttr = paramInfo + .GetCustomAttributes(true) #pragma warning restore CS0618 // Type or member is obsolete .FirstOrDefault(); // also check for AliasAs - return nameAttr?.Name ?? paramInfo.GetCustomAttributes(true).FirstOrDefault()?.Name!; + return nameAttr?.Name + ?? paramInfo.GetCustomAttributes(true).FirstOrDefault()?.Name!; } - Tuple? FindBodyParameter(IList parameterList, bool isMultipart, HttpMethod method) + Tuple? FindBodyParameter( + IList parameterList, + bool isMultipart, + HttpMethod method + ) { - // The body parameter is found using the following logic / order of precedence: // 1) [Body] attribute // 2) POST/PUT/PATCH: Reference type other than string // 3) If there are two reference types other than string, without the body attribute, throw var bodyParams = parameterList - .Select(x => new { Parameter = x, BodyAttribute = x.GetCustomAttributes(true).OfType().FirstOrDefault() }) + .Select( + x => + new + { + Parameter = x, + BodyAttribute = x.GetCustomAttributes(true) + .OfType() + .FirstOrDefault() + } + ) .Where(x => x.BodyAttribute != null) .ToList(); @@ -342,7 +435,9 @@ static string GetAttachmentNameForParameter(ParameterInfo paramInfo) { if (bodyParams.Count > 0) { - throw new ArgumentException("Multipart requests may not contain a Body parameter"); + throw new ArgumentException( + "Multipart requests may not contain a Body parameter" + ); } return null; } @@ -356,35 +451,51 @@ static string GetAttachmentNameForParameter(ParameterInfo paramInfo) if (bodyParams.Count == 1) { var ret = bodyParams[0]; - return Tuple.Create(ret.BodyAttribute!.SerializationMethod, ret.BodyAttribute.Buffered ?? RefitSettings.Buffered, - parameterList.IndexOf(ret.Parameter)); + return Tuple.Create( + ret.BodyAttribute!.SerializationMethod, + ret.BodyAttribute.Buffered ?? RefitSettings.Buffered, + parameterList.IndexOf(ret.Parameter) + ); } // Not in post/put/patch? bail - if (!method.Equals(HttpMethod.Post) && !method.Equals(HttpMethod.Put) && !method.Equals(PatchMethod)) + if ( + !method.Equals(HttpMethod.Post) + && !method.Equals(HttpMethod.Put) + && !method.Equals(PatchMethod) + ) { return null; } // see if we're a post/put/patch // explicitly skip [Query], [HeaderCollection], and [Property]-denoted params - var refParams = parameterList.Where(pi => - !pi.ParameterType.GetTypeInfo().IsValueType && - pi.ParameterType != typeof(string) && - pi.GetCustomAttribute() == null && - pi.GetCustomAttribute() == null && - pi.GetCustomAttribute() == null) + var refParams = parameterList + .Where( + pi => + !pi.ParameterType.GetTypeInfo().IsValueType + && pi.ParameterType != typeof(string) + && pi.GetCustomAttribute() == null + && pi.GetCustomAttribute() == null + && pi.GetCustomAttribute() == null + ) .ToList(); // Check for rule #3 if (refParams.Count > 1) { - throw new ArgumentException("Multiple complex types found. Specify one parameter as the body using BodyAttribute"); + throw new ArgumentException( + "Multiple complex types found. Specify one parameter as the body using BodyAttribute" + ); } if (refParams.Count == 1) { - return Tuple.Create(BodySerializationMethod.Serialized, RefitSettings.Buffered, parameterList.IndexOf(refParams[0])); + return Tuple.Create( + BodySerializationMethod.Serialized, + RefitSettings.Buffered, + parameterList.IndexOf(refParams[0]) + ); } return null; @@ -393,7 +504,16 @@ static string GetAttachmentNameForParameter(ParameterInfo paramInfo) static Tuple? FindAuthorizationParameter(IList parameterList) { var authorizeParams = parameterList - .Select(x => new { Parameter = x, AuthorizeAttribute = x.GetCustomAttributes(true).OfType().FirstOrDefault() }) + .Select( + x => + new + { + Parameter = x, + AuthorizeAttribute = x.GetCustomAttributes(true) + .OfType() + .FirstOrDefault() + } + ) .Where(x => x.AuthorizeAttribute != null) .ToList(); @@ -405,7 +525,10 @@ static string GetAttachmentNameForParameter(ParameterInfo paramInfo) if (authorizeParams.Count == 1) { var ret = authorizeParams[0]; - return Tuple.Create(ret.AuthorizeAttribute!.Scheme, parameterList.IndexOf(ret.Parameter)); + return Tuple.Create( + ret.AuthorizeAttribute!.Scheme, + parameterList.IndexOf(ret.Parameter) + ); } return null; @@ -415,32 +538,40 @@ static string GetAttachmentNameForParameter(ParameterInfo paramInfo) { var ret = new Dictionary(); - var inheritedAttributes = methodInfo.DeclaringType != null - ? methodInfo.DeclaringType.GetInterfaces().SelectMany(i => i.GetTypeInfo().GetCustomAttributes(true)).Reverse() - : Array.Empty(); + var inheritedAttributes = + methodInfo.DeclaringType != null + ? methodInfo.DeclaringType + .GetInterfaces() + .SelectMany(i => i.GetTypeInfo().GetCustomAttributes(true)) + .Reverse() + : Array.Empty(); - var declaringTypeAttributes = methodInfo.DeclaringType != null - ? methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true) - : Array.Empty(); + var declaringTypeAttributes = + methodInfo.DeclaringType != null + ? methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true) + : Array.Empty(); // Headers set on the declaring type have to come first, // so headers set on the method can replace them. Switching // the order here will break stuff. - var headers = inheritedAttributes.Concat(declaringTypeAttributes).Concat(methodInfo.GetCustomAttributes(true)) + var headers = inheritedAttributes + .Concat(declaringTypeAttributes) + .Concat(methodInfo.GetCustomAttributes(true)) .OfType() .SelectMany(ha => ha.Headers); foreach (var header in headers) { - if (string.IsNullOrWhiteSpace(header)) continue; + if (string.IsNullOrWhiteSpace(header)) + continue; // NB: Silverlight doesn't have an overload for String.Split() // with a count parameter, but header values can contain // ':' so we have to re-join all but the first part to get the // value. var parts = header.Split(':'); - ret[parts[0].Trim()] = parts.Length > 1 ? - string.Join(":", parts.Skip(1)).Trim() : null; + ret[parts[0].Trim()] = + parts.Length > 1 ? string.Join(":", parts.Skip(1)).Trim() : null; } return ret; @@ -452,7 +583,8 @@ static Dictionary BuildHeaderParameterMap(List param for (var i = 0; i < parameterList.Count; i++) { - var header = parameterList[i].GetCustomAttributes(true) + var header = parameterList[i] + .GetCustomAttributes(true) .OfType() .Select(ha => ha.Header) .FirstOrDefault(); @@ -469,23 +601,33 @@ static Dictionary BuildHeaderParameterMap(List param void DetermineReturnTypeInfo(MethodInfo methodInfo) { var returnType = methodInfo.ReturnType; - if (returnType.IsGenericType && (methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task<>) - || methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>) - || methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(IObservable<>))) + if ( + returnType.IsGenericType + && ( + methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task<>) + || methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>) + || methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(IObservable<>) + ) + ) { ReturnType = returnType; ReturnResultType = returnType.GetGenericArguments()[0]; - if (ReturnResultType.IsGenericType && - (ReturnResultType.GetGenericTypeDefinition() == typeof(ApiResponse<>) - || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>))) + if ( + ReturnResultType.IsGenericType + && ( + ReturnResultType.GetGenericTypeDefinition() == typeof(ApiResponse<>) + || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>) + ) + ) { - DeserializedResultType = ReturnResultType.GetGenericArguments()[0]; + DeserializedResultType = ReturnResultType.GetGenericArguments()[0]; } else if (ReturnResultType == typeof(IApiResponse)) { DeserializedResultType = typeof(HttpContent); - }else + } + else DeserializedResultType = ReturnResultType; } else if (returnType == typeof(Task)) @@ -495,16 +637,18 @@ void DetermineReturnTypeInfo(MethodInfo methodInfo) DeserializedResultType = typeof(void); } else - throw new ArgumentException($"Method \"{methodInfo.Name}\" is invalid. All REST Methods must return either Task or ValueTask or IObservable"); + throw new ArgumentException( + $"Method \"{methodInfo.Name}\" is invalid. All REST Methods must return either Task or ValueTask or IObservable" + ); } void DetermineIfResponseMustBeDisposed() { // Rest method caller will have to dispose if it's one of those 3 - ShouldDisposeResponse = DeserializedResultType != typeof(HttpResponseMessage) && - DeserializedResultType != typeof(HttpContent) && - DeserializedResultType != typeof(Stream); + ShouldDisposeResponse = + DeserializedResultType != typeof(HttpResponseMessage) + && DeserializedResultType != typeof(HttpContent) + && DeserializedResultType != typeof(Stream); } - } } diff --git a/Refit/RestMethodParameterInfo.cs b/Refit/RestMethodParameterInfo.cs index 3fa5453f9..c5542bca4 100644 --- a/Refit/RestMethodParameterInfo.cs +++ b/Refit/RestMethodParameterInfo.cs @@ -15,10 +15,12 @@ public RestMethodParameterInfo(bool isObjectPropertyParameter, ParameterInfo par IsObjectPropertyParameter = isObjectPropertyParameter; ParameterInfo = parameterInfo; } + public string? Name { get; set; } public ParameterInfo ParameterInfo { get; set; } public bool IsObjectPropertyParameter { get; set; } - public List ParameterProperties { get; set; } = new List(); + public List ParameterProperties { get; set; } = + new List(); public ParameterType Type { get; set; } = ParameterType.Normal; } @@ -29,6 +31,7 @@ public RestMethodParameterProperty(string name, PropertyInfo propertyInfo) Name = name; PropertyInfo = propertyInfo; } + public string Name { get; set; } public PropertyInfo PropertyInfo { get; set; } } diff --git a/Refit/RestService.cs b/Refit/RestService.cs index 8e9e3f415..0cf2571d8 100644 --- a/Refit/RestService.cs +++ b/Refit/RestService.cs @@ -70,7 +70,11 @@ public static T For(string hostUrl, RefitSettings? settings) /// The the implementation will use to send requests. /// to use to build requests. /// An instance that implements . - public static object For(Type refitInterfaceType, HttpClient client, IRequestBuilder builder) + public static object For( + Type refitInterfaceType, + HttpClient client, + IRequestBuilder builder + ) { var generatedType = TypeMapping.GetOrAdd(refitInterfaceType, GetGeneratedType); @@ -84,7 +88,11 @@ public static object For(Type refitInterfaceType, HttpClient client, IRequestBui /// The the implementation will use to send requests. /// to use to configure the HttpClient. /// An instance that implements . - public static object For(Type refitInterfaceType, HttpClient client, RefitSettings? settings) + public static object For( + Type refitInterfaceType, + HttpClient client, + RefitSettings? settings + ) { var requestBuilder = RequestBuilder.ForType(refitInterfaceType, settings); @@ -97,7 +105,8 @@ public static object For(Type refitInterfaceType, HttpClient client, RefitSettin /// Interface to create the implementation for. /// The the implementation will use to send requests. /// An instance that implements . - public static object For(Type refitInterfaceType, HttpClient client) => For(refitInterfaceType, client, (RefitSettings?)null); + public static object For(Type refitInterfaceType, HttpClient client) => + For(refitInterfaceType, client, (RefitSettings?)null); /// /// Generate a Refit implementation of the specified interface. @@ -119,7 +128,8 @@ public static object For(Type refitInterfaceType, string hostUrl, RefitSettings? /// Interface to create the implementation for. /// Base address the implementation will use. /// An instance that implements . - public static object For(Type refitInterfaceType, string hostUrl) => For(refitInterfaceType, hostUrl, null); + public static object For(Type refitInterfaceType, string hostUrl) => + For(refitInterfaceType, hostUrl, null); /// /// Create an with as the base address. @@ -134,7 +144,8 @@ public static HttpClient CreateHttpClient(string hostUrl, RefitSettings? setting { throw new ArgumentException( $"`{nameof(hostUrl)}` must not be null or whitespace.", - nameof(hostUrl)); + nameof(hostUrl) + ); } // check to see if user provided custom auth token @@ -148,11 +159,17 @@ public static HttpClient CreateHttpClient(string hostUrl, RefitSettings? setting if (settings.AuthorizationHeaderValueGetter != null) { - innerHandler = new AuthenticatedHttpClientHandler(settings.AuthorizationHeaderValueGetter, innerHandler); + innerHandler = new AuthenticatedHttpClientHandler( + settings.AuthorizationHeaderValueGetter, + innerHandler + ); } } - return new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl.TrimEnd('/')) }; + return new HttpClient(innerHandler ?? new HttpClientHandler()) + { + BaseAddress = new Uri(hostUrl.TrimEnd('/')) + }; } static Type GetGeneratedType(Type refitInterfaceType) @@ -163,7 +180,10 @@ static Type GetGeneratedType(Type refitInterfaceType) if (generatedType == null) { - var message = refitInterfaceType.Name + " doesn't look like a Refit interface. Make sure it has at least one " + "method with a Refit HTTP method attribute and Refit is installed in the project."; + var message = + refitInterfaceType.Name + + " doesn't look like a Refit interface. Make sure it has at least one " + + "method with a Refit HTTP method attribute and Refit is installed in the project."; throw new InvalidOperationException(message); } diff --git a/Refit/SystemTextJsonContentSerializer.cs b/Refit/SystemTextJsonContentSerializer.cs index a45210831..b3f17a8b7 100644 --- a/Refit/SystemTextJsonContentSerializer.cs +++ b/Refit/SystemTextJsonContentSerializer.cs @@ -19,9 +19,8 @@ public sealed class SystemTextJsonContentSerializer : IHttpContentSerializer /// /// Creates a new instance /// - public SystemTextJsonContentSerializer() : this(GetDefaultJsonSerializerOptions()) - { - } + public SystemTextJsonContentSerializer() + : this(GetDefaultJsonSerializerOptions()) { } /// /// Creates a new instance with the specified parameters @@ -41,9 +40,14 @@ public HttpContent ToHttpContent(T item) } /// - public async Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) + public async Task FromHttpContentAsync( + HttpContent content, + CancellationToken cancellationToken = default + ) { - var item = await content.ReadFromJsonAsync(jsonSerializerOptions, cancellationToken).ConfigureAwait(false); + var item = await content + .ReadFromJsonAsync(jsonSerializerOptions, cancellationToken) + .ConfigureAwait(false); return item; } @@ -52,9 +56,10 @@ public HttpContent ToHttpContent(T item) if (propertyInfo is null) throw new ArgumentNullException(nameof(propertyInfo)); - return propertyInfo.GetCustomAttributes(true) - .Select(a => a.Name) - .FirstOrDefault(); + return propertyInfo + .GetCustomAttributes(true) + .Select(a => a.Name) + .FirstOrDefault(); } /// @@ -67,36 +72,37 @@ public static JsonSerializerOptions GetDefaultJsonSerializerOptions() jsonSerializerOptions.PropertyNameCaseInsensitive = true; jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; jsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); + jsonSerializerOptions.Converters.Add( + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) + ); return jsonSerializerOptions; } } // From https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0#deserialize-inferred-types-to-object-properties - public class ObjectToInferredTypesConverter - : JsonConverter + public class ObjectToInferredTypesConverter : JsonConverter { public override object? Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => reader.TokenType switch - { - JsonTokenType.True => true, - JsonTokenType.False => false, - JsonTokenType.Number when reader.TryGetInt64(out var l) => l, - JsonTokenType.Number => reader.GetDouble(), - JsonTokenType.String when reader.TryGetDateTime(out var datetime) => datetime, - JsonTokenType.String => reader.GetString(), - _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() - }; + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) => + reader.TokenType switch + { + JsonTokenType.True => true, + JsonTokenType.False => false, + JsonTokenType.Number when reader.TryGetInt64(out var l) => l, + JsonTokenType.Number => reader.GetDouble(), + JsonTokenType.String when reader.TryGetDateTime(out var datetime) => datetime, + JsonTokenType.String => reader.GetString(), + _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() + }; public override void Write( Utf8JsonWriter writer, object objectToWrite, - JsonSerializerOptions options) => - JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); + JsonSerializerOptions options + ) => JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); } - } - diff --git a/Refit/UniqueName.cs b/Refit/UniqueName.cs index 2737ba1f4..335334dc3 100644 --- a/Refit/UniqueName.cs +++ b/Refit/UniqueName.cs @@ -26,10 +26,13 @@ public static string ForType(Type refitInterfaceType) // Or Nested+IFrob var genericArgs = string.Empty; // if there's any generics, split that - if(refitInterfaceType.IsGenericType) + if (refitInterfaceType.IsGenericType) { genericArgs = interfaceTypeName.Substring(interfaceTypeName.IndexOf("[")); - interfaceTypeName = interfaceTypeName.Substring(0, interfaceTypeName.Length - genericArgs.Length); + interfaceTypeName = interfaceTypeName.Substring( + 0, + interfaceTypeName.Length - genericArgs.Length + ); } // Remove any + from the type name portion @@ -42,7 +45,8 @@ public static string ForType(Type refitInterfaceType) // Refit.Implementation // E.g., Refit.Implementation.Generated.NamespaceContaingTpeInterfaceType - var refitTypeName = $"Refit.Implementation.Generated+{ns}{interfaceTypeName}{genericArgs}"; + var refitTypeName = + $"Refit.Implementation.Generated+{ns}{interfaceTypeName}{genericArgs}"; var assmQualified = $"{refitTypeName}, {refitInterfaceType.Assembly.FullName}"; diff --git a/Refit/ValidationApiException.cs b/Refit/ValidationApiException.cs index 2ec29309d..b6ec6f7aa 100644 --- a/Refit/ValidationApiException.cs +++ b/Refit/ValidationApiException.cs @@ -15,13 +15,19 @@ static ValidationApiException() SerializerOptions.PropertyNameCaseInsensitive = true; SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; SerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - } - - ValidationApiException(ApiException apiException) : - base(apiException.RequestMessage, apiException.HttpMethod, apiException.Content, apiException.StatusCode, apiException.ReasonPhrase, apiException.Headers, apiException.RefitSettings) - { } + ValidationApiException(ApiException apiException) + : base( + apiException.RequestMessage, + apiException.HttpMethod, + apiException.Content, + apiException.StatusCode, + apiException.ReasonPhrase, + apiException.Headers, + apiException.RefitSettings + ) { } + /// /// Creates a new instance of a ValidationException from an existing ApiException. /// @@ -32,13 +38,18 @@ public static ValidationApiException Create(ApiException exception) if (exception is null) throw new ArgumentNullException(nameof(exception)); if (string.IsNullOrWhiteSpace(exception.Content)) - throw new ArgumentException("Content must be an 'application/problem+json' compliant json string."); + throw new ArgumentException( + "Content must be an 'application/problem+json' compliant json string." + ); var ex = new ValidationApiException(exception); - if(!string.IsNullOrWhiteSpace(exception.Content)) + if (!string.IsNullOrWhiteSpace(exception.Content)) { - ex.Content = JsonSerializer.Deserialize(exception.Content!, SerializerOptions); + ex.Content = JsonSerializer.Deserialize( + exception.Content!, + SerializerOptions + ); } return ex; diff --git a/samples/Meow.Common/Middleware/HttpClientDiagnosticsHandler.cs b/samples/Meow.Common/Middleware/HttpClientDiagnosticsHandler.cs index 0a42d8629..b7653971e 100644 --- a/samples/Meow.Common/Middleware/HttpClientDiagnosticsHandler.cs +++ b/samples/Meow.Common/Middleware/HttpClientDiagnosticsHandler.cs @@ -9,15 +9,15 @@ namespace HttpClientDiagnostics [DebuggerStepThrough] public class HttpClientDiagnosticsHandler : DelegatingHandler { - public HttpClientDiagnosticsHandler(HttpMessageHandler innerHandler) : base(innerHandler) - { - } + public HttpClientDiagnosticsHandler(HttpMessageHandler innerHandler) + : base(innerHandler) { } - public HttpClientDiagnosticsHandler() - { - } + public HttpClientDiagnosticsHandler() { } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken + ) { var totalElapsedTime = Stopwatch.StartNew(); @@ -39,10 +39,17 @@ protected override async Task SendAsync(HttpRequestMessage } responseElapsedTime.Stop(); - Log.Debug(string.Format("Response elapsed time: {0} ms", responseElapsedTime.ElapsedMilliseconds)); + Log.Debug( + string.Format( + "Response elapsed time: {0} ms", + responseElapsedTime.ElapsedMilliseconds + ) + ); totalElapsedTime.Stop(); - Log.Debug(string.Format("Total elapsed time: {0} ms", totalElapsedTime.ElapsedMilliseconds)); + Log.Debug( + string.Format("Total elapsed time: {0} ms", totalElapsedTime.ElapsedMilliseconds) + ); return response; } diff --git a/samples/Meow.Common/Responses/SearchResponse.cs b/samples/Meow.Common/Responses/SearchResponse.cs index 08ea793ef..ff58c93fd 100644 --- a/samples/Meow.Common/Responses/SearchResponse.cs +++ b/samples/Meow.Common/Responses/SearchResponse.cs @@ -58,5 +58,4 @@ public class Weight public string imperial { get; set; } public string metric { get; set; } } - } diff --git a/samples/Meow.Common/Services/CatsService.cs b/samples/Meow.Common/Services/CatsService.cs index 1cac0851b..66da25105 100644 --- a/samples/Meow.Common/Services/CatsService.cs +++ b/samples/Meow.Common/Services/CatsService.cs @@ -16,7 +16,10 @@ public class CatsService public CatsService(Uri baseUrl) { - _httpClient = new HttpClient(new HttpClientDiagnosticsHandler(new HttpClientHandler())) { BaseAddress = baseUrl }; + _httpClient = new HttpClient(new HttpClientDiagnosticsHandler(new HttpClientHandler())) + { + BaseAddress = baseUrl + }; _theCatsApi = RestService.For(_httpClient); } diff --git a/samples/Meow/Program.cs b/samples/Meow/Program.cs index 03b3ce216..f9cc0d943 100644 --- a/samples/Meow/Program.cs +++ b/samples/Meow/Program.cs @@ -8,16 +8,15 @@ class Program { static async Task Main(string[] args) { - Log.Logger = new LoggerConfiguration() - .WriteTo.Console() - .MinimumLevel.Verbose() - .CreateLogger(); + Log.Logger = new LoggerConfiguration().WriteTo + .Console() + .MinimumLevel.Verbose() + .CreateLogger(); var service = new CatsService(new Uri("https://api.thecatapi.com")); var results = await service.Search("bengal"); Log.Debug("{results}", results); - } } } diff --git a/samples/sampleUsngLocalApi/ConsoleApplication/Program.cs b/samples/sampleUsngLocalApi/ConsoleApplication/Program.cs index 2d3547f7c..2e80e9ec5 100644 --- a/samples/sampleUsngLocalApi/ConsoleApplication/Program.cs +++ b/samples/sampleUsngLocalApi/ConsoleApplication/Program.cs @@ -12,12 +12,11 @@ class Program static void Main(string[] args) { Console.WriteLine("Hello World!"); - HttpClient _client = new HttpClient - { - BaseAddress = new Uri("http://localhost:61868") - }; + HttpClient _client = new HttpClient { BaseAddress = new Uri("http://localhost:61868") }; IRestService _restApiService = RestService.For(_client); - Console.WriteLine("Enter from the following numbers to access the APIs,\n1 for get ,\n2 for get with argument, \n3 for post,\n4 for put, \n5 for Delete \n"); + Console.WriteLine( + "Enter from the following numbers to access the APIs,\n1 for get ,\n2 for get with argument, \n3 for post,\n4 for put, \n5 for Delete \n" + ); while (true) { int choice = Int32.Parse(Console.ReadLine() ?? "6"); @@ -36,7 +35,9 @@ static void Main(string[] args) Console.WriteLine(result3); break; case 4: - var result4 = _restApiService.PutWithParameters(4, new ModelForTest()).Result; + var result4 = _restApiService + .PutWithParameters(4, new ModelForTest()) + .Result; Console.WriteLine(result4); break; case 5: diff --git a/samples/sampleUsngLocalApi/RestApiforTest/Program.cs b/samples/sampleUsngLocalApi/RestApiforTest/Program.cs index d27f806b2..a060b9c32 100644 --- a/samples/sampleUsngLocalApi/RestApiforTest/Program.cs +++ b/samples/sampleUsngLocalApi/RestApiforTest/Program.cs @@ -18,7 +18,6 @@ public static void Main(string[] args) } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); + WebHost.CreateDefaultBuilder(args).UseStartup(); } }