diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 65dfa58..e6af3a7 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-sonarscanner": { - "version": "8.0.3", + "version": "9.0.0", "commands": [ "dotnet-sonarscanner" ], diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ec867e5..49f397f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -25,7 +25,7 @@ A clear and concise description of what you expected to happen. **Background (please complete the following information):** - Version of library: [e.g. 0.10] - - Version of .NET: [e.g. 7.0] + - Version of .NET: [e.g. 8.0] **Additional context** Add any other context about the problem here. diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index c17ca6b..810812a 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -4,8 +4,15 @@ updates: directory: "/" groups: all-dependencies: - patterns: "*" + patterns: + - "*" schedule: interval: "daily" reviewers: - - "dnperfors" \ No newline at end of file + - "dnperfors" +- package-ecosystem: "github-actions" + directory: ".github/" + schedule: + interval: "daily" + reviewers: + - "dnperfors" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ba3ace..e60cae8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,19 +15,21 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Update Java SDK for SonarQube - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: '17' + distribution: 'microsoft' + java-version: '21' - name: Setup .NET versions - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x 8.0.x + 9.0.x include-prerelease: true - name: Dump .NET info run: dotnet --info @@ -52,6 +54,7 @@ jobs: run: dotnet sonarscanner end -d:sonar.token=${{env.SONAR_TOKEN}} - name: Check source file format run: dotnet format --no-restore --verify-no-changes + continue-on-error: true - name: Pack run: dotnet pack --output ./artifacts --configuration Release --no-build - uses: actions/upload-artifact@v4 @@ -70,15 +73,16 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Fetch all history for all tags and branches run: git fetch --prune --unshallow - name: Setup .NET versions - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x 8.0.x + 9.0.x include-prerelease: true - name: Dump .NET info run: dotnet --info @@ -95,12 +99,12 @@ jobs: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup .NET versions - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: | - 8.0.x + 9.0.x include-prerelease: true - uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index eadb7f0..de69e5f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,8 +27,8 @@ jobs: with: dotnet-version: | 6.0.x - 7.0.x 8.0.x + 9.0.x include-prerelease: true - name: Initialize CodeQL uses: github/codeql-action/init@v2 @@ -37,6 +37,6 @@ jobs: languages: csharp config-file: ./.github/codeql-config.yml - name: Build source code - run: dotnet build --configuration Release --framework net6.0 + run: dotnet build --configuration Release --framework net8.0 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e948d..91f4e92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.12] - unplanned +### Added +- Support for .NET 9.0 ## [0.11] - 2024-06-15 ### Removed diff --git a/Directory.Build.props b/Directory.Build.props index eb9e4ff..4125f0e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 12.0 + 13.0 enable false true diff --git a/LICENSE.md b/LICENSE.md index 935c46f..02259ba 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2022 David Perfors +Copyright (c) 2020-2024 David Perfors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 882abbd..d50e42d 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ The following versions are being actively tested and thus supported: - .NET Framework 4.6, 4.7 and 4.8 - .NET 6.0 - .NET 8.0 +- .NET 9.0 These versions are supported as long as Microsoft supports them, we do our best to test and support newer versions as soon as possible. diff --git a/global.json b/global.json index 33d26e5..217f7c9 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.100", "allowPrerelease": false, "rollForward": "latestMajor" } diff --git a/src/TestableHttpClient/TestableHttpClient.csproj b/src/TestableHttpClient/TestableHttpClient.csproj index b1aece1..01b284e 100644 --- a/src/TestableHttpClient/TestableHttpClient.csproj +++ b/src/TestableHttpClient/TestableHttpClient.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net6.0;net8.0 + netstandard2.0;net6.0;net8.0;net9.0 @@ -33,7 +33,8 @@ - + + diff --git a/src/TestableHttpClient/TestableHttpMessageHandlerOptions.cs b/src/TestableHttpClient/TestableHttpMessageHandlerOptions.cs index 723f427..c86f2db 100644 --- a/src/TestableHttpClient/TestableHttpMessageHandlerOptions.cs +++ b/src/TestableHttpClient/TestableHttpMessageHandlerOptions.cs @@ -1,6 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace TestableHttpClient; +namespace TestableHttpClient; public sealed class TestableHttpMessageHandlerOptions { diff --git a/src/TestableHttpClient/Utils/UriPatternParser.cs b/src/TestableHttpClient/Utils/UriPatternParser.cs index e63ce95..0f01e17 100644 --- a/src/TestableHttpClient/Utils/UriPatternParser.cs +++ b/src/TestableHttpClient/Utils/UriPatternParser.cs @@ -75,49 +75,64 @@ private static UriPattern ParsePattern(ReadOnlySpan patternSpan) Query = ParseQuery(queryPattern) }; - static Value ParseScheme(ReadOnlySpan scheme) => scheme switch + static Value ParseScheme(ReadOnlySpan scheme) { - [] => Value.Any(), - ['*'] => Value.Any(), - _ when scheme.IndexOf('*') != -1 => Value.Pattern(scheme.ToString()), - _ => Value.Exact(scheme.ToString()) - }; + return scheme switch + { + [] => Value.Any(), + ['*'] => Value.Any(), + _ when scheme.IndexOf('*') != -1 => Value.Pattern(scheme.ToString()), + _ => Value.Exact(scheme.ToString()) + }; + } - static Value ParseHost(ReadOnlySpan host) => host switch + static Value ParseHost(ReadOnlySpan host) { - [] => Value.Any(), - ['*'] => Value.Any(), - _ when host.IndexOf('*') != -1 => Value.Pattern(host.ToString()), - _ => Value.Exact(host.ToString()) - }; + return host switch + { + [] => Value.Any(), + ['*'] => Value.Any(), + _ when host.IndexOf('*') != -1 => Value.Pattern(host.ToString()), + _ => Value.Exact(host.ToString()) + }; + } - static Value ParsePort(ReadOnlySpan port) => port switch + static Value ParsePort(ReadOnlySpan port) { - [] => Value.Any(), - [':'] => throw new UriPatternParserException("Invalid port"), - [':', '*'] => Value.Any(), - [':', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()), - [':', .. var rest] => Value.Exact(rest.ToString()), - _ => throw new UnreachableException() - }; + return port switch + { + [] => Value.Any(), + [':'] => throw new UriPatternParserException("Invalid port"), + [':', '*'] => Value.Any(), + [':', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()), + [':', .. var rest] => Value.Exact(rest.ToString()), + _ => throw new UnreachableException() + }; + } - static Value ParsePath(ReadOnlySpan path) => path switch + static Value ParsePath(ReadOnlySpan path) { - [] => Value.Any(), - ['/', '*'] => Value.Any(), - ['/', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(path.ToString()), - ['/', ..] => Value.Exact(path.ToString()), - _ => throw new UnreachableException() - }; + return path switch + { + [] => Value.Any(), + ['/', '*'] => Value.Any(), + ['/', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(path.ToString()), + ['/', ..] => Value.Exact(path.ToString()), + _ => throw new UnreachableException() + }; + } - static Value ParseQuery(ReadOnlySpan query) => query switch + static Value ParseQuery(ReadOnlySpan query) { - [] => Value.Any(), - ['?'] => Value.Any(), - ['?', '*'] => Value.Any(), - ['?', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()), - ['?', .. var rest] => Value.Exact(rest.ToString()), - _ => throw new UnreachableException() - }; + return query switch + { + [] => Value.Any(), + ['?'] => Value.Any(), + ['?', '*'] => Value.Any(), + ['?', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()), + ['?', .. var rest] => Value.Exact(rest.ToString()), + _ => throw new UnreachableException() + }; + } } } diff --git a/test/.editorconfig b/test/.editorconfig index ad65050..8e17cb4 100644 --- a/test/.editorconfig +++ b/test/.editorconfig @@ -14,3 +14,9 @@ dotnet_diagnostic.CA2007.severity = silent # CA2234: Pass system uri objects instead of strings dotnet_diagnostic.CA2234.severity = silent + +# CA1515: Because an application's API isn't typically referenced from outside the assembly, types can be made internal +dotnet_diagnostic.CA1515.severity = silent + +# IDE0058: Expression value is never used +dotnet_diagnostic.IDE0058.severity = silent \ No newline at end of file diff --git a/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs b/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs index 654f4b2..fdfcce1 100644 --- a/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs +++ b/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs @@ -72,12 +72,16 @@ public async Task UsingTestHandlerWithCustomResponseFactory_AllowsForAdvancedUse { using TestableHttpMessageHandler testHandler = new(); - static IResponse PathBasedResponse(HttpResponseContext context) => context.HttpRequestMessage switch + static IResponse PathBasedResponse(HttpResponseContext context) { - _ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/200" => StatusCode(HttpStatusCode.OK), - _ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/400" => StatusCode(HttpStatusCode.BadRequest), - _ => StatusCode(HttpStatusCode.NotFound) - }; + return context.HttpRequestMessage switch + { + _ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/200" => StatusCode(HttpStatusCode.OK), + _ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/400" => StatusCode(HttpStatusCode.BadRequest), + _ => StatusCode(HttpStatusCode.NotFound) + }; + } + testHandler.RespondWith(SelectResponse(PathBasedResponse)); using HttpClient httpClient = new(testHandler); diff --git a/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj b/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj index 552bd57..53f20cc 100644 --- a/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj +++ b/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj @@ -1,11 +1,12 @@  - net462;net47;net48;net6.0;net8.0 + net462;net47;net48;net6.0;net8.0;net9.0 - + + @@ -15,11 +16,17 @@ - - - + + + - + + + + + + + diff --git a/test/TestableHttpClient.Tests/HttpRequestMessagesCheckExtensionsTests/Args.cs b/test/TestableHttpClient.Tests/HttpRequestMessagesCheckExtensionsTests/Args.cs index 902dce6..e23bde5 100644 --- a/test/TestableHttpClient.Tests/HttpRequestMessagesCheckExtensionsTests/Args.cs +++ b/test/TestableHttpClient.Tests/HttpRequestMessagesCheckExtensionsTests/Args.cs @@ -2,7 +2,7 @@ namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests; -public static class Args +internal static class Args { [System.Diagnostics.CodeAnalysis.SuppressMessage("Non-substitutable member", "NS1004:Argument matcher used with a non-virtual member of a class.", Justification = "This is a custom matcher.")] public static ref Func AnyPredicate() => ref Arg.Any>(); diff --git a/test/TestableHttpClient.Tests/Response/ResponseTestHelpers.cs b/test/TestableHttpClient.Tests/Response/ResponseTestHelpers.cs index db46b95..dc660f0 100644 --- a/test/TestableHttpClient.Tests/Response/ResponseTestHelpers.cs +++ b/test/TestableHttpClient.Tests/Response/ResponseTestHelpers.cs @@ -1,6 +1,6 @@ namespace TestableHttpClient.Tests.Response; -public static class ResponseTestHelpers +internal static class ResponseTestHelpers { public static Task TestAsync(this IResponse response) => TestAsync(response, "http://httpbin.org"); public static Task TestAsync(this IResponse response, string url) diff --git a/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj b/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj index aeff99b..1d7c36f 100644 --- a/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj +++ b/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj @@ -1,11 +1,11 @@ - net462;net47;net48;net6.0;net8.0 + net462;net47;net48;net6.0;net8.0;net9.0 - +