From c591ea0767cce5bb9cd997da9946f2de32cf8fdc Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Wed, 12 Jun 2024 22:59:29 +0200 Subject: [PATCH] Cleanup and optimise --- .../CsvHelperSerializer.cs | 2 +- .../JsonNetSerializer.cs | 8 +- .../SerializeAsAttribute.cs | 2 + .../XmlDeserializer.cs | 10 +- .../XmlSerializer.cs | 1 + src/RestSharp/AsyncHelpers.cs | 30 +-- .../OAuth/OAuth1Authenticator.cs | 4 +- .../Authenticators/OAuth/OAuthTools.cs | 4 +- .../Authenticators/OAuth/OAuthWorkflow.cs | 16 +- .../Authenticators/OAuth/WebPairCollection.cs | 2 +- src/RestSharp/BuildUriExtensions.cs | 2 +- src/RestSharp/ContentType.cs | 10 +- src/RestSharp/Ensure.cs | 2 +- src/RestSharp/Enum.cs | 1 - .../Extensions/GenerateImmutableAttribute.cs | 4 +- src/RestSharp/Extensions/StringExtensions.cs | 95 ++++++-- .../Interceptors/CompatibilityInterceptor.cs | 15 +- src/RestSharp/KnownHeaders.cs | 4 +- src/RestSharp/Options/RestClientOptions.cs | 3 +- src/RestSharp/Parameters/BodyParameter.cs | 2 + src/RestSharp/Parameters/DefaultParameters.cs | 2 +- src/RestSharp/Parameters/ObjectParser.cs | 18 +- .../Parameters/ParametersCollection.cs | 2 +- .../ParametersCollectionExtensions.cs | 2 +- src/RestSharp/Parameters/RequestParameters.cs | 35 +++ .../Parameters/UrlSegmentParameter.cs | 11 +- src/RestSharp/Polyfills/Range.cs | 2 +- src/RestSharp/Polyfills/Strings.cs | 22 ++ src/RestSharp/Properties/AssemblyInfo.cs | 3 + src/RestSharp/Request/PropertyCache.cs | 2 +- src/RestSharp/Request/RequestContent.cs | 2 +- src/RestSharp/Request/RequestHeaders.cs | 1 - src/RestSharp/Request/RestRequest.cs | 5 +- .../Request/RestRequestExtensions.Headers.cs | 13 +- .../Request/RestRequestExtensions.cs | 2 - src/RestSharp/Request/UriExtensions.cs | 10 +- src/RestSharp/Response/RestResponse.cs | 1 - src/RestSharp/Response/RestResponseBase.cs | 3 +- src/RestSharp/RestClient.Async.cs | 7 +- src/RestSharp/RestClient.Extensions.Post.cs | 2 - src/RestSharp/RestClient.Extensions.Put.cs | 2 - src/RestSharp/RestClient.Extensions.cs | 2 +- src/RestSharp/RestClient.cs | 2 +- src/RestSharp/Serializers/RestSerializers.cs | 1 + .../Serializers/Xml/DotNetXmlSerializer.cs | 12 +- .../Serializers/Xml/XmlRestSerializer.cs | 26 +-- src/RestSharp/SimpleClientFactory.cs | 2 +- test/RestSharp.InteractiveTests/Program.cs | 3 +- .../TwitterClient.cs | 7 +- .../Authentication/OAuth2Tests.cs | 2 +- .../Fixtures/CaptureFixture.cs | 4 +- .../Interceptor/InterceptorTests.cs | 3 +- .../MultipartFormDataTests.cs | 2 +- .../StatusCodeTests.cs | 2 +- .../UploadFileTests.cs | 1 - .../XmlResponseTests.cs | 2 +- .../NewtonsoftJson/IntegratedSimpleTests.cs | 1 - .../SystemTextJson/SystemTextJsonTests.cs | 1 - .../SampleClasses/Lastfm.cs | 5 +- .../SampleClasses/misc.cs | 16 +- .../SampleClasses/twitter.cs | 3 +- .../SampleData/Lastfm.xml | 24 +- .../XmlDeserializerTests.cs | 216 +++++++++--------- .../XmlSerializerTests.cs | 86 +++---- .../Extensions/UriExtensions.cs | 2 +- .../Fixtures/Handlers.cs | 6 +- .../Fixtures/WebServer.cs | 2 + test/RestSharp.Tests/Auth/OAuth1AuthTests.cs | 1 + .../Auth/OAuth1SignatureTests.cs | 2 +- test/RestSharp.Tests/Auth/OAuthTests.cs | 2 +- test/RestSharp.Tests/ObjectParserTests.cs | 1 + .../ParameterValidationTests.cs | 4 +- test/RestSharp.Tests/UrlBuilderTests.cs | 143 ++++++------ 73 files changed, 547 insertions(+), 403 deletions(-) create mode 100644 src/RestSharp/Polyfills/Strings.cs diff --git a/src/RestSharp.Serializers.CsvHelper/CsvHelperSerializer.cs b/src/RestSharp.Serializers.CsvHelper/CsvHelperSerializer.cs index 719e92248..f2ea1cc7c 100644 --- a/src/RestSharp.Serializers.CsvHelper/CsvHelperSerializer.cs +++ b/src/RestSharp.Serializers.CsvHelper/CsvHelperSerializer.cs @@ -54,7 +54,7 @@ public CsvHelperSerializer() : this(new CsvConfiguration(CultureInfo.InvariantCu } foreach (var record in csvReader.GetRecords(itemType)) { - method.Invoke(result, new[] { record }); + method.Invoke(result, [record]); } return result; diff --git a/src/RestSharp.Serializers.NewtonsoftJson/JsonNetSerializer.cs b/src/RestSharp.Serializers.NewtonsoftJson/JsonNetSerializer.cs index 94e60b40b..2b41db918 100644 --- a/src/RestSharp.Serializers.NewtonsoftJson/JsonNetSerializer.cs +++ b/src/RestSharp.Serializers.NewtonsoftJson/JsonNetSerializer.cs @@ -34,7 +34,7 @@ public class JsonNetSerializer : IRestSerializer, ISerializer, IDeserializer { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; - [ThreadStatic] static WriterBuffer? writerBuffer; + [ThreadStatic] static WriterBuffer? _writerBuffer; readonly JsonSerializer _serializer; @@ -52,11 +52,11 @@ public class JsonNetSerializer : IRestSerializer, ISerializer, IDeserializer { public string? Serialize(object? obj) { if (obj == null) return null; - using var writerBuffer = JsonNetSerializer.writerBuffer ??= new WriterBuffer(_serializer); + using var buffer = _writerBuffer ??= new WriterBuffer(_serializer); - _serializer.Serialize(writerBuffer.GetJsonTextWriter(), obj, obj.GetType()); + _serializer.Serialize(buffer.GetJsonTextWriter(), obj, obj.GetType()); - return writerBuffer.GetStringWriter().ToString(); + return buffer.GetStringWriter().ToString(); } public string? Serialize(Parameter bodyParameter) => Serialize(bodyParameter.Value); diff --git a/src/RestSharp.Serializers.Xml/SerializeAsAttribute.cs b/src/RestSharp.Serializers.Xml/SerializeAsAttribute.cs index 30ec91c16..fb1474d7b 100644 --- a/src/RestSharp.Serializers.Xml/SerializeAsAttribute.cs +++ b/src/RestSharp.Serializers.Xml/SerializeAsAttribute.cs @@ -14,6 +14,8 @@ using System.Globalization; using RestSharp.Extensions; +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable MemberCanBePrivate.Global // ReSharper disable once CheckNamespace namespace RestSharp.Serializers; diff --git a/src/RestSharp.Serializers.Xml/XmlDeserializer.cs b/src/RestSharp.Serializers.Xml/XmlDeserializer.cs index bc77fe45c..ee2fbf8af 100644 --- a/src/RestSharp.Serializers.Xml/XmlDeserializer.cs +++ b/src/RestSharp.Serializers.Xml/XmlDeserializer.cs @@ -19,6 +19,7 @@ using System.Xml; using System.Xml.Linq; using RestSharp.Extensions; +// ReSharper disable VirtualMemberNeverOverridden.Global namespace RestSharp.Serializers.Xml; @@ -37,7 +38,7 @@ public class XmlDeserializer : IXmlDeserializer, IWithRootElement, IWithDateForm if (string.IsNullOrEmpty(response.Content)) return default; - var doc = XDocument.Parse(response.Content); + var doc = XDocument.Parse(response.Content!); var root = doc.Root; var rootElement = response.RootElement ?? RootElement; @@ -161,8 +162,7 @@ protected virtual object Map(object x, XElement? root) { var asType = type.AsType(); if (asType == typeof(bool)) { - var toConvert = value.ToString()! - .ToLower(Culture); + var toConvert = value.ToString()!.ToLower(Culture); prop.SetValue(x, XmlConvert.ToBoolean(toConvert), null); } @@ -227,9 +227,7 @@ protected virtual object Map(object x, XElement? root) { else if (asType == typeof(Guid)) { var raw = value.ToString(); - value = string.IsNullOrEmpty(raw) - ? Guid.Empty - : new Guid(value.ToString()!); + value = string.IsNullOrEmpty(raw) ? Guid.Empty : new Guid(value.ToString()!); prop.SetValue(x, value, null); } diff --git a/src/RestSharp.Serializers.Xml/XmlSerializer.cs b/src/RestSharp.Serializers.Xml/XmlSerializer.cs index d5c235f1e..170954c28 100644 --- a/src/RestSharp.Serializers.Xml/XmlSerializer.cs +++ b/src/RestSharp.Serializers.Xml/XmlSerializer.cs @@ -33,6 +33,7 @@ public XmlSerializer() { } /// Specify the namespaced to be used when serializing /// /// XML namespace + [PublicAPI] public XmlSerializer(string @namespace) => Namespace = @namespace; /// diff --git a/src/RestSharp/AsyncHelpers.cs b/src/RestSharp/AsyncHelpers.cs index d65bac248..5d3db9db4 100644 --- a/src/RestSharp/AsyncHelpers.cs +++ b/src/RestSharp/AsyncHelpers.cs @@ -24,7 +24,7 @@ static class AsyncHelpers { /// Executes a task synchronously on the calling thread by installing a temporary synchronization context that queues continuations /// /// Callback for asynchronous task to run - public static void RunSync(Func task) { + static void RunSync(Func task) { var currentContext = SynchronizationContext.Current; var customContext = new CustomSynchronizationContext(task); @@ -80,19 +80,6 @@ public override void Post(SendOrPostCallback function, object? state) { /// Enqueues the function to be executed and executes all resulting continuations until it is completely done /// public void Run() { - async void PostCallback(object? _) { - try { - await _task().ConfigureAwait(false); - } - catch (Exception exception) { - _caughtException = ExceptionDispatchInfo.Capture(exception); - throw; - } - finally { - Post(_ => _done = true, null); - } - } - Post(PostCallback, null); while (!_done) { @@ -107,6 +94,21 @@ async void PostCallback(object? _) { _workItemsWaiting.WaitOne(); } } + + return; + + async void PostCallback(object? _) { + try { + await _task().ConfigureAwait(false); + } + catch (Exception exception) { + _caughtException = ExceptionDispatchInfo.Capture(exception); + throw; + } + finally { + Post(_ => _done = true, null); + } + } } /// diff --git a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs index 4960bb12f..f69f5ff39 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs @@ -15,6 +15,7 @@ using RestSharp.Authenticators.OAuth; using RestSharp.Extensions; using System.Web; +// ReSharper disable PropertyCanBeMadeInitOnly.Global // ReSharper disable NotResolvedInText // ReSharper disable CheckNamespace @@ -22,6 +23,7 @@ namespace RestSharp.Authenticators; /// RFC: The OAuth 1.0 Protocol +// ReSharper disable once ClassWithVirtualMembersNeverInherited.Global public class OAuth1Authenticator : IAuthenticator { public virtual string? Realm { get; set; } public virtual OAuthParameterHandling ParameterHandling { get; set; } @@ -246,7 +248,7 @@ internal static void AddOAuthData( var url = client.BuildUri(request).ToString(); var queryStringStart = url.IndexOf('?'); - if (queryStringStart != -1) url = url.Substring(0, queryStringStart); + if (queryStringStart != -1) url = url[..queryStringStart]; var method = request.Method.ToString().ToUpperInvariant(); var parameters = new WebPairCollection(); diff --git a/src/RestSharp/Authenticators/OAuth/OAuthTools.cs b/src/RestSharp/Authenticators/OAuth/OAuthTools.cs index 696440bd4..e8cf4102a 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuthTools.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuthTools.cs @@ -36,9 +36,9 @@ static class OAuthTools { /// /// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986. /// - static readonly string[] UriRfc3986CharsToEscape = { "!", "*", "'", "(", ")" }; + static readonly string[] UriRfc3986CharsToEscape = ["!", "*", "'", "(", ")"]; - static readonly string[] UriRfc3968EscapedHex = { "%21", "%2A", "%27", "%28", "%29" }; + static readonly string[] UriRfc3968EscapedHex = ["%21", "%2A", "%27", "%28", "%29"]; static OAuthTools() { var bytes = new byte[4]; diff --git a/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs b/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs index 052325324..9b7a41837 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs @@ -167,14 +167,14 @@ WebPairCollection GenerateAuthParameters(string timestamp, string nonce) WebPairCollection GenerateXAuthParameters(string timestamp, string nonce) => [ - new("x_auth_username", Ensure.NotNull(ClientUsername, nameof(ClientUsername))), - new("x_auth_password", Ensure.NotNull(ClientPassword, nameof(ClientPassword))), - new("x_auth_mode", "client_auth"), - new("oauth_consumer_key", Ensure.NotNull(ConsumerKey, nameof(ConsumerKey)), true), - new("oauth_signature_method", SignatureMethod.ToRequestValue()), - new("oauth_timestamp", timestamp), - new("oauth_nonce", nonce), - new("oauth_version", Version ?? "1.0") + new WebPair("x_auth_username", Ensure.NotNull(ClientUsername, nameof(ClientUsername))), + new WebPair("x_auth_password", Ensure.NotNull(ClientPassword, nameof(ClientPassword))), + new WebPair("x_auth_mode", "client_auth"), + new WebPair("oauth_consumer_key", Ensure.NotNull(ConsumerKey, nameof(ConsumerKey)), true), + new WebPair("oauth_signature_method", SignatureMethod.ToRequestValue()), + new WebPair("oauth_timestamp", timestamp), + new WebPair("oauth_nonce", nonce), + new WebPair("oauth_version", Version ?? "1.0") ]; internal class OAuthParameters { diff --git a/src/RestSharp/Authenticators/OAuth/WebPairCollection.cs b/src/RestSharp/Authenticators/OAuth/WebPairCollection.cs index 0c602e6f8..29134488f 100644 --- a/src/RestSharp/Authenticators/OAuth/WebPairCollection.cs +++ b/src/RestSharp/Authenticators/OAuth/WebPairCollection.cs @@ -17,7 +17,7 @@ namespace RestSharp.Authenticators.OAuth; class WebPairCollection : IList { - readonly List _parameters = new(); + readonly List _parameters = []; public IEnumerator GetEnumerator() => _parameters.GetEnumerator(); diff --git a/src/RestSharp/BuildUriExtensions.cs b/src/RestSharp/BuildUriExtensions.cs index 13c663b81..ba6676230 100644 --- a/src/RestSharp/BuildUriExtensions.cs +++ b/src/RestSharp/BuildUriExtensions.cs @@ -84,7 +84,7 @@ string EncodeParameter(Parameter parameter) } static void DoBuildUriValidations(IRestClient client, RestRequest request) { - if (client.Options.BaseUrl == null && !request.Resource.ToLowerInvariant().StartsWith("http")) + if (client.Options.BaseUrl == null && !request.Resource.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)) throw new ArgumentOutOfRangeException( nameof(request), "Request resource doesn't contain a valid scheme for an empty base URL of the client" diff --git a/src/RestSharp/ContentType.cs b/src/RestSharp/ContentType.cs index c2250548e..6425dec89 100644 --- a/src/RestSharp/ContentType.cs +++ b/src/RestSharp/ContentType.cs @@ -41,7 +41,7 @@ public class ContentType : IEquatable { public override string ToString() => Value; - public static implicit operator ContentType(string? contentType) => contentType == null ? Undefined : new(contentType); + public static implicit operator ContentType(string? contentType) => contentType == null ? Undefined : new ContentType(contentType); public static implicit operator string(ContentType contentType) => contentType.Value; @@ -59,13 +59,9 @@ public class ContentType : IEquatable { { DataFormat.Binary, Binary } }; - public static readonly string[] JsonAccept = { - Json, "text/json", "text/x-json", "text/javascript" - }; + public static readonly string[] JsonAccept = [Json, "text/json", "text/x-json", "text/javascript"]; - public static readonly string[] XmlAccept = { - Xml, "text/xml" - }; + public static readonly string[] XmlAccept = [Xml, "text/xml"]; readonly string _value; diff --git a/src/RestSharp/Ensure.cs b/src/RestSharp/Ensure.cs index 2153c3944..5d985c860 100644 --- a/src/RestSharp/Ensure.cs +++ b/src/RestSharp/Ensure.cs @@ -24,4 +24,4 @@ public static string NotEmptyString(object? value, [InvokerParameterName] string var s = value as string ?? value?.ToString(); return string.IsNullOrWhiteSpace(s) ? throw new ArgumentNullException(name) : s!; } -} +} \ No newline at end of file diff --git a/src/RestSharp/Enum.cs b/src/RestSharp/Enum.cs index fd584bc8c..c6ebf0cfb 100644 --- a/src/RestSharp/Enum.cs +++ b/src/RestSharp/Enum.cs @@ -11,7 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -using System.Net; namespace RestSharp; diff --git a/src/RestSharp/Extensions/GenerateImmutableAttribute.cs b/src/RestSharp/Extensions/GenerateImmutableAttribute.cs index c4fe51817..27c6176e5 100644 --- a/src/RestSharp/Extensions/GenerateImmutableAttribute.cs +++ b/src/RestSharp/Extensions/GenerateImmutableAttribute.cs @@ -16,7 +16,7 @@ namespace RestSharp.Extensions; [AttributeUsage(AttributeTargets.Class)] -class GenerateImmutableAttribute : Attribute { } +class GenerateImmutableAttribute : Attribute; [AttributeUsage(AttributeTargets.Property)] -class Exclude : Attribute { } +class Exclude : Attribute; diff --git a/src/RestSharp/Extensions/StringExtensions.cs b/src/RestSharp/Extensions/StringExtensions.cs index e4ddb718f..6980d3a45 100644 --- a/src/RestSharp/Extensions/StringExtensions.cs +++ b/src/RestSharp/Extensions/StringExtensions.cs @@ -20,20 +20,21 @@ namespace RestSharp.Extensions; -static class StringExtensions { - static readonly Regex IsUpperCaseRegex = new(@"^[A-Z]+$"); +// ReSharper disable once PartialTypeWithSinglePart +static partial class StringExtensions { + static readonly Regex IsUpperCaseRegex = IsUpperCase(); - static readonly Regex AddUnderscoresRegex1 = new(@"[-\s]"); - static readonly Regex AddUnderscoresRegex2 = new(@"([a-z\d])([A-Z])"); - static readonly Regex AddUnderscoresRegex3 = new(@"([A-Z]+)([A-Z][a-z])"); + static readonly Regex AddUnderscoresRegex1 = AddUnderscores1(); + static readonly Regex AddUnderscoresRegex2 = AddUnderscores2(); + static readonly Regex AddUnderscoresRegex3 = AddUnderscores3(); - static readonly Regex AddDashesRegex1 = new(@"[\s]"); - static readonly Regex AddDashesRegex2 = new(@"([a-z\d])([A-Z])"); - static readonly Regex AddDashesRegex3 = new(@"([A-Z]+)([A-Z][a-z])"); + static readonly Regex AddDashesRegex1 = AddDashes1(); + static readonly Regex AddDashesRegex2 = AddDashes2(); + static readonly Regex AddDashesRegex3 = AddDashes3(); - static readonly Regex AddSpacesRegex1 = new(@"[-\s]"); - static readonly Regex AddSpacesRegex2 = new(@"([a-z\d])([A-Z])"); - static readonly Regex AddSpacesRegex3 = new(@"([A-Z]+)([A-Z][a-z])"); + static readonly Regex AddSpacesRegex1 = AddSpaces1(); + static readonly Regex AddSpacesRegex2 = AddSpaces2(); + static readonly Regex AddSpacesRegex3 = AddSpaces3(); internal static string UrlDecode(this string input) => HttpUtility.UrlDecode(input); @@ -67,7 +68,7 @@ internal static string UrlEncode(this string input) { return sb.ToString(); } - internal static string? UrlEncode(this string input, Encoding encoding) { + internal static string? UrlEncode(this string? input, Encoding encoding) { var encoded = HttpUtility.UrlEncode(input, encoding); return encoded?.Replace("+", "%20"); } @@ -91,7 +92,7 @@ internal static string ToPascalCase(this string text, bool removeUnderscores, Cu .JoinToString(joinString); string CaseWord(string word) { - var restOfWord = word.Substring(1); + var restOfWord = word[1..]; var firstChar = char.ToUpper(word[0], culture); if (restOfWord.IsUpperCase()) restOfWord = restOfWord.ToLower(culture); @@ -151,8 +152,7 @@ internal static IEnumerable GetNameVariants(this string name, CultureInf internal static string JoinToString(this IEnumerable strings, string separator) => string.Join(separator, strings); - static string MakeInitialLowerCase(this string word, CultureInfo culture) - => string.Concat(word.Substring(0, 1).ToLower(culture), word.Substring(1)); + static string MakeInitialLowerCase(this string word, CultureInfo culture) => string.Concat(word[..1].ToLower(culture), word[1..]); static string AddUnderscores(this string pascalCasedWord) => AddUnderscoresRegex1.Replace( @@ -184,4 +184,67 @@ static string AddSpaces(this string pascalCasedWord) ), " " ); -} + + const string RIsUpperCase = "^[A-Z]+$"; + const string RAddUnderscore1 = @"[-\s]"; + const string RAddUnderscore2 = @"([a-z\d])([A-Z])"; + const string RAddUnderscore3 = "([A-Z]+)([A-Z][a-z])"; + const string RAddDashes1 = @"[\s]"; + const string RAddDashes2 = @"([a-z\d])([A-Z])"; + const string RAddDashes3 = "([A-Z]+)([A-Z][a-z])"; + const string RAddSpaces1 = @"[-\s]"; + const string RAddSpaces2 = @"([a-z\d])([A-Z])"; + const string RAddSpaces3 = "([A-Z]+)([A-Z][a-z])"; + +#if NET7_0_OR_GREATER + [GeneratedRegex(RIsUpperCase)] + private static partial Regex IsUpperCase(); + + [GeneratedRegex(RAddUnderscore1)] + private static partial Regex AddUnderscores1(); + + [GeneratedRegex(RAddUnderscore2)] + private static partial Regex AddUnderscores2(); + + [GeneratedRegex(RAddUnderscore3)] + private static partial Regex AddUnderscores3(); + + [GeneratedRegex(RAddDashes1)] + private static partial Regex AddDashes1(); + + [GeneratedRegex(RAddDashes2)] + private static partial Regex AddDashes2(); + + [GeneratedRegex(RAddDashes3)] + private static partial Regex AddDashes3(); + + [GeneratedRegex(RAddSpaces1)] + private static partial Regex AddSpaces1(); + + [GeneratedRegex(RAddSpaces2)] + private static partial Regex AddSpaces2(); + + [GeneratedRegex(RAddSpaces3)] + private static partial Regex AddSpaces3(); +#else + static Regex IsUpperCase() => new(RIsUpperCase); + + static Regex AddUnderscores1() => new(RAddUnderscore1); + + static Regex AddUnderscores2() => new(RAddUnderscore2); + + static Regex AddUnderscores3() => new(RAddUnderscore3); + + static Regex AddDashes1() => new(RAddDashes1); + + static Regex AddDashes2() => new(RAddDashes2); + + static Regex AddDashes3() => new(RAddDashes3); + + static Regex AddSpaces1() => new(RAddSpaces1); + + static Regex AddSpaces2() => new(RAddSpaces1); + + static Regex AddSpaces3() => new(RAddSpaces1); +#endif +} \ No newline at end of file diff --git a/src/RestSharp/Interceptors/CompatibilityInterceptor.cs b/src/RestSharp/Interceptors/CompatibilityInterceptor.cs index f39b2f361..34ac4354c 100644 --- a/src/RestSharp/Interceptors/CompatibilityInterceptor.cs +++ b/src/RestSharp/Interceptors/CompatibilityInterceptor.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// ReSharper disable UnusedAutoPropertyAccessor.Global namespace RestSharp.Interceptors; /// @@ -28,13 +29,15 @@ public override ValueTask BeforeDeserialization(RestResponse response, Cancellat return default; } - public override ValueTask BeforeHttpRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken) { - OnBeforeRequest?.Invoke(requestMessage); - return default; + public override async ValueTask BeforeHttpRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken) { + if (OnBeforeRequest != null) { + await OnBeforeRequest(requestMessage); + } } - public override ValueTask AfterHttpRequest(HttpResponseMessage responseMessage, CancellationToken cancellationToken) { - OnAfterRequest?.Invoke(responseMessage); - return default; + public override async ValueTask AfterHttpRequest(HttpResponseMessage responseMessage, CancellationToken cancellationToken) { + if (OnAfterRequest != null) { + await OnAfterRequest(responseMessage); + } } } \ No newline at end of file diff --git a/src/RestSharp/KnownHeaders.cs b/src/RestSharp/KnownHeaders.cs index 3871c4d59..edf9d47bb 100644 --- a/src/RestSharp/KnownHeaders.cs +++ b/src/RestSharp/KnownHeaders.cs @@ -39,10 +39,10 @@ public static class KnownHeaders { public const string SetCookie = "Set-Cookie"; public const string UserAgent = "User-Agent"; - internal static readonly string[] ContentHeaders = { + internal static readonly string[] ContentHeaders = [ Allow, Expires, ContentDisposition, ContentEncoding, ContentLanguage, ContentLength, ContentLocation, ContentRange, ContentType, ContentMD5, LastModified - }; + ]; static readonly HashSet ContentHeadersHash = new(ContentHeaders, StringComparer.InvariantCultureIgnoreCase); diff --git a/src/RestSharp/Options/RestClientOptions.cs b/src/RestSharp/Options/RestClientOptions.cs index 69c4a0353..13442fdb2 100644 --- a/src/RestSharp/Options/RestClientOptions.cs +++ b/src/RestSharp/Options/RestClientOptions.cs @@ -13,7 +13,6 @@ // limitations under the License. // -using System.Net; using System.Net.Http.Headers; using System.Net.Security; using System.Reflection; @@ -70,7 +69,7 @@ public RestClientOptions(string baseUrl) : this(new Uri(Ensure.NotEmptyString(ba /// List of interceptors that will be executed before the request is sent /// [Exclude] - public List Interceptors { get; set; } = new(); + public List Interceptors { get; set; } = []; /// /// Passed to Credentials property diff --git a/src/RestSharp/Parameters/BodyParameter.cs b/src/RestSharp/Parameters/BodyParameter.cs index cc63fbfad..09948880d 100644 --- a/src/RestSharp/Parameters/BodyParameter.cs +++ b/src/RestSharp/Parameters/BodyParameter.cs @@ -41,6 +41,7 @@ public BodyParameter(object value, ContentType contentType, DataFormat dataForma } public record XmlParameter : BodyParameter { + [PublicAPI] public XmlParameter(string name, object value, string? xmlNamespace = null, ContentType? contentType = null) : base(name, value, contentType ?? ContentType.Xml, DataFormat.Xml) => XmlNamespace = xmlNamespace; @@ -52,6 +53,7 @@ public XmlParameter(object value, string? xmlNamespace = null, ContentType? cont } public record JsonParameter : BodyParameter { + [PublicAPI] public JsonParameter(string name, object value, ContentType? contentType = null) : base(name, value, contentType ?? ContentType.Json, DataFormat.Json) { } diff --git a/src/RestSharp/Parameters/DefaultParameters.cs b/src/RestSharp/Parameters/DefaultParameters.cs index 6ceb740fd..8ba19ccdc 100644 --- a/src/RestSharp/Parameters/DefaultParameters.cs +++ b/src/RestSharp/Parameters/DefaultParameters.cs @@ -69,5 +69,5 @@ public DefaultParameters ReplaceParameter(Parameter parameter) RemoveParameter(Ensure.NotEmptyString(parameter.Name, "Parameter name"), parameter.Type) .AddParameter(parameter); - static readonly ParameterType[] MultiParameterTypes = { ParameterType.QueryString, ParameterType.GetOrPost }; + static readonly ParameterType[] MultiParameterTypes = [ParameterType.QueryString, ParameterType.GetOrPost]; } diff --git a/src/RestSharp/Parameters/ObjectParser.cs b/src/RestSharp/Parameters/ObjectParser.cs index 52ab89865..db9a03d9d 100644 --- a/src/RestSharp/Parameters/ObjectParser.cs +++ b/src/RestSharp/Parameters/ObjectParser.cs @@ -36,6 +36,15 @@ public static IEnumerable GetProperties(this object obj, params properties.Add(GetValue(prop, val)); } + return properties; + + ParsedParameter GetValue(PropertyInfo propertyInfo, object? value) { + var attribute = propertyInfo.GetCustomAttribute(); + var name = attribute?.Name ?? propertyInfo.Name; + var val = ParseValue(attribute?.Format, value); + return new ParsedParameter(name, val, attribute?.Encode ?? true); + } + IEnumerable GetArray(PropertyInfo propertyInfo, object? value) { var elementType = propertyInfo.PropertyType.GetElementType(); var array = (Array)value!; @@ -60,15 +69,6 @@ IEnumerable GetArray(PropertyInfo propertyInfo, object? value) } - ParsedParameter GetValue(PropertyInfo propertyInfo, object? value) { - var attribute = propertyInfo.GetCustomAttribute(); - var name = attribute?.Name ?? propertyInfo.Name; - var val = ParseValue(attribute?.Format, value); - return new ParsedParameter(name, val, attribute?.Encode ?? true); - } - - return properties; - bool IsAllowedProperty(string propertyName) => includedProperties.Length == 0 || includedProperties.Length > 0 && includedProperties.Contains(propertyName); diff --git a/src/RestSharp/Parameters/ParametersCollection.cs b/src/RestSharp/Parameters/ParametersCollection.cs index 2ee80c3f6..2d675820e 100644 --- a/src/RestSharp/Parameters/ParametersCollection.cs +++ b/src/RestSharp/Parameters/ParametersCollection.cs @@ -18,7 +18,7 @@ namespace RestSharp; public abstract class ParametersCollection : IReadOnlyCollection { - protected readonly List Parameters = new(); + protected readonly List Parameters = []; // public ParametersCollection(IEnumerable parameters) => _parameters.AddRange(parameters); diff --git a/src/RestSharp/Parameters/ParametersCollectionExtensions.cs b/src/RestSharp/Parameters/ParametersCollectionExtensions.cs index b003b326d..83b6eefa6 100644 --- a/src/RestSharp/Parameters/ParametersCollectionExtensions.cs +++ b/src/RestSharp/Parameters/ParametersCollectionExtensions.cs @@ -26,7 +26,7 @@ internal static IEnumerable GetQueryParameters(this ParametersCollect } internal static IEnumerable GetContentParameters(this ParametersCollection parameters, Method method) - => IsPost(method) ? parameters.GetParameters() : Enumerable.Empty(); + => IsPost(method) ? parameters.GetParameters() : []; static bool IsPost(Method method) => method is Method.Post or Method.Put or Method.Patch; } diff --git a/src/RestSharp/Parameters/RequestParameters.cs b/src/RestSharp/Parameters/RequestParameters.cs index 4545488b3..96d5c8a98 100644 --- a/src/RestSharp/Parameters/RequestParameters.cs +++ b/src/RestSharp/Parameters/RequestParameters.cs @@ -15,24 +15,59 @@ namespace RestSharp; +/// +/// Collection of request parameters +/// public sealed class RequestParameters : ParametersCollection { + /// + /// Create an empty parameters collection + /// public RequestParameters() { } + /// + /// Creates a parameters collection from a collection of parameter objects + /// + /// Collection of existing parameters public RequestParameters(IEnumerable parameters) => Parameters.AddRange(parameters); + /// + /// Adds multiple parameters to the collection + /// + /// Parameters to add + /// + // ReSharper disable once UnusedMethodReturnValue.Global public ParametersCollection AddParameters(IEnumerable parameters) { Parameters.AddRange(parameters); return this; } + /// + /// Add parameters from another parameters collection + /// + /// + /// + // ReSharper disable once UnusedMember.Global public ParametersCollection AddParameters(ParametersCollection parameters) { Parameters.AddRange(parameters); return this; } + /// + /// Adds a single parameter to the collection + /// + /// Parameter to add public void AddParameter(Parameter parameter) => Parameters.Add(parameter); + /// + /// Remove one or more parameters from the collection by name + /// + /// Name of the parameter to remove + // ReSharper disable once UnusedMember.Global public void RemoveParameter(string name) => Parameters.RemoveAll(x => x.Name == name); + /// + /// Remove parameter from the collection by reference + /// + /// Parameter to remove public void RemoveParameter(Parameter parameter) => Parameters.Remove(parameter); } diff --git a/src/RestSharp/Parameters/UrlSegmentParameter.cs b/src/RestSharp/Parameters/UrlSegmentParameter.cs index 402215a7f..82d6dc2fd 100644 --- a/src/RestSharp/Parameters/UrlSegmentParameter.cs +++ b/src/RestSharp/Parameters/UrlSegmentParameter.cs @@ -16,8 +16,8 @@ namespace RestSharp; -public record UrlSegmentParameter : NamedParameter { - static readonly Regex RegexPattern = new("%2f", RegexOptions.IgnoreCase | RegexOptions.Compiled); +public partial record UrlSegmentParameter : NamedParameter { + static readonly Regex RegexPattern = Pattern(); /// /// Instantiates a new query parameter instance that will be added to the request URL by replacing part of the absolute path. @@ -33,4 +33,11 @@ public UrlSegmentParameter(string name, string value, bool encode = true) ParameterType.UrlSegment, encode ) { } + +#if NET7_0_OR_GREATER + [GeneratedRegex("%2f", RegexOptions.IgnoreCase | RegexOptions.Compiled, "en-NO")] + private static partial Regex Pattern(); +#else + static Regex Pattern() => new("%2f", RegexOptions.IgnoreCase | RegexOptions.Compiled); +#endif } \ No newline at end of file diff --git a/src/RestSharp/Polyfills/Range.cs b/src/RestSharp/Polyfills/Range.cs index 8b9682db6..15a45b036 100644 --- a/src/RestSharp/Polyfills/Range.cs +++ b/src/RestSharp/Polyfills/Range.cs @@ -4,7 +4,7 @@ #if !NET using System.Runtime.CompilerServices; - +#pragma warning disable CS3019 // ReSharper disable once CheckNamespace namespace System; diff --git a/src/RestSharp/Polyfills/Strings.cs b/src/RestSharp/Polyfills/Strings.cs new file mode 100644 index 000000000..d26fa2076 --- /dev/null +++ b/src/RestSharp/Polyfills/Strings.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !NET +// ReSharper disable once CheckNamespace +namespace System; + +static class Strings { + public static string[] Split(this string str, char separator, StringSplitOptions options) => str.Split([separator], options); +} +#endif \ No newline at end of file diff --git a/src/RestSharp/Properties/AssemblyInfo.cs b/src/RestSharp/Properties/AssemblyInfo.cs index 77ebd40f7..831846141 100644 --- a/src/RestSharp/Properties/AssemblyInfo.cs +++ b/src/RestSharp/Properties/AssemblyInfo.cs @@ -10,6 +10,9 @@ InternalsVisibleTo( "RestSharp.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100fda57af14a288d46e3efea89617037585c4de57159cd536ca6dff792ea1d6addc665f2fccb4285413d9d44db5a1be87cb82686db200d16325ed9c42c89cd4824d8cc447f7cee2ac000924c3bceeb1b7fcb5cc1a3901785964d48ce14172001084134f4dcd9973c3776713b595443b1064bb53e2eeb924969244d354e46495e9d" ), + InternalsVisibleTo( + "RestSharp.Tests.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100fda57af14a288d46e3efea89617037585c4de57159cd536ca6dff792ea1d6addc665f2fccb4285413d9d44db5a1be87cb82686db200d16325ed9c42c89cd4824d8cc447f7cee2ac000924c3bceeb1b7fcb5cc1a3901785964d48ce14172001084134f4dcd9973c3776713b595443b1064bb53e2eeb924969244d354e46495e9d" + ), InternalsVisibleTo( "RestSharp.Serializers.Xml, PublicKey=0024000004800000940000000602000000240000525341310004000001000100fda57af14a288d46e3efea89617037585c4de57159cd536ca6dff792ea1d6addc665f2fccb4285413d9d44db5a1be87cb82686db200d16325ed9c42c89cd4824d8cc447f7cee2ac000924c3bceeb1b7fcb5cc1a3901785964d48ce14172001084134f4dcd9973c3776713b595443b1064bb53e2eeb924969244d354e46495e9d" )] diff --git a/src/RestSharp/Request/PropertyCache.cs b/src/RestSharp/Request/PropertyCache.cs index 5427323b5..1b15e7faf 100644 --- a/src/RestSharp/Request/PropertyCache.cs +++ b/src/RestSharp/Request/PropertyCache.cs @@ -60,7 +60,7 @@ internal static IEnumerable GetParameters(T entity, params string[] i /// internal static IEnumerable GetParameters(T entity) => GetParameters(entity, Populators); - static IEnumerable GetParameters(T entity, IEnumerable populators) { + static List GetParameters(T entity, IEnumerable populators) { var parameters = new List(capacity: Populators.Count); foreach (var populator in populators) { diff --git a/src/RestSharp/Request/RequestContent.cs b/src/RestSharp/Request/RequestContent.cs index 02b775b9d..997cfd177 100644 --- a/src/RestSharp/Request/RequestContent.cs +++ b/src/RestSharp/Request/RequestContent.cs @@ -32,7 +32,7 @@ public HttpContent BuildContent() { var postParameters = _parameters.GetContentParameters(request.Method).ToArray(); var postParametersExists = postParameters.Length > 0; var bodyParametersExists = request.TryGetBodyParameter(out var bodyParameter); - var filesExists = request.Files.Any(); + var filesExists = request.Files.Count != 0; if (request.HasFiles() || BodyShouldBeMultipartForm(bodyParameter) || diff --git a/src/RestSharp/Request/RequestHeaders.cs b/src/RestSharp/Request/RequestHeaders.cs index 9b139d81d..c1318c954 100644 --- a/src/RestSharp/Request/RequestHeaders.cs +++ b/src/RestSharp/Request/RequestHeaders.cs @@ -15,7 +15,6 @@ // ReSharper disable InvertIf -using System.Net; using RestSharp.Extensions; namespace RestSharp; diff --git a/src/RestSharp/Request/RestRequest.cs b/src/RestSharp/Request/RestRequest.cs index 83c8447b7..85c34c4ae 100644 --- a/src/RestSharp/Request/RestRequest.cs +++ b/src/RestSharp/Request/RestRequest.cs @@ -16,6 +16,7 @@ using RestSharp.Authenticators; using RestSharp.Extensions; using RestSharp.Interceptors; +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global // ReSharper disable UnusedAutoPropertyAccessor.Global @@ -49,14 +50,14 @@ public RestRequest(string? resource, Method method = Method.Get) : this() { if (queryStringStart < 0 || Resource.IndexOf('=') <= queryStringStart) return; var queryParams = ParseQuery(Resource[(queryStringStart + 1)..]); - Resource = Resource.Substring(0, queryStringStart); + Resource = Resource[..queryStringStart]; foreach (var param in queryParams) this.AddQueryParameter(param.Key, param.Value, false); return; static IEnumerable> ParseQuery(string query) - => query.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries) + => query.Split('&', StringSplitOptions.RemoveEmptyEntries) .Select( x => { var position = x.IndexOf('='); diff --git a/src/RestSharp/Request/RestRequestExtensions.Headers.cs b/src/RestSharp/Request/RestRequestExtensions.Headers.cs index 08db84887..a0bdc0f37 100644 --- a/src/RestSharp/Request/RestRequestExtensions.Headers.cs +++ b/src/RestSharp/Request/RestRequestExtensions.Headers.cs @@ -102,10 +102,12 @@ static void CheckAndThrowsDuplicateKeys(ICollection .Select(group => group.Key) .ToList(); - if (duplicateKeys.Any()) throw new ArgumentException($"Duplicate header names exist: {string.Join(", ", duplicateKeys)}"); + if (duplicateKeys.Count == 0) { + throw new ArgumentException($"Duplicate header names exist: {string.Join(", ", duplicateKeys)}"); + } } - static readonly Regex PortSplitRegex = new(@":\d+"); + static readonly Regex PortSplitRegex = PartSplit(); static void CheckAndThrowsForInvalidHost(string name, string value) { if (name == KnownHeaders.Host && InvalidHost(value)) @@ -115,4 +117,11 @@ static void CheckAndThrowsForInvalidHost(string name, string value) { static bool InvalidHost(string host) => Uri.CheckHostName(PortSplitRegex.Split(host)[0]) == UriHostNameType.Unknown; } + +#if NET7_0_OR_GREATER + [GeneratedRegex(@":\d+")] + private static partial Regex PartSplit(); +#else + static Regex PartSplit() => new(@":\d+"); +#endif } \ No newline at end of file diff --git a/src/RestSharp/Request/RestRequestExtensions.cs b/src/RestSharp/Request/RestRequestExtensions.cs index b25823bda..57d2572a8 100644 --- a/src/RestSharp/Request/RestRequestExtensions.cs +++ b/src/RestSharp/Request/RestRequestExtensions.cs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Net; - namespace RestSharp; [PublicAPI] diff --git a/src/RestSharp/Request/UriExtensions.cs b/src/RestSharp/Request/UriExtensions.cs index 95ad66611..f6e414f42 100644 --- a/src/RestSharp/Request/UriExtensions.cs +++ b/src/RestSharp/Request/UriExtensions.cs @@ -21,7 +21,7 @@ static class UriExtensions { public static Uri MergeBaseUrlAndResource(this Uri? baseUrl, string? resource) { var assembled = resource; - if (assembled.IsNotEmpty() && assembled.StartsWith("/")) assembled = assembled.Substring(1); + if (assembled.IsNotEmpty() && assembled[0] == '/') assembled = assembled[1..]; if (baseUrl == null || baseUrl.AbsoluteUri.IsEmpty()) { return assembled.IsNotEmpty() @@ -29,7 +29,7 @@ public static Uri MergeBaseUrlAndResource(this Uri? baseUrl, string? resource) { : throw new ArgumentException("Both BaseUrl and Resource are empty", nameof(resource)); } - var usingBaseUri = baseUrl.AbsoluteUri.EndsWith("/") || assembled.IsEmpty() ? baseUrl : new Uri(baseUrl.AbsoluteUri + "/"); + var usingBaseUri = baseUrl.AbsoluteUri[^1] == '/' || assembled.IsEmpty() ? baseUrl : new Uri(baseUrl.AbsoluteUri + "/"); return assembled != null ? new Uri(usingBaseUri, assembled) : baseUrl; } @@ -37,8 +37,8 @@ public static Uri MergeBaseUrlAndResource(this Uri? baseUrl, string? resource) { public static Uri AddQueryString(this Uri uri, string? query) { if (query == null) return uri; - var absoluteUri = uri.AbsoluteUri; - var separator = absoluteUri.Contains('?') ? "&" : "?"; + var absoluteUri = uri.AbsoluteUri; + var separator = absoluteUri.Contains('?') ? "&" : "?"; return new Uri($"{absoluteUri}{separator}{query}"); } @@ -72,4 +72,4 @@ params ParametersCollection[] parametersCollections } } -record UrlSegmentParamsValues(Uri Uri, string Resource); +record UrlSegmentParamsValues(Uri Uri, string Resource); \ No newline at end of file diff --git a/src/RestSharp/Response/RestResponse.cs b/src/RestSharp/Response/RestResponse.cs index 7aba25740..22e294e57 100644 --- a/src/RestSharp/Response/RestResponse.cs +++ b/src/RestSharp/Response/RestResponse.cs @@ -13,7 +13,6 @@ // limitations under the License. using System.Diagnostics; -using System.Net; using System.Text; using RestSharp.Extensions; diff --git a/src/RestSharp/Response/RestResponseBase.cs b/src/RestSharp/Response/RestResponseBase.cs index 0bbff2d55..8b54bb920 100644 --- a/src/RestSharp/Response/RestResponseBase.cs +++ b/src/RestSharp/Response/RestResponseBase.cs @@ -13,7 +13,8 @@ // limitations under the License. using System.Diagnostics; -using System.Net; +// ReSharper disable PropertyCanBeMadeInitOnly.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global namespace RestSharp; diff --git a/src/RestSharp/RestClient.Async.cs b/src/RestSharp/RestClient.Async.cs index ce6706216..61d988c43 100644 --- a/src/RestSharp/RestClient.Async.cs +++ b/src/RestSharp/RestClient.Async.cs @@ -91,10 +91,13 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo Ensure.NotNull(request, nameof(request)); // Make sure we are not disposed of when someone tries to call us! +#if NET8_0_OR_GREATER + ObjectDisposedException.ThrowIf(_disposed, this); +#else if (_disposed) { throw new ObjectDisposedException(nameof(RestClient)); } - +#endif CombineInterceptors(request); await OnBeforeRequest(request, cancellationToken).ConfigureAwait(false); request.ValidateParameters(); @@ -219,4 +222,4 @@ internal static HttpMethod AsHttpMethod(Method method) Method.Search => new HttpMethod("SEARCH"), _ => throw new ArgumentOutOfRangeException(nameof(method)) }; -} +} \ No newline at end of file diff --git a/src/RestSharp/RestClient.Extensions.Post.cs b/src/RestSharp/RestClient.Extensions.Post.cs index beddd15a5..ff1171c6e 100644 --- a/src/RestSharp/RestClient.Extensions.Post.cs +++ b/src/RestSharp/RestClient.Extensions.Post.cs @@ -13,8 +13,6 @@ // limitations under the License. // -using System.Net; - namespace RestSharp; public static partial class RestClientExtensions { diff --git a/src/RestSharp/RestClient.Extensions.Put.cs b/src/RestSharp/RestClient.Extensions.Put.cs index 44a37d768..e34115c1c 100644 --- a/src/RestSharp/RestClient.Extensions.Put.cs +++ b/src/RestSharp/RestClient.Extensions.Put.cs @@ -13,8 +13,6 @@ // limitations under the License. // -using System.Net; - namespace RestSharp; public static partial class RestClientExtensions { diff --git a/src/RestSharp/RestClient.Extensions.cs b/src/RestSharp/RestClient.Extensions.cs index f37dbeb34..7e16487a7 100644 --- a/src/RestSharp/RestClient.Extensions.cs +++ b/src/RestSharp/RestClient.Extensions.cs @@ -181,7 +181,7 @@ [EnumeratorCancellation] CancellationToken cancellationToken using var reader = new StreamReader(stream); while (!reader.EndOfStream && !cancellationToken.IsCancellationRequested) { -#if NET7_0 +#if NET7_0_OR_GREATER var line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false); #else var line = await reader.ReadLineAsync().ConfigureAwait(false); diff --git a/src/RestSharp/RestClient.cs b/src/RestSharp/RestClient.cs index d9b6c72d6..0b3f58380 100644 --- a/src/RestSharp/RestClient.cs +++ b/src/RestSharp/RestClient.cs @@ -278,7 +278,7 @@ void ConfigureDefaultParameters(RestClientOptions options) { if (options.UserAgent == null) return; if (!options.AllowMultipleDefaultParametersWithSameName && - DefaultParameters.Any(parameter => parameter.Type == ParameterType.HttpHeader && parameter.Name == KnownHeaders.UserAgent)) + DefaultParameters.Any(parameter => parameter is { Type: ParameterType.HttpHeader, Name: KnownHeaders.UserAgent })) DefaultParameters.RemoveParameter(KnownHeaders.UserAgent, ParameterType.HttpHeader); DefaultParameters.AddParameter(Parameter.CreateParameter(KnownHeaders.UserAgent, options.UserAgent, ParameterType.HttpHeader)); } diff --git a/src/RestSharp/Serializers/RestSerializers.cs b/src/RestSharp/Serializers/RestSerializers.cs index 4216c0452..157f5cf19 100644 --- a/src/RestSharp/Serializers/RestSerializers.cs +++ b/src/RestSharp/Serializers/RestSerializers.cs @@ -104,6 +104,7 @@ static async ValueTask OnBeforeDeserialization(RestResponse response, Cancellati var serializer = Serializers.Values.FirstOrDefault(x => x.SupportsContentType(contentType)); + // ReSharper disable once InvertIf if (serializer == null) { var detectedType = DetectContentType()?.Value; diff --git a/src/RestSharp/Serializers/Xml/DotNetXmlSerializer.cs b/src/RestSharp/Serializers/Xml/DotNetXmlSerializer.cs index 6e8351f82..6fb69c3f2 100644 --- a/src/RestSharp/Serializers/Xml/DotNetXmlSerializer.cs +++ b/src/RestSharp/Serializers/Xml/DotNetXmlSerializer.cs @@ -86,8 +86,8 @@ static XmlSerializer GetXmlSerializer(Type type, string? rootElement) { CacheLock.EnterReadLock(); try { - if (Cache.ContainsKey(key)) { - serializer = Cache[key]; + if (Cache.TryGetValue(key, out var value)) { + serializer = value; } } finally { @@ -103,13 +103,13 @@ static XmlSerializer GetXmlSerializer(Type type, string? rootElement) { try { // check again for a cached instance, because between the EnterWriteLock // and the last check, some other thread could have added an instance - if (!Cache.ContainsKey(key)) { + if (!Cache.TryGetValue(key, out var value)) { var root = rootElement == null ? null : new XmlRootAttribute(rootElement); - - Cache[key] = new XmlSerializer(type, root); + value = new XmlSerializer(type, root); + Cache[key] = value; } - serializer = Cache[key]; + serializer = value; } finally { CacheLock.ExitWriteLock(); diff --git a/src/RestSharp/Serializers/Xml/XmlRestSerializer.cs b/src/RestSharp/Serializers/Xml/XmlRestSerializer.cs index 85b2688cf..c3409ca1d 100644 --- a/src/RestSharp/Serializers/Xml/XmlRestSerializer.cs +++ b/src/RestSharp/Serializers/Xml/XmlRestSerializer.cs @@ -14,19 +14,11 @@ namespace RestSharp.Serializers.Xml; -public class XmlRestSerializer : IRestSerializer { - IXmlDeserializer _xmlDeserializer; - IXmlSerializer _xmlSerializer; - +public class XmlRestSerializer(IXmlSerializer serializer, IXmlDeserializer deserializer) : IRestSerializer { public XmlRestSerializer() : this(new DotNetXmlSerializer(), new DotNetXmlDeserializer()) { } - public XmlRestSerializer(IXmlSerializer xmlSerializer, IXmlDeserializer xmlDeserializer) { - _xmlDeserializer = xmlDeserializer; - _xmlSerializer = xmlSerializer; - } - - public ISerializer Serializer => _xmlSerializer; - public IDeserializer Deserializer => _xmlDeserializer; + public ISerializer Serializer => serializer; + public IDeserializer Deserializer => deserializer; public string[] AcceptedContentTypes => ContentType.XmlAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("xml", StringComparison.InvariantCultureIgnoreCase); @@ -39,23 +31,23 @@ public XmlRestSerializer(IXmlSerializer xmlSerializer, IXmlDeserializer xmlDeser if (parameter.Value == null) throw new ArgumentNullException(nameof(parameter), "Parameter value is null"); - var savedNamespace = _xmlSerializer.Namespace; - _xmlSerializer.Namespace = xmlParameter.XmlNamespace ?? savedNamespace; + var savedNamespace = serializer.Namespace; + serializer.Namespace = xmlParameter.XmlNamespace ?? savedNamespace; - var result = _xmlSerializer.Serialize(parameter.Value); + var result = serializer.Serialize(parameter.Value); - _xmlSerializer.Namespace = savedNamespace; + serializer.Namespace = savedNamespace; return result; } public XmlRestSerializer WithXmlSerializer(IXmlSerializer xmlSerializer) { - _xmlSerializer = xmlSerializer; + serializer = xmlSerializer; return this; } public XmlRestSerializer WithXmlDeserializer(IXmlDeserializer xmlDeserializer) { - _xmlDeserializer = xmlDeserializer; + deserializer = xmlDeserializer; return this; } } \ No newline at end of file diff --git a/src/RestSharp/SimpleClientFactory.cs b/src/RestSharp/SimpleClientFactory.cs index eb28780e2..09ca395c1 100644 --- a/src/RestSharp/SimpleClientFactory.cs +++ b/src/RestSharp/SimpleClientFactory.cs @@ -22,6 +22,6 @@ static class SimpleClientFactory { public static HttpClient GetClient(Uri baseUrl, Func getClient) { var key = baseUrl.ToString(); - return CachedClients.GetOrAdd(key, key => getClient()); + return CachedClients.GetOrAdd(key, _ => getClient()); } } diff --git a/test/RestSharp.InteractiveTests/Program.cs b/test/RestSharp.InteractiveTests/Program.cs index 270e9de34..bea2b8123 100644 --- a/test/RestSharp.InteractiveTests/Program.cs +++ b/test/RestSharp.InteractiveTests/Program.cs @@ -1,4 +1,5 @@ using RestSharp.InteractiveTests; +// ReSharper disable HeuristicUnreachableCode using var client = new TwitterClient("apikey", "apisecret"); @@ -11,7 +12,7 @@ #pragma warning disable CS0162 // Unreachable code detected var keys = new AuthenticationTests.TwitterKeys { ConsumerKey = Prompt("Consumer key"), - ConsumerSecret = Prompt("Consumer secret"), + ConsumerSecret = Prompt("Consumer secret") }; await AuthenticationTests.Can_Authenticate_With_OAuth_Async_With_Callback(keys); diff --git a/test/RestSharp.InteractiveTests/TwitterClient.cs b/test/RestSharp.InteractiveTests/TwitterClient.cs index 24b95e8c7..72785683a 100644 --- a/test/RestSharp.InteractiveTests/TwitterClient.cs +++ b/test/RestSharp.InteractiveTests/TwitterClient.cs @@ -16,6 +16,7 @@ using System.Runtime.CompilerServices; using System.Text.Json.Serialization; using RestSharp.Authenticators; +// ReSharper disable ClassNeverInstantiated.Local namespace RestSharp.InteractiveTests; @@ -34,7 +35,7 @@ public TwitterClient(string apiKey, string apiKeySecret) { } public async Task GetUser(string user) { - var response = await _client.GetJsonAsync>( + var response = await _client.GetAsync>( "users/by/username/{user}", new { user } ); @@ -50,14 +51,14 @@ public async Task AddSearchRules(params AddStreamSearchRu } public async Task GetSearchRules() { - var response = await _client.GetJsonAsync>("tweets/search/stream/rules"); + var response = await _client.GetAsync>("tweets/search/stream/rules"); return response?.Data; } public async IAsyncEnumerable SearchStream([EnumeratorCancellation] CancellationToken cancellationToken = default) { var response = _client.StreamJsonAsync>("tweets/search/stream", cancellationToken); - await foreach (var item in response.WithCancellation(cancellationToken)) { + await foreach (var item in response) { yield return item.Data; } } diff --git a/test/RestSharp.Tests.Integrated/Authentication/OAuth2Tests.cs b/test/RestSharp.Tests.Integrated/Authentication/OAuth2Tests.cs index 1fe318615..3a15901a3 100644 --- a/test/RestSharp.Tests.Integrated/Authentication/OAuth2Tests.cs +++ b/test/RestSharp.Tests.Integrated/Authentication/OAuth2Tests.cs @@ -8,7 +8,7 @@ public async Task ShouldHaveProperHeader() { var auth = new OAuth2AuthorizationRequestHeaderAuthenticator("token", "Bearer"); using var client = new RestClient(server.Url!, o => o.Authenticator = auth); - var response = await client.GetJsonAsync("headers"); + var response = await client.GetAsync("headers"); var authHeader = response!.FirstOrDefault(x => x.Name == KnownHeaders.Authorization); authHeader.Should().NotBeNull(); diff --git a/test/RestSharp.Tests.Integrated/Fixtures/CaptureFixture.cs b/test/RestSharp.Tests.Integrated/Fixtures/CaptureFixture.cs index 2402785a1..2ca70efb7 100644 --- a/test/RestSharp.Tests.Integrated/Fixtures/CaptureFixture.cs +++ b/test/RestSharp.Tests.Integrated/Fixtures/CaptureFixture.cs @@ -3,12 +3,12 @@ namespace RestSharp.Tests.Integrated.Fixtures; public class CaptureFixture { - public CaptureFixture() => RequestHeadCapturer.Initialize(); + protected CaptureFixture() => RequestHeadCapturer.Initialize(); protected class RequestHeadCapturer { public const string Resource = "Capture"; - public static NameValueCollection? CapturedHeaders { get; set; } + public static NameValueCollection? CapturedHeaders { get; private set; } public static void Initialize() => CapturedHeaders = null; diff --git a/test/RestSharp.Tests.Integrated/Interceptor/InterceptorTests.cs b/test/RestSharp.Tests.Integrated/Interceptor/InterceptorTests.cs index 621c6dc73..a70784e71 100644 --- a/test/RestSharp.Tests.Integrated/Interceptor/InterceptorTests.cs +++ b/test/RestSharp.Tests.Integrated/Interceptor/InterceptorTests.cs @@ -1,4 +1,5 @@ -namespace RestSharp.Tests.Integrated.Interceptor; +// ReSharper disable AccessToDisposedClosure +namespace RestSharp.Tests.Integrated.Interceptor; public class InterceptorTests(WireMockTestServer server) : IClassFixture { [Fact] diff --git a/test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs b/test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs index 59fd83d5c..389329235 100644 --- a/test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs +++ b/test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs @@ -186,7 +186,7 @@ public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() { using var client = new RestClient(_server.Url!); var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post) { - AlwaysMultipartFormData = true, + AlwaysMultipartFormData = true }; var capturer = _server.ConfigureBodyCapturer(Method.Post); diff --git a/test/RestSharp.Tests.Integrated/StatusCodeTests.cs b/test/RestSharp.Tests.Integrated/StatusCodeTests.cs index cfcee8362..bb821e574 100644 --- a/test/RestSharp.Tests.Integrated/StatusCodeTests.cs +++ b/test/RestSharp.Tests.Integrated/StatusCodeTests.cs @@ -16,7 +16,7 @@ public StatusCodeTests() { ResponseMessage CreateResponse(IRequestMessage request) { var url = new Uri(request.Url); - return new ResponseMessage() { + return new ResponseMessage { StatusCode = int.Parse(url.Segments.Last()) }; } diff --git a/test/RestSharp.Tests.Integrated/UploadFileTests.cs b/test/RestSharp.Tests.Integrated/UploadFileTests.cs index 83b2b5965..2d0b2ab54 100644 --- a/test/RestSharp.Tests.Integrated/UploadFileTests.cs +++ b/test/RestSharp.Tests.Integrated/UploadFileTests.cs @@ -2,7 +2,6 @@ using HttpMultipartParser; using RestSharp.Extensions; -using RestSharp.Tests.Shared.Fixtures; namespace RestSharp.Tests.Integrated; diff --git a/test/RestSharp.Tests.Integrated/XmlResponseTests.cs b/test/RestSharp.Tests.Integrated/XmlResponseTests.cs index 7cb9946ab..257f18ad6 100644 --- a/test/RestSharp.Tests.Integrated/XmlResponseTests.cs +++ b/test/RestSharp.Tests.Integrated/XmlResponseTests.cs @@ -114,7 +114,7 @@ public async Task ContentType_Additional_Information() { static ResponseMessage ContentTypeOData(IRequestMessage request) { var contentType = request.Headers![KnownHeaders.ContentType]; - var hasCorrectHeader = contentType!.Contains($"{ContentType.Json}; odata=verbose"); + var hasCorrectHeader = contentType.Contains($"{ContentType.Json}; odata=verbose"); var response = new ResponseMessage { StatusCode = hasCorrectHeader ? 200 : 400 diff --git a/test/RestSharp.Tests.Serializers.Json/NewtonsoftJson/IntegratedSimpleTests.cs b/test/RestSharp.Tests.Serializers.Json/NewtonsoftJson/IntegratedSimpleTests.cs index a19e9b612..cf7e54c11 100644 --- a/test/RestSharp.Tests.Serializers.Json/NewtonsoftJson/IntegratedSimpleTests.cs +++ b/test/RestSharp.Tests.Serializers.Json/NewtonsoftJson/IntegratedSimpleTests.cs @@ -1,6 +1,5 @@ using RestSharp.Serializers.NewtonsoftJson; using RestSharp.Tests.Shared.Extensions; -using RestSharp.Tests.Shared.Fixtures; namespace RestSharp.Tests.Serializers.Json.NewtonsoftJson; diff --git a/test/RestSharp.Tests.Serializers.Json/SystemTextJson/SystemTextJsonTests.cs b/test/RestSharp.Tests.Serializers.Json/SystemTextJson/SystemTextJsonTests.cs index 62c4a6c6d..cc1177171 100644 --- a/test/RestSharp.Tests.Serializers.Json/SystemTextJson/SystemTextJsonTests.cs +++ b/test/RestSharp.Tests.Serializers.Json/SystemTextJson/SystemTextJsonTests.cs @@ -1,6 +1,5 @@ using RestSharp.Serializers.Json; using RestSharp.Tests.Shared.Extensions; -using RestSharp.Tests.Shared.Fixtures; namespace RestSharp.Tests.Serializers.Json.SystemTextJson; diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/Lastfm.cs b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/Lastfm.cs index 1e7b872b7..ac5174c3b 100644 --- a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/Lastfm.cs +++ b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/Lastfm.cs @@ -1,4 +1,7 @@ // ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable ClassNeverInstantiated.Global #pragma warning disable CS8981 namespace RestSharp.Tests.Serializers.Xml.SampleClasses; @@ -28,7 +31,7 @@ public class Event : LastfmBase { public int cancelled { get; set; } } -public class EventArtistList : List { } +public class EventArtistList : List; public class artist { public string Value { get; set; } diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/misc.cs b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/misc.cs index 9f88370e6..75777b12c 100644 --- a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/misc.cs +++ b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/misc.cs @@ -1,6 +1,10 @@ using RestSharp.Serializers; -namespace RestSharp.Tests.Serializers.Xml.SampleClasses; +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable CollectionNeverUpdated.Global + +namespace RestSharp.Tests.Serializers.Xml.SampleClasses; public class PersonForXml { public string Name { get; set; } @@ -49,13 +53,13 @@ public class Band { } public class ValueCollectionForXml { - public string Value { get; set; } + public string Value { get; set; } public List Values { get; set; } } public class ValueForXml { public DateTime Timestamp { get; set; } - public string Value { get; set; } + public string Value { get; set; } } public class IncomingInvoice { @@ -141,7 +145,7 @@ public class ObjectProperties { public object ObjectProperty { get; set; } } -public class DatabaseCollection : List { } +public class DatabaseCollection : List; public class Database { public string Name { get; set; } @@ -242,8 +246,8 @@ public class DecimalNumber { } public class Note { - public const string TITLE = "What a note."; - public const string MESSAGE = "Content"; + public const string ConstTitle = "What a note."; + public const string ConstMessage = "Content"; [SerializeAs(Attribute = true), DeserializeAs(Attribute = true)] public int Id { get; set; } diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs index cd02cc6ad..3a10375d9 100644 --- a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs +++ b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs @@ -1,8 +1,7 @@ using RestSharp.Serializers; // ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global -#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language. -#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language. +// ReSharper disable ClassNeverInstantiated.Global #pragma warning disable CS8981 namespace RestSharp.Tests.Serializers.Xml.SampleClasses; diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleData/Lastfm.xml b/test/RestSharp.Tests.Serializers.Xml/SampleData/Lastfm.xml index a14a0d218..2e5b76eb4 100644 --- a/test/RestSharp.Tests.Serializers.Xml/SampleData/Lastfm.xml +++ b/test/RestSharp.Tests.Serializers.Xml/SampleData/Lastfm.xml @@ -20,25 +20,25 @@ -0.093609 - http://www.last.fm/venue/8777860+Barbican+Centre - http://www.barbican.org.uk + https://www.last.fm/venue/8777860+Barbican+Centre + https://www.barbican.org.uk - http://userserve-ak.last.fm/serve/34/418510.jpg - http://userserve-ak.last.fm/serve/64/418510.jpg - http://userserve-ak.last.fm/serve/126/418510.jpg - http://userserve-ak.last.fm/serve/252/418510.jpg - http://userserve-ak.last.fm/serve/500/418510/Barbican+Centre.jpg + https://userserve-ak.last.fm/serve/34/418510.jpg + https://userserve-ak.last.fm/serve/64/418510.jpg + https://userserve-ak.last.fm/serve/126/418510.jpg + https://userserve-ak.last.fm/serve/252/418510.jpg + https://userserve-ak.last.fm/serve/500/418510/Barbican+Centre.jpg Thu, 12 Jun 2008 19:30:00 - http://userserve-ak.last.fm/serve/34/39466081.png - http://userserve-ak.last.fm/serve/64/39466081.png - http://userserve-ak.last.fm/serve/126/39466081.png - http://userserve-ak.last.fm/serve/252/39466081.png + https://userserve-ak.last.fm/serve/34/39466081.png + https://userserve-ak.last.fm/serve/64/39466081.png + https://userserve-ak.last.fm/serve/126/39466081.png + https://userserve-ak.last.fm/serve/252/39466081.png 48 0 lastfm:event=328799 - http://www.last.fm/event/328799+Philip+Glass+at+Barbican+Centre+on+12+June+2008 + https://www.last.fm/event/328799+Philip+Glass+at+Barbican+Centre+on+12+June+2008 0 diff --git a/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs b/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs index f9c680b3a..b8569e82c 100644 --- a/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs +++ b/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs @@ -30,7 +30,7 @@ static string CreateUnderscoresXml() { root.Add(new XElement("Ignore", "dummy")); root.Add(new XAttribute("Read_Only", "dummy")); root.Add(new XElement("Unique_Id", new Guid(GuidString))); - root.Add(new XElement("Url", "http://example.com")); + root.Add(new XElement("Url", "https://example.com")); root.Add(new XElement("Url_Path", "/foo/bar")); root.Add( @@ -47,7 +47,7 @@ static string CreateUnderscoresXml() { friends.Add( new XElement( "Friend", - new XElement("Name", "Friend" + i), + new XElement("Name", $"Friend{i}"), new XAttribute("Since", DateTime.Now.Year - i) ) ); @@ -59,7 +59,7 @@ static string CreateUnderscoresXml() { foes.Add(new XAttribute("Team", "Yankees")); - for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", "Foe" + i))); + for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", $"Foe{i}"))); root.Add(foes); doc.Add(root); @@ -80,7 +80,7 @@ static string CreateLowercaseUnderscoresXml() { root.Add(new XElement("Ignore", "dummy")); root.Add(new XAttribute("read_only", "dummy")); root.Add(new XElement("unique_id", new Guid(GuidString))); - root.Add(new XElement("Url", "http://example.com")); + root.Add(new XElement("Url", "https://example.com")); root.Add(new XElement("url_path", "/foo/bar")); root.Add( @@ -97,7 +97,7 @@ static string CreateLowercaseUnderscoresXml() { friends.Add( new XElement( "Friend", - new XElement("Name", "Friend" + i), + new XElement("Name", $"Friend{i}"), new XAttribute("Since", DateTime.Now.Year - i) ) ); @@ -109,7 +109,7 @@ static string CreateLowercaseUnderscoresXml() { foes.Add(new XAttribute("Team", "Yankees")); - for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", "Foe" + i))); + for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", $"Foe{i}"))); root.Add(foes); doc.Add(root); @@ -130,7 +130,7 @@ static string CreateDashesXml() { root.Add(new XElement("Ignore", "dummy")); root.Add(new XAttribute("Read-Only", "dummy")); root.Add(new XElement("Unique-Id", new Guid(GuidString))); - root.Add(new XElement("Url", "http://example.com")); + root.Add(new XElement("Url", "https://example.com")); root.Add(new XElement("Url-Path", "/foo/bar")); root.Add( @@ -147,7 +147,7 @@ static string CreateDashesXml() { friends.Add( new XElement( "Friend", - new XElement("Name", "Friend" + i), + new XElement("Name", $"Friend{i}"), new XAttribute("Since", DateTime.Now.Year - i) ) ); @@ -159,7 +159,7 @@ static string CreateDashesXml() { foes.Add(new XAttribute("Team", "Yankees")); - for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", "Foe" + i))); + for (var i = 0; i < 5; i++) foes.Add(new XElement("Foe", new XElement("Nickname", $"Foe{i}"))); root.Add(foes); doc.Add(root); @@ -194,7 +194,7 @@ static string CreateElementsXml() { root.Add(new XElement("ReadOnly", "dummy")); root.Add(new XElement("UniqueId", new Guid(GuidString))); root.Add(new XElement("EmptyGuid", "")); - root.Add(new XElement("Url", "http://example.com")); + root.Add(new XElement("Url", "https://example.com")); root.Add(new XElement("UrlPath", "/foo/bar")); root.Add(new XElement("Order", "third")); root.Add(new XElement("Disposition", "so-so")); @@ -213,7 +213,7 @@ static string CreateElementsXml() { friends.Add( new XElement( "Friend", - new XElement("Name", "Friend" + i), + new XElement("Name", $"Friend{i}"), new XElement("Since", DateTime.Now.Year - i) ) ); @@ -238,7 +238,7 @@ static string CreateAttributesXml() { root.Add(new XAttribute("Ignore", "dummy")); root.Add(new XAttribute("ReadOnly", "dummy")); root.Add(new XAttribute("UniqueId", new Guid(GuidString))); - root.Add(new XAttribute("Url", "http://example.com")); + root.Add(new XAttribute("Url", "https://example.com")); root.Add(new XAttribute("UrlPath", "/foo/bar")); root.Add( @@ -259,8 +259,8 @@ static string CreateNoteXml() { var root = new XElement("Note"); root.SetAttributeValue("Id", 1); - root.Value = Note.MESSAGE; - root.Add(new XElement("Title", Note.TITLE)); + root.Value = Note.ConstMessage; + root.Add(new XElement("Title", Note.ConstTitle)); doc.Add(root); @@ -272,9 +272,9 @@ static string CreateXmlWithNullValues() { var root = new XElement("NullableValues"); root.Add( - new XElement("Id", null), - new XElement("StartDate", null), - new XElement("UniqueId", null) + new XElement("Id", null!), + new XElement("StartDate", null!), + new XElement("UniqueId", null!) ); doc.Add(root); @@ -337,13 +337,13 @@ static string CreateXmlWithAttributesAndNullValues() { static string CreateXmlWithAttributesAndNullValuesAndPopulatedValues() { var doc = new XDocument(); var root = new XElement("NullableValues"); - var idElement = new XElement("Id", null); + var idElement = new XElement("Id", null!); idElement.SetAttributeValue("SomeAttribute", "SomeAttribute_Value"); root.Add( idElement, - new XElement("StartDate", null), + new XElement("StartDate", null!), new XElement("UniqueId", new Guid(GuidString)) ); @@ -354,10 +354,10 @@ static string CreateXmlWithAttributesAndNullValuesAndPopulatedValues() { [Fact] public void Able_to_use_alternative_name_for_arrays() { - var xmlpath = PathFor("header_and_rows.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize
(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("header_and_rows.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize
(new RestResponse { Content = doc.ToString() })!; Assert.NotNull(output); Assert.Equal("text title", output.Title); @@ -365,7 +365,7 @@ public void Able_to_use_alternative_name_for_arrays() { } [Fact] - public void Can_deal_with_value_attrbiute() { + public void Can_deal_with_value_attribute() { const string content = "Green255"; var xml = new XmlDeserializer(); var output = xml.Deserialize(new RestResponse { Content = content })!; @@ -377,7 +377,7 @@ public void Can_deal_with_value_attrbiute() { [Fact] public void Can_Deserialize_Attribute_Using_Exact_Name_Defined_In_DeserializeAs_Attribute() { - var content = @""; + const string content = """"""; var expected = new NodeWithAttributeAndValue { AttributeValue = "711" @@ -432,7 +432,7 @@ public void Can_Deserialize_Attributes_On_Default_Root() { Assert.Equal(99.9999m, p.Percent); Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.NotNull(p.BestFriend); Assert.Equal("The Fonz", p.BestFriend.Name); @@ -441,30 +441,31 @@ public void Can_Deserialize_Attributes_On_Default_Root() { [Fact] public void Can_Deserialize_Boolean_From_Number() { - var xmlpath = PathFor("boolean_from_number.xml"); - var doc = XDocument.Load(xmlpath); - var response = new RestResponse { Content = doc.ToString() }; - var d = new XmlDeserializer(); - var output = d.Deserialize(response)!; + var xmlFilePath = PathFor("boolean_from_number.xml"); + var doc = XDocument.Load(xmlFilePath); + var response = new RestResponse { Content = doc.ToString() }; + var d = new XmlDeserializer(); + var output = d.Deserialize(response)!; Assert.True(output.Value); } [Fact] public void Can_Deserialize_Boolean_From_String() { - var xmlpath = PathFor("boolean_from_string.xml"); - var doc = XDocument.Load(xmlpath); - var response = new RestResponse { Content = doc.ToString() }; - var d = new XmlDeserializer(); - var output = d.Deserialize(response)!; + var xmlFilePath = PathFor("boolean_from_string.xml"); + var doc = XDocument.Load(xmlFilePath); + var response = new RestResponse { Content = doc.ToString() }; + var d = new XmlDeserializer(); + var output = d.Deserialize(response)!; Assert.True(output.Value); } [Fact] public void Can_Deserialize_Custom_Formatted_Date() { + const string format = "dd yyyy MMM, hh:mm ss tt zzz"; + var culture = CultureInfo.InvariantCulture; - var format = "dd yyyy MMM, hh:mm ss tt zzz"; var date = new DateTime(2010, 2, 8, 11, 11, 11); var doc = new XDocument(); var root = new XElement("Person"); @@ -511,10 +512,10 @@ public void Can_Deserialize_DateTimeOffset() { [Fact] public void Can_Deserialize_Directly_To_Lists_Off_Root_Element() { - var xmlpath = PathFor("directlists.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("directlists.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; Assert.Equal(2, output.Count); } @@ -524,7 +525,7 @@ public void Can_Deserialize_ElementNamedValue() { var doc = new XDocument(); var root = new XElement("ValueCollection"); - var valueName = "First moon landing events"; + const string valueName = "First moon landing events"; root.Add(new XElement("Value", valueName)); var xmlCollection = new XElement("Values"); @@ -568,7 +569,7 @@ public void Can_Deserialize_Elements_On_Default_Root() { Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); Assert.Equal(Guid.Empty, p.EmptyGuid); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.Equal(Order.Third, p.Order); Assert.Equal(Disposition.SoSo, p.Disposition); @@ -621,25 +622,25 @@ public void Can_Deserialize_Empty_Elements_With_Attributes_to_Nullable_Values() [Fact] public void Can_Deserialize_Eventful_Xml() { - var xmlpath = PathFor("eventful.xml"); - var doc = XDocument.Load(xmlpath); - var response = new RestResponse { Content = doc.ToString() }; - var d = new XmlDeserializer(); - var output = d.Deserialize(response)!; + var xmlFilePath = PathFor("eventful.xml"); + var doc = XDocument.Load(xmlFilePath); + var response = new RestResponse { Content = doc.ToString() }; + var d = new XmlDeserializer(); + var output = d.Deserialize(response)!; Assert.Equal(3, output.venues.Count); Assert.Equal("Tivoli", output.venues[0].name); - Assert.Equal("http://eventful.com/brisbane/venues/tivoli-/V0-001-002169294-8", output.venues[1].url); + Assert.Equal("https://eventful.com/brisbane/venues/tivoli-/V0-001-002169294-8", output.venues[1].url); Assert.Equal("V0-001-000266914-3", output.venues[2].id); } [Fact] public void Can_Deserialize_Goodreads_Xml() { - var xmlpath = PathFor("Goodreads.xml"); - var doc = XDocument.Load(xmlpath); - var response = new RestResponse { Content = doc.ToString() }; - var d = new XmlDeserializer(); - var output = d.Deserialize(response)!; + var xmlFilePath = PathFor("Goodreads.xml"); + var doc = XDocument.Load(xmlFilePath); + var response = new RestResponse { Content = doc.ToString() }; + var d = new XmlDeserializer(); + var output = d.Deserialize(response)!; Assert.Equal(2, output.Reviews.Count); Assert.Equal("1208943892", output.Reviews[0].Id); // This fails without fixing the XmlDeserializer @@ -701,10 +702,10 @@ public void Can_Deserialize_Lastfm_Xml() { var output = d.Deserialize(response)!; Assert.Equal( - "http://www.last.fm/event/328799+Philip+Glass+at+Barbican+Centre+on+12+June+2008", + "https://www.last.fm/event/328799+Philip+Glass+at+Barbican+Centre+on+12+June+2008", output.url ); - Assert.Equal("http://www.last.fm/venue/8777860+Barbican+Centre", output.venue.url); + Assert.Equal("https://www.last.fm/venue/8777860+Barbican+Centre", output.venue.url); } [Fact] @@ -718,7 +719,7 @@ public void Can_Deserialize_Lists_of_Simple_Types() { )!; Assert.False(output.Names[0].Length == 0); - Assert.False(output.Numbers.Sum() == 0); + Assert.False(output.Numbers.Sum() == 0); } [Fact] @@ -735,7 +736,7 @@ public void Can_Deserialize_Lower_Cased_Root_Elements_With_Dashes() { Assert.Equal(99.9999m, p.Percent); Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.NotNull(p.Friends); Assert.Equal(10, p.Friends.Count); @@ -772,7 +773,7 @@ public void Can_Deserialize_Names_With_Dashes_On_Default_Root() { Assert.Equal(99.9999m, p.Percent); Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.NotNull(p.Friends); Assert.Equal(10, p.Friends.Count); @@ -798,7 +799,7 @@ public void Can_Deserialize_Names_With_Underscores_On_Default_Root() { Assert.Equal(99.9999m, p.Percent); Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.NotNull(p.Friends); Assert.Equal(10, p.Friends.Count); @@ -824,7 +825,7 @@ public void Can_Deserialize_Names_With_Underscores_Without_Matching_Case_On_Defa Assert.Equal(99.9999m, p.Percent); Assert.False(p.IsCool); Assert.Equal(new Guid(GuidString), p.UniqueId); - Assert.Equal(new Uri("http://example.com", UriKind.RelativeOrAbsolute), p.Url); + Assert.Equal(new Uri("https://example.com", UriKind.RelativeOrAbsolute), p.Url); Assert.Equal(new Uri("/foo/bar", UriKind.RelativeOrAbsolute), p.UrlPath); Assert.NotNull(p.Friends); Assert.Equal(10, p.Friends.Count); @@ -838,20 +839,20 @@ public void Can_Deserialize_Names_With_Underscores_Without_Matching_Case_On_Defa [Fact] public void Can_Deserialize_Nested_List_Items_With_Matching_Class_Name() { - var xmlpath = PathFor("NestedListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("NestedListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.images.Count); } [Fact] public void Can_Deserialize_Nested_List_Items_Without_Matching_Class_Name() { - var xmlpath = PathFor("NestedListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("NestedListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.Images.Count); } @@ -878,13 +879,13 @@ public void Can_Deserialize_Node_That_Has_Attribute_And_Content() { var note = d.Deserialize(response)!; Assert.Equal(1, note.Id); - Assert.Equal(Note.TITLE, note.Title); - Assert.Equal(Note.MESSAGE, note.Message); + Assert.Equal(Note.ConstTitle, note.Title); + Assert.Equal(Note.ConstMessage, note.Message); } [Fact] public void Can_Deserialize_Node_Using_Exact_Name_Defined_In_DeserializeAs_Attribute() { - const string content = @"711"; + const string content = "711"; var expected = new SingleNode { Node = "711" @@ -899,30 +900,30 @@ public void Can_Deserialize_Node_Using_Exact_Name_Defined_In_DeserializeAs_Attri [Fact] public void Can_Deserialize_Parentless_aka_Inline_List_Items_With_Matching_Class_Name() { - var xmlpath = PathFor("InlineListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("InlineListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.images.Count); } [Fact] public void Can_Deserialize_Parentless_aka_Inline_List_Items_With_Matching_Class_Name_With_Additional_Property() { - var xmlpath = PathFor("InlineListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("InlineListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.Count); } [Fact] public void Can_Deserialize_Parentless_aka_Inline_List_Items_Without_Matching_Class_Name() { - var xmlpath = PathFor("InlineListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("InlineListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.Images.Count); } @@ -941,19 +942,18 @@ public void Can_Deserialize_Root_Elements_Without_Matching_Case_And_Dashes() { [Fact] public void Can_Deserialize_TimeSpan() { - var culture = CultureInfo.InvariantCulture; - var doc = new XDocument(culture); - TimeSpan? nullTimespan = null; - TimeSpan? nullValueTimeSpan = new TimeSpan(21, 30, 7); - var root = new XElement("Person"); + var culture = CultureInfo.InvariantCulture; + var doc = new XDocument(culture); + TimeSpan? nullable = new TimeSpan(21, 30, 7); + var root = new XElement("Person"); root.Add(new XElement("Tick", new TimeSpan(468006))); root.Add(new XElement("Millisecond", new TimeSpan(0, 0, 0, 0, 125))); root.Add(new XElement("Second", new TimeSpan(0, 0, 8))); root.Add(new XElement("Minute", new TimeSpan(0, 55, 2))); root.Add(new XElement("Hour", new TimeSpan(21, 30, 7))); - root.Add(new XElement("NullableWithoutValue", nullTimespan)); - root.Add(new XElement("NullableWithValue", nullValueTimeSpan)); + root.Add(new XElement("NullableWithoutValue", (TimeSpan?)null)); + root.Add(new XElement("NullableWithValue", nullable)); doc.Add(root); @@ -978,10 +978,10 @@ public void Can_Deserialize_TimeSpan() { [Fact] public void Can_Deserialize_To_List_Inheritor_From_Custom_Root_With_Attributes() { - var xmlpath = PathFor("ListWithAttributes.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer { RootElement = "Calls" }; - var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("ListWithAttributes.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer { RootElement = "Calls" }; + var output = xml.Deserialize(new RestResponse { Content = doc.ToString() })!; Assert.Equal(3, output.NumPages); Assert.Equal(2, output.Count); @@ -989,20 +989,20 @@ public void Can_Deserialize_To_List_Inheritor_From_Custom_Root_With_Attributes() [Fact] public void Can_Deserialize_To_Standalone_List_With_Matching_Class_Case() { - var xmlpath = PathFor("InlineListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("InlineListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.Count); } [Fact] public void Can_Deserialize_To_Standalone_List_Without_Matching_Class_Case() { - var xmlpath = PathFor("InlineListSample.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("InlineListSample.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; Assert.Equal(4, output.Count); } @@ -1034,10 +1034,10 @@ public void Can_Use_DeserializeAs_Attribute() { [Fact] public void Can_Use_DeserializeAs_Attribute_for_List() { - var xmlpath = PathFor("deserialize_as_list.xml"); - var doc = XDocument.Load(xmlpath); - var xml = new XmlDeserializer(); - var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; + var xmlFilePath = PathFor("deserialize_as_list.xml"); + var doc = XDocument.Load(xmlFilePath); + var xml = new XmlDeserializer(); + var output = xml.Deserialize>(new RestResponse { Content = doc.ToString() })!; Assert.NotNull(output); Assert.Equal("1", output[0].Sid); @@ -1089,4 +1089,4 @@ public void Ignore_ReadOnly_Property_That_Exists_In_Data() { Assert.Null(p.ReadOnlyProxy); } -} +} \ No newline at end of file diff --git a/test/RestSharp.Tests.Serializers.Xml/XmlSerializerTests.cs b/test/RestSharp.Tests.Serializers.Xml/XmlSerializerTests.cs index 4f1eba686..4762f26d8 100644 --- a/test/RestSharp.Tests.Serializers.Xml/XmlSerializerTests.cs +++ b/test/RestSharp.Tests.Serializers.Xml/XmlSerializerTests.cs @@ -15,17 +15,18 @@ public XmlSerializerTests() { [Fact] public void Can_serialize_a_list_of_items_with_interface_type() { var items = new NamedItems { - Items = new List { + Items = [ new Person { Name = "Foo", Age = 50, Price = 19.95m, StartDate = new DateTime(2009, 12, 18, 10, 2, 23), - Items = new List { new() { Name = "One", Value = 1 } } + Items = [new Item { Name = "One", Value = 1 }] }, + new Item { Name = "Two", Value = 2 }, new Item { Name = "Three", Value = 3 } - } + ] }; var xml = new XmlSerializer(); @@ -38,30 +39,31 @@ public void Can_serialize_a_list_of_items_with_interface_type() { [Fact] public void Can_serialize_a_list_which_is_the_content_of_root_element() { var contacts = new Contacts { - People = new List { - new() { + People = [ + new Person { Name = "Foo", Age = 50, Price = 19.95m, StartDate = new DateTime(2009, 12, 18, 10, 2, 23), - Items = new List { - new() { Name = "One", Value = 1 }, - new() { Name = "Two", Value = 2 }, - new() { Name = "Three", Value = 3 } - } + Items = [ + new Item { Name = "One", Value = 1 }, + new Item { Name = "Two", Value = 2 }, + new Item { Name = "Three", Value = 3 } + ] }, - new() { + + new Person { Name = "Bar", Age = 23, Price = 23.23m, StartDate = new DateTime(2009, 12, 23, 10, 23, 23), - Items = new List { - new() { Name = "One", Value = 1 }, - new() { Name = "Two", Value = 2 }, - new() { Name = "Three", Value = 3 } - } + Items = [ + new Item { Name = "One", Value = 1 }, + new Item { Name = "Two", Value = 2 }, + new Item { Name = "Three", Value = 3 } + ] } - } + ] }; var xml = new XmlSerializer(); @@ -79,22 +81,22 @@ public void Can_serialize_a_list_which_is_the_root_element() { Age = 50, Price = 19.95m, StartDate = new DateTime(2009, 12, 18, 10, 2, 23), - Items = new List { - new() { Name = "One", Value = 1 }, - new() { Name = "Two", Value = 2 }, - new() { Name = "Three", Value = 3 } - } + Items = [ + new Item { Name = "One", Value = 1 }, + new Item { Name = "Two", Value = 2 }, + new Item { Name = "Three", Value = 3 } + ] }, new() { Name = "Bar", Age = 23, Price = 23.23m, StartDate = new DateTime(2009, 12, 23, 10, 23, 23), - Items = new List { - new() { Name = "One", Value = 1 }, - new() { Name = "Two", Value = 2 }, - new() { Name = "Three", Value = 3 } - } + Items = [ + new Item { Name = "One", Value = 1 }, + new Item { Name = "Two", Value = 2 }, + new Item { Name = "Three", Value = 3 } + ] } }; var xml = new XmlSerializer(); @@ -108,8 +110,8 @@ public void Can_serialize_a_list_which_is_the_root_element() { public void Can_Serialize_An_Object_To_Node_With_Attribute_And_Text_Content() { var note = new Note { Id = 1, - Title = Note.TITLE, - Message = Note.MESSAGE + Title = Note.ConstTitle, + Message = Note.ConstMessage }; var xml = new XmlSerializer(); @@ -142,11 +144,11 @@ public void Can_serialize_simple_POCO() { Age = 50, Price = 19.95m, StartDate = new DateTime(2009, 12, 18, 10, 2, 23), - Items = new List { - new() { Name = "One", Value = 1 }, - new() { Name = "Two", Value = 2 }, - new() { Name = "Three", Value = 3 } - } + Items = [ + new Item { Name = "One", Value = 1 }, + new Item { Name = "Two", Value = 2 }, + new Item { Name = "Three", Value = 3 } + ] }; var xml = new XmlSerializer(); var doc = xml.Serialize(poco); @@ -178,12 +180,12 @@ public void Can_serialize_simple_POCO_With_Attribute_Options_Defined_And_Propert Price = 19.95m, StartDate = new DateTime(2009, 12, 18, 10, 2, 23), ContactData = new ContactData { - EmailAddresses = new List { - new() { + EmailAddresses = [ + new EmailAddress { Address = "test@test.com", Location = "Work" } - } + ] } }; var xml = new XmlSerializer(); @@ -324,13 +326,11 @@ class Contacts { } [SerializeAs(Name = "People")] - class PersonList : List { } + class PersonList : List; class ContactData { - public ContactData() => EmailAddresses = new List(); - [SerializeAs(Name = "email-addresses")] - public List EmailAddresses { get; set; } + public List EmailAddresses { get; set; } = []; } [SerializeAs(Name = "email-address")] @@ -347,8 +347,8 @@ static XDocument GetNoteXDoc() { var root = new XElement("Note"); root.SetAttributeValue("Id", 1); - root.Value = Note.MESSAGE; - root.Add(new XElement("Title", Note.TITLE)); + root.Value = Note.ConstMessage; + root.Add(new XElement("Title", Note.ConstTitle)); doc.Add(root); diff --git a/test/RestSharp.Tests.Shared/Extensions/UriExtensions.cs b/test/RestSharp.Tests.Shared/Extensions/UriExtensions.cs index e60e81dae..c1c512ad0 100644 --- a/test/RestSharp.Tests.Shared/Extensions/UriExtensions.cs +++ b/test/RestSharp.Tests.Shared/Extensions/UriExtensions.cs @@ -2,7 +2,7 @@ namespace RestSharp.Tests.Shared.Extensions; public static class UriExtensions { public static IDictionary ParseQuery(this Uri uri) { - var query = uri.Query.Substring(1).Split('&'); + var query = uri.Query[1..].Split('&'); return query.Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]); } } \ No newline at end of file diff --git a/test/RestSharp.Tests.Shared/Fixtures/Handlers.cs b/test/RestSharp.Tests.Shared/Fixtures/Handlers.cs index 6aa76d27b..a61b05550 100644 --- a/test/RestSharp.Tests.Shared/Fixtures/Handlers.cs +++ b/test/RestSharp.Tests.Shared/Fixtures/Handlers.cs @@ -30,9 +30,9 @@ public static class Handlers { BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static ); - if (method.IsStatic) - method.Invoke(null, new object[] { ctx }); + if (method!.IsStatic) + method.Invoke(null, [ctx]); else - method.Invoke(new T(), new object[] { ctx }); + method.Invoke(new T(), [ctx]); }; } \ No newline at end of file diff --git a/test/RestSharp.Tests.Shared/Fixtures/WebServer.cs b/test/RestSharp.Tests.Shared/Fixtures/WebServer.cs index 76c1433b1..364ea6751 100644 --- a/test/RestSharp.Tests.Shared/Fixtures/WebServer.cs +++ b/test/RestSharp.Tests.Shared/Fixtures/WebServer.cs @@ -39,6 +39,8 @@ public async Task Run(CancellationToken token) { Console.WriteLine(e.ToString()); } + return; + Task GetContextAsync() => taskFactory.FromAsync( (callback, state) => ((HttpListener)state!).BeginGetContext(callback, state), diff --git a/test/RestSharp.Tests/Auth/OAuth1AuthTests.cs b/test/RestSharp.Tests/Auth/OAuth1AuthTests.cs index cbbcb0401..22cf3e1b9 100644 --- a/test/RestSharp.Tests/Auth/OAuth1AuthTests.cs +++ b/test/RestSharp.Tests/Auth/OAuth1AuthTests.cs @@ -76,6 +76,7 @@ public void Authenticate_ShouldAddSignatureToRequestAsSeparateParameters_OnUrlOr ParameterShouldBe("oauth_version", "Version"); ParameterShouldHaveValue("oauth_nonce"); ParameterShouldHaveValue("oauth_timestamp"); + return; void ParameterShould(string name, Func check) { var parameter = parameters.FirstOrDefault(x => x.Type == ParameterType.GetOrPost && x.Name == name); diff --git a/test/RestSharp.Tests/Auth/OAuth1SignatureTests.cs b/test/RestSharp.Tests/Auth/OAuth1SignatureTests.cs index b489b3dc6..782a7a121 100644 --- a/test/RestSharp.Tests/Auth/OAuth1SignatureTests.cs +++ b/test/RestSharp.Tests/Auth/OAuth1SignatureTests.cs @@ -13,7 +13,7 @@ public class OAuth1SignatureTests { SignatureMethod = OAuthSignatureMethod.HmacSha1, Version = "1.0", GetNonce = () => "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg", - GetTimestamp = () => "1318622958", + GetTimestamp = () => "1318622958" }; readonly RestClient _client = new("https://api.twitter.com/1.1"); diff --git a/test/RestSharp.Tests/Auth/OAuthTests.cs b/test/RestSharp.Tests/Auth/OAuthTests.cs index 374760e6a..94e41010d 100644 --- a/test/RestSharp.Tests/Auth/OAuthTests.cs +++ b/test/RestSharp.Tests/Auth/OAuthTests.cs @@ -86,7 +86,7 @@ public void RsaSha1_Signs_Correctly(string value, int keySize) { [InlineData("%$%", "%25%24%25")] [InlineData("%", "%25")] [InlineData("/:;<=>?@", "%2F%3A%3B%3C%3D%3E%3F%40")] - [InlineData("\x00\x01\a\b\f\n\r\t\v", @"%00%01%07%08%0C%0A%0D%09%0B")] + [InlineData("\x00\x01\a\b\f\n\r\t\v", "%00%01%07%08%0C%0A%0D%09%0B")] public void UrlStrictEncode_Encodes_Correctly(string value, string expected) { var actual = OAuthTools.UrlEncodeStrict(value); diff --git a/test/RestSharp.Tests/ObjectParserTests.cs b/test/RestSharp.Tests/ObjectParserTests.cs index 74835f454..6bcbef081 100644 --- a/test/RestSharp.Tests/ObjectParserTests.cs +++ b/test/RestSharp.Tests/ObjectParserTests.cs @@ -1,3 +1,4 @@ +// ReSharper disable PropertyCanBeMadeInitOnly.Local namespace RestSharp.Tests; public class ObjectParserTests { diff --git a/test/RestSharp.Tests/ParameterValidationTests.cs b/test/RestSharp.Tests/ParameterValidationTests.cs index 7a39c7ac5..365da204d 100644 --- a/test/RestSharp.Tests/ParameterValidationTests.cs +++ b/test/RestSharp.Tests/ParameterValidationTests.cs @@ -26,7 +26,7 @@ public void RestRequest_AlwaysSingleFileAsContent_And_AlwaysMultipartFormData_Is public void RestRequest_AlwaysSingleFileAsContent_And_PostParameters_IsNotAllowed() { var request = new RestRequest { Method = Method.Post, - AlwaysSingleFileAsContent = true, + AlwaysSingleFileAsContent = true }; request.AddParameter("name", "value", ParameterType.GetOrPost); @@ -35,7 +35,7 @@ public void RestRequest_AlwaysSingleFileAsContent_And_PostParameters_IsNotAllowe [Fact] public void RestRequest_AlwaysSingleFileAsContent_And_BodyParameters_IsNotAllowed() { - var request = new RestRequest { AlwaysSingleFileAsContent = true, }; + var request = new RestRequest { AlwaysSingleFileAsContent = true }; request.AddParameter("name", "value", ParameterType.RequestBody); Assert.Throws(() => request.ValidateParameters()); } diff --git a/test/RestSharp.Tests/UrlBuilderTests.cs b/test/RestSharp.Tests/UrlBuilderTests.cs index 0373919a5..be8519f2b 100644 --- a/test/RestSharp.Tests/UrlBuilderTests.cs +++ b/test/RestSharp.Tests/UrlBuilderTests.cs @@ -6,11 +6,14 @@ namespace RestSharp.Tests; /// Note: These tests do not handle QueryString building, which is handled in Http, not RestClient ///
public class UrlBuilderTests { + const string Base = "https://some.path"; + const string Resource = "resource"; + [Fact] public void GET_with_empty_base_and_query_parameters_without_encoding() { - var request = new RestRequest("http://example.com/resource?param1=value1") + var request = new RestRequest($"{Base}/{Resource}?param1=value1") .AddQueryParameter("foo", "bar,baz", false); - var expected = new Uri("http://example.com/resource?param1=value1&foo=bar,baz"); + var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz"); using var client = new RestClient(); @@ -20,12 +23,12 @@ public void GET_with_empty_base_and_query_parameters_without_encoding() { [Fact] public void GET_with_empty_base_and_resource_containing_tokens() { - var request = new RestRequest("http://example.com/resource/{foo}"); + var request = new RestRequest($"{Base}/{Resource}/{{foo}}"); request.AddUrlSegment("foo", "bar"); using var client = new RestClient(); - var expected = new Uri("http://example.com/resource/bar"); + var expected = new Uri($"{Base}/{Resource}/bar"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -34,9 +37,9 @@ public void GET_with_empty_base_and_resource_containing_tokens() { [Fact] public void GET_with_empty_request() { var request = new RestRequest(); - var expected = new Uri("http://example.com/"); + var expected = new Uri(Base); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -45,9 +48,9 @@ public void GET_with_empty_request() { [Fact] public void GET_with_empty_request_and_bare_hostname() { var request = new RestRequest(); - var expected = new Uri("http://example.com/"); + var expected = new Uri(Base); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -57,9 +60,9 @@ public void GET_with_empty_request_and_bare_hostname() { public void GET_with_empty_request_and_query_parameters_without_encoding() { var request = new RestRequest(); request.AddQueryParameter("foo", "bar,baz", false); - var expected = new Uri("http://example.com/resource?param1=value1&foo=bar,baz"); + var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz"); - using var client = new RestClient("http://example.com/resource?param1=value1"); + using var client = new RestClient($"{Base}/{Resource}?param1=value1"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -68,17 +71,15 @@ public void GET_with_empty_request_and_query_parameters_without_encoding() { [Fact] public void GET_with_Invalid_Url_string_throws_exception() => Assert.Throws( - () => { - var unused = new RestClient("invalid url"); - } + () => { _ = new RestClient("invalid url"); } ); [Fact] public void GET_with_leading_slash() { - var request = new RestRequest("/resource"); - var expected = new Uri("http://example.com/resource"); + var request = new RestRequest($"/{Resource}"); + var expected = new Uri($"{Base}/{Resource}"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -86,11 +87,11 @@ public void GET_with_leading_slash() { [Fact] public void GET_with_leading_slash_and_baseurl_trailing_slash() { - var request = new RestRequest("/resource"); + var request = new RestRequest($"/{Resource}"); request.AddParameter("foo", "bar"); - var expected = new Uri("http://example.com/resource?foo=bar"); + var expected = new Uri($"{Base}/{Resource}?foo=bar"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -113,16 +114,16 @@ public void GET_with_multiple_instances_of_same_key() { [Fact] public void GET_with_resource_containing_null_token() { - var request = new RestRequest("/resource/{foo}"); - Assert.Throws(() => request.AddUrlSegment("foo", null)); + var request = new RestRequest($"/{Resource}/{{foo}}"); + Assert.Throws(() => request.AddUrlSegment("foo", null!)); } [Fact] public void GET_with_resource_containing_slashes() { - var request = new RestRequest("resource/foo"); - var expected = new Uri("http://example.com/resource/foo"); + var request = new RestRequest($"{Resource}/foo"); + var expected = new Uri($"{Base}/{Resource}/foo"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -130,11 +131,11 @@ public void GET_with_resource_containing_slashes() { [Fact] public void GET_with_resource_containing_tokens() { - var request = new RestRequest("resource/{foo}"); + var request = new RestRequest($"{Resource}/{{foo}}"); request.AddUrlSegment("foo", "bar"); - var expected = new Uri("http://example.com/resource/bar"); + var expected = new Uri($"{Base}/{Resource}/bar"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -142,12 +143,12 @@ public void GET_with_resource_containing_tokens() { [Fact] public void GET_with_Uri_and_resource_containing_tokens() { - var request = new RestRequest("resource/{baz}"); + var request = new RestRequest($"{Resource}/{{baz}}"); request.AddUrlSegment("foo", "bar"); request.AddUrlSegment("baz", "bat"); - var expected = new Uri("http://example.com/bar/resource/bat"); + var expected = new Uri($"{Base}/bar/{Resource}/bat"); - using var client = new RestClient(new Uri("http://example.com/{foo}")); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -157,9 +158,9 @@ public void GET_with_Uri_and_resource_containing_tokens() { public void GET_with_Uri_containing_tokens() { var request = new RestRequest(); request.AddUrlSegment("foo", "bar"); - var expected = new Uri("http://example.com/bar"); + var expected = new Uri(Base); - using var client = new RestClient(new Uri("http://example.com/{foo}")); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -167,12 +168,12 @@ public void GET_with_Uri_containing_tokens() { [Fact] public void GET_with_Url_string_and_resource_containing_tokens() { - var request = new RestRequest("resource/{baz}"); + var request = new RestRequest($"{Resource}/{{baz}}"); request.AddUrlSegment("foo", "bar"); request.AddUrlSegment("baz", "bat"); - var expected = new Uri("http://example.com/bar/resource/bat"); + var expected = new Uri($"{Base}/bar/{Resource}/bat"); - using var client = new RestClient("http://example.com/{foo}"); + using var client = new RestClient($"{Base}/{{foo}}"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -182,9 +183,9 @@ public void GET_with_Url_string_and_resource_containing_tokens() { public void GET_with_Url_string_containing_tokens() { var request = new RestRequest(); request.AddUrlSegment("foo", "bar"); - var expected = new Uri("http://example.com/bar"); + var expected = new Uri(Base); - using var client = new RestClient("http://example.com/{foo}"); + using var client = new RestClient($"{Base}/{{foo}}"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -192,11 +193,11 @@ public void GET_with_Url_string_containing_tokens() { [Fact] public void GET_wth_trailing_slash_and_query_parameters() { - var request = new RestRequest("/resource/"); + var request = new RestRequest($"/{Resource}/"); request.AddParameter("foo", "bar"); - var expected = new Uri("http://example.com/resource/?foo=bar"); + var expected = new Uri($"{Base}/{Resource}/?foo=bar"); - using var client = new RestClient("http://example.com"); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -204,10 +205,10 @@ public void GET_wth_trailing_slash_and_query_parameters() { [Fact] public void POST_with_leading_slash() { - var request = new RestRequest("/resource", Method.Post); - var expected = new Uri("http://example.com/resource"); + var request = new RestRequest($"/{Resource}", Method.Post); + var expected = new Uri($"{Base}/{Resource}"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(new Uri(Base)); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -215,10 +216,10 @@ public void POST_with_leading_slash() { [Fact] public void POST_with_leading_slash_and_baseurl_trailing_slash() { - var request = new RestRequest("/resource", Method.Post); - var expected = new Uri("http://example.com/resource"); + var request = new RestRequest($"/{Resource}", Method.Post); + var expected = new Uri($"{Base}/{Resource}"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -226,11 +227,11 @@ public void POST_with_leading_slash_and_baseurl_trailing_slash() { [Fact] public void POST_with_querystring_containing_tokens() { - var request = new RestRequest("resource", Method.Post); + var request = new RestRequest(Resource, Method.Post); request.AddParameter("foo", "bar", ParameterType.QueryString); - var expected = new Uri("http://example.com/resource?foo=bar"); + var expected = new Uri($"{Base}/{Resource}?foo=bar"); - using var client = new RestClient("http://example.com"); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -238,10 +239,10 @@ public void POST_with_querystring_containing_tokens() { [Fact] public void POST_with_resource_containing_slashes() { - var request = new RestRequest("resource/foo", Method.Post); - var expected = new Uri("http://example.com/resource/foo"); + var request = new RestRequest($"{Resource}/foo", Method.Post); + var expected = new Uri($"{Base}/{Resource}/foo"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -249,11 +250,11 @@ public void POST_with_resource_containing_slashes() { [Fact] public void POST_with_resource_containing_tokens() { - var request = new RestRequest("resource/{foo}", Method.Post); + var request = new RestRequest($"{Resource}/{{foo}}", Method.Post); request.AddUrlSegment("foo", "bar"); - var expected = new Uri("http://example.com/resource/bar"); + var expected = new Uri($"{Base}/{Resource}/bar"); - using var client = new RestClient(new Uri("http://example.com")); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -264,9 +265,9 @@ public void Should_add_parameter_if_it_is_new() { var request = new RestRequest(); request.AddOrUpdateParameter("param2", "value2"); request.AddOrUpdateParameter("param3", "value3"); - var expected = new Uri("http://example.com/resource?param1=value1¶m2=value2¶m3=value3"); + var expected = new Uri($"{Base}/{Resource}?param1=value1¶m2=value2¶m3=value3"); - using var client = new RestClient("http://example.com/resource?param1=value1"); + using var client = new RestClient($"{Base}/{Resource}?param1=value1"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -278,22 +279,22 @@ public void Should_build_uri_using_selected_encoding() { // adding parameter with o-slash character which is encoded differently between // utf-8 and iso-8859-1 request.AddOrUpdateParameter("town", "Hillerød"); - var expectedDefaultEncoding = new Uri("http://example.com/resource?town=Hiller%C3%B8d"); - var expectedIso89591Encoding = new Uri("http://example.com/resource?town=Hiller%f8d"); + var expectedDefaultEncoding = new Uri($"{Base}/{Resource}?town=Hiller%C3%B8d"); + var expectedIso89591Encoding = new Uri($"{Base}/{Resource}?town=Hiller%f8d"); - using var client1 = new RestClient(new RestClientOptions("http://example.com/resource")); + using var client1 = new RestClient(new RestClientOptions($"{Base}/{Resource}")); Assert.Equal(expectedDefaultEncoding, client1.BuildUri(request)); - using var client2 = new RestClient(new RestClientOptions("http://example.com/resource") { Encoding = Encoding.GetEncoding("ISO-8859-1") }); + using var client2 = new RestClient(new RestClientOptions($"{Base}/{Resource}") { Encoding = Encoding.GetEncoding("ISO-8859-1") }); Assert.Equal(expectedIso89591Encoding, client2.BuildUri(request)); } [Fact] public void Should_build_uri_with_resource_full_uri() { - var request = new RestRequest("https://www.example1.com/connect/authorize"); - var expected = new Uri("https://www.example1.com/connect/authorize"); + var request = new RestRequest($"{Base}/connect/authorize"); + var expected = new Uri($"{Base}/connect/authorize"); - using var client = new RestClient("https://www.example1.com/"); + using var client = new RestClient(Base); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -306,9 +307,9 @@ public void Should_encode_colon() { // utf-8 and iso-8859-1 request.AddOrUpdateParameter("parameter", "some:value"); - using var client = new RestClient("http://example.com/resource"); + using var client = new RestClient($"{Base}/{Resource}"); - var expectedDefaultEncoding = new Uri("http://example.com/resource?parameter=some%3avalue"); + var expectedDefaultEncoding = new Uri($"{Base}/{Resource}?parameter=some%3avalue"); Assert.Equal(expectedDefaultEncoding, client.BuildUri(request)); } @@ -316,9 +317,9 @@ public void Should_encode_colon() { public void Should_not_duplicate_question_mark() { var request = new RestRequest(); request.AddParameter("param2", "value2"); - var expected = new Uri("http://example.com/resource?param1=value1¶m2=value2"); + var expected = new Uri($"{Base}/{Resource}?param1=value1¶m2=value2"); - using var client = new RestClient("http://example.com/resource?param1=value1"); + using var client = new RestClient($"{Base}/{Resource}?param1=value1"); var output = client.BuildUri(request); Assert.Equal(expected, output); @@ -326,7 +327,7 @@ public void Should_not_duplicate_question_mark() { [Fact] public void Should_not_touch_request_url() { - const string baseUrl = "http://rs.test.org"; + const string baseUrl = "https://rs.test.org"; const string requestUrl = "reportserver?/Prod/Report"; var req = new RestRequest(requestUrl, Method.Post); @@ -342,9 +343,9 @@ public void Should_update_parameter_if_it_already_exists() { var request = new RestRequest(); request.AddOrUpdateParameter("param2", "value2"); request.AddOrUpdateParameter("param2", "value2-1"); - var expected = new Uri("http://example.com/resource?param1=value1¶m2=value2-1"); + var expected = new Uri($"{Base}/{Resource}?param1=value1¶m2=value2-1"); - using var client = new RestClient("http://example.com/resource?param1=value1"); + using var client = new RestClient($"{Base}/{Resource}?param1=value1"); var output = client.BuildUri(request); Assert.Equal(expected, output);