From fcda1b634548c8cf4df512ee2ef5ec90d1c3c88a Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Fri, 29 Sep 2023 02:26:31 +0200 Subject: [PATCH 01/16] Multi-target against .NET 6 and .NET 8 --- .github/workflows/build.yml | 18 +++++--- Directory.Build.props | 34 ++------------- JsonApiDotNetCore.sln | 1 + README.md | 29 ++++++++----- benchmarks/Benchmarks.csproj | 4 +- cleanupcode.ps1 | 6 +-- docs/generate-examples.ps1 | 2 +- inspectcode.ps1 | 2 +- package-versions.props | 42 +++++++++++++++++++ .../DapperExample/DapperExample.csproj | 6 ++- .../Definitions/TodoItemDefinition.cs | 13 +++--- src/Examples/DapperExample/IClock.cs | 6 +++ src/Examples/DapperExample/Program.cs | 3 +- src/Examples/DapperExample/SystemClock.cs | 6 +++ .../DatabasePerTenantExample.csproj | 6 ++- .../GettingStarted/GettingStarted.csproj | 4 +- .../Definitions/TodoItemDefinition.cs | 18 ++++++-- .../JsonApiDotNetCoreExample.csproj | 6 ++- .../JsonApiDotNetCoreExample/Program.cs | 8 +++- .../MultiDbContextExample.csproj | 4 +- .../NoEntityFrameworkExample.csproj | 4 +- .../ReportsExample/ReportsExample.csproj | 9 ++-- .../JsonApiDotNetCore.Annotations.csproj | 5 ++- .../JsonApiDotNetCore.SourceGenerators.csproj | 3 +- .../JsonApiDotNetCore.csproj | 4 +- .../Response/FingerprintGenerator.cs | 4 ++ test/AnnotationTests/AnnotationTests.csproj | 5 ++- test/DapperTests/DapperTests.csproj | 4 +- .../IntegrationTests/DapperTestContext.cs | 7 +++- .../IntegrationTests/FrozenClock.cs | 11 +++++ test/DiscoveryTests/DiscoveryTests.csproj | 4 +- .../Creating/AtomicCreateResourceTests.cs | 1 - ...reateResourceWithClientGeneratedIdTests.cs | 1 - .../DateMustBeInThePastAttribute.cs | 2 +- .../Meta/AtomicResourceMetaTests.cs | 1 - .../AtomicModelStateValidationTests.cs | 1 - .../QueryStrings/AtomicQueryStringTests.cs | 1 - .../MusicTrackReleaseDefinition.cs | 2 +- .../Resources/AtomicUpdateResourceTests.cs | 1 - .../ApiControllerAttributeTests.cs | 6 +-- .../ModelState/ModelStateValidationTests.cs | 6 ++- .../FilterRewritingResourceDefinition.cs | 2 +- .../TimeOffset/FilterTimeOffsetRewriter.cs | 2 +- .../TimeOffset/TimeOffsetTests.cs | 1 - .../GiftCertificate.cs | 2 +- .../InjectionDbContext.cs | 1 - .../PostOffice.cs | 2 +- .../ResourceInjectionTests.cs | 1 - .../SoftDeletionAwareResourceService.cs | 2 +- .../SoftDeletion/SoftDeletionTests.cs | 1 - .../JsonApiDotNetCoreTests.csproj | 6 ++- .../MultiDbContextTests.csproj | 4 +- .../NoEntityFrameworkTests.csproj | 4 +- .../NullSafeExpressionRewriterTests.cs | 4 ++ .../SourceGeneratorTests.csproj | 4 +- .../TestBuildingBlocks/DbContextExtensions.cs | 3 ++ test/TestBuildingBlocks/FrozenSystemClock.cs | 1 - test/TestBuildingBlocks/ISystemClock.cs | 6 +++ .../TestBuildingBlocks.csproj | 6 ++- test/UnitTests/UnitTests.csproj | 4 +- 60 files changed, 233 insertions(+), 123 deletions(-) create mode 100644 package-versions.props create mode 100644 src/Examples/DapperExample/IClock.cs create mode 100644 src/Examples/DapperExample/SystemClock.cs create mode 100644 test/DapperTests/IntegrationTests/FrozenClock.cs create mode 100644 test/TestBuildingBlocks/ISystemClock.cs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08df1de510..e907bbbc02 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: | + 6.0.x + 8.0.x - name: Setup PowerShell (Ubuntu) if: matrix.os == 'ubuntu-latest' run: | @@ -182,7 +184,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: | + 6.0.x + 8.0.x - name: Git checkout uses: actions/checkout@v4 - name: Restore tools @@ -193,7 +197,7 @@ jobs: run: | $inspectCodeOutputPath = Join-Path $env:RUNNER_TEMP 'jetbrains-inspectcode-results.xml' Write-Output "INSPECT_CODE_OUTPUT_PATH=$inspectCodeOutputPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - dotnet jb inspectcode JsonApiDotNetCore.sln --build --output="$inspectCodeOutputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal + dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal - name: Verify outcome shell: pwsh run: | @@ -233,7 +237,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: | + 6.0.x + 8.0.x - name: Git checkout uses: actions/checkout@v4 with: @@ -254,13 +260,13 @@ jobs: $baseCommitHash = git rev-parse HEAD~1 Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash in pull request." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff - name: CleanupCode (on branch) if: github.event_name == 'push' || github.event_name == 'release' shell: pwsh run: | Write-Output "Running code cleanup on all files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN --fail-on-diff --print-diff + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version)--jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN --fail-on-diff --print-diff publish: timeout-minutes: 60 diff --git a/Directory.Build.props b/Directory.Build.props index d780fbefbf..7ce9eb9a00 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -13,43 +13,15 @@ true - - - net6.0 - 4.1.0 - 0.4.1 - 6.0.0 - 2.14.1 - - - 6.0.* - 0.13.* - 34.0.* - 3.8.* - 4.7.* - 6.0.* - 2.1.* - 2.1.* - 7.0.* - 6.12.* - 2.3.* - 1.3.* - 2023.3.* - 7.0.* - 8.0.* - 7.0.* - 17.8.* - 2.5.* - - - - + + enable + latest enable false false diff --git a/JsonApiDotNetCore.sln b/JsonApiDotNetCore.sln index 4f8bd6f8ef..e821d4175d 100644 --- a/JsonApiDotNetCore.sln +++ b/JsonApiDotNetCore.sln @@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CSharpGuidelinesAnalyzer.config = CSharpGuidelinesAnalyzer.config Directory.Build.props = Directory.Build.props tests.runsettings = tests.runsettings + package-versions.props = package-versions.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{026FBC6C-AF76-4568-9B87-EC73457899FD}" diff --git a/README.md b/README.md index fe2658711f..f34dfd1bee 100644 --- a/README.md +++ b/README.md @@ -76,17 +76,24 @@ app.MapControllers(); The following chart should help you pick the best version, based on your environment. See also our [versioning policy](./VERSIONING_POLICY.md). -| JsonApiDotNetCore | Status | .NET | Entity Framework Core | -| ----------------- | ----------- | -------- | --------------------- | -| 3.x | Stable | Core 2.x | 2.x | -| 4.x | Stable | Core 3.1 | 3.1 | -| | | Core 3.1 | 5 | -| | | 5 | 5 | -| | | 6 | 5 | -| 5.0.0-5.0.2 | Stable | 6 | 6 | -| 5.0.3+ | Stable | 6 | 6 | -| | | 6 | 7 | -| | | 7 | 7 | +| JsonApiDotNetCore | Status | .NET | Entity Framework Core | +| ----------------- | ------------ | -------- | --------------------- | +| 3.x | Stable | Core 2.x | 2.x | +| 4.x | Stable | Core 3.1 | 3.1, 5 | +| | | 5 | 5 | +| | | 6 | 5 | +| 5.0.0-5.0.2 | Stable | 6 | 6 | +| 5.0.3-5.4.0 | Stable | 6 | 6, 7 | +| | | 7 | 7 | +| 5.5+ | Stable | 6 | 6, 7 | +| | | 7 | 7 | +| | | 8 | 8 | +| master | Preview | 6 | 6, 7 | +| | | 7 | 7 | +| | | 8 | 8 | +| openapi | Experimental | 6 | 6, 7 | +| | | 7 | 7 | +| | | 8 | 8 | ## Contributing diff --git a/benchmarks/Benchmarks.csproj b/benchmarks/Benchmarks.csproj index 1e97dd290f..9dbb9ba093 100644 --- a/benchmarks/Benchmarks.csproj +++ b/benchmarks/Benchmarks.csproj @@ -1,10 +1,12 @@ Exe - $(TargetFrameworkName) + net8.0 true + + diff --git a/cleanupcode.ps1 b/cleanupcode.ps1 index ba1b0ca4c0..3ab4d620ae 100644 --- a/cleanupcode.ps1 +++ b/cleanupcode.ps1 @@ -28,17 +28,17 @@ if ($revision) { if ($baseCommitHash -eq $headCommitHash) { Write-Output "Running code cleanup on staged/unstaged files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified VerifySuccessExitCode } else { Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash, including staged/unstaged files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified,commits -a $headCommitHash -b $baseCommitHash + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified,commits -a $headCommitHash -b $baseCommitHash VerifySuccessExitCode } } else { Write-Output "Running code cleanup on all files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN VerifySuccessExitCode } diff --git a/docs/generate-examples.ps1 b/docs/generate-examples.ps1 index 4b13408460..ea6b2bd8f2 100644 --- a/docs/generate-examples.ps1 +++ b/docs/generate-examples.ps1 @@ -34,7 +34,7 @@ function Start-WebServer { Write-Output "Starting web server" $startTimeUtc = Get-Date -AsUTC $job = Start-Job -ScriptBlock { - dotnet run --project ..\src\Examples\GettingStarted\GettingStarted.csproj --configuration Debug --property:TreatWarningsAsErrors=True --urls=http://0.0.0.0:14141 + dotnet run --project ..\src\Examples\GettingStarted\GettingStarted.csproj --framework net8.0 --configuration Debug --property:TreatWarningsAsErrors=True --urls=http://0.0.0.0:14141 } $webProcessId = $null diff --git a/inspectcode.ps1 b/inspectcode.ps1 index b379bce1c6..14c3eb1736 100644 --- a/inspectcode.ps1 +++ b/inspectcode.ps1 @@ -10,7 +10,7 @@ if ($LastExitCode -ne 0) { $outputPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'jetbrains-inspectcode-results.xml') $resultPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'jetbrains-inspectcode-results.html') -dotnet jb inspectcode JsonApiDotNetCore.sln --build --output="$outputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal +dotnet jb inspectcode JsonApiDotNetCore.sln --dotnetcoresdk=$(dotnet --version) --build --output="$outputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal if ($LastExitCode -ne 0) { throw "Code inspection failed with exit code $LastExitCode" diff --git a/package-versions.props b/package-versions.props new file mode 100644 index 0000000000..dd842f59f6 --- /dev/null +++ b/package-versions.props @@ -0,0 +1,42 @@ + + + + 4.1.0 + 0.4.1 + 2.14.1 + + + 0.13.* + 34.0.* + 4.7.* + 6.0.* + 2.1.* + 6.12.* + 2.3.* + 1.3.* + 8.0.* + 17.8.* + 2.5.* + + + + + 8.0.0 + + + 8.0.* + 8.0.*-* + $(AspNetCoreVersion) + + + + + 6.0.0 + + + 6.0.* + 2.1.* + 7.0.* + 7.0.* + + diff --git a/src/Examples/DapperExample/DapperExample.csproj b/src/Examples/DapperExample/DapperExample.csproj index 4445af8c1e..f49c3e4b40 100644 --- a/src/Examples/DapperExample/DapperExample.csproj +++ b/src/Examples/DapperExample/DapperExample.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + - + diff --git a/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs b/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs index 77bf6f9548..6fed60fadd 100644 --- a/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs +++ b/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs @@ -6,21 +6,20 @@ using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; -using Microsoft.AspNetCore.Authentication; namespace DapperExample.Definitions; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TodoItemDefinition : JsonApiResourceDefinition { - private readonly ISystemClock _systemClock; + private readonly IClock _clock; - public TodoItemDefinition(IResourceGraph resourceGraph, ISystemClock systemClock) + public TodoItemDefinition(IResourceGraph resourceGraph, IClock clock) : base(resourceGraph) { - ArgumentGuard.NotNull(systemClock); + ArgumentGuard.NotNull(clock); - _systemClock = systemClock; + _clock = clock; } public override SortExpression OnApplySort(SortExpression? existingSort) @@ -41,11 +40,11 @@ public override Task OnWritingAsync(TodoItem resource, WriteOperationKind writeO { if (writeOperation == WriteOperationKind.CreateResource) { - resource.CreatedAt = _systemClock.UtcNow; + resource.CreatedAt = _clock.UtcNow; } else if (writeOperation == WriteOperationKind.UpdateResource) { - resource.LastModifiedAt = _systemClock.UtcNow; + resource.LastModifiedAt = _clock.UtcNow; } return Task.CompletedTask; diff --git a/src/Examples/DapperExample/IClock.cs b/src/Examples/DapperExample/IClock.cs new file mode 100644 index 0000000000..0319c42480 --- /dev/null +++ b/src/Examples/DapperExample/IClock.cs @@ -0,0 +1,6 @@ +namespace DapperExample; + +public interface IClock +{ + DateTimeOffset UtcNow { get; } +} diff --git a/src/Examples/DapperExample/Program.cs b/src/Examples/DapperExample/Program.cs index e19e45478f..00ab54ca97 100644 --- a/src/Examples/DapperExample/Program.cs +++ b/src/Examples/DapperExample/Program.cs @@ -9,7 +9,6 @@ using JsonApiDotNetCore.AtomicOperations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Repositories; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -18,7 +17,7 @@ // Add services to the container. -builder.Services.TryAddSingleton(); +builder.Services.TryAddSingleton(); DatabaseProvider databaseProvider = GetDatabaseProvider(builder.Configuration); string? connectionString = builder.Configuration.GetConnectionString($"DapperExample{databaseProvider}"); diff --git a/src/Examples/DapperExample/SystemClock.cs b/src/Examples/DapperExample/SystemClock.cs new file mode 100644 index 0000000000..3fed87c586 --- /dev/null +++ b/src/Examples/DapperExample/SystemClock.cs @@ -0,0 +1,6 @@ +namespace DapperExample; + +public sealed class SystemClock : IClock +{ + public DateTimeOffset UtcNow => DateTimeOffset.UtcNow; +} diff --git a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj index c219dfd0f5..0ccb4bbc5f 100644 --- a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj +++ b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + - + diff --git a/src/Examples/GettingStarted/GettingStarted.csproj b/src/Examples/GettingStarted/GettingStarted.csproj index 9e0c80b7f4..1f4645f323 100644 --- a/src/Examples/GettingStarted/GettingStarted.csproj +++ b/src/Examples/GettingStarted/GettingStarted.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + { - private readonly ISystemClock _systemClock; + private readonly Func _getUtcNow; +#if NET6_0 public TodoItemDefinition(IResourceGraph resourceGraph, ISystemClock systemClock) : base(resourceGraph) { - _systemClock = systemClock; + _getUtcNow = () => systemClock.UtcNow; } +#else + public TodoItemDefinition(IResourceGraph resourceGraph, TimeProvider timeProvider) + : base(resourceGraph) + { + _getUtcNow = timeProvider.GetUtcNow; + } +#endif public override SortExpression OnApplySort(SortExpression? existingSort) { @@ -38,11 +48,11 @@ public override Task OnWritingAsync(TodoItem resource, WriteOperationKind writeO { if (writeOperation == WriteOperationKind.CreateResource) { - resource.CreatedAt = _systemClock.UtcNow; + resource.CreatedAt = _getUtcNow(); } else if (writeOperation == WriteOperationKind.UpdateResource) { - resource.LastModifiedAt = _systemClock.UtcNow; + resource.LastModifiedAt = _getUtcNow(); } return Task.CompletedTask; diff --git a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj index c219dfd0f5..0ccb4bbc5f 100644 --- a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj +++ b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + - + diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs index a65563c681..52b27759e9 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Program.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs @@ -4,10 +4,12 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Diagnostics; using JsonApiDotNetCoreExample.Data; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.DependencyInjection.Extensions; +#if NET6_0 +using Microsoft.AspNetCore.Authentication; +#endif [assembly: ExcludeFromCodeCoverage] @@ -45,7 +47,11 @@ static void ConfigureServices(WebApplicationBuilder builder) { using IDisposable _ = CodeTimingSessionManager.Current.Measure("Configure services"); +#if NET6_0 builder.Services.TryAddSingleton(); +#else + builder.Services.TryAddSingleton(TimeProvider.System); +#endif builder.Services.AddDbContext(options => { diff --git a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj index 9e0c80b7f4..1f4645f323 100644 --- a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj +++ b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + - $(TargetFrameworkName) + net8.0;net6.0 + + - $(TargetFrameworkName) + net8.0;net6.0 + + - - - - - diff --git a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj index 48ca676b4a..1b93c24975 100644 --- a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj +++ b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj @@ -1,12 +1,13 @@ - $(TargetFrameworkName);netstandard1.0 + net8.0;net6.0;netstandard1.0 true true JsonApiDotNetCore - latest + + $(JsonApiDotNetCoreVersionPrefix) jsonapidotnetcore;jsonapi;json:api;dotnet;asp.net;rest;web-api diff --git a/src/JsonApiDotNetCore.SourceGenerators/JsonApiDotNetCore.SourceGenerators.csproj b/src/JsonApiDotNetCore.SourceGenerators/JsonApiDotNetCore.SourceGenerators.csproj index ca6de1a5b7..f784ada6f9 100644 --- a/src/JsonApiDotNetCore.SourceGenerators/JsonApiDotNetCore.SourceGenerators.csproj +++ b/src/JsonApiDotNetCore.SourceGenerators/JsonApiDotNetCore.SourceGenerators.csproj @@ -5,10 +5,11 @@ true false $(NoWarn);NU5128 - latest true + + $(JsonApiDotNetCoreVersionPrefix) jsonapidotnetcore;jsonapi;json:api;dotnet;asp.net;rest;web-api diff --git a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj index 4407edaf1f..1757b54a82 100644 --- a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj +++ b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj @@ -1,10 +1,12 @@ - $(TargetFrameworkName) + net8.0;net6.0 true true + + $(JsonApiDotNetCoreVersionPrefix) jsonapidotnetcore;jsonapi;json:api;dotnet;asp.net;rest;web-api diff --git a/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs b/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs index e0b3e56b10..3ecc0b2c5a 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs @@ -6,7 +6,11 @@ namespace JsonApiDotNetCore.Serialization.Response; /// internal sealed class FingerprintGenerator : IFingerprintGenerator { +#if NET6_0 private static readonly byte[] Separator = Encoding.UTF8.GetBytes("|"); +#else + private static readonly byte[] Separator = "|"u8.ToArray(); +#endif private static readonly uint[] LookupTable = Enumerable.Range(0, 256).Select(ToLookupEntry).ToArray(); private static uint ToLookupEntry(int index) diff --git a/test/AnnotationTests/AnnotationTests.csproj b/test/AnnotationTests/AnnotationTests.csproj index b712b1bb67..081046adb0 100644 --- a/test/AnnotationTests/AnnotationTests.csproj +++ b/test/AnnotationTests/AnnotationTests.csproj @@ -1,9 +1,10 @@ - $(TargetFrameworkName);netstandard2.0 - latest + net8.0;net6.0;netstandard2.0 + + diff --git a/test/DapperTests/DapperTests.csproj b/test/DapperTests/DapperTests.csproj index c7ce96a37a..45d9c6a88d 100644 --- a/test/DapperTests/DapperTests.csproj +++ b/test/DapperTests/DapperTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + diff --git a/test/DapperTests/IntegrationTests/DapperTestContext.cs b/test/DapperTests/IntegrationTests/DapperTestContext.cs index 084444e896..0257490065 100644 --- a/test/DapperTests/IntegrationTests/DapperTestContext.cs +++ b/test/DapperTests/IntegrationTests/DapperTestContext.cs @@ -8,7 +8,6 @@ using FluentAssertions.Extensions; using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; -using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; @@ -17,6 +16,7 @@ using Microsoft.Extensions.Logging; using TestBuildingBlocks; using Xunit.Abstractions; +using IClock = DapperExample.IClock; namespace DapperTests.IntegrationTests; @@ -74,7 +74,7 @@ private WebApplicationFactory CreateFactory() builder.ConfigureServices(services => { - services.AddSingleton(new FrozenSystemClock + services.AddSingleton(new FrozenClock { UtcNow = FrozenTime }); @@ -114,7 +114,10 @@ public async Task ClearAllTablesAsync(DbContext dbContext) _ => throw new NotSupportedException($"Unsupported database provider '{databaseProvider}'.") }; +#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. + // Justification: Table names cannot be parameterized. await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM {escapedTableName}"); +#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. } } } diff --git a/test/DapperTests/IntegrationTests/FrozenClock.cs b/test/DapperTests/IntegrationTests/FrozenClock.cs new file mode 100644 index 0000000000..0de2390b71 --- /dev/null +++ b/test/DapperTests/IntegrationTests/FrozenClock.cs @@ -0,0 +1,11 @@ +using DapperExample; +using FluentAssertions.Extensions; + +namespace DapperTests.IntegrationTests; + +internal sealed class FrozenClock : IClock +{ + private static readonly DateTimeOffset DefaultTime = 1.January(2020).At(1, 1, 1).AsUtc(); + + public DateTimeOffset UtcNow { get; set; } = DefaultTime; +} diff --git a/test/DiscoveryTests/DiscoveryTests.csproj b/test/DiscoveryTests/DiscoveryTests.csproj index a09e322203..a64d3be689 100644 --- a/test/DiscoveryTests/DiscoveryTests.csproj +++ b/test/DiscoveryTests/DiscoveryTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index 99b3b3bc5b..5639d44f40 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -3,7 +3,6 @@ using FluentAssertions.Extensions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index 5bd4acb39e..62013322e5 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -2,7 +2,6 @@ using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/DateMustBeInThePastAttribute.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/DateMustBeInThePastAttribute.cs index 0421f2e396..b273eca898 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/DateMustBeInThePastAttribute.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/DateMustBeInThePastAttribute.cs @@ -1,8 +1,8 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JsonApiDotNetCore.Resources; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs index 3edb88b14a..f98bc1b49d 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs @@ -4,7 +4,6 @@ using FluentAssertions.Extensions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index 4a8b7d9e52..98564f3a57 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -1,7 +1,6 @@ using System.Net; using FluentAssertions; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index a9d0fbd44b..6db0926773 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -2,7 +2,6 @@ using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs index 65ab4a4344..84827322ad 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs @@ -2,8 +2,8 @@ using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Primitives; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.QueryStrings; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 0af67d4c20..943d2d9bb4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -3,7 +3,6 @@ using FluentAssertions.Extensions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs index 28e6ba2439..a27ef77329 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs @@ -33,7 +33,7 @@ public async Task ApiController_attribute_transforms_NotFound_action_result_with ErrorObject error = responseDocument.Errors[0]; error.Links.ShouldNotBeNull(); - error.Links.About.Should().Be("https://tools.ietf.org/html/rfc7231#section-6.5.4"); + error.Links.About.Should().StartWith("https://tools.ietf.org/html/rfc"); } [Fact] @@ -66,7 +66,7 @@ public async Task ProblemDetails_from_invalid_ModelState_is_translated_into_erro ErrorObject error1 = responseDocument.Errors[0]; error1.StatusCode.Should().Be(HttpStatusCode.BadRequest); error1.Links.ShouldNotBeNull(); - error1.Links.About.Should().Be("https://tools.ietf.org/html/rfc7231#section-6.5.1"); + error1.Links.About.Should().StartWith("https://tools.ietf.org/html/rfc"); error1.Title.Should().Be("One or more validation errors occurred."); error1.Detail.Should().Be("The Name field is required."); error1.Source.Should().BeNull(); @@ -74,7 +74,7 @@ public async Task ProblemDetails_from_invalid_ModelState_is_translated_into_erro ErrorObject error2 = responseDocument.Errors[1]; error2.StatusCode.Should().Be(HttpStatusCode.BadRequest); error2.Links.ShouldNotBeNull(); - error2.Links.About.Should().Be("https://tools.ietf.org/html/rfc7231#section-6.5.1"); + error2.Links.About.Should().StartWith("https://tools.ietf.org/html/rfc"); error2.Title.Should().Be("One or more validation errors occurred."); error2.Detail.Should().Be("The field YearOfBirth must be between 1900 and 2050."); error2.Source.Should().BeNull(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs index 55e293aab1..e6e83fa7c3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs @@ -1,9 +1,11 @@ using System.Net; using FluentAssertions; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; +#if NET6_0 +using Microsoft.Extensions.DependencyInjection; +#endif namespace JsonApiDotNetCoreTests.IntegrationTests.InputValidation.ModelState; @@ -19,11 +21,13 @@ public ModelStateValidationTests(IntegrationTestContext(); testContext.UseController(); +#if NET6_0 testContext.ConfigureServices(services => { // Polyfill for missing DateOnly/TimeOnly support in .NET 6 ModelState validation. services.AddDateOnlyTimeOnlyStringConverters(); }); +#endif } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs index 138ccdeafd..c3e5941a19 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs @@ -2,7 +2,7 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; -using Microsoft.AspNetCore.Authentication; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.TimeOffset; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs index 8adc07fdf0..2d2ee4da89 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs @@ -1,5 +1,5 @@ using JsonApiDotNetCore.Queries.Expressions; -using Microsoft.AspNetCore.Authentication; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.TimeOffset; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/TimeOffsetTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/TimeOffsetTests.cs index baec74602b..8b8062674c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/TimeOffsetTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/TimeOffsetTests.cs @@ -6,7 +6,6 @@ using JsonApiDotNetCore.Queries.Parsing; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs index 2cd1ff91d8..6da63a30cb 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs @@ -2,7 +2,7 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; -using Microsoft.AspNetCore.Authentication; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs index bb3bbfd85b..57ec534cae 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs @@ -1,6 +1,5 @@ using JetBrains.Annotations; using JsonApiDotNetCore; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs index da163d9cee..f7bd504cd8 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs @@ -2,7 +2,7 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; -using Microsoft.AspNetCore.Authentication; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 403f86757b..7dd8c92726 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -2,7 +2,6 @@ using FluentAssertions; using FluentAssertions.Extensions; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs index 299a40bad8..2b6e3be294 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs @@ -5,8 +5,8 @@ using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; -using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; +using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.SoftDeletion; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs index f750826f8c..7bd7fe66f1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs @@ -3,7 +3,6 @@ using FluentAssertions.Extensions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj index 7a3fa8ddf8..38d665aa5b 100644 --- a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj +++ b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + - + diff --git a/test/MultiDbContextTests/MultiDbContextTests.csproj b/test/MultiDbContextTests/MultiDbContextTests.csproj index 394d72e2d2..54497bfada 100644 --- a/test/MultiDbContextTests/MultiDbContextTests.csproj +++ b/test/MultiDbContextTests/MultiDbContextTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + diff --git a/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj b/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj index 84a36dcbb1..080666d491 100644 --- a/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj +++ b/test/NoEntityFrameworkTests/NoEntityFrameworkTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + diff --git a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs index 57da032819..e8fe1585ca 100644 --- a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs +++ b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs @@ -498,7 +498,11 @@ public void Can_rewrite_order_by_clause_with_IntPtr() Parent = new TestResource { Id = generator.GetNext(), +#if NET6_0 Pointer = (IntPtr)1 +#else + Pointer = 1 +#endif } } }; diff --git a/test/SourceGeneratorTests/SourceGeneratorTests.csproj b/test/SourceGeneratorTests/SourceGeneratorTests.csproj index d361de38e5..e28bdc20d1 100644 --- a/test/SourceGeneratorTests/SourceGeneratorTests.csproj +++ b/test/SourceGeneratorTests/SourceGeneratorTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + diff --git a/test/TestBuildingBlocks/DbContextExtensions.cs b/test/TestBuildingBlocks/DbContextExtensions.cs index 7f32073874..d3a8a0e8ad 100644 --- a/test/TestBuildingBlocks/DbContextExtensions.cs +++ b/test/TestBuildingBlocks/DbContextExtensions.cs @@ -44,7 +44,10 @@ private static async Task ClearTablesAsync(this DbContext dbContext, params Type } else { +#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. + // Justification: Table names cannot be parameterized. await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM \"{tableName}\""); +#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. } } } diff --git a/test/TestBuildingBlocks/FrozenSystemClock.cs b/test/TestBuildingBlocks/FrozenSystemClock.cs index a1d85e1fcc..6ffe8feaaf 100644 --- a/test/TestBuildingBlocks/FrozenSystemClock.cs +++ b/test/TestBuildingBlocks/FrozenSystemClock.cs @@ -1,5 +1,4 @@ using FluentAssertions.Extensions; -using Microsoft.AspNetCore.Authentication; namespace TestBuildingBlocks; diff --git a/test/TestBuildingBlocks/ISystemClock.cs b/test/TestBuildingBlocks/ISystemClock.cs new file mode 100644 index 0000000000..eb1c8628a3 --- /dev/null +++ b/test/TestBuildingBlocks/ISystemClock.cs @@ -0,0 +1,6 @@ +namespace TestBuildingBlocks; + +public interface ISystemClock +{ + DateTimeOffset UtcNow { get; } +} diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj index ba9a2f5da3..ae6cf32ff6 100644 --- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj +++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + @@ -15,7 +17,7 @@ - + diff --git a/test/UnitTests/UnitTests.csproj b/test/UnitTests/UnitTests.csproj index f8dcbce984..99fc7ce781 100644 --- a/test/UnitTests/UnitTests.csproj +++ b/test/UnitTests/UnitTests.csproj @@ -1,8 +1,10 @@ - $(TargetFrameworkName) + net8.0;net6.0 + + From d1a36649743a0a420a1e806079a61e5339510796 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:14:56 +0100 Subject: [PATCH 02/16] Create codeql.yml --- .github/workflows/codeql.yml | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..5b1868eae5 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,43 @@ +name: "CodeQL" + +on: + push: + branches: [ 'master', 'release/**' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'master', 'release/**' ] + schedule: + - cron: '0 0 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: 'ubuntu-latest' + timeout-minutes: 60 + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'csharp' ] + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: | + 6.0.x + 8.0.x + - name: Git checkout + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From f3f382a9ac74481dab2e11e11e38c88dc11ea6a7 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:50:10 +0100 Subject: [PATCH 03/16] Revert "Workaround failure while installing latest PowerShell that requires .NET 8" This reverts commit 4d2ffd893b4c33d0a5503ae755941bbb5279326b. --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e907bbbc02..ca7042c976 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,8 +53,7 @@ jobs: - name: Setup PowerShell (Ubuntu) if: matrix.os == 'ubuntu-latest' run: | - # Temporary version downgrade because .NET 8 is not installed on runner. - dotnet tool install --global PowerShell --version 7.3.10 + dotnet tool install --global PowerShell - name: Find latest PowerShell version (Windows) if: matrix.os == 'windows-latest' shell: pwsh From 875ac5484acf49cde842e75d43a482a801c22a53 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:05:43 +0100 Subject: [PATCH 04/16] Resharper: Use collection expression --- JsonApiDotNetCore.sln.DotSettings | 3 + WarningSeverities.DotSettings | 2 + .../DapperExample/Data/RotatingList.cs | 2 +- .../Definitions/TodoItemDefinition.cs | 5 +- .../Repositories/DapperFacade.cs | 4 +- .../Repositories/ResourceChangeDetector.cs | 22 +++--- .../Repositories/ResultSetMapper.cs | 12 +-- .../Repositories/SqlCaptureStore.cs | 2 +- .../Builders/InsertStatementBuilder.cs | 2 +- .../Builders/SelectStatementBuilder.cs | 36 ++++----- .../Builders/SqlQueryBuilder.cs | 10 +-- .../UpdateResourceStatementBuilder.cs | 2 +- .../DataModel/BaseDataModelService.cs | 4 +- .../DataModel/FromEntitiesDataModelService.cs | 4 +- .../TranslationToSql/ParameterFormatter.cs | 6 +- .../ColumnSelectorUsageCollector.cs | 2 +- .../StaleColumnReferenceRewriter.cs | 4 +- .../UnusedSelectorsRewriter.cs | 4 +- .../TranslationToSql/TreeNodes/SelectNode.cs | 2 +- .../TranslationToSql/TreeNodes/TableNode.cs | 2 +- .../Controllers/NonJsonApiController.cs | 5 +- .../Data/RotatingList.cs | 2 +- .../Definitions/TodoItemDefinition.cs | 5 +- .../NoEntityFrameworkExample/Data/Database.cs | 26 +++---- .../NullSafeExpressionRewriter.cs | 4 +- .../Configuration/ResourceType.cs | 8 +- .../ObjectExtensions.cs | 15 +--- .../ResourceDescriptorAssemblyCache.cs | 2 +- .../Configuration/ResourceGraph.cs | 4 +- .../Configuration/ResourceGraphBuilder.cs | 8 +- .../Configuration/ServiceDiscoveryFacade.cs | 17 ++-- .../Diagnostics/CascadingCodeTimer.cs | 2 +- .../Errors/InvalidModelStateException.cs | 2 +- .../Middleware/JsonApiRoutingConvention.cs | 6 +- .../Expressions/IncludeChainConverter.cs | 2 +- .../Queries/Parsing/FilterParser.cs | 6 +- .../Queries/Parsing/IncludeParser.cs | 4 +- .../QueryableBuilding/IncludeClauseBuilder.cs | 2 +- .../QueryableBuilding/LambdaScopeFactory.cs | 2 +- .../QueryStrings/FieldChains/MatchState.cs | 2 +- .../FieldChains/MatchTraceScope.cs | 2 +- .../FieldChains/PatternMatcher.cs | 2 +- .../QueryStrings/FieldChains/PatternParser.cs | 6 +- .../FilterQueryStringParameterReader.cs | 2 +- .../PaginationQueryStringParameterReader.cs | 2 +- ...ourceDefinitionQueryableParameterReader.cs | 2 +- .../SortQueryStringParameterReader.cs | 2 +- .../Resources/TargetedFields.cs | 4 +- .../Serialization/Response/MetaBuilder.cs | 2 +- .../Response/ResourceObjectTreeNode.cs | 8 +- .../UnitTests/SqlTreeNodeVisitorTests.cs | 4 +- .../ServiceDiscoveryFacadeTests.cs | 2 +- .../AtomicAddToToManyRelationshipTests.cs | 4 +- ...AtomicRemoveFromToManyRelationshipTests.cs | 4 +- .../AtomicReplaceToManyRelationshipTests.cs | 4 +- .../AtomicReplaceToManyRelationshipTests.cs | 4 +- .../Authorization/Scopes/AuthScopeSet.cs | 2 +- .../IdObfuscation/HexadecimalCodec.cs | 2 +- .../Microservices/MessagingGroupDefinition.cs | 2 +- .../Microservices/MessagingUserDefinition.cs | 2 +- .../NonJsonApiController.cs | 6 +- .../CustomFunctions/Sum/SumFilterParser.cs | 6 +- .../SparseFieldSets/ResourceCaptureStore.cs | 2 +- .../Reading/StarDefinition.cs | 5 +- .../WheelSortDefinition.cs | 5 +- .../Serialization/SerializationFakers.cs | 4 +- .../Serialization/SerializationTests.cs | 2 +- .../TestableQueryExpressionRewriter.cs | 2 +- .../CreateSortExpressionFromLambdaTests.cs | 78 ++++++------------- .../CompilationBuilder.cs | 4 +- .../SourceGeneratorTests/SourceCodeBuilder.cs | 2 +- test/TestBuildingBlocks/FakeLoggerFactory.cs | 2 +- .../IgnoreLineEndingsComparer.cs | 4 +- 73 files changed, 193 insertions(+), 245 deletions(-) diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings index bf7a5182f0..64125e085d 100644 --- a/JsonApiDotNetCore.sln.DotSettings +++ b/JsonApiDotNetCore.sln.DotSettings @@ -93,6 +93,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); SUGGESTION SUGGESTION WARNING + SUGGESTION <?xml version="1.0" encoding="utf-16"?><Profile name="JADNC Full Cleanup"><XMLReformatCode>True</XMLReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JsInsertSemicolon>True</JsInsertSemicolon><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSReformatInactiveBranches>True</CSReformatInactiveBranches></Profile> JADNC Full Cleanup Required @@ -125,6 +126,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); False False True + 1 NEVER NEVER False @@ -145,6 +147,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); True WRAP_IF_LONG 160 + CHOP_IF_LONG WRAP_IF_LONG CHOP_ALWAYS CHOP_ALWAYS diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index 96f358da23..b5e5ca9c42 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -240,6 +240,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -264,4 +265,5 @@ WARNING WARNING WARNING + WARNING \ No newline at end of file diff --git a/src/Examples/DapperExample/Data/RotatingList.cs b/src/Examples/DapperExample/Data/RotatingList.cs index 3fa04762a3..67c19bea4a 100644 --- a/src/Examples/DapperExample/Data/RotatingList.cs +++ b/src/Examples/DapperExample/Data/RotatingList.cs @@ -4,7 +4,7 @@ internal abstract class RotatingList { public static RotatingList Create(int count, Func createElement) { - List elements = new(); + List elements = []; for (int index = 0; index < count; index++) { diff --git a/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs b/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs index 6fed60fadd..dc7c1802c8 100644 --- a/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs +++ b/src/Examples/DapperExample/Definitions/TodoItemDefinition.cs @@ -29,11 +29,10 @@ public override SortExpression OnApplySort(SortExpression? existingSort) private SortExpression GetDefaultSortOrder() { - return CreateSortExpressionFromLambda(new PropertySortOrder - { + return CreateSortExpressionFromLambda([ (todoItem => todoItem.Priority, ListSortDirection.Ascending), (todoItem => todoItem.LastModifiedAt, ListSortDirection.Descending) - }); + ]); } public override Task OnWritingAsync(TodoItem resource, WriteOperationKind writeOperation, CancellationToken cancellationToken) diff --git a/src/Examples/DapperExample/Repositories/DapperFacade.cs b/src/Examples/DapperExample/Repositories/DapperFacade.cs index d3247967f9..4d30e430c7 100644 --- a/src/Examples/DapperExample/Repositories/DapperFacade.cs +++ b/src/Examples/DapperExample/Repositories/DapperFacade.cs @@ -38,7 +38,7 @@ public IReadOnlyCollection BuildSqlCommandsForOneToOneRelatio { ArgumentGuard.NotNull(changeDetector); - List sqlCommands = new(); + List sqlCommands = []; foreach ((HasOneAttribute relationship, (object? currentRightId, object newRightId)) in changeDetector.GetOneToOneRelationshipsChangedToNotNull()) { @@ -81,7 +81,7 @@ public IReadOnlyCollection BuildSqlCommandsForChangedRelation { ArgumentGuard.NotNull(changeDetector); - List sqlCommands = new(); + List sqlCommands = []; foreach ((HasOneAttribute hasOneRelationship, (object? currentRightId, object? newRightId)) in changeDetector .GetChangedToOneRelationshipsWithForeignKeyAtRightSide()) diff --git a/src/Examples/DapperExample/Repositories/ResourceChangeDetector.cs b/src/Examples/DapperExample/Repositories/ResourceChangeDetector.cs index bd6537b547..1d9b998340 100644 --- a/src/Examples/DapperExample/Repositories/ResourceChangeDetector.cs +++ b/src/Examples/DapperExample/Repositories/ResourceChangeDetector.cs @@ -15,11 +15,11 @@ internal sealed class ResourceChangeDetector private readonly CollectionConverter _collectionConverter = new(); private readonly IDataModelService _dataModelService; - private Dictionary _currentColumnValues = new(); - private Dictionary _newColumnValues = new(); + private Dictionary _currentColumnValues = []; + private Dictionary _newColumnValues = []; - private Dictionary> _currentRightResourcesByRelationship = new(); - private Dictionary> _newRightResourcesByRelationship = new(); + private Dictionary> _currentRightResourcesByRelationship = []; + private Dictionary> _newRightResourcesByRelationship = []; public ResourceType ResourceType { get; } @@ -52,7 +52,7 @@ public void CaptureNewValues(IIdentifiable resource) private Dictionary CaptureColumnValues(IIdentifiable resource) { - Dictionary columnValues = new(); + Dictionary columnValues = []; foreach ((string columnName, ResourceFieldAttribute? _) in _dataModelService.GetColumnMappings(ResourceType)) { @@ -64,7 +64,7 @@ public void CaptureNewValues(IIdentifiable resource) private Dictionary> CaptureRightResourcesByRelationship(IIdentifiable resource) { - Dictionary> relationshipValues = new(); + Dictionary> relationshipValues = []; foreach (RelationshipAttribute relationship in ResourceType.Relationships) { @@ -107,7 +107,7 @@ public void AssertIsNotClearingAnyRequiredToOneRelationships(string resourceName public IReadOnlyDictionary GetOneToOneRelationshipsChangedToNotNull() { - Dictionary changes = new(); + Dictionary changes = []; foreach ((RelationshipAttribute relationship, ISet newRightResources) in _newRightResourcesByRelationship) { @@ -135,7 +135,7 @@ public void AssertIsNotClearingAnyRequiredToOneRelationships(string resourceName public IReadOnlyDictionary GetChangedColumnValues() { - Dictionary changes = new(); + Dictionary changes = []; foreach ((string columnName, object? newColumnValue) in _newColumnValues) { @@ -152,7 +152,7 @@ public void AssertIsNotClearingAnyRequiredToOneRelationships(string resourceName public IReadOnlyDictionary GetChangedToOneRelationshipsWithForeignKeyAtRightSide() { - Dictionary changes = new(); + Dictionary changes = []; foreach ((RelationshipAttribute relationship, ISet newRightResources) in _newRightResourcesByRelationship) { @@ -183,7 +183,7 @@ public void AssertIsNotClearingAnyRequiredToOneRelationships(string resourceName public IReadOnlyDictionary currentRightIds, ISet newRightIds)> GetChangedToManyRelationships() { - Dictionary currentRightIds, ISet newRightIds)> changes = new(); + Dictionary currentRightIds, ISet newRightIds)> changes = []; foreach ((RelationshipAttribute relationship, ISet newRightResources) in _newRightResourcesByRelationship) { @@ -194,7 +194,7 @@ public void AssertIsNotClearingAnyRequiredToOneRelationships(string resourceName HashSet currentRightIds = _currentRightResourcesByRelationship.TryGetValue(hasManyRelationship, out ISet? currentRightResources) ? currentRightResources.Select(resource => resource.GetTypedId()).ToHashSet() - : new HashSet(); + : []; if (!currentRightIds.SetEquals(newRightIds)) { diff --git a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs index e0a6efddd0..61421d7331 100644 --- a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs +++ b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs @@ -12,20 +12,20 @@ namespace DapperExample.Repositories; internal sealed class ResultSetMapper where TResource : class, IIdentifiable { - private readonly List _joinObjectTypes = new(); + private readonly List _joinObjectTypes = []; // For each object type, we keep a map of ID/instance pairs. // Note we don't do full bidirectional relationship fix-up; this just avoids duplicate instances. - private readonly Dictionary> _resourceByTypeCache = new(); + private readonly Dictionary> _resourceByTypeCache = []; // Optimization to avoid unneeded calls to expensive Activator.CreateInstance() method, which is needed multiple times per row. - private readonly Dictionary _defaultValueByTypeCache = new(); + private readonly Dictionary _defaultValueByTypeCache = []; // Used to determine where in the tree of included relationships a join object belongs to. private readonly Dictionary _includeElementToJoinObjectArrayIndexLookup = new(ReferenceEqualityComparer.Instance); // The return value of the mapping process. - private readonly List _primaryResourcesInOrder = new(); + private readonly List _primaryResourcesInOrder = []; // The included relationships for which an INNER/LEFT JOIN statement was produced, which we're mapping. private readonly IncludeExpression _include; @@ -36,7 +36,7 @@ public ResultSetMapper(IncludeExpression? include) { _include = include ?? IncludeExpression.Empty; _joinObjectTypes.Add(typeof(TResource)); - _resourceByTypeCache[typeof(TResource)] = new Dictionary(); + _resourceByTypeCache[typeof(TResource)] = []; var walker = new IncludeElementWalker(_include); int index = 1; @@ -44,7 +44,7 @@ public ResultSetMapper(IncludeExpression? include) foreach (IncludeElementExpression includeElement in walker.BreadthFirstEnumerate()) { _joinObjectTypes.Add(includeElement.Relationship.RightType.ClrType); - _resourceByTypeCache[includeElement.Relationship.RightType.ClrType] = new Dictionary(); + _resourceByTypeCache[includeElement.Relationship.RightType.ClrType] = []; _includeElementToJoinObjectArrayIndexLookup[includeElement] = index; index++; diff --git a/src/Examples/DapperExample/Repositories/SqlCaptureStore.cs b/src/Examples/DapperExample/Repositories/SqlCaptureStore.cs index 272dedbd37..15d4e95d81 100644 --- a/src/Examples/DapperExample/Repositories/SqlCaptureStore.cs +++ b/src/Examples/DapperExample/Repositories/SqlCaptureStore.cs @@ -9,7 +9,7 @@ namespace DapperExample.Repositories; [PublicAPI] public sealed class SqlCaptureStore { - private readonly List _sqlCommands = new(); + private readonly List _sqlCommands = []; public IReadOnlyList SqlCommands => _sqlCommands; diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs index b362a0e7b4..7e444b45a1 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs @@ -28,7 +28,7 @@ public InsertNode Build(ResourceType resourceType, IReadOnlyDictionary GetColumnAssignments(IReadOnlyDictionary columnsToSet, TableNode table) { - List assignments = new(); + List assignments = []; ColumnNode idColumn = table.GetIdColumn(table.Alias); foreach ((string columnName, object? columnValue) in columnsToSet) diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs index 550faba632..cd97a63d32 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs @@ -23,16 +23,16 @@ internal sealed class SelectStatementBuilder : QueryExpressionVisitor> _selectorsPerTable; + private readonly Dictionary> _selectorsPerTable = []; // Used to assign unique names when adding selectors, in case tables are joined that would result in duplicate column names. - private readonly HashSet _selectorNamesUsed; + private readonly HashSet _selectorNamesUsed = []; // Filter constraints. - private readonly List _whereFilters; + private readonly List _whereFilters = []; // Sorting on columns, or COUNT(*) in a sub-query. - private readonly List _orderByTerms; + private readonly List _orderByTerms = []; // Indicates whether to select a set of columns, the number of rows, or only the first (unnamed) column. private SelectShape _selectShape; @@ -45,10 +45,6 @@ public SelectStatementBuilder(IDataModelService dataModelService, ILoggerFactory private SelectStatementBuilder(QueryState queryState) { _queryState = queryState; - _selectorsPerTable = new Dictionary>(); - _selectorNamesUsed = new HashSet(); - _whereFilters = new List(); - _orderByTerms = new List(); } public SelectNode Build(QueryLayer queryLayer, SelectShape selectShape) @@ -105,7 +101,7 @@ private void TrackPrimaryTable(TableAccessorNode tableAccessor) throw new InvalidOperationException("A primary table already exists."); } - _queryState.RelatedTables.Add(tableAccessor, new Dictionary()); + _queryState.RelatedTables.Add(tableAccessor, []); _selectorsPerTable[tableAccessor] = _selectShape switch { @@ -146,8 +142,8 @@ private void ConvertQueryLayer(QueryLayer queryLayer, TableAccessorNode tableAcc private void ConvertFieldSelectors(FieldSelectors selectors, TableAccessorNode tableAccessor) { - HashSet selectedColumns = new(); - Dictionary nextLayers = new(); + HashSet selectedColumns = []; + Dictionary nextLayers = []; if (selectors.IsEmpty || selectors.ContainsReadOnlyAttribute || selectors.ContainsOnlyRelationships) { @@ -204,7 +200,7 @@ private void SetColumnSelectors(TableAccessorNode tableAccessor, IEnumerable PreserveColumnOrderEnsuringUniqueNames(IEnumerable columns) { - List selectors = new(); + List selectors = []; foreach (ColumnNode column in columns) { @@ -219,12 +215,12 @@ private List PreserveColumnOrderEnsuringUniqueNames(IEnumerable OrderColumnsWithIdAtFrontEnsuringUniqueNames(IEnumerable columns) { - Dictionary> selectorsPerTable = new(); + Dictionary> selectorsPerTable = []; foreach (ColumnNode column in columns.OrderBy(column => column.GetTableAliasIndex()).ThenBy(column => column.Name)) { string tableAlias = column.TableAlias ?? "!"; - selectorsPerTable.TryAdd(tableAlias, new List()); + selectorsPerTable.TryAdd(tableAlias, []); string uniqueName = GetUniqueSelectorName(column.Name); string? selectorAlias = uniqueName != column.Name ? uniqueName : null; @@ -354,7 +350,7 @@ private ComparisonNode CreateJoinCondition(TableSourceNode outerTableSource, Rel private void TrackRelatedTable(TableAccessorNode leftTableAccessor, RelationshipAttribute relationship, TableAccessorNode rightTableAccessor) { - _queryState.RelatedTables.Add(rightTableAccessor, new Dictionary()); + _queryState.RelatedTables.Add(rightTableAccessor, []); _selectorsPerTable[rightTableAccessor] = Array.Empty(); _queryState.RelatedTables[leftTableAccessor].Add(relationship, rightTableAccessor); @@ -362,7 +358,7 @@ private void TrackRelatedTable(TableAccessorNode leftTableAccessor, Relationship private IReadOnlyList MapSelectorsFromSubQuery(IEnumerable innerSelectorsToKeep, SelectNode select) { - List outerColumnsToKeep = new(); + List outerColumnsToKeep = []; foreach (SelectorNode innerSelector in innerSelectorsToKeep) { @@ -385,7 +381,7 @@ private IReadOnlyList MapSelectorsFromSubQuery(IEnumerable MapOrderingsFromSubQuery(IEnumerable innerOrderingsToKeep, SelectNode select) { - List orderingsToKeep = new(); + List orderingsToKeep = []; foreach (OrderByTermNode innerTerm in innerOrderingsToKeep) { @@ -470,7 +466,7 @@ private SelectNode ToSelect(bool isSubQuery, bool createAlias) private static Dictionary> AliasSelectorsToTableColumnNames( Dictionary> selectorsPerTable) { - Dictionary> aliasedSelectors = new(); + Dictionary> aliasedSelectors = []; foreach ((TableAccessorNode tableAccessor, IReadOnlyList tableSelectors) in selectorsPerTable) { @@ -754,11 +750,11 @@ private sealed class QueryState // Prevents importing a table multiple times and enables to reference a table imported by an inner/outer query. // In case of sub-queries, this may include temporary tables that won't survive in the final query. - public Dictionary> RelatedTables { get; } = new(); + public Dictionary> RelatedTables { get; } = []; // In case of sub-queries, we track old/new table aliases, so we can rewrite stale references afterwards. // This cannot be done in the moment itself, because references to tables are on method call stacks. - public Dictionary OldToNewTableAliasMap { get; } = new(); + public Dictionary OldToNewTableAliasMap { get; } = []; public QueryState(IDataModelService dataModelService, TableAliasGenerator tableAliasGenerator, ParameterGenerator parameterGenerator, ILoggerFactory loggerFactory) diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs index f8a3412b36..3e3d48eb10 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs @@ -11,23 +11,23 @@ namespace DapperExample.TranslationToSql.Builders; internal sealed class SqlQueryBuilder : SqlTreeNodeVisitor { private static readonly char[] SpecialCharactersInLikeDefault = - { + [ '\\', '%', '_' - }; + ]; private static readonly char[] SpecialCharactersInLikeSqlServer = - { + [ '\\', '%', '_', '[', ']' - }; + ]; private readonly DatabaseProvider _databaseProvider; - private readonly Dictionary _parametersByName = new(); + private readonly Dictionary _parametersByName = []; private int _indentDepth; private char[] SpecialCharactersInLike => diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs index ad4514dca6..62fc3b7e20 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs @@ -32,7 +32,7 @@ public UpdateNode Build(ResourceType resourceType, IReadOnlyDictionary GetColumnAssignments(IReadOnlyDictionary columnsToUpdate, TableNode table) { - List assignments = new(); + List assignments = []; foreach ((string columnName, object? columnValue) in columnsToUpdate) { diff --git a/src/Examples/DapperExample/TranslationToSql/DataModel/BaseDataModelService.cs b/src/Examples/DapperExample/TranslationToSql/DataModel/BaseDataModelService.cs index c964b6b3e7..589852ad80 100644 --- a/src/Examples/DapperExample/TranslationToSql/DataModel/BaseDataModelService.cs +++ b/src/Examples/DapperExample/TranslationToSql/DataModel/BaseDataModelService.cs @@ -16,7 +16,7 @@ namespace DapperExample.TranslationToSql.DataModel; /// public abstract class BaseDataModelService : IDataModelService { - private readonly Dictionary> _columnMappingsByType = new(); + private readonly Dictionary> _columnMappingsByType = []; protected IResourceGraph ResourceGraph { get; } @@ -54,7 +54,7 @@ private void ScanColumnMappings() private IReadOnlyDictionary ScanColumnMappings(ResourceType resourceType) { - Dictionary mappings = new(); + Dictionary mappings = []; foreach (PropertyInfo property in resourceType.ClrType.GetProperties()) { diff --git a/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs b/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs index 81f2778a14..0f030debdb 100644 --- a/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs +++ b/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs @@ -14,8 +14,8 @@ namespace DapperExample.TranslationToSql.DataModel; /// public sealed class FromEntitiesDataModelService : BaseDataModelService { - private readonly Dictionary _foreignKeysByRelationship = new(); - private readonly Dictionary _columnNullabilityPerAttribute = new(); + private readonly Dictionary _foreignKeysByRelationship = []; + private readonly Dictionary _columnNullabilityPerAttribute = []; private string? _connectionString; private DatabaseProvider? _databaseProvider; diff --git a/src/Examples/DapperExample/TranslationToSql/ParameterFormatter.cs b/src/Examples/DapperExample/TranslationToSql/ParameterFormatter.cs index 9d4053b5a4..5dc1591bca 100644 --- a/src/Examples/DapperExample/TranslationToSql/ParameterFormatter.cs +++ b/src/Examples/DapperExample/TranslationToSql/ParameterFormatter.cs @@ -8,8 +8,8 @@ namespace DapperExample.TranslationToSql; /// internal sealed class ParameterFormatter { - private static readonly HashSet NumericTypes = new[] - { + private static readonly HashSet NumericTypes = + [ typeof(bool), typeof(int), typeof(uint), @@ -21,7 +21,7 @@ internal sealed class ParameterFormatter typeof(float), typeof(double), typeof(decimal) - }.ToHashSet(); + ]; public string Format(string parameterName, object? parameterValue) { diff --git a/src/Examples/DapperExample/TranslationToSql/Transformations/ColumnSelectorUsageCollector.cs b/src/Examples/DapperExample/TranslationToSql/Transformations/ColumnSelectorUsageCollector.cs index ac447bcdc3..b5d560448c 100644 --- a/src/Examples/DapperExample/TranslationToSql/Transformations/ColumnSelectorUsageCollector.cs +++ b/src/Examples/DapperExample/TranslationToSql/Transformations/ColumnSelectorUsageCollector.cs @@ -8,7 +8,7 @@ namespace DapperExample.TranslationToSql.Transformations; /// internal sealed class ColumnSelectorUsageCollector : SqlTreeNodeVisitor { - private readonly HashSet _usedColumns = new(); + private readonly HashSet _usedColumns = []; private readonly ILogger _logger; public ISet UsedColumns => _usedColumns; diff --git a/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs b/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs index 00bb7b0756..03692baf2d 100644 --- a/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs +++ b/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs @@ -88,7 +88,7 @@ private Dictionary CopyTopStackElement() { if (_tablesInScopeStack.Count == 0) { - return new Dictionary(); + return []; } Dictionary topElement = _tablesInScopeStack.Peek(); @@ -98,7 +98,7 @@ private Dictionary CopyTopStackElement() private IReadOnlyDictionary> VisitSelectors( IReadOnlyDictionary> selectors, ColumnVisitMode mode) { - Dictionary> newSelectors = new(); + Dictionary> newSelectors = []; foreach ((TableAccessorNode tableAccessor, IReadOnlyList tableSelectors) in selectors) { diff --git a/src/Examples/DapperExample/TranslationToSql/Transformations/UnusedSelectorsRewriter.cs b/src/Examples/DapperExample/TranslationToSql/Transformations/UnusedSelectorsRewriter.cs index 36bb3f0c0a..7cffc8e29a 100644 --- a/src/Examples/DapperExample/TranslationToSql/Transformations/UnusedSelectorsRewriter.cs +++ b/src/Examples/DapperExample/TranslationToSql/Transformations/UnusedSelectorsRewriter.cs @@ -76,7 +76,7 @@ public override SqlTreeNode VisitSelect(SelectNode node, ISet usedCo private IReadOnlyDictionary> VisitSelectors(SelectNode select, ISet usedColumns) { - Dictionary> newSelectors = new(); + Dictionary> newSelectors = []; foreach ((TableAccessorNode tableAccessor, IReadOnlyList tableSelectors) in select.Selectors) { @@ -90,7 +90,7 @@ private IReadOnlyDictionary> Visi private List VisitTableSelectors(IEnumerable selectors, ISet usedColumns) { - List newTableSelectors = new(); + List newTableSelectors = []; foreach (SelectorNode selector in selectors) { diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectNode.cs index 1b7b96c3f9..0fc42b1ba0 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectNode.cs @@ -13,7 +13,7 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// internal sealed class SelectNode : TableSourceNode { - private readonly List _columns = new(); + private readonly List _columns = []; public IReadOnlyDictionary> Selectors { get; } public WhereNode? Where { get; } diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableNode.cs index 03d8353eb5..31977f1546 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableNode.cs @@ -17,7 +17,7 @@ internal sealed class TableNode : TableSourceNode { private readonly ResourceType _resourceType; private readonly IReadOnlyDictionary _columnMappings; - private readonly List _columns = new(); + private readonly List _columns = []; public string Name => _resourceType.ClrType.Name.Pluralize(); diff --git a/src/Examples/JsonApiDotNetCoreExample/Controllers/NonJsonApiController.cs b/src/Examples/JsonApiDotNetCoreExample/Controllers/NonJsonApiController.cs index be5e01b7a9..3c89ac3bcf 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Controllers/NonJsonApiController.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Controllers/NonJsonApiController.cs @@ -8,10 +8,7 @@ public sealed class NonJsonApiController : ControllerBase [HttpGet] public IActionResult Get() { - string[] result = - { - "Welcome!" - }; + string[] result = ["Welcome!"]; return Ok(result); } diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs b/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs index 59247532b9..778119c6be 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs @@ -4,7 +4,7 @@ internal abstract class RotatingList { public static RotatingList Create(int count, Func createElement) { - List elements = new(); + List elements = []; for (int index = 0; index < count; index++) { diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs index 85b0928412..31aee37585 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs @@ -37,11 +37,10 @@ public override SortExpression OnApplySort(SortExpression? existingSort) private SortExpression GetDefaultSortOrder() { - return CreateSortExpressionFromLambda(new PropertySortOrder - { + return CreateSortExpressionFromLambda([ (todoItem => todoItem.Priority, ListSortDirection.Ascending), (todoItem => todoItem.LastModifiedAt, ListSortDirection.Descending) - }); + ]); } public override Task OnWritingAsync(TodoItem resource, WriteOperationKind writeOperation, CancellationToken cancellationToken) diff --git a/src/Examples/NoEntityFrameworkExample/Data/Database.cs b/src/Examples/NoEntityFrameworkExample/Data/Database.cs index eee64653ee..5d0c00eb17 100644 --- a/src/Examples/NoEntityFrameworkExample/Data/Database.cs +++ b/src/Examples/NoEntityFrameworkExample/Data/Database.cs @@ -48,9 +48,9 @@ static Database() Name = "Business" }; - TodoItems = new List - { - new() + TodoItems = + [ + new TodoItem { Id = ++todoItemIndex, Description = "Make homework", @@ -63,7 +63,7 @@ static Database() personalTag } }, - new() + new TodoItem { Id = ++todoItemIndex, Description = "Book vacation", @@ -75,7 +75,7 @@ static Database() personalTag } }, - new() + new TodoItem { Id = ++todoItemIndex, Description = "Cook dinner", @@ -89,7 +89,7 @@ static Database() personalTag } }, - new() + new TodoItem { Id = ++todoItemIndex, Description = "Check emails", @@ -102,20 +102,20 @@ static Database() businessTag } } - }; + ]; - Tags = new List - { + Tags = + [ personalTag, familyTag, businessTag - }; + ]; - People = new List - { + People = + [ john, jane - }; + ]; foreach (Tag tag in Tags) { diff --git a/src/Examples/NoEntityFrameworkExample/NullSafeExpressionRewriter.cs b/src/Examples/NoEntityFrameworkExample/NullSafeExpressionRewriter.cs index 35b2a29e9e..67b04d1d3d 100644 --- a/src/Examples/NoEntityFrameworkExample/NullSafeExpressionRewriter.cs +++ b/src/Examples/NoEntityFrameworkExample/NullSafeExpressionRewriter.cs @@ -20,14 +20,14 @@ public sealed class NullSafeExpressionRewriter : ExpressionVisitor private static readonly ConstantExpression Int32MinValueConstant = Expression.Constant(int.MinValue, typeof(int)); private static readonly ExpressionType[] ComparisonExpressionTypes = - { + [ ExpressionType.LessThan, ExpressionType.LessThanOrEqual, ExpressionType.GreaterThan, ExpressionType.GreaterThanOrEqual, ExpressionType.Equal // ExpressionType.NotEqual is excluded because WhereClauseBuilder never produces that. - }; + ]; private readonly Stack _callStack = new(); diff --git a/src/JsonApiDotNetCore.Annotations/Configuration/ResourceType.cs b/src/JsonApiDotNetCore.Annotations/Configuration/ResourceType.cs index 29bd5559b1..47542def56 100644 --- a/src/JsonApiDotNetCore.Annotations/Configuration/ResourceType.cs +++ b/src/JsonApiDotNetCore.Annotations/Configuration/ResourceType.cs @@ -9,8 +9,8 @@ namespace JsonApiDotNetCore.Configuration; [PublicAPI] public sealed class ResourceType { - private readonly Dictionary _fieldsByPublicName = new(); - private readonly Dictionary _fieldsByPropertyName = new(); + private readonly Dictionary _fieldsByPublicName = []; + private readonly Dictionary _fieldsByPropertyName = []; private readonly Lazy> _lazyAllConcreteDerivedTypes; /// @@ -273,7 +273,7 @@ private static IReadOnlySet GetAttributesInTypeOrDerived(Resource // Hiding base members using the 'new' keyword instead of 'override' (effectively breaking inheritance) is currently not supported. // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords - HashSet attributesInDerivedTypes = new(); + HashSet attributesInDerivedTypes = []; foreach (AttrAttribute attributeInDerivedType in resourceType.DirectlyDerivedTypes .Select(derivedType => GetAttributesInTypeOrDerived(derivedType, publicName)).SelectMany(attributesInDerivedType => attributesInDerivedType)) @@ -300,7 +300,7 @@ private static IReadOnlySet GetRelationshipsInTypeOrDeriv // Hiding base members using the 'new' keyword instead of 'override' (effectively breaking inheritance) is currently not supported. // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords - HashSet relationshipsInDerivedTypes = new(); + HashSet relationshipsInDerivedTypes = []; foreach (RelationshipAttribute relationshipInDerivedType in resourceType.DirectlyDerivedTypes .Select(derivedType => GetRelationshipsInTypeOrDerived(derivedType, publicName)) diff --git a/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs b/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs index b7fd934fbe..2e8f9acfc6 100644 --- a/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs +++ b/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs @@ -11,25 +11,16 @@ public static IEnumerable AsEnumerable(this T element) public static T[] AsArray(this T element) { - return new[] - { - element - }; + return [element]; } public static List AsList(this T element) { - return new List - { - element - }; + return [element]; } public static HashSet AsHashSet(this T element) { - return new HashSet - { - element - }; + return [element]; } } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceDescriptorAssemblyCache.cs b/src/JsonApiDotNetCore/Configuration/ResourceDescriptorAssemblyCache.cs index 0e9f5d753f..a220d96e01 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceDescriptorAssemblyCache.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceDescriptorAssemblyCache.cs @@ -8,7 +8,7 @@ namespace JsonApiDotNetCore.Configuration; internal sealed class ResourceDescriptorAssemblyCache { private readonly TypeLocator _typeLocator = new(); - private readonly Dictionary?> _resourceDescriptorsPerAssembly = new(); + private readonly Dictionary?> _resourceDescriptorsPerAssembly = []; public void RegisterAssembly(Assembly assembly) { diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index 884b8ccd79..e763ec2ae0 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -13,8 +13,8 @@ public sealed class ResourceGraph : IResourceGraph private static readonly Type? ProxyTargetAccessorType = Type.GetType("Castle.DynamicProxy.IProxyTargetAccessor, Castle.Core"); private readonly IReadOnlySet _resourceTypeSet; - private readonly Dictionary _resourceTypesByClrType = new(); - private readonly Dictionary _resourceTypesByPublicName = new(); + private readonly Dictionary _resourceTypesByClrType = []; + private readonly Dictionary _resourceTypesByPublicName = []; public ResourceGraph(IReadOnlySet resourceTypeSet) { diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index 4ea0cb30e6..b0ebd8bb60 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -17,7 +17,7 @@ public class ResourceGraphBuilder { private readonly IJsonApiOptions _options; private readonly ILogger _logger; - private readonly Dictionary _resourceTypesByClrType = new(); + private readonly Dictionary _resourceTypesByClrType = []; private readonly TypeLocator _typeLocator = new(); public ResourceGraphBuilder(IJsonApiOptions options, ILoggerFactory loggerFactory) @@ -34,7 +34,7 @@ public ResourceGraphBuilder(IJsonApiOptions options, ILoggerFactory loggerFactor /// public IResourceGraph Build() { - HashSet resourceTypes = _resourceTypesByClrType.Values.ToHashSet(); + HashSet resourceTypes = [.. _resourceTypesByClrType.Values]; if (!resourceTypes.Any()) { @@ -81,7 +81,7 @@ private static void SetRelationshipTypes(ResourceGraph resourceGraph) private static void SetDirectlyDerivedTypes(ResourceGraph resourceGraph) { - Dictionary> directlyDerivedTypesPerBaseType = new(); + Dictionary> directlyDerivedTypesPerBaseType = []; foreach (ResourceType resourceType in resourceGraph.GetResourceTypes()) { @@ -93,7 +93,7 @@ private static void SetDirectlyDerivedTypes(ResourceGraph resourceGraph) if (!directlyDerivedTypesPerBaseType.ContainsKey(baseType)) { - directlyDerivedTypesPerBaseType[baseType] = new HashSet(); + directlyDerivedTypesPerBaseType[baseType] = []; } directlyDerivedTypesPerBaseType[baseType].Add(resourceType); diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index d17ddfa1ba..5d2ac7190b 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -16,8 +16,8 @@ namespace JsonApiDotNetCore.Configuration; [PublicAPI] public sealed class ServiceDiscoveryFacade { - internal static readonly HashSet ServiceUnboundInterfaces = new() - { + internal static readonly HashSet ServiceUnboundInterfaces = + [ typeof(IResourceService<,>), typeof(IResourceCommandService<,>), typeof(IResourceQueryService<,>), @@ -31,19 +31,16 @@ public sealed class ServiceDiscoveryFacade typeof(ISetRelationshipService<,>), typeof(IDeleteService<,>), typeof(IRemoveFromRelationshipService<,>) - }; + ]; - internal static readonly HashSet RepositoryUnboundInterfaces = new() - { + internal static readonly HashSet RepositoryUnboundInterfaces = + [ typeof(IResourceRepository<,>), typeof(IResourceWriteRepository<,>), typeof(IResourceReadRepository<,>) - }; + ]; - internal static readonly HashSet ResourceDefinitionUnboundInterfaces = new() - { - typeof(IResourceDefinition<,>) - }; + internal static readonly HashSet ResourceDefinitionUnboundInterfaces = [typeof(IResourceDefinition<,>)]; private readonly ILogger _logger; private readonly IServiceCollection _services; diff --git a/src/JsonApiDotNetCore/Diagnostics/CascadingCodeTimer.cs b/src/JsonApiDotNetCore/Diagnostics/CascadingCodeTimer.cs index 4b4d82b62b..8fc75dad4e 100644 --- a/src/JsonApiDotNetCore/Diagnostics/CascadingCodeTimer.cs +++ b/src/JsonApiDotNetCore/Diagnostics/CascadingCodeTimer.cs @@ -12,7 +12,7 @@ internal sealed class CascadingCodeTimer : ICodeTimer { private readonly Stopwatch _stopwatch = new(); private readonly Stack _activeScopeStack = new(); - private readonly List _completedScopes = new(); + private readonly List _completedScopes = []; static CascadingCodeTimer() { diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index 50cb511b14..b5805e15dc 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -30,7 +30,7 @@ private static IEnumerable FromModelStateDictionary(IReadOnlyDictio ArgumentGuard.NotNull(modelType); ArgumentGuard.NotNull(resourceGraph); - List errorObjects = new(); + List errorObjects = []; foreach ((ModelStateEntry entry, string? sourcePointer) in ResolveSourcePointers(modelState, modelType, resourceGraph, getCollectionElementTypeCallback)) diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index a6ef712adf..c2df736e96 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -32,9 +32,9 @@ public sealed class JsonApiRoutingConvention : IJsonApiRoutingConvention private readonly IJsonApiOptions _options; private readonly IResourceGraph _resourceGraph; private readonly ILogger _logger; - private readonly Dictionary _registeredControllerNameByTemplate = new(); - private readonly Dictionary _resourceTypePerControllerTypeMap = new(); - private readonly Dictionary _controllerPerResourceTypeMap = new(); + private readonly Dictionary _registeredControllerNameByTemplate = []; + private readonly Dictionary _resourceTypePerControllerTypeMap = []; + private readonly Dictionary _controllerPerResourceTypeMap = []; public JsonApiRoutingConvention(IJsonApiOptions options, IResourceGraph resourceGraph, ILogger logger) { diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs index 8b2034a374..f88cb60a86 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs @@ -46,7 +46,7 @@ private sealed class IncludeToChainsConverter : QueryExpressionVisitor _parentRelationshipStack = new(); - public List Chains { get; } = new(); + public List Chains { get; } = []; public override object? VisitInclude(IncludeExpression expression, object? argument) { diff --git a/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs b/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs index 1af9656154..cbd6ee4b21 100644 --- a/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs +++ b/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs @@ -14,8 +14,8 @@ namespace JsonApiDotNetCore.Queries.Parsing; [PublicAPI] public class FilterParser : QueryExpressionParser, IFilterParser { - private static readonly HashSet FilterKeywords = new(new[] - { + private static readonly HashSet FilterKeywords = + [ Keywords.Not, Keywords.And, Keywords.Or, @@ -31,7 +31,7 @@ public class FilterParser : QueryExpressionParser, IFilterParser Keywords.Count, Keywords.Has, Keywords.IsType - }); + ]; private readonly IResourceFactory _resourceFactory; private readonly Stack _resourceTypeStack = new(); diff --git a/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs b/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs index 27fffb9467..79f286da91 100644 --- a/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs @@ -111,8 +111,8 @@ private ICollection ParseRelationshipName(string source, IColle private static ICollection LookupRelationshipName(string relationshipName, ICollection parents, string source, int position) { - List children = new(); - HashSet relationshipsFound = new(); + List children = []; + HashSet relationshipsFound = []; foreach (IncludeTreeNode parent in parents) { diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs index 3b0793f774..81a0db533e 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs @@ -22,7 +22,7 @@ public virtual Expression ApplyInclude(IncludeExpression include, QueryClauseBui public override Expression VisitInclude(IncludeExpression expression, QueryClauseBuilderContext context) { // De-duplicate chains coming from derived relationships. - HashSet propertyPaths = new(); + HashSet propertyPaths = []; ApplyEagerLoads(context.ResourceType.EagerLoads, null, propertyPaths); diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/LambdaScopeFactory.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/LambdaScopeFactory.cs index cf8a30e1db..257906b69f 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/LambdaScopeFactory.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/LambdaScopeFactory.cs @@ -10,7 +10,7 @@ namespace JsonApiDotNetCore.Queries.QueryableBuilding; [PublicAPI] public sealed class LambdaScopeFactory { - private readonly HashSet _namesInScope = new(); + private readonly HashSet _namesInScope = []; /// /// Finds the next unique lambda parameter name. Dispose the returned scope to release the claimed name, so it can be reused. diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchState.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchState.cs index 90255191d7..a0aa58e377 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchState.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchState.cs @@ -245,7 +245,7 @@ public IReadOnlyList GetAllFieldsMatched() current = current._parentMatch; } - List fields = new(); + List fields = []; while (matchStack.Count > 0) { diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchTraceScope.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchTraceScope.cs index 63c6c67876..653c029e46 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchTraceScope.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/MatchTraceScope.cs @@ -69,7 +69,7 @@ public void LogMatchResult(MatchState resultState) } else { - List chain = new(resultState.FieldsMatched.Select(attribute => attribute.PublicName)); + List chain = [..resultState.FieldsMatched.Select(attribute => attribute.PublicName)]; if (resultState.FieldsRemaining != null) { diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternMatcher.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternMatcher.cs index 8172bdaa95..049aac2b94 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternMatcher.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternMatcher.cs @@ -186,7 +186,7 @@ private MatchState MatchField(MatchState state) /// private HashSet LookupFields(ResourceType? resourceType, string publicName) { - HashSet fields = new(); + HashSet fields = []; if (resourceType != null) { diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternParser.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternParser.cs index a00ec26846..cc0fa0a69e 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternParser.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternParser.cs @@ -28,12 +28,12 @@ internal sealed class PatternParser [Token.Field] = FieldTypes.Field }; - private static readonly HashSet QuantifierTokens = new(new[] - { + private static readonly HashSet QuantifierTokens = + [ Token.QuestionMark, Token.Plus, Token.Asterisk - }); + ]; private string _source = null!; private Queue _tokenQueue = null!; diff --git a/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs index fe8d35bdca..3c8d16a3f0 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs @@ -22,7 +22,7 @@ public class FilterQueryStringParameterReader : QueryStringParameterReader, IFil private readonly IQueryStringParameterScopeParser _scopeParser; private readonly IFilterParser _filterParser; private readonly ImmutableArray.Builder _filtersInGlobalScope = ImmutableArray.CreateBuilder(); - private readonly Dictionary.Builder> _filtersPerScope = new(); + private readonly Dictionary.Builder> _filtersPerScope = []; public bool AllowEmptyValue => false; diff --git a/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs index 93e180275a..3364217efb 100644 --- a/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs @@ -165,7 +165,7 @@ public virtual IReadOnlyCollection GetConstraints() private sealed class PaginationState { private readonly MutablePaginationEntry _globalScope = new(); - private readonly Dictionary _nestedScopes = new(); + private readonly Dictionary _nestedScopes = []; public MutablePaginationEntry ResolveEntryInScope(ResourceFieldChainExpression? scope) { diff --git a/src/JsonApiDotNetCore/QueryStrings/ResourceDefinitionQueryableParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/ResourceDefinitionQueryableParameterReader.cs index c881f04dc4..3d844e4b48 100644 --- a/src/JsonApiDotNetCore/QueryStrings/ResourceDefinitionQueryableParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/ResourceDefinitionQueryableParameterReader.cs @@ -15,7 +15,7 @@ public class ResourceDefinitionQueryableParameterReader : IResourceDefinitionQue { private readonly IJsonApiRequest _request; private readonly IResourceDefinitionAccessor _resourceDefinitionAccessor; - private readonly List _constraints = new(); + private readonly List _constraints = []; public bool AllowEmptyValue => false; diff --git a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs index 542d69b8ec..4362f95ed5 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs @@ -17,7 +17,7 @@ public class SortQueryStringParameterReader : QueryStringParameterReader, ISortQ { private readonly IQueryStringParameterScopeParser _scopeParser; private readonly ISortParser _sortParser; - private readonly List _constraints = new(); + private readonly List _constraints = []; public bool AllowEmptyValue => false; diff --git a/src/JsonApiDotNetCore/Resources/TargetedFields.cs b/src/JsonApiDotNetCore/Resources/TargetedFields.cs index cb3a0874e0..2e841873b2 100644 --- a/src/JsonApiDotNetCore/Resources/TargetedFields.cs +++ b/src/JsonApiDotNetCore/Resources/TargetedFields.cs @@ -10,8 +10,8 @@ public sealed class TargetedFields : ITargetedFields IReadOnlySet ITargetedFields.Attributes => Attributes; IReadOnlySet ITargetedFields.Relationships => Relationships; - public HashSet Attributes { get; } = new(); - public HashSet Relationships { get; } = new(); + public HashSet Attributes { get; } = []; + public HashSet Relationships { get; } = []; /// public void CopyFrom(ITargetedFields other) diff --git a/src/JsonApiDotNetCore/Serialization/Response/MetaBuilder.cs b/src/JsonApiDotNetCore/Serialization/Response/MetaBuilder.cs index 3d1eb5dd26..a5e647c853 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/MetaBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/MetaBuilder.cs @@ -12,7 +12,7 @@ public sealed class MetaBuilder : IMetaBuilder private readonly IJsonApiOptions _options; private readonly IResponseMeta _responseMeta; - private Dictionary _meta = new(); + private Dictionary _meta = []; public MetaBuilder(IPaginationContext paginationContext, IJsonApiOptions options, IResponseMeta responseMeta) { diff --git a/src/JsonApiDotNetCore/Serialization/Response/ResourceObjectTreeNode.cs b/src/JsonApiDotNetCore/Serialization/Response/ResourceObjectTreeNode.cs index 901c1d94fc..ab50d6f674 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/ResourceObjectTreeNode.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/ResourceObjectTreeNode.cs @@ -55,7 +55,7 @@ public void AttachDirectChild(ResourceObjectTreeNode treeNode) { ArgumentGuard.NotNull(treeNode); - _directChildren ??= new List(); + _directChildren ??= []; _directChildren.Add(treeNode); } @@ -63,11 +63,11 @@ public void EnsureHasRelationship(RelationshipAttribute relationship) { ArgumentGuard.NotNull(relationship); - _childrenByRelationship ??= new Dictionary>(); + _childrenByRelationship ??= []; if (!_childrenByRelationship.ContainsKey(relationship)) { - _childrenByRelationship[relationship] = new HashSet(); + _childrenByRelationship[relationship] = []; } } @@ -182,7 +182,7 @@ public IList GetResponseIncluded() } ISet primaryResourceObjectSet = GetDirectChildren().Select(node => node.ResourceObject).ToHashSet(ResourceObjectComparer.Instance); - List includes = new(); + List includes = []; foreach (ResourceObject include in visited.Select(node => node.ResourceObject)) { diff --git a/test/DapperTests/UnitTests/SqlTreeNodeVisitorTests.cs b/test/DapperTests/UnitTests/SqlTreeNodeVisitorTests.cs index 394cdecc5b..53ef375e0a 100644 --- a/test/DapperTests/UnitTests/SqlTreeNodeVisitorTests.cs +++ b/test/DapperTests/UnitTests/SqlTreeNodeVisitorTests.cs @@ -18,10 +18,10 @@ public void Visitor_methods_call_default_visit() .Where(method => method.Name.StartsWith("Visit", StringComparison.Ordinal) && method.Name != "Visit").ToArray(); object?[] parameters = - { + [ null, null - }; + ]; // Act foreach (MethodInfo method in visitMethods) diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs index 78c4213e93..e4f16dbb1f 100644 --- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs +++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs @@ -15,7 +15,7 @@ namespace DiscoveryTests; public sealed class ServiceDiscoveryFacadeTests { - private readonly ServiceCollection _services = new(); + private readonly ServiceCollection _services = []; public ServiceDiscoveryFacadeTests() { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 909467ad18..293b4b495c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -910,10 +910,10 @@ public async Task Cannot_add_for_unknown_IDs_in_data() RecordCompany existingCompany = _fakers.RecordCompany.Generate(); string[] trackIds = - { + [ Unknown.StringId.For(), Unknown.StringId.AltFor() - }; + ]; await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index 71b4a1bf09..7e9654ab30 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -870,10 +870,10 @@ public async Task Cannot_remove_for_unknown_IDs_in_data() RecordCompany existingCompany = _fakers.RecordCompany.Generate(); string[] trackIds = - { + [ Unknown.StringId.For(), Unknown.StringId.AltFor() - }; + ]; await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index f36144ce70..bcedf104bf 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -963,10 +963,10 @@ public async Task Cannot_replace_for_unknown_IDs_in_data() RecordCompany existingCompany = _fakers.RecordCompany.Generate(); string[] trackIds = - { + [ Unknown.StringId.For(), Unknown.StringId.AltFor() - }; + ]; await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index 0d8c5e1d80..10da541794 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -668,10 +668,10 @@ public async Task Cannot_replace_for_unknown_IDs_in_relationship_data() RecordCompany existingCompany = _fakers.RecordCompany.Generate(); string[] trackIds = - { + [ Unknown.StringId.For(), Unknown.StringId.AltFor() - }; + ]; await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/AuthScopeSet.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/AuthScopeSet.cs index 3a99d3c015..547c008afa 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/AuthScopeSet.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/AuthScopeSet.cs @@ -14,7 +14,7 @@ internal sealed class AuthScopeSet public const string ScopesHeaderName = "X-Auth-Scopes"; - private readonly Dictionary _scopes = new(); + private readonly Dictionary _scopes = []; public static AuthScopeSet GetRequestedScopes(IHeaderDictionary requestHeaders) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs index 1e95efa717..aa12e5ceb3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs @@ -39,7 +39,7 @@ private static string FromHexString(string hexString) bytes.Add(bt); } - char[] chars = Encoding.ASCII.GetChars(bytes.ToArray()); + char[] chars = Encoding.ASCII.GetChars([.. bytes]); return new string(chars); } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs index 9365ff08a0..d1772330ca 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs @@ -11,7 +11,7 @@ public abstract class MessagingGroupDefinition : HitCountingResourceDefinition _userSet; private readonly DbSet _groupSet; - private readonly List _pendingMessages = new(); + private readonly List _pendingMessages = []; private string? _beforeGroupName; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs index 499c572b88..cb8e84e8ba 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs @@ -10,7 +10,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices; public abstract class MessagingUserDefinition : HitCountingResourceDefinition { private readonly DbSet _userSet; - private readonly List _pendingMessages = new(); + private readonly List _pendingMessages = []; private string? _beforeLoginName; private string? _beforeDisplayName; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiController.cs index 170a8eb194..59a17ab95a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiController.cs @@ -8,11 +8,7 @@ public sealed class NonJsonApiController : ControllerBase [HttpGet] public IActionResult Get() { - string[] result = - { - "Welcome!" - }; - + string[] result = ["Welcome!"]; return Ok(result); } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs index 0668d32644..76087dc31f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs @@ -10,8 +10,8 @@ internal sealed class SumFilterParser : FilterParser { private static readonly FieldChainPattern SingleToManyRelationshipChain = FieldChainPattern.Parse("M"); - private static readonly HashSet NumericTypes = new(new[] - { + private static readonly HashSet NumericTypes = + [ typeof(sbyte), typeof(byte), typeof(short), @@ -23,7 +23,7 @@ internal sealed class SumFilterParser : FilterParser typeof(float), typeof(double), typeof(decimal) - }); + ]; public SumFilterParser(IResourceFactory resourceFactory) : base(resourceFactory) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs index e2ef670d71..0c6d016081 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.SparseFieldSets; public sealed class ResourceCaptureStore { - internal List Resources { get; } = new(); + internal List Resources { get; } = []; internal void Add(IEnumerable resources) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs index 55b5b53918..6146e04367 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs @@ -26,11 +26,10 @@ public override SortExpression OnApplySort(SortExpression? existingSort) private SortExpression GetDefaultSortOrder() { - return CreateSortExpressionFromLambda(new PropertySortOrder - { + return CreateSortExpressionFromLambda([ (star => star.SolarMass, ListSortDirection.Descending), (star => star.SolarRadius, ListSortDirection.Descending) - }); + ]); } public override PaginationExpression OnApplyPagination(PaginationExpression? existingPagination) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/WheelSortDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/WheelSortDefinition.cs index e66e05bc64..7785622e9e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/WheelSortDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/WheelSortDefinition.cs @@ -61,12 +61,11 @@ private SortExpression CreateSortFromExpressionSyntax() private SortExpression CreateSortFromLambdaSyntax() { - return CreateSortExpressionFromLambda(new PropertySortOrder - { + return CreateSortExpressionFromLambda([ (wheel => (wheel as ChromeWheel)!.PaintColor, ListSortDirection.Ascending), (wheel => ((CarbonWheel)wheel).HasTube, ListSortDirection.Descending), (wheel => ((GasolineEngine)((Car)wheel.Vehicle!).Engine).Cylinders.Count, ListSortDirection.Ascending), (wheel => wheel.Id, ListSortDirection.Ascending) - }); + ]); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationFakers.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationFakers.cs index be5f72b3f8..ca3b246f3f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationFakers.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationFakers.cs @@ -9,12 +9,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Serialization; internal sealed class SerializationFakers : FakerContainer { private static readonly TimeSpan[] MeetingDurations = - { + [ TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(45), TimeSpan.FromMinutes(60) - }; + ]; private readonly Lazy> _lazyMeetingFaker = new(() => new Faker() .UseSeed(GetFakerSeed()) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs index b7f55bee8e..bb2df33c33 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs @@ -589,7 +589,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - string[] meetingIds = meeting.Attendees.Select(attendee => attendee.StringId!).OrderBy(id => id).ToArray(); + string[] meetingIds = [.. meeting.Attendees.Select(attendee => attendee.StringId!).OrderBy(id => id)]; responseDocument.Should().BeJson(@"{ ""links"": { diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Queries/TestableQueryExpressionRewriter.cs b/test/JsonApiDotNetCoreTests/UnitTests/Queries/TestableQueryExpressionRewriter.cs index b30c4c6158..ec4da0702a 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Queries/TestableQueryExpressionRewriter.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Queries/TestableQueryExpressionRewriter.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreTests.UnitTests.Queries; internal sealed class TestableQueryExpressionRewriter : QueryExpressionRewriter { - public List ExpressionsVisited { get; } = new(); + public List ExpressionsVisited { get; } = []; public override QueryExpression DefaultVisit(QueryExpression expression, object? argument) { diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs index 8b919a87cc..337940b75c 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs @@ -24,24 +24,23 @@ public void Can_convert_chain_of_ToOne_relationships_ending_in_attribute() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - SortExpression expression = resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { + SortExpression expression = resourceDefinition.GetSortExpressionFromLambda([ (file => file.Content, ListSortDirection.Descending), (file => file.Name, ListSortDirection.Ascending), (file => file.Length, ListSortDirection.Ascending), (file => file.Parent.Name, ListSortDirection.Ascending), (file => file.Parent.Parent.Name, ListSortDirection.Ascending) - }); + ]); // Assert string[] expected = - { + [ "-fileEntries:content", "fileEntries:name", "fileEntries:length", "fileSystemEntries:parent.fileSystemEntries:name", "fileSystemEntries:parent.fileSystemEntries:parent.fileSystemEntries:name" - }; + ]; expression.ToFullString().Should().Be(string.Join(',', expected)); } @@ -55,25 +54,24 @@ public void Can_convert_chain_of_ToOne_relationships_ending_in_count_of_ToMany_r var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - SortExpression expression = resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { + SortExpression expression = resourceDefinition.GetSortExpressionFromLambda([ (directory => directory.Subdirectories.Count, ListSortDirection.Ascending), // ReSharper disable once UseCollectionCountProperty (directory => directory.Files.Count(), ListSortDirection.Descending), (directory => directory.Children.Count, ListSortDirection.Ascending), (directory => directory.Parent.Children.Count, ListSortDirection.Ascending), (directory => directory.Parent.Parent.Children.Count, ListSortDirection.Ascending) - }); + ]); // Assert string[] expected = - { + [ "count(directoryEntries:subdirectories)", "-count(directoryEntries:files)", "count(fileSystemEntries:children)", "count(fileSystemEntries:parent.fileSystemEntries:children)", "count(fileSystemEntries:parent.fileSystemEntries:parent.fileSystemEntries:children)" - }; + ]; expression.ToFullString().Should().Be(string.Join(',', expected)); } @@ -87,24 +85,23 @@ public void Can_convert_chain_with_conversion_to_derived_types() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - SortExpression expression = resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { + SortExpression expression = resourceDefinition.GetSortExpressionFromLambda([ (entry => ((FileEntry)entry).Content, ListSortDirection.Ascending), (entry => (entry.Parent as FileEntry)!.Content, ListSortDirection.Ascending), (entry => ((DirectoryEntry)entry).Subdirectories.Count, ListSortDirection.Ascending), (entry => ((DirectoryEntry)((FileEntry)entry).Parent).Files.Count, ListSortDirection.Ascending), (entry => ((DirectoryEntry)(FileSystemEntry)(FileEntry)entry).Name, ListSortDirection.Descending) - }); + ]); // Assert string[] expected = - { + [ "fileEntries:content", "fileSystemEntries:parent.fileEntries:content", "count(directoryEntries:subdirectories)", "count(fileSystemEntries:parent.directoryEntries:files)", "-directoryEntries:name" - }; + ]; expression.ToFullString().Should().Be(string.Join(',', expected)); } @@ -118,10 +115,7 @@ public void Cannot_convert_unexposed_attribute() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (file => file.IsCompressed, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(file => file.IsCompressed, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -143,10 +137,7 @@ public void Cannot_convert_unexposed_ToMany_relationship() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (file => file.Content.Length, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(file => file.Content.Length, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -168,10 +159,7 @@ public void Cannot_convert_unexposed_ToOne_relationship() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (file => file.ParentDirectory!.Name, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(file => file.ParentDirectory!.Name, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -193,10 +181,7 @@ public void Cannot_convert_unexposed_resource_type() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (entry => ((FileEntry)entry).Content, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(entry => ((FileEntry)entry).Content, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -218,10 +203,7 @@ public void Cannot_convert_count_with_predicate() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (directory => directory.Files.Count(_ => true), ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(directory => directory.Files.Count(_ => true), ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -243,10 +225,7 @@ public void Cannot_convert_null_selector() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (_ => null, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(_ => null, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -267,10 +246,7 @@ public void Cannot_convert_self_selector() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (entry => entry, ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(entry => entry, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -291,10 +267,8 @@ public void Cannot_convert_conditional_operator() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (file => file.IsCompressed ? file.Content : file.Length, ListSortDirection.Ascending) - }); + Action action = () => + resourceDefinition.GetSortExpressionFromLambda([(file => file.IsCompressed ? file.Content : file.Length, ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -315,10 +289,7 @@ public void Cannot_convert_concatenation_operator() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { - (file => $"{file.Name}:{file.Content}", ListSortDirection.Ascending) - }); + Action action = () => resourceDefinition.GetSortExpressionFromLambda([(file => $"{file.Name}:{file.Content}", ListSortDirection.Ascending)]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; @@ -339,14 +310,13 @@ public void Cannot_convert_projection_into_anonymous_type() var resourceDefinition = new WrapperResourceDefinition(resourceGraph); // Act - Action action = () => resourceDefinition.GetSortExpressionFromLambda(new JsonApiResourceDefinition.PropertySortOrder - { + Action action = () => resourceDefinition.GetSortExpressionFromLambda([ (file => new { file.Length, file.Content }, ListSortDirection.Ascending) - }); + ]); // Assert JsonApiException exception = action.Should().ThrowExactly().Which; diff --git a/test/SourceGeneratorTests/CompilationBuilder.cs b/test/SourceGeneratorTests/CompilationBuilder.cs index b4830e25f3..90c0d6e396 100644 --- a/test/SourceGeneratorTests/CompilationBuilder.cs +++ b/test/SourceGeneratorTests/CompilationBuilder.cs @@ -17,8 +17,8 @@ internal sealed class CompilationBuilder ["CS1701"] = ReportDiagnostic.Suppress }); - private readonly HashSet _syntaxTrees = new(); - private readonly HashSet _references = new(); + private readonly HashSet _syntaxTrees = []; + private readonly HashSet _references = []; public Compilation Build() { diff --git a/test/SourceGeneratorTests/SourceCodeBuilder.cs b/test/SourceGeneratorTests/SourceCodeBuilder.cs index e734604e31..05bdc031a4 100644 --- a/test/SourceGeneratorTests/SourceCodeBuilder.cs +++ b/test/SourceGeneratorTests/SourceCodeBuilder.cs @@ -4,7 +4,7 @@ namespace SourceGeneratorTests; internal sealed class SourceCodeBuilder { - private readonly HashSet _namespaceImports = new(); + private readonly HashSet _namespaceImports = []; private string? _namespace; private string? _code; diff --git a/test/TestBuildingBlocks/FakeLoggerFactory.cs b/test/TestBuildingBlocks/FakeLoggerFactory.cs index c946ede4ed..9d8e74c5b3 100644 --- a/test/TestBuildingBlocks/FakeLoggerFactory.cs +++ b/test/TestBuildingBlocks/FakeLoggerFactory.cs @@ -31,7 +31,7 @@ public sealed class FakeLogger : ILogger private readonly LogLevel _minimumLevel; private readonly object _lockObject = new(); - private readonly List _messages = new(); + private readonly List _messages = []; public FakeLogger(LogLevel minimumLevel) { diff --git a/test/TestBuildingBlocks/IgnoreLineEndingsComparer.cs b/test/TestBuildingBlocks/IgnoreLineEndingsComparer.cs index 2d6886e00c..bb043bd0c5 100644 --- a/test/TestBuildingBlocks/IgnoreLineEndingsComparer.cs +++ b/test/TestBuildingBlocks/IgnoreLineEndingsComparer.cs @@ -3,11 +3,11 @@ namespace TestBuildingBlocks; public sealed class IgnoreLineEndingsComparer : IEqualityComparer { private static readonly string[] LineSeparators = - { + [ "\r\n", "\r", "\n" - }; + ]; public static readonly IgnoreLineEndingsComparer Instance = new(); From ca91b1f9cf727a82ddbf51a5ca5107389a7d2a33 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Sun, 19 Nov 2023 11:12:07 +0100 Subject: [PATCH 05/16] Resharper: remove redundant body --- .../TranslationToSql/TreeNodes/FilterNode.cs | 4 +--- .../TranslationToSql/TreeNodes/SqlValueNode.cs | 4 +--- .../Controllers/EmployeesController.cs | 4 +--- .../Annotations/EagerLoadAttribute.netstandard.cs | 4 +--- .../Annotations/NoResourceAttribute.shared.cs | 4 +--- .../Processors/IAddToRelationshipProcessor.cs | 4 +--- .../AtomicOperations/Processors/ICreateProcessor.cs | 4 +--- .../AtomicOperations/Processors/IDeleteProcessor.cs | 4 +--- .../Processors/IRemoveFromRelationshipProcessor.cs | 4 +--- .../Processors/ISetRelationshipProcessor.cs | 4 +--- .../AtomicOperations/Processors/IUpdateProcessor.cs | 4 +--- .../Annotations/DisableRoutingConventionAttribute.cs | 4 +--- .../IAsyncConvertEmptyActionResultFilter.cs | 4 +--- .../Middleware/IAsyncJsonApiExceptionFilter.cs | 4 +--- .../Middleware/IAsyncQueryStringActionFilter.cs | 4 +--- .../Middleware/IJsonApiInputFormatter.cs | 4 +--- .../Middleware/IJsonApiOutputFormatter.cs | 4 +--- .../Middleware/IJsonApiRoutingConvention.cs | 4 +--- .../Queries/Expressions/IdentifierExpression.cs | 4 +--- .../IFilterQueryStringParameterReader.cs | 4 +--- .../IIncludeQueryStringParameterReader.cs | 4 +--- .../IPaginationQueryStringParameterReader.cs | 4 +--- .../IResourceDefinitionQueryableParameterReader.cs | 4 +--- .../QueryStrings/ISortQueryStringParameterReader.cs | 4 +--- .../ISparseFieldSetQueryStringParameterReader.cs | 4 +--- .../Repositories/IResourceRepository.cs | 4 +--- .../Resources/JsonApiResourceDefinition.cs | 4 +--- .../Resources/QueryStringParameterHandlers.cs | 4 +--- .../Services/IResourceCommandService.cs | 4 +--- .../Services/IResourceQueryService.cs | 4 +--- src/JsonApiDotNetCore/Services/IResourceService.cs | 4 +--- test/DiscoveryTests/PrivateResource.cs | 4 +--- .../HostingInIIS/PaintingsController.cs | 4 +--- .../MultiTenancy/WebProductsController.cs | 4 +--- .../MultiTenancy/WebShopsController.cs | 4 +--- .../RestrictedControllers/PillowsController.cs | 4 +--- .../RestrictedControllers/SofasController.cs | 4 +--- .../DependencyContainerRegistrationTests.cs | 4 +--- .../ServiceCollectionExtensionsTests.cs | 12 +++--------- .../UnitTests/Links/LinkInclusionTests.cs | 4 +--- .../UnitTests/Middleware/JsonApiMiddlewareTests.cs | 4 +--- .../ResourceGraph/ResourceGraphBuilderTests.cs | 8 ++------ .../TypeConversion/RuntimeTypeConverterTests.cs | 12 +++--------- test/UnitTests/Graph/BaseType.cs | 4 +--- test/UnitTests/Graph/DerivedType.cs | 4 +--- test/UnitTests/Graph/IGenericInterface.cs | 4 +--- test/UnitTests/Graph/Implementation.cs | 4 +--- test/UnitTests/Graph/Model.cs | 4 +--- .../Models/ResourceConstructionExpressionTests.cs | 4 +--- 49 files changed, 54 insertions(+), 162 deletions(-) diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/FilterNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/FilterNode.cs index 1874fc16e4..92a24bac6d 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/FilterNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/FilterNode.cs @@ -3,6 +3,4 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// /// Represents the base type for filters that return a boolean value. /// -internal abstract class FilterNode : SqlTreeNode -{ -} +internal abstract class FilterNode : SqlTreeNode; diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SqlValueNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SqlValueNode.cs index bacbd5672f..da1b097757 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SqlValueNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SqlValueNode.cs @@ -3,6 +3,4 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// /// Represents the base type for values, such as parameters, column references and NULL. /// -internal abstract class SqlValueNode : SqlTreeNode -{ -} +internal abstract class SqlValueNode : SqlTreeNode; diff --git a/src/Examples/DatabasePerTenantExample/Controllers/EmployeesController.cs b/src/Examples/DatabasePerTenantExample/Controllers/EmployeesController.cs index f9d5595123..5bae37f9b9 100644 --- a/src/Examples/DatabasePerTenantExample/Controllers/EmployeesController.cs +++ b/src/Examples/DatabasePerTenantExample/Controllers/EmployeesController.cs @@ -5,6 +5,4 @@ namespace DatabasePerTenantExample.Controllers; [DisableRoutingConvention] [Route("api/{tenantName}/employees")] -partial class EmployeesController -{ -} +partial class EmployeesController; diff --git a/src/JsonApiDotNetCore.Annotations/Resources/Annotations/EagerLoadAttribute.netstandard.cs b/src/JsonApiDotNetCore.Annotations/Resources/Annotations/EagerLoadAttribute.netstandard.cs index 47052a078c..3083d7f436 100644 --- a/src/JsonApiDotNetCore.Annotations/Resources/Annotations/EagerLoadAttribute.netstandard.cs +++ b/src/JsonApiDotNetCore.Annotations/Resources/Annotations/EagerLoadAttribute.netstandard.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Resources.Annotations; /// [PublicAPI] [AttributeUsage(AttributeTargets.Property)] -public sealed class EagerLoadAttribute : Attribute -{ -} +public sealed class EagerLoadAttribute : Attribute; diff --git a/src/JsonApiDotNetCore.Annotations/Resources/Annotations/NoResourceAttribute.shared.cs b/src/JsonApiDotNetCore.Annotations/Resources/Annotations/NoResourceAttribute.shared.cs index 8be53b0d03..02d19761d7 100644 --- a/src/JsonApiDotNetCore.Annotations/Resources/Annotations/NoResourceAttribute.shared.cs +++ b/src/JsonApiDotNetCore.Annotations/Resources/Annotations/NoResourceAttribute.shared.cs @@ -8,6 +8,4 @@ namespace JsonApiDotNetCore.Resources.Annotations; /// [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] -public sealed class NoResourceAttribute : Attribute -{ -} +public sealed class NoResourceAttribute : Attribute; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs index 8b9990342a..91d23e3358 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs @@ -16,6 +16,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface IAddToRelationshipProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs index 9fd1de2186..6cc04043f3 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs @@ -16,6 +16,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface ICreateProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs index 67627cd8c0..42f5f71c14 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs @@ -16,6 +16,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface IDeleteProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs index 6492c992f1..2dc7bdb17d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs @@ -12,6 +12,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface IRemoveFromRelationshipProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs index dd950d203d..7928aa76b0 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs @@ -16,6 +16,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface ISetRelationshipProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs index 6051837749..77b83f65f7 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs @@ -17,6 +17,4 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors; /// [PublicAPI] public interface IUpdateProcessor : IOperationProcessor - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs index 34e1132789..19df79dc2b 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs @@ -11,6 +11,4 @@ namespace JsonApiDotNetCore.Controllers.Annotations; /// ]]> [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] -public sealed class DisableRoutingConventionAttribute : Attribute -{ -} +public sealed class DisableRoutingConventionAttribute : Attribute; diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs index 87676657e5..3116b45d40 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs @@ -14,6 +14,4 @@ namespace JsonApiDotNetCore.Middleware; /// https://github.com/dotnet/aspnetcore/issues/16969 /// [PublicAPI] -public interface IAsyncConvertEmptyActionResultFilter : IAsyncAlwaysRunResultFilter -{ -} +public interface IAsyncConvertEmptyActionResultFilter : IAsyncAlwaysRunResultFilter; diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs index fb0cbb9b17..1fc4e136af 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Middleware; /// Application-wide exception filter that invokes for JSON:API requests. /// [PublicAPI] -public interface IAsyncJsonApiExceptionFilter : IAsyncExceptionFilter -{ -} +public interface IAsyncJsonApiExceptionFilter : IAsyncExceptionFilter; diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs index 0c9cbfbb29..d3df469f64 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Middleware; /// Application-wide entry point for processing JSON:API request query strings. /// [PublicAPI] -public interface IAsyncQueryStringActionFilter : IAsyncActionFilter -{ -} +public interface IAsyncQueryStringActionFilter : IAsyncActionFilter; diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs index cb5fe76167..7879530650 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Middleware; /// Application-wide entry point for reading JSON:API request bodies. /// [PublicAPI] -public interface IJsonApiInputFormatter : IInputFormatter -{ -} +public interface IJsonApiInputFormatter : IInputFormatter; diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs index bc7213ebed..ff285e26e7 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Middleware; /// Application-wide entry point for writing JSON:API response bodies. /// [PublicAPI] -public interface IJsonApiOutputFormatter : IOutputFormatter -{ -} +public interface IJsonApiOutputFormatter : IOutputFormatter; diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs index 86b68a9b03..a83156f33f 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.Middleware; /// Service for specifying which routing convention to use. This can be overridden to customize the relation between controllers and mapped routes. /// [PublicAPI] -public interface IJsonApiRoutingConvention : IApplicationModelConvention, IControllerResourceMapping -{ -} +public interface IJsonApiRoutingConvention : IApplicationModelConvention, IControllerResourceMapping; diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IdentifierExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/IdentifierExpression.cs index 5b7d63ef96..5a978b54f6 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IdentifierExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IdentifierExpression.cs @@ -3,6 +3,4 @@ namespace JsonApiDotNetCore.Queries.Expressions; /// /// Represents the base type for an identifier, such as a JSON:API attribute/relationship name, a constant value between quotes, or null. /// -public abstract class IdentifierExpression : QueryExpression -{ -} +public abstract class IdentifierExpression : QueryExpression; diff --git a/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs index b9a7fb8c6b..4fdefe2124 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// Reads the 'filter' query string parameter and produces a set of query constraints from it. /// [PublicAPI] -public interface IFilterQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface IFilterQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs index 1993d249fc..822df2ee68 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// Reads the 'include' query string parameter and produces a set of query constraints from it. /// [PublicAPI] -public interface IIncludeQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface IIncludeQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs index 198bff6ff8..56141e5615 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// Reads the 'page' query string parameter and produces a set of query constraints from it. /// [PublicAPI] -public interface IPaginationQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface IPaginationQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs index 9ef114e4b3..965eb2d884 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs @@ -9,6 +9,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// query constraints from it. /// [PublicAPI] -public interface IResourceDefinitionQueryableParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface IResourceDefinitionQueryableParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs index 5cb221a399..763d1a67f1 100644 --- a/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// Reads the 'sort' query string parameter and produces a set of query constraints from it. /// [PublicAPI] -public interface ISortQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface ISortQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs index e943121ecc..1f0bdaf90f 100644 --- a/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs @@ -7,6 +7,4 @@ namespace JsonApiDotNetCore.QueryStrings; /// Reads the 'fields' query string parameter and produces a set of query constraints from it. /// [PublicAPI] -public interface ISparseFieldSetQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider -{ -} +public interface ISparseFieldSetQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider; diff --git a/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs b/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs index 26b7c4513e..218a09cb93 100644 --- a/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs @@ -14,6 +14,4 @@ namespace JsonApiDotNetCore.Repositories; /// [PublicAPI] public interface IResourceRepository : IResourceReadRepository, IResourceWriteRepository - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs index f6653b9bdb..f069c155e8 100644 --- a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs @@ -177,7 +177,5 @@ public virtual void OnSerialize(TResource resource) /// This is an alias type intended to simplify the implementation's method signature. See for usage /// details. /// - public sealed class PropertySortOrder : List<(Expression> KeySelector, ListSortDirection SortDirection)> - { - } + public sealed class PropertySortOrder : List<(Expression> KeySelector, ListSortDirection SortDirection)>; } diff --git a/src/JsonApiDotNetCore/Resources/QueryStringParameterHandlers.cs b/src/JsonApiDotNetCore/Resources/QueryStringParameterHandlers.cs index 52c9f7d71a..b48c46e26e 100644 --- a/src/JsonApiDotNetCore/Resources/QueryStringParameterHandlers.cs +++ b/src/JsonApiDotNetCore/Resources/QueryStringParameterHandlers.cs @@ -6,6 +6,4 @@ namespace JsonApiDotNetCore.Resources; /// This is an alias type intended to simplify the implementation's method signature. See /// for usage details. /// -public sealed class QueryStringParameterHandlers : Dictionary, StringValues, IQueryable>> -{ -} +public sealed class QueryStringParameterHandlers : Dictionary, StringValues, IQueryable>>; diff --git a/src/JsonApiDotNetCore/Services/IResourceCommandService.cs b/src/JsonApiDotNetCore/Services/IResourceCommandService.cs index 6c6dc408c9..7bc47b6c20 100644 --- a/src/JsonApiDotNetCore/Services/IResourceCommandService.cs +++ b/src/JsonApiDotNetCore/Services/IResourceCommandService.cs @@ -14,6 +14,4 @@ namespace JsonApiDotNetCore.Services; public interface IResourceCommandService : ICreateService, IAddToRelationshipService, IUpdateService, ISetRelationshipService, IDeleteService, IRemoveFromRelationshipService - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/Services/IResourceQueryService.cs b/src/JsonApiDotNetCore/Services/IResourceQueryService.cs index 7c9d32071f..b2de9b03fc 100644 --- a/src/JsonApiDotNetCore/Services/IResourceQueryService.cs +++ b/src/JsonApiDotNetCore/Services/IResourceQueryService.cs @@ -13,6 +13,4 @@ namespace JsonApiDotNetCore.Services; /// public interface IResourceQueryService : IGetAllService, IGetByIdService, IGetRelationshipService, IGetSecondaryService - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/src/JsonApiDotNetCore/Services/IResourceService.cs b/src/JsonApiDotNetCore/Services/IResourceService.cs index 87637e53a2..2a75be7151 100644 --- a/src/JsonApiDotNetCore/Services/IResourceService.cs +++ b/src/JsonApiDotNetCore/Services/IResourceService.cs @@ -12,6 +12,4 @@ namespace JsonApiDotNetCore.Services; /// The resource identifier type. /// public interface IResourceService : IResourceCommandService, IResourceQueryService - where TResource : class, IIdentifiable -{ -} + where TResource : class, IIdentifiable; diff --git a/test/DiscoveryTests/PrivateResource.cs b/test/DiscoveryTests/PrivateResource.cs index facbfb6c35..9ad2daef51 100644 --- a/test/DiscoveryTests/PrivateResource.cs +++ b/test/DiscoveryTests/PrivateResource.cs @@ -6,6 +6,4 @@ namespace DiscoveryTests; [UsedImplicitly(ImplicitUseTargetFlags.Members)] [Resource] -public sealed class PrivateResource : Identifiable -{ -} +public sealed class PrivateResource : Identifiable; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/PaintingsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/PaintingsController.cs index dc4c27ca54..c27e628642 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/PaintingsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/PaintingsController.cs @@ -5,6 +5,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.HostingInIIS; [DisableRoutingConvention] [Route("custom/path/to/paintings-of-the-world")] -partial class PaintingsController -{ -} +partial class PaintingsController; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebProductsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebProductsController.cs index bdc7068a3d..4fe81d3fe3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebProductsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebProductsController.cs @@ -5,6 +5,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.MultiTenancy; [DisableRoutingConvention] [Route("{countryCode}/products")] -partial class WebProductsController -{ -} +partial class WebProductsController; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebShopsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebShopsController.cs index ee31954740..1e0e53d0f6 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebShopsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/WebShopsController.cs @@ -5,6 +5,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.MultiTenancy; [DisableRoutingConvention] [Route("{countryCode}/shops")] -partial class WebShopsController -{ -} +partial class WebShopsController; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/PillowsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/PillowsController.cs index e260788905..16ef346e70 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/PillowsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/PillowsController.cs @@ -3,6 +3,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.RestrictedControllers; [DisableQueryString("skipCache")] -partial class PillowsController -{ -} +partial class PillowsController; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/SofasController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/SofasController.cs index d6d2d66fa8..03e0d48665 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/SofasController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/SofasController.cs @@ -4,6 +4,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.RestrictedControllers; [DisableQueryString(JsonApiQueryStringParameters.Sort | JsonApiQueryStringParameters.Page)] -partial class SofasController -{ -} +partial class SofasController; diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs index 2e9f74add6..0289585dfb 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs @@ -153,9 +153,7 @@ public SomeSingletonService(SomeScopedService scopedService) } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] - private sealed class SomeScopedService - { - } + private sealed class SomeScopedService; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class CircularServiceA diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs index d4002a1932..0f7e8b0b09 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs @@ -164,14 +164,10 @@ public void Can_register_resource_definition_for_Id_type_Guid() provider.GetRequiredService(typeof(IResourceDefinition)).Should().BeOfType(); } - private sealed class ResourceOfInt32 : Identifiable - { - } + private sealed class ResourceOfInt32 : Identifiable; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] - private sealed class ResourceOfGuid : Identifiable - { - } + private sealed class ResourceOfGuid : Identifiable; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class ResourceServiceOfInt32 : IResourceService @@ -584,7 +580,5 @@ public TestDbContext(DbContextOptions options) } [UsedImplicitly(ImplicitUseKindFlags.Access)] - private sealed class Person : Identifiable - { - } + private sealed class Person : Identifiable; } diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Links/LinkInclusionTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Links/LinkInclusionTests.cs index 03cb0e2a4c..392d61709a 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Links/LinkInclusionTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Links/LinkInclusionTests.cs @@ -372,9 +372,7 @@ public void Applies_cascading_settings_for_relationship_links(LinkTypes linksInR } } - private sealed class ExampleResource : Identifiable - { - } + private sealed class ExampleResource : Identifiable; private sealed class FakeHttpContextAccessor : IHttpContextAccessor { diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs index a57f5ff5b0..d11eb53a19 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -172,9 +172,7 @@ public enum IsCollection } [UsedImplicitly(ImplicitUseTargetFlags.Itself)] - private sealed class Person : Identifiable - { - } + private sealed class Person : Identifiable; [UsedImplicitly(ImplicitUseTargetFlags.Members)] private sealed class ItemTag : Identifiable diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs index 11ae36cd72..ebce906b9d 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs @@ -428,15 +428,11 @@ private sealed class ResourceWithoutId : IIdentifiable } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] - private sealed class NonResource - { - } + private sealed class NonResource; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] [NoResource] - private sealed class NonResourceWithSuppression - { - } + private sealed class NonResourceWithSuppression; // ReSharper disable once ClassCanBeSealed.Global [UsedImplicitly(ImplicitUseTargetFlags.Members)] diff --git a/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs index f633bb5b62..4fbe4f3d22 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs @@ -150,15 +150,9 @@ public void Returns_default_value_for_empty_string(Type type, object expectedVal result.Should().Be(expectedValue); } - private interface IFace - { - } + private interface IFace; - private class BaseType : IFace - { - } + private class BaseType : IFace; - private sealed class DerivedType : BaseType - { - } + private sealed class DerivedType : BaseType; } diff --git a/test/UnitTests/Graph/BaseType.cs b/test/UnitTests/Graph/BaseType.cs index 8fdbe4f4ae..3343b4ef65 100644 --- a/test/UnitTests/Graph/BaseType.cs +++ b/test/UnitTests/Graph/BaseType.cs @@ -2,6 +2,4 @@ namespace UnitTests.Graph; -internal class BaseType -{ -} +internal class BaseType; diff --git a/test/UnitTests/Graph/DerivedType.cs b/test/UnitTests/Graph/DerivedType.cs index 4453c7b56a..9f2aca9ced 100644 --- a/test/UnitTests/Graph/DerivedType.cs +++ b/test/UnitTests/Graph/DerivedType.cs @@ -1,5 +1,3 @@ namespace UnitTests.Graph; -internal sealed class DerivedType : BaseType -{ -} +internal sealed class DerivedType : BaseType; diff --git a/test/UnitTests/Graph/IGenericInterface.cs b/test/UnitTests/Graph/IGenericInterface.cs index c9fdd83e18..aa76ce34f7 100644 --- a/test/UnitTests/Graph/IGenericInterface.cs +++ b/test/UnitTests/Graph/IGenericInterface.cs @@ -2,6 +2,4 @@ namespace UnitTests.Graph; -internal interface IGenericInterface -{ -} +internal interface IGenericInterface; diff --git a/test/UnitTests/Graph/Implementation.cs b/test/UnitTests/Graph/Implementation.cs index 5e851f4afe..e098482049 100644 --- a/test/UnitTests/Graph/Implementation.cs +++ b/test/UnitTests/Graph/Implementation.cs @@ -1,5 +1,3 @@ namespace UnitTests.Graph; -internal sealed class Implementation : IGenericInterface -{ -} +internal sealed class Implementation : IGenericInterface; diff --git a/test/UnitTests/Graph/Model.cs b/test/UnitTests/Graph/Model.cs index ad9608a946..d0ba3f4eee 100644 --- a/test/UnitTests/Graph/Model.cs +++ b/test/UnitTests/Graph/Model.cs @@ -2,6 +2,4 @@ namespace UnitTests.Graph; -internal sealed class Model : Identifiable -{ -} +internal sealed class Model : Identifiable; diff --git a/test/UnitTests/Models/ResourceConstructionExpressionTests.cs b/test/UnitTests/Models/ResourceConstructionExpressionTests.cs index aca0d91db1..277af5f013 100644 --- a/test/UnitTests/Models/ResourceConstructionExpressionTests.cs +++ b/test/UnitTests/Models/ResourceConstructionExpressionTests.cs @@ -41,9 +41,7 @@ public void When_resource_has_constructor_with_string_parameter_it_must_fail() .WithMessage($"Failed to create an instance of '{typeof(ResourceWithStringConstructor).FullName}': Parameter 'text' could not be resolved."); } - private sealed class ResourceWithoutConstructor : Identifiable - { - } + private sealed class ResourceWithoutConstructor : Identifiable; [UsedImplicitly(ImplicitUseTargetFlags.Members)] private sealed class ResourceWithStringConstructor : Identifiable From 3e1b27b6c4723b08e827904e9ffdd30f8fb71383 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Sun, 19 Nov 2023 11:15:33 +0100 Subject: [PATCH 06/16] Resharper: Replace async method with Task return --- WarningSeverities.DotSettings | 1 + .../Repositories/DapperRepository.cs | 4 +- .../AtomicOperations/OperationsProcessor.cs | 4 +- .../Controllers/JsonApiController.cs | 40 +++++++++---------- .../JsonApiOperationsController.cs | 4 +- .../Middleware/JsonApiOutputFormatter.cs | 4 +- .../Serialization/Response/JsonApiWriter.cs | 8 ++-- .../Services/JsonApiResourceService.cs | 12 +++--- .../AtomicOperations/AtomicOperationsTests.cs | 4 +- .../CreateMusicTrackOperationsController.cs | 4 +- ...micSerializationResourceDefinitionTests.cs | 4 +- .../Transactions/AtomicRollbackTests.cs | 8 ++-- .../Meta/ResponseMetaTests.cs | 4 +- .../Meta/TopLevelCountTests.cs | 4 +- .../Microservices/MessagingGroupDefinition.cs | 4 +- .../Microservices/MessagingUserDefinition.cs | 4 +- .../OutboxTests.Group.cs | 4 +- .../OutboxTests.User.cs | 4 +- .../SoftDeletionAwareResourceService.cs | 10 ++--- .../ZeroKeys/EmptyGuidAsKeyTests.cs | 4 +- .../ZeroKeys/ZeroAsKeyTests.cs | 4 +- .../TestBuildingBlocks/DbContextExtensions.cs | 8 ++-- test/TestBuildingBlocks/IntegrationTest.cs | 28 ++++++------- .../TestBuildingBlocks/QueryableExtensions.cs | 4 +- 24 files changed, 89 insertions(+), 90 deletions(-) diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index b5e5ca9c42..37457deebc 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -163,6 +163,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING diff --git a/src/Examples/DapperExample/Repositories/DapperRepository.cs b/src/Examples/DapperExample/Repositories/DapperRepository.cs index bbbeda2ea3..c263ad7767 100644 --- a/src/Examples/DapperExample/Repositories/DapperRepository.cs +++ b/src/Examples/DapperExample/Repositories/DapperRepository.cs @@ -161,7 +161,7 @@ public async Task> GetAsync(QueryLayer queryLayer } /// - public async Task CountAsync(FilterExpression? filter, CancellationToken cancellationToken) + public Task CountAsync(FilterExpression? filter, CancellationToken cancellationToken) { var queryLayer = new QueryLayer(ResourceType) { @@ -173,7 +173,7 @@ public async Task CountAsync(FilterExpression? filter, CancellationToken ca CommandDefinition sqlCommand = _dapperFacade.GetSqlCommand(selectNode, cancellationToken); LogSqlCommand(sqlCommand); - return await ExecuteQueryAsync(async connection => await connection.ExecuteScalarAsync(sqlCommand), cancellationToken); + return ExecuteQueryAsync(connection => connection.ExecuteScalarAsync(sqlCommand), cancellationToken); } /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs index cf1cdd7b65..9e78fcfcbe 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs @@ -99,7 +99,7 @@ public OperationsProcessor(IOperationProcessorAccessor operationProcessorAccesso return results; } - protected virtual async Task ProcessOperationAsync(OperationContainer operation, CancellationToken cancellationToken) + protected virtual Task ProcessOperationAsync(OperationContainer operation, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -108,7 +108,7 @@ public OperationsProcessor(IOperationProcessorAccessor operationProcessorAccesso _targetedFields.CopyFrom(operation.TargetedFields); _request.CopyFrom(operation.Request); - return await _operationProcessorAccessor.ProcessAsync(operation, cancellationToken); + return _operationProcessorAccessor.ProcessAsync(operation, cancellationToken); } protected void TrackLocalIdsForOperation(OperationContainer operation) diff --git a/src/JsonApiDotNetCore/Controllers/JsonApiController.cs b/src/JsonApiDotNetCore/Controllers/JsonApiController.cs index 091bbee47b..19c679404f 100644 --- a/src/JsonApiDotNetCore/Controllers/JsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/JsonApiController.cs @@ -41,77 +41,77 @@ protected JsonApiController(IJsonApiOptions options, IResourceGraph resourceGrap /// [HttpGet] [HttpHead] - public override async Task GetAsync(CancellationToken cancellationToken) + public override Task GetAsync(CancellationToken cancellationToken) { - return await base.GetAsync(cancellationToken); + return base.GetAsync(cancellationToken); } /// [HttpGet("{id}")] [HttpHead("{id}")] - public override async Task GetAsync(TId id, CancellationToken cancellationToken) + public override Task GetAsync(TId id, CancellationToken cancellationToken) { - return await base.GetAsync(id, cancellationToken); + return base.GetAsync(id, cancellationToken); } /// [HttpGet("{id}/{relationshipName}")] [HttpHead("{id}/{relationshipName}")] - public override async Task GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken) + public override Task GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken) { - return await base.GetSecondaryAsync(id, relationshipName, cancellationToken); + return base.GetSecondaryAsync(id, relationshipName, cancellationToken); } /// [HttpGet("{id}/relationships/{relationshipName}")] [HttpHead("{id}/relationships/{relationshipName}")] - public override async Task GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken) + public override Task GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken) { - return await base.GetRelationshipAsync(id, relationshipName, cancellationToken); + return base.GetRelationshipAsync(id, relationshipName, cancellationToken); } /// [HttpPost] - public override async Task PostAsync([FromBody] TResource resource, CancellationToken cancellationToken) + public override Task PostAsync([FromBody] TResource resource, CancellationToken cancellationToken) { - return await base.PostAsync(resource, cancellationToken); + return base.PostAsync(resource, cancellationToken); } /// [HttpPost("{id}/relationships/{relationshipName}")] - public override async Task PostRelationshipAsync(TId id, string relationshipName, [FromBody] ISet rightResourceIds, + public override Task PostRelationshipAsync(TId id, string relationshipName, [FromBody] ISet rightResourceIds, CancellationToken cancellationToken) { - return await base.PostRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken); + return base.PostRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken); } /// [HttpPatch("{id}")] - public override async Task PatchAsync(TId id, [FromBody] TResource resource, CancellationToken cancellationToken) + public override Task PatchAsync(TId id, [FromBody] TResource resource, CancellationToken cancellationToken) { - return await base.PatchAsync(id, resource, cancellationToken); + return base.PatchAsync(id, resource, cancellationToken); } /// [HttpPatch("{id}/relationships/{relationshipName}")] - public override async Task PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object? rightValue, + public override Task PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object? rightValue, CancellationToken cancellationToken) { - return await base.PatchRelationshipAsync(id, relationshipName, rightValue, cancellationToken); + return base.PatchRelationshipAsync(id, relationshipName, rightValue, cancellationToken); } /// [HttpDelete("{id}")] - public override async Task DeleteAsync(TId id, CancellationToken cancellationToken) + public override Task DeleteAsync(TId id, CancellationToken cancellationToken) { - return await base.DeleteAsync(id, cancellationToken); + return base.DeleteAsync(id, cancellationToken); } /// [HttpDelete("{id}/relationships/{relationshipName}")] - public override async Task DeleteRelationshipAsync(TId id, string relationshipName, [FromBody] ISet rightResourceIds, + public override Task DeleteRelationshipAsync(TId id, string relationshipName, [FromBody] ISet rightResourceIds, CancellationToken cancellationToken) { - return await base.DeleteRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken); + return base.DeleteRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken); } } diff --git a/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs index 452a5eac09..70d65aa7b3 100644 --- a/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs @@ -21,8 +21,8 @@ protected JsonApiOperationsController(IJsonApiOptions options, IResourceGraph re /// [HttpPost] - public override async Task PostOperationsAsync([FromBody] IList operations, CancellationToken cancellationToken) + public override Task PostOperationsAsync([FromBody] IList operations, CancellationToken cancellationToken) { - return await base.PostOperationsAsync(operations, cancellationToken); + return base.PostOperationsAsync(operations, cancellationToken); } } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs b/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs index 80d7863251..f88e11c33d 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs @@ -16,11 +16,11 @@ public bool CanWriteResult(OutputFormatterCanWriteContext context) } /// - public async Task WriteAsync(OutputFormatterWriteContext context) + public Task WriteAsync(OutputFormatterWriteContext context) { ArgumentGuard.NotNull(context); var writer = context.HttpContext.RequestServices.GetRequiredService(); - await writer.WriteAsync(context.Object, context.HttpContext); + return writer.WriteAsync(context.Object, context.HttpContext); } } diff --git a/src/JsonApiDotNetCore/Serialization/Response/JsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/Response/JsonApiWriter.cs index 22de5284a2..8ea0d060e2 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/JsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/JsonApiWriter.cs @@ -44,14 +44,14 @@ public JsonApiWriter(IJsonApiRequest request, IJsonApiOptions options, IResponse } /// - public async Task WriteAsync(object? model, HttpContext httpContext) + public Task WriteAsync(object? model, HttpContext httpContext) { ArgumentGuard.NotNull(httpContext); if (model == null && !CanWriteBody((HttpStatusCode)httpContext.Response.StatusCode)) { // Prevent exception from Kestrel server, caused by writing data:null json response. - return; + return Task.CompletedTask; } string? responseBody = GetResponseBody(model, httpContext); @@ -59,7 +59,7 @@ public async Task WriteAsync(object? model, HttpContext httpContext) if (httpContext.Request.Method == HttpMethod.Head.Method) { httpContext.Response.GetTypedHeaders().ContentLength = responseBody == null ? 0 : Encoding.UTF8.GetByteCount(responseBody); - return; + return Task.CompletedTask; } _traceWriter.LogMessage(() => @@ -70,7 +70,7 @@ public async Task WriteAsync(object? model, HttpContext httpContext) return $"Sending {httpContext.Response.StatusCode} response for {method} request at '{url}' with body: <<{responseBody}>>"; }); - await SendResponseBodyAsync(httpContext.Response, responseBody); + return SendResponseBodyAsync(httpContext.Response, responseBody); } private static bool CanWriteBody(HttpStatusCode statusCode) diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index 5984b6215b..c9a19ff73d 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -244,19 +244,19 @@ protected async Task AssertPrimaryResourceDoesNotExistAsync(TResource resource, } } - protected virtual async Task InitializeResourceAsync(TResource resourceForDatabase, CancellationToken cancellationToken) + protected virtual Task InitializeResourceAsync(TResource resourceForDatabase, CancellationToken cancellationToken) { - await _resourceDefinitionAccessor.OnPrepareWriteAsync(resourceForDatabase, WriteOperationKind.CreateResource, cancellationToken); + return _resourceDefinitionAccessor.OnPrepareWriteAsync(resourceForDatabase, WriteOperationKind.CreateResource, cancellationToken); } - private async Task AccurizeResourceTypesInHierarchyToAssignInRelationshipsAsync(TResource primaryResource, CancellationToken cancellationToken) + private Task AccurizeResourceTypesInHierarchyToAssignInRelationshipsAsync(TResource primaryResource, CancellationToken cancellationToken) { - await ValidateResourcesToAssignInRelationshipsExistWithRefreshAsync(primaryResource, true, cancellationToken); + return ValidateResourcesToAssignInRelationshipsExistWithRefreshAsync(primaryResource, true, cancellationToken); } - protected async Task AssertResourcesToAssignInRelationshipsExistAsync(TResource primaryResource, CancellationToken cancellationToken) + protected Task AssertResourcesToAssignInRelationshipsExistAsync(TResource primaryResource, CancellationToken cancellationToken) { - await ValidateResourcesToAssignInRelationshipsExistWithRefreshAsync(primaryResource, false, cancellationToken); + return ValidateResourcesToAssignInRelationshipsExistWithRefreshAsync(primaryResource, false, cancellationToken); } private async Task ValidateResourcesToAssignInRelationshipsExistWithRefreshAsync(TResource primaryResource, bool onlyIfTypeHierarchy, diff --git a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs index 194d55d837..316acc3381 100644 --- a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs +++ b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs @@ -396,9 +396,9 @@ public async Task Can_rollback_on_error() const string personLocalId = "new-person"; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await _testContext.ClearAllTablesAsync(dbContext); + return _testContext.ClearAllTablesAsync(dbContext); }); var requestBody = new diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs index 517cf4c792..5c9647f6f7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs @@ -22,11 +22,11 @@ public CreateMusicTrackOperationsController(IJsonApiOptions options, IResourceGr { } - public override async Task PostOperationsAsync(IList operations, CancellationToken cancellationToken) + public override Task PostOperationsAsync(IList operations, CancellationToken cancellationToken) { AssertOnlyCreatingMusicTracks(operations); - return await base.PostOperationsAsync(operations, cancellationToken); + return base.PostOperationsAsync(operations, cancellationToken); } private static void AssertOnlyCreatingMusicTracks(IEnumerable operations) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs index 4e2fa4f937..e18153fc60 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs @@ -42,9 +42,9 @@ public async Task Transforms_on_create_resource_with_side_effects() List newCompanies = _fakers.RecordCompany.Generate(2); - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); var requestBody = new diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs index 82646686d4..54e1ca2b76 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs @@ -27,9 +27,9 @@ public async Task Can_rollback_on_error() DateTimeOffset newBornAt = _fakers.Performer.Generate().BornAt; string newTitle = _fakers.MusicTrack.Generate().Title; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTablesAsync(); + return dbContext.ClearTablesAsync(); }); string unknownPerformerId = Unknown.StringId.For(); @@ -113,9 +113,9 @@ public async Task Can_restore_to_previous_savepoint_on_error() // Arrange string newTrackTitle = _fakers.MusicTrack.Generate().Title; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTablesAsync(); + return dbContext.ClearTablesAsync(); }); const string trackLid = "track-1"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs index a5ae347886..1ba0e6e746 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs @@ -32,9 +32,9 @@ public ResponseMetaTests(IntegrationTestContext, public async Task Returns_top_level_meta() { // Arrange - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); const string route = "/supportTickets"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs index 955a8514b6..b7d7126d16 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs @@ -86,9 +86,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Renders_resource_count_for_empty_collection() { // Arrange - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); const string route = "/supportTickets"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs index d1772330ca..b30c8ef88f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs @@ -172,8 +172,8 @@ protected async Task FinishWriteAsync(DomainGroup group, WriteOperationKind writ protected abstract Task FlushMessageAsync(OutgoingMessage message, CancellationToken cancellationToken); - protected virtual async Task GetGroupToDeleteAsync(Guid groupId, CancellationToken cancellationToken) + protected virtual Task GetGroupToDeleteAsync(Guid groupId, CancellationToken cancellationToken) { - return await _groupSet.Include(group => group.Users).FirstOrDefaultAsync(group => group.Id == groupId, cancellationToken); + return _groupSet.Include(group => group.Users).FirstOrDefaultAsync(group => group.Id == groupId, cancellationToken); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs index cb8e84e8ba..74b5190cd1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs @@ -118,8 +118,8 @@ protected async Task FinishWriteAsync(DomainUser user, WriteOperationKind writeO protected abstract Task FlushMessageAsync(OutgoingMessage message, CancellationToken cancellationToken); - protected virtual async Task GetUserToDeleteAsync(Guid userId, CancellationToken cancellationToken) + protected virtual Task GetUserToDeleteAsync(Guid userId, CancellationToken cancellationToken) { - return await _userSet.Include(domainUser => domainUser.Group).FirstOrDefaultAsync(domainUser => domainUser.Id == userId, cancellationToken); + return _userSet.Include(domainUser => domainUser.Group).FirstOrDefaultAsync(domainUser => domainUser.Id == userId, cancellationToken); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs index cc5b5e84ab..38f78abb50 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs @@ -19,9 +19,9 @@ public async Task Create_group_writes_to_outbox() string newGroupName = _fakers.DomainGroup.Generate().Name; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); var requestBody = new diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs index 5ec47bb34a..a00463843a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs @@ -20,9 +20,9 @@ public async Task Create_user_writes_to_outbox() string newLoginName = _fakers.DomainUser.Generate().LoginName; string newDisplayName = _fakers.DomainUser.Generate().DisplayName!; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); var requestBody = new diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs index 2b6e3be294..6a865eaf85 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs @@ -79,16 +79,14 @@ public override async Task AddToToManyRelationshipAsync(TId leftId, string relat await base.AddToToManyRelationshipAsync(leftId, relationshipName, rightResourceIds, cancellationToken); } - public override async Task DeleteAsync(TId id, CancellationToken cancellationToken) + public override Task DeleteAsync(TId id, CancellationToken cancellationToken) { if (IsSoftDeletable(typeof(TResource))) { - await SoftDeleteAsync(id, cancellationToken); - } - else - { - await base.DeleteAsync(id, cancellationToken); + return SoftDeleteAsync(id, cancellationToken); } + + return base.DeleteAsync(id, cancellationToken); } private async Task SoftDeleteAsync(TId id, CancellationToken cancellationToken) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs index 93881be9eb..665f0bf5f4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs @@ -97,9 +97,9 @@ public async Task Can_create_resource_with_empty_ID() // Arrange string newName = _fakers.Map.Generate().Name; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); var requestBody = new diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs index 19baa0cf58..746ab7d6d2 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs @@ -96,9 +96,9 @@ public async Task Can_create_resource_with_zero_ID() // Arrange string newTitle = _fakers.Game.Generate().Title; - await _testContext.RunOnDatabaseAsync(async dbContext => + await _testContext.RunOnDatabaseAsync(dbContext => { - await dbContext.ClearTableAsync(); + return dbContext.ClearTableAsync(); }); var requestBody = new diff --git a/test/TestBuildingBlocks/DbContextExtensions.cs b/test/TestBuildingBlocks/DbContextExtensions.cs index d3a8a0e8ad..f7c8eb7251 100644 --- a/test/TestBuildingBlocks/DbContextExtensions.cs +++ b/test/TestBuildingBlocks/DbContextExtensions.cs @@ -10,17 +10,17 @@ public static void AddInRange(this DbContext dbContext, params object[] entities dbContext.AddRange(entities); } - public static async Task ClearTableAsync(this DbContext dbContext) + public static Task ClearTableAsync(this DbContext dbContext) where TEntity : class { - await ClearTablesAsync(dbContext, typeof(TEntity)); + return ClearTablesAsync(dbContext, typeof(TEntity)); } - public static async Task ClearTablesAsync(this DbContext dbContext) + public static Task ClearTablesAsync(this DbContext dbContext) where TEntity1 : class where TEntity2 : class { - await ClearTablesAsync(dbContext, typeof(TEntity1), typeof(TEntity2)); + return ClearTablesAsync(dbContext, typeof(TEntity1), typeof(TEntity2)); } private static async Task ClearTablesAsync(this DbContext dbContext, params Type[] modelTypes) diff --git a/test/TestBuildingBlocks/IntegrationTest.cs b/test/TestBuildingBlocks/IntegrationTest.cs index 73ced10d8d..d657d02e23 100644 --- a/test/TestBuildingBlocks/IntegrationTest.cs +++ b/test/TestBuildingBlocks/IntegrationTest.cs @@ -22,40 +22,40 @@ static IntegrationTest() ThrottleSemaphore = new SemaphoreSlim(maxConcurrentTestRuns); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteHeadAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteHeadAsync(string requestUrl, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Head, requestUrl, null, null, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Head, requestUrl, null, null, setRequestHeaders); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteGetAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteGetAsync(string requestUrl, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Get, requestUrl, null, null, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Get, requestUrl, null, null, setRequestHeaders); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePostAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePostAsync(string requestUrl, object requestBody, string contentType = HeaderConstants.MediaType, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Post, requestUrl, requestBody, contentType, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Post, requestUrl, requestBody, contentType, setRequestHeaders); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePostAtomicAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePostAtomicAsync(string requestUrl, object requestBody, string contentType = HeaderConstants.AtomicOperationsMediaType, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Post, requestUrl, requestBody, contentType, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Post, requestUrl, requestBody, contentType, setRequestHeaders); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePatchAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecutePatchAsync(string requestUrl, object requestBody, string contentType = HeaderConstants.MediaType, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Patch, requestUrl, requestBody, contentType, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Patch, requestUrl, requestBody, contentType, setRequestHeaders); } - public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteDeleteAsync(string requestUrl, + public Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteDeleteAsync(string requestUrl, object? requestBody = null, string contentType = HeaderConstants.MediaType, Action? setRequestHeaders = null) { - return await ExecuteRequestAsync(HttpMethod.Delete, requestUrl, requestBody, contentType, setRequestHeaders); + return ExecuteRequestAsync(HttpMethod.Delete, requestUrl, requestBody, contentType, setRequestHeaders); } private async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteRequestAsync(HttpMethod method, @@ -116,9 +116,9 @@ static IntegrationTest() } } - public async Task InitializeAsync() + public Task InitializeAsync() { - await ThrottleSemaphore.WaitAsync(); + return ThrottleSemaphore.WaitAsync(); } public virtual Task DisposeAsync() diff --git a/test/TestBuildingBlocks/QueryableExtensions.cs b/test/TestBuildingBlocks/QueryableExtensions.cs index 71538f13c0..e3f6f33e27 100644 --- a/test/TestBuildingBlocks/QueryableExtensions.cs +++ b/test/TestBuildingBlocks/QueryableExtensions.cs @@ -11,10 +11,10 @@ public static Task FirstWithIdAsync(this IQueryable Equals(resource.Id, id), cancellationToken); } - public static async Task FirstWithIdOrDefaultAsync(this IQueryable resources, TId id, + public static Task FirstWithIdOrDefaultAsync(this IQueryable resources, TId id, CancellationToken cancellationToken = default) where TResource : IIdentifiable { - return await resources.FirstOrDefaultAsync(resource => Equals(resource.Id, id), cancellationToken); + return resources.FirstOrDefaultAsync(resource => Equals(resource.Id, id), cancellationToken); } } From cde7b63738a27f30f5f68d3dc1e5895fbde365d5 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Sun, 19 Nov 2023 11:19:00 +0100 Subject: [PATCH 07/16] Resharper: Use lambda expression --- .../AtomicOperations/AtomicOperationsTests.cs | 5 +---- .../IntegrationTests/Archiving/ArchiveTests.cs | 5 +---- .../Creating/AtomicCreateResourceTests.cs | 5 +---- .../Links/AtomicAbsoluteLinksTests.cs | 5 +---- .../AtomicRelativeLinksWithNamespaceTests.cs | 5 +---- .../Mixed/AtomicTraceLoggingTests.cs | 5 +---- .../AtomicModelStateValidationTests.cs | 5 +---- .../AtomicSerializationResourceDefinitionTests.cs | 5 +---- .../Transactions/AtomicRollbackTests.cs | 10 ++-------- .../IntegrationTests/Blobs/BlobTests.cs | 5 +---- .../ContentNegotiation/AcceptHeaderTests.cs | 5 +---- .../ApiControllerAttributeLogTests.cs | 5 +---- .../ModelState/ModelStateValidationTests.cs | 4 +--- .../InputValidation/RequestBody/WorkflowTests.cs | 5 +---- .../Links/AbsoluteLinksWithNamespaceTests.cs | 5 +---- .../Links/AbsoluteLinksWithoutNamespaceTests.cs | 5 +---- .../Links/RelativeLinksWithNamespaceTests.cs | 5 +---- .../Links/RelativeLinksWithoutNamespaceTests.cs | 5 +---- .../IntegrationTests/Logging/LoggingTests.cs | 5 +---- .../IntegrationTests/Meta/ResponseMetaTests.cs | 10 ++-------- .../IntegrationTests/Meta/TopLevelCountTests.cs | 10 ++-------- .../OutboxTests.Group.cs | 5 +---- .../OutboxTests.User.cs | 5 +---- .../CreateResourceWithClientGeneratedIdTests.cs | 5 +---- .../RemoveFromToManyRelationshipTests.cs | 5 +---- .../Resources/ReplaceToManyRelationshipTests.cs | 5 +---- .../Resources/UpdateToOneRelationshipTests.cs | 5 +---- .../ResourceInjectionTests.cs | 5 +---- .../ResourceInheritanceReadTests.cs | 5 +---- .../IntegrationTests/Serialization/ETagTests.cs | 15 +++------------ .../Serialization/SerializationTests.cs | 5 +---- .../ZeroKeys/EmptyGuidAsKeyTests.cs | 5 +---- .../IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs | 5 +---- test/TestBuildingBlocks/IntegrationTestContext.cs | 11 ++--------- 34 files changed, 40 insertions(+), 160 deletions(-) diff --git a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs index 316acc3381..d434d1359c 100644 --- a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs +++ b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs @@ -396,10 +396,7 @@ public async Task Can_rollback_on_error() const string personLocalId = "new-person"; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return _testContext.ClearAllTablesAsync(dbContext); - }); + await _testContext.RunOnDatabaseAsync(dbContext => _testContext.ClearAllTablesAsync(dbContext)); var requestBody = new { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs index 7c282051f0..6b400325e3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs @@ -21,10 +21,7 @@ public ArchiveTests(IntegrationTestContext, testContext.UseController(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index 5639d44f40..c77610d8dc 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -26,10 +26,7 @@ public AtomicCreateResourceTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddSingleton(); - }); + testContext.ConfigureServices(services => services.AddSingleton()); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.AllowUnknownFieldsInRequestBody = false; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs index fdc7369a71..4b1ed95619 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs @@ -25,10 +25,7 @@ public AtomicAbsoluteLinksTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs index 9184161c07..6d5a276ecb 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs @@ -26,10 +26,7 @@ public AtomicRelativeLinksWithNamespaceTests( testContext.UseController(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs index d9c315513d..30099131ce 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs @@ -29,10 +29,7 @@ public AtomicTraceLoggingTests(IntegrationTestContext category != null && category.StartsWith("JsonApiDotNetCore.", StringComparison.Ordinal)); }); - testContext.ConfigureServices(services => - { - services.AddSingleton(loggerFactory); - }); + testContext.ConfigureServices(services => services.AddSingleton(loggerFactory)); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index 98564f3a57..1d095377bd 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -17,10 +17,7 @@ public AtomicModelStateValidationTests(IntegrationTestContext - { - services.AddSingleton(); - }); + _testContext.ConfigureServices(services => services.AddSingleton()); testContext.UseController(); } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs index e18153fc60..b8095b38f9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/AtomicSerializationResourceDefinitionTests.cs @@ -42,10 +42,7 @@ public async Task Transforms_on_create_resource_with_side_effects() List newCompanies = _fakers.RecordCompany.Generate(2); - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); var requestBody = new { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs index 54e1ca2b76..5fe125928c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs @@ -27,10 +27,7 @@ public async Task Can_rollback_on_error() DateTimeOffset newBornAt = _fakers.Performer.Generate().BornAt; string newTitle = _fakers.MusicTrack.Generate().Title; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTablesAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTablesAsync()); string unknownPerformerId = Unknown.StringId.For(); @@ -113,10 +110,7 @@ public async Task Can_restore_to_previous_savepoint_on_error() // Arrange string newTrackTitle = _fakers.MusicTrack.Generate().Title; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTablesAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTablesAsync()); const string trackLid = "track-1"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobTests.cs index 727245f06e..fca26c66c3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobTests.cs @@ -19,10 +19,7 @@ public BlobTests(IntegrationTestContext, BlobDbCo testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs index 20fc6f8032..f06df45bb4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs @@ -225,10 +225,7 @@ public async Task Denies_JsonApi_in_Accept_headers_at_operations_endpoint() const string route = "/operations"; const string contentType = HeaderConstants.AtomicOperationsMediaType; - Action setRequestHeaders = headers => - { - headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(HeaderConstants.MediaType)); - }; + Action setRequestHeaders = headers => headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(HeaderConstants.MediaType)); // Act (HttpResponseMessage httpResponse, Document responseDocument) = diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeLogTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeLogTests.cs index 949ea5da3b..5a83599a3a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeLogTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/ApiControllerAttributeLogTests.cs @@ -22,10 +22,7 @@ public ApiControllerAttributeLogTests() options.AddProvider(_loggerFactory); }); - ConfigureServices(services => - { - services.AddSingleton(_loggerFactory); - }); + ConfigureServices(services => services.AddSingleton(_loggerFactory)); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs index e6e83fa7c3..21fe575a2b 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateValidationTests.cs @@ -23,10 +23,8 @@ public ModelStateValidationTests(IntegrationTestContext - { // Polyfill for missing DateOnly/TimeOnly support in .NET 6 ModelState validation. - services.AddDateOnlyTimeOnlyStringConverters(); - }); + services.AddDateOnlyTimeOnlyStringConverters()); #endif } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowTests.cs index 895a8d2dc8..290a168fb1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowTests.cs @@ -17,10 +17,7 @@ public WorkflowTests(IntegrationTestContext, testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs index e2449d802b..3221215461 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs @@ -25,10 +25,7 @@ public AbsoluteLinksWithNamespaceTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = true; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs index 48f49abb99..b6060e3d7c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs @@ -25,10 +25,7 @@ public AbsoluteLinksWithoutNamespaceTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = true; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs index fb26ca6533..79a2b8408a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs @@ -25,10 +25,7 @@ public RelativeLinksWithNamespaceTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = true; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs index 4fc2198bca..7e7e1d8f7a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs @@ -25,10 +25,7 @@ public RelativeLinksWithoutNamespaceTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = true; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs index 8cb79e0376..81aca9c43e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs @@ -30,10 +30,7 @@ public LoggingTests(IntegrationTestContext, Lo options.AddFilter((category, _) => category != null && category.StartsWith("JsonApiDotNetCore.", StringComparison.Ordinal)); }); - testContext.ConfigureServices(services => - { - services.AddSingleton(loggerFactory); - }); + testContext.ConfigureServices(services => services.AddSingleton(loggerFactory)); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs index 1ba0e6e746..c96183dca0 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs @@ -19,10 +19,7 @@ public ResponseMetaTests(IntegrationTestContext, testContext.UseController(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddSingleton(); - }); + testContext.ConfigureServices(services => services.AddSingleton()); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = false; @@ -32,10 +29,7 @@ public ResponseMetaTests(IntegrationTestContext, public async Task Returns_top_level_meta() { // Arrange - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); const string route = "/supportTickets"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs index b7d7126d16..fbad011db0 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs @@ -21,10 +21,7 @@ public TopLevelCountTests(IntegrationTestContext, testContext.UseController(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeTotalResourceCount = true; @@ -86,10 +83,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Renders_resource_count_for_empty_collection() { // Arrange - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); const string route = "/supportTickets"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs index 38f78abb50..505675269f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.Group.cs @@ -19,10 +19,7 @@ public async Task Create_group_writes_to_outbox() string newGroupName = _fakers.DomainGroup.Generate().Name; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); var requestBody = new { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs index a00463843a..d725731020 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxTests.User.cs @@ -20,10 +20,7 @@ public async Task Create_user_writes_to_outbox() string newLoginName = _fakers.DomainUser.Generate().LoginName; string newDisplayName = _fakers.DomainUser.Generate().DisplayName!; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); var requestBody = new { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index 3a04f5e937..92c88d72a4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -22,10 +22,7 @@ public CreateResourceWithClientGeneratedIdTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.ClientIdGeneration = ClientIdGenerationMode.Required; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index c4928b0924..567559b5d4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -25,10 +25,7 @@ public RemoveFromToManyRelationshipTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddSingleton, RemoveExtraFromWorkItemDefinition>(); - }); + testContext.ConfigureServices(services => services.AddSingleton, RemoveExtraFromWorkItemDefinition>()); var workItemDefinition = (RemoveExtraFromWorkItemDefinition)testContext.Factory.Services.GetRequiredService>(); workItemDefinition.Reset(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index b3007bb936..0cee60ef86 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -22,10 +22,7 @@ public ReplaceToManyRelationshipTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index 636dbe6d3c..e04c33d1eb 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -22,10 +22,7 @@ public UpdateToOneRelationshipTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 7dd8c92726..3f371b2a67 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -21,10 +21,7 @@ public ResourceInjectionTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddSingleton(); - }); + testContext.ConfigureServices(services => services.AddSingleton()); _fakers = new InjectionFakers(testContext.Factory.Services); } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs index 9cea6284b8..2e0417370c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs @@ -35,10 +35,7 @@ protected ResourceInheritanceReadTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddResourceDefinition(); - }); + testContext.ConfigureServices(services => services.AddResourceDefinition()); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.UseRelativeLinks = true; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/ETagTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/ETagTests.cs index d9006ae629..4c950ee98e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/ETagTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/ETagTests.cs @@ -155,10 +155,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => string route = $"/meetings/{existingMeeting.StringId}"; - Action setRequestHeaders = headers => - { - headers.IfMatch.ParseAdd("\"12345\""); - }; + Action setRequestHeaders = headers => headers.IfMatch.ParseAdd("\"12345\""); // Act (HttpResponseMessage httpResponse, Document responseDocument) = @@ -196,10 +193,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => string responseETag = httpResponse1.Headers.ETag!.Tag; - Action setRequestHeaders2 = headers => - { - headers.IfNoneMatch.ParseAdd($"\"12345\", W/\"67890\", {responseETag}"); - }; + Action setRequestHeaders2 = headers => headers.IfNoneMatch.ParseAdd($"\"12345\", W/\"67890\", {responseETag}"); // Act (HttpResponseMessage httpResponse2, string responseDocument2) = await _testContext.ExecuteGetAsync(route, setRequestHeaders2); @@ -229,10 +223,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => const string route = "/meetings"; - Action setRequestHeaders = headers => - { - headers.IfNoneMatch.ParseAdd("\"Not-a-matching-value\""); - }; + Action setRequestHeaders = headers => headers.IfNoneMatch.ParseAdd("\"Not-a-matching-value\""); // Act (HttpResponseMessage httpResponse, string responseDocument) = await _testContext.ExecuteGetAsync(route, setRequestHeaders); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs index bb2df33c33..00680558a7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs @@ -23,10 +23,7 @@ public SerializationTests(IntegrationTestContext(); testContext.UseController(); - testContext.ConfigureServices(services => - { - services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>)); - }); + testContext.ConfigureServices(services => services.AddScoped(typeof(IResourceChangeTracker<>), typeof(NeverSameResourceChangeTracker<>))); var options = (JsonApiOptions)testContext.Factory.Services.GetRequiredService(); options.IncludeExceptionStackTraceInErrors = false; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs index 665f0bf5f4..fbe71bb1a1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs @@ -97,10 +97,7 @@ public async Task Can_create_resource_with_empty_ID() // Arrange string newName = _fakers.Map.Generate().Name; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); var requestBody = new { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs index 746ab7d6d2..7c5c682e1f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs @@ -96,10 +96,7 @@ public async Task Can_create_resource_with_zero_ID() // Arrange string newTitle = _fakers.Game.Generate().Title; - await _testContext.RunOnDatabaseAsync(dbContext => - { - return dbContext.ClearTableAsync(); - }); + await _testContext.RunOnDatabaseAsync(dbContext => dbContext.ClearTableAsync()); var requestBody = new { diff --git a/test/TestBuildingBlocks/IntegrationTestContext.cs b/test/TestBuildingBlocks/IntegrationTestContext.cs index a7158f9933..dc186b474b 100644 --- a/test/TestBuildingBlocks/IntegrationTestContext.cs +++ b/test/TestBuildingBlocks/IntegrationTestContext.cs @@ -170,17 +170,10 @@ protected override IHostBuilder CreateHostBuilder() }) .ConfigureWebHostDefaults(webBuilder => { - webBuilder.ConfigureServices(services => - { - _configureServices?.Invoke(services); - }); - + webBuilder.ConfigureServices(services => _configureServices?.Invoke(services)); webBuilder.UseStartup(); }) - .ConfigureLogging(options => - { - _loggingConfiguration?.Invoke(options); - }); + .ConfigureLogging(options => _loggingConfiguration?.Invoke(options)); // @formatter:wrap_before_first_method_call restore // @formatter:wrap_chained_method_calls restore From 250cfdf21e208143ce34ec03a1f03b7b4ade819c Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:22:57 +0100 Subject: [PATCH 08/16] Resharper: use raw strings --- JsonApiDotNetCore.sln.DotSettings | 3 + WarningSeverities.DotSettings | 2 + .../AtomicOperations/AtomicOperationsTests.cs | 170 ++- .../IntegrationTests/DapperTestContext.cs | 5 +- .../QueryStrings/FilterTests.cs | 493 ++++--- .../QueryStrings/IncludeTests.cs | 42 +- .../QueryStrings/SortTests.cs | 152 +- .../QueryStrings/SparseFieldSets.cs | 85 +- .../AddToToManyRelationshipTests.cs | 8 +- .../Relationships/FetchRelationshipTests.cs | 42 +- .../RemoveFromToManyRelationshipTests.cs | 66 +- .../ReplaceToManyRelationshipTests.cs | 107 +- .../UpdateToOneRelationshipTests.cs | 308 +++-- .../Resources/CreateResourceTests.cs | 134 +- .../Resources/DeleteResourceTests.cs | 20 +- .../ReadWrite/Resources/FetchResourceTests.cs | 75 +- .../Resources/UpdateResourceTests.cs | 90 +- .../Sql/SubQueryInJoinTests.cs | 315 +++-- .../IntegrationTests/SqlTextAdapter.cs | 2 +- .../UnitTests/RelationshipForeignKeyTests.cs | 8 +- .../Mixed/AtomicSerializationTests.cs | 118 +- .../Mixed/AtomicTraceLoggingTests.cs | 398 +++--- .../ExceptionHandlerTests.cs | 2 +- .../IntegrationTests/Logging/LoggingTests.cs | 240 ++-- .../Meta/ResponseMetaTests.cs | 36 +- .../ResourceInheritanceReadTests.cs | 1222 +++++++++-------- .../Serialization/SerializationTests.cs | 781 ++++++----- .../Response/ResponseModelAdapterTests.cs | 838 +++++------ .../ControllerGenerationTests.cs | 371 ++--- 29 files changed, 3305 insertions(+), 2828 deletions(-) diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings index 64125e085d..a945c3a40d 100644 --- a/JsonApiDotNetCore.sln.DotSettings +++ b/JsonApiDotNetCore.sln.DotSettings @@ -66,6 +66,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); WARNING WARNING WARNING + SUGGESTION SUGGESTION SUGGESTION DO_NOT_SHOW @@ -92,6 +93,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); WARNING SUGGESTION SUGGESTION + SUGGESTION WARNING SUGGESTION <?xml version="1.0" encoding="utf-16"?><Profile name="JADNC Full Cleanup"><XMLReformatCode>True</XMLReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JsInsertSemicolon>True</JsInsertSemicolon><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSReformatInactiveBranches>True</CSReformatInactiveBranches></Profile> @@ -114,6 +116,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); True True True + INDENT 1 1 False diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index 37457deebc..5c641e606f 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -124,6 +124,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -260,6 +261,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING diff --git a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs index d434d1359c..286820b702 100644 --- a/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs +++ b/test/DapperTests/IntegrationTests/AtomicOperations/AtomicOperationsTests.cs @@ -214,9 +214,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""People"" (""FirstName"", ""LastName"", ""AccountId"") -VALUES (@p1, @p2, @p3) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "People" ("FirstName", "LastName", "AccountId") + VALUES (@p1, @p2, @p3) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", newOwner.FirstName); @@ -226,9 +228,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newOwnerId); @@ -236,9 +240,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""People"" (""FirstName"", ""LastName"", ""AccountId"") -VALUES (@p1, @p2, @p3) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "People" ("FirstName", "LastName", "AccountId") + VALUES (@p1, @p2, @p3) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", newAssignee.FirstName); @@ -248,9 +254,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[3].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newAssigneeId); @@ -258,9 +266,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[4].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""Tags"" (""Name"", ""TodoItemId"") -VALUES (@p1, @p2) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "Tags" ("Name", "TodoItemId") + VALUES (@p1, @p2) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newTag.Name); @@ -269,9 +279,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[5].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTagId); @@ -279,10 +291,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[6].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"INSERT INTO ""TodoItems"" (""Description"", ""Priority"", ""DurationInHours"", ""CreatedAt"", ""LastModifiedAt"", ""OwnerId"", ""AssigneeId"") -VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "TodoItems" ("Description", "Priority", "DurationInHours", "CreatedAt", "LastModifiedAt", "OwnerId", "AssigneeId") + VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(7); command.Parameters.Should().Contain("@p1", newTodoItem.Description); @@ -296,10 +309,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[7].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -307,11 +321,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[8].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -319,9 +334,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[9].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newAssigneeId); @@ -330,11 +347,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[10].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""Name"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."Name" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -342,9 +360,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[11].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""LastModifiedAt"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "LastModifiedAt" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", DapperTestContext.FrozenTime); @@ -353,9 +373,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[12].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""Tags"" -SET ""TodoItemId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "Tags" + SET "TodoItemId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -364,10 +386,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[13].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -375,8 +398,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[14].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""People"" -WHERE ""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "People" + WHERE "Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newAssigneeId); @@ -463,9 +488,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""People"" (""FirstName"", ""LastName"", ""AccountId"") -VALUES (@p1, @p2, @p3) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "People" ("FirstName", "LastName", "AccountId") + VALUES (@p1, @p2, @p3) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", null); @@ -475,9 +502,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.ShouldContainKey("@p1").With(value => value.ShouldNotBeNull()); @@ -485,11 +514,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""AssigneeId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."AssigneeId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.ShouldContainKey("@p1").With(value => value.ShouldNotBeNull()); @@ -497,9 +527,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[3].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.ShouldContainKey("@p1").With(value => value.ShouldNotBeNull()); @@ -508,9 +540,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[4].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", unknownTodoItemId); diff --git a/test/DapperTests/IntegrationTests/DapperTestContext.cs b/test/DapperTests/IntegrationTests/DapperTestContext.cs index 0257490065..6bbcca6777 100644 --- a/test/DapperTests/IntegrationTests/DapperTestContext.cs +++ b/test/DapperTests/IntegrationTests/DapperTestContext.cs @@ -23,10 +23,11 @@ namespace DapperTests.IntegrationTests; [PublicAPI] public sealed class DapperTestContext : IntegrationTest { - private const string SqlServerClearAllTablesScript = @" + private const string SqlServerClearAllTablesScript = """ EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'; EXEC sp_MSForEachTable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'; - EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL';"; + EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'; + """; public static readonly DateTimeOffset FrozenTime = 29.September(2018).At(16, 41, 56).AsUtc().ToDateTimeOffset(); diff --git a/test/DapperTests/IntegrationTests/QueryStrings/FilterTests.cs b/test/DapperTests/IntegrationTests/QueryStrings/FilterTests.cs index d23a90765a..56bfdd5a7c 100644 --- a/test/DapperTests/IntegrationTests/QueryStrings/FilterTests.cs +++ b/test/DapperTests/IntegrationTests/QueryStrings/FilterTests.cs @@ -60,10 +60,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -LEFT JOIN ""RgbColors"" AS t2 ON t1.""Id"" = t2.""TagId"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", 0x00FF00); @@ -71,11 +73,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -LEFT JOIN ""RgbColors"" AS t2 ON t1.""Id"" = t2.""TagId"" -WHERE t2.""Id"" = @p1 -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId" + WHERE t2."Id" = @p1 + ORDER BY t1."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", 0x00FF00); @@ -121,10 +125,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -LEFT JOIN ""RgbColors"" AS t2 ON t1.""Id"" = t2.""TagId"" -WHERE t2.""Id"" IN (@p1, @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId" + WHERE t2."Id" IN (@p1, @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", 0x00FF00); @@ -133,11 +139,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -LEFT JOIN ""RgbColors"" AS t2 ON t1.""Id"" = t2.""TagId"" -WHERE t2.""Id"" IN (@p1, @p2) -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + LEFT JOIN "RgbColors" AS t2 ON t1."Id" = t2."TagId" + WHERE t2."Id" IN (@p1, @p2) + ORDER BY t1."Id" + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", 0x00FF00); @@ -180,11 +188,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -LEFT JOIN ""People"" AS t3 ON t1.""AssigneeId"" = t3.""Id"" -WHERE (t2.""Id"" = @p1) AND (t3.""Id"" IS NULL)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + LEFT JOIN "People" AS t3 ON t1."AssigneeId" = t3."Id" + WHERE (t2."Id" = @p1) AND (t3."Id" IS NULL) + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -192,17 +202,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t4.""Id"", t4.""CreatedAt"", t4.""Description"", t4.""DurationInHours"", t4.""LastModifiedAt"", t4.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - LEFT JOIN ""People"" AS t3 ON t2.""AssigneeId"" = t3.""Id"" - WHERE t3.""Id"" IS NULL -) AS t4 ON t1.""Id"" = t4.""OwnerId"" -WHERE t1.""Id"" = @p1 -ORDER BY t4.""Priority"", t4.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t4."Id", t4."CreatedAt", t4."Description", t4."DurationInHours", t4."LastModifiedAt", t4."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + LEFT JOIN "People" AS t3 ON t2."AssigneeId" = t3."Id" + WHERE t3."Id" IS NULL + ) AS t4 ON t1."Id" = t4."OwnerId" + WHERE t1."Id" = @p1 + ORDER BY t4."Priority", t4."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -244,10 +255,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE (t2.""Id"" = @p1) AND (t1.""DurationInHours"" IS NULL)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE (t2."Id" = @p1) AND (t1."DurationInHours" IS NULL) + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -255,16 +268,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t3.""Id"", t3.""CreatedAt"", t3.""Description"", t3.""DurationInHours"", t3.""LastModifiedAt"", t3.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE t2.""DurationInHours"" IS NULL -) AS t3 ON t1.""Id"" = t3.""OwnerId"" -WHERE t1.""Id"" = @p1 -ORDER BY t3.""Priority"", t3.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t3."Id", t3."CreatedAt", t3."Description", t3."DurationInHours", t3."LastModifiedAt", t3."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + WHERE t2."DurationInHours" IS NULL + ) AS t3 ON t1."Id" = t3."OwnerId" + WHERE t1."Id" = @p1 + ORDER BY t3."Priority", t3."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -309,9 +323,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -WHERE t1.""Priority"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + WHERE t1."Priority" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItems[1].Priority); @@ -319,11 +335,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Priority"" = @p1 -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Priority" = @p1 + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItems[1].Priority); @@ -368,10 +385,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE (t2.""Id"" = @p1) AND (t1.""Description"" = @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE (t2."Id" = @p1) AND (t1."Description" = @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", person.Id); @@ -380,16 +399,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t3.""Id"", t3.""CreatedAt"", t3.""Description"", t3.""DurationInHours"", t3.""LastModifiedAt"", t3.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""AssigneeId"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE t2.""Description"" = @p2 -) AS t3 ON t1.""Id"" = t3.""AssigneeId"" -WHERE t1.""Id"" = @p1 -ORDER BY t3.""Priority"", t3.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t3."Id", t3."CreatedAt", t3."Description", t3."DurationInHours", t3."LastModifiedAt", t3."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."AssigneeId", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "TodoItems" AS t2 + WHERE t2."Description" = @p2 + ) AS t3 ON t1."Id" = t3."AssigneeId" + WHERE t1."Id" = @p1 + ORDER BY t3."Priority", t3."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", person.Id); @@ -435,22 +455,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t2.""LastName"" = t2.""FirstName""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t2."LastName" = t2."FirstName" + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t2.""LastName"" = t2.""FirstName"" -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t2."LastName" = t2."FirstName" + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -493,10 +516,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE (t2.""Id"" = @p1) AND (t1.""Priority"" = @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE (t2."Id" = @p1) AND (t1."Priority" = @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", person.Id); @@ -505,16 +530,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t3.""Id"", t3.""CreatedAt"", t3.""Description"", t3.""DurationInHours"", t3.""LastModifiedAt"", t3.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE t2.""Priority"" = @p2 -) AS t3 ON t1.""Id"" = t3.""OwnerId"" -WHERE t1.""Id"" = @p1 -ORDER BY t3.""Priority"", t3.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t3."Id", t3."CreatedAt", t3."Description", t3."DurationInHours", t3."LastModifiedAt", t3."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + WHERE t2."Priority" = @p2 + ) AS t3 ON t1."Id" = t3."OwnerId" + WHERE t1."Id" = @p1 + ORDER BY t3."Priority", t3."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", person.Id); @@ -558,9 +584,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -WHERE t1.""Description"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + WHERE t1."Description" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -568,11 +596,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Description"" = @p1 -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Description" = @p1 + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -617,9 +646,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1 -WHERE (NOT (t1.""FirstName"" = @p1)) OR (t1.""FirstName"" IS NULL)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + WHERE (NOT (t1."FirstName" = @p1)) OR (t1."FirstName" IS NULL) + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -627,10 +658,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE (NOT (t1.""FirstName"" = @p1)) OR (t1.""FirstName"" IS NULL) -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE (NOT (t1."FirstName" = @p1)) OR (t1."FirstName" IS NULL) + ORDER BY t1."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -676,10 +709,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE (NOT ((t2.""FirstName"" = @p1) AND (t2.""LastName"" = @p2))) OR (t2.""FirstName"" IS NULL) OR (t2.""LastName"" IS NULL)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE (NOT ((t2."FirstName" = @p1) AND (t2."LastName" = @p2))) OR (t2."FirstName" IS NULL) OR (t2."LastName" IS NULL) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", "X"); @@ -688,12 +723,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE (NOT ((t2.""FirstName"" = @p1) AND (t2.""LastName"" = @p2))) OR (t2.""FirstName"" IS NULL) OR (t2.""LastName"" IS NULL) -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE (NOT ((t2."FirstName" = @p1) AND (t2."LastName" = @p2))) OR (t2."FirstName" IS NULL) OR (t2."LastName" IS NULL) + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", "X"); @@ -742,10 +778,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE (t1.""Description"" LIKE 'T%') AND (NOT (t1.""Description"" IN (@p1, @p2))) AND (t2.""FirstName"" = @p3) AND (t1.""Description"" LIKE '%o%')")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE (t1."Description" LIKE 'T%') AND (NOT (t1."Description" IN (@p1, @p2))) AND (t2."FirstName" = @p3) AND (t1."Description" LIKE '%o%') + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "Four"); @@ -755,12 +793,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE (t1.""Description"" LIKE 'T%') AND (NOT (t1.""Description"" IN (@p1, @p2))) AND (t2.""FirstName"" = @p3) AND (t1.""Description"" LIKE '%o%') -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE (t1."Description" LIKE 'T%') AND (NOT (t1."Description" IN (@p1, @p2))) AND (t2."FirstName" = @p3) AND (t1."Description" LIKE '%o%') + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "Four"); @@ -813,19 +852,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -WHERE (t1.""Name"" LIKE '%A\%%' ESCAPE '\') OR (t1.""Name"" LIKE '%A\_%' ESCAPE '\') OR (t1.""Name"" LIKE '%A\\%' ESCAPE '\') OR (t1.""Name"" LIKE '%A''%') OR (t1.""Name"" LIKE '%\%\_\\''%' ESCAPE '\')")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + WHERE (t1."Name" LIKE '%A\%%' ESCAPE '\') OR (t1."Name" LIKE '%A\_%' ESCAPE '\') OR (t1."Name" LIKE '%A\\%' ESCAPE '\') OR (t1."Name" LIKE '%A''%') OR (t1."Name" LIKE '%\%\_\\''%' ESCAPE '\') + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -WHERE (t1.""Name"" LIKE '%A\%%' ESCAPE '\') OR (t1.""Name"" LIKE '%A\_%' ESCAPE '\') OR (t1.""Name"" LIKE '%A\\%' ESCAPE '\') OR (t1.""Name"" LIKE '%A''%') OR (t1.""Name"" LIKE '%\%\_\\''%' ESCAPE '\') -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + WHERE (t1."Name" LIKE '%A\%%' ESCAPE '\') OR (t1."Name" LIKE '%A\_%' ESCAPE '\') OR (t1."Name" LIKE '%A\\%' ESCAPE '\') OR (t1."Name" LIKE '%A''%') OR (t1."Name" LIKE '%\%\_\\''%' ESCAPE '\') + ORDER BY t1."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -871,9 +914,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -WHERE (t1.""DurationInHours"" > @p1) OR (t1.""DurationInHours"" <= @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + WHERE (t1."DurationInHours" > @p1) OR (t1."DurationInHours" <= @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", 250); @@ -882,11 +927,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE (t1.""DurationInHours"" > @p1) OR (t1.""DurationInHours"" <= @p2) -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE (t1."DurationInHours" > @p1) OR (t1."DurationInHours" <= @p2) + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", 250); @@ -932,15 +978,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t4 ON t1.""OwnerId"" = t4.""Id"" -WHERE (( - SELECT COUNT(*) - FROM ""People"" AS t2 - LEFT JOIN ""TodoItems"" AS t3 ON t2.""Id"" = t3.""AssigneeId"" - WHERE t1.""OwnerId"" = t2.""Id"" -) > @p1) AND (NOT (t4.""Id"" IS NULL))")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t4 ON t1."OwnerId" = t4."Id" + WHERE (( + SELECT COUNT(*) + FROM "People" AS t2 + LEFT JOIN "TodoItems" AS t3 ON t2."Id" = t3."AssigneeId" + WHERE t1."OwnerId" = t2."Id" + ) > @p1) AND (NOT (t4."Id" IS NULL)) + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", 1); @@ -948,17 +996,18 @@ SELECT COUNT(*) store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t4 ON t1.""OwnerId"" = t4.""Id"" -WHERE (( - SELECT COUNT(*) - FROM ""People"" AS t2 - LEFT JOIN ""TodoItems"" AS t3 ON t2.""Id"" = t3.""AssigneeId"" - WHERE t1.""OwnerId"" = t2.""Id"" -) > @p1) AND (NOT (t4.""Id"" IS NULL)) -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t4 ON t1."OwnerId" = t4."Id" + WHERE (( + SELECT COUNT(*) + FROM "People" AS t2 + LEFT JOIN "TodoItems" AS t3 ON t2."Id" = t3."AssigneeId" + WHERE t1."OwnerId" = t2."Id" + ) > @p1) AND (NOT (t4."Id" IS NULL)) + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", 1); @@ -1013,19 +1062,21 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -WHERE EXISTS ( - SELECT 1 - FROM ""People"" AS t2 - LEFT JOIN ""TodoItems"" AS t3 ON t2.""Id"" = t3.""AssigneeId"" - INNER JOIN ""People"" AS t5 ON t3.""OwnerId"" = t5.""Id"" - WHERE (t1.""OwnerId"" = t2.""Id"") AND (EXISTS ( - SELECT 1 - FROM ""Tags"" AS t4 - WHERE (t3.""Id"" = t4.""TodoItemId"") AND (t4.""Name"" = @p1) - )) AND (t5.""LastName"" = @p2) AND (t3.""Description"" = @p3) -)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + WHERE EXISTS ( + SELECT 1 + FROM "People" AS t2 + LEFT JOIN "TodoItems" AS t3 ON t2."Id" = t3."AssigneeId" + INNER JOIN "People" AS t5 ON t3."OwnerId" = t5."Id" + WHERE (t1."OwnerId" = t2."Id") AND (EXISTS ( + SELECT 1 + FROM "Tags" AS t4 + WHERE (t3."Id" = t4."TodoItemId") AND (t4."Name" = @p1) + )) AND (t5."LastName" = @p2) AND (t3."Description" = @p3) + ) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "Personal"); @@ -1035,21 +1086,22 @@ SELECT 1 store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE EXISTS ( - SELECT 1 - FROM ""People"" AS t2 - LEFT JOIN ""TodoItems"" AS t3 ON t2.""Id"" = t3.""AssigneeId"" - INNER JOIN ""People"" AS t5 ON t3.""OwnerId"" = t5.""Id"" - WHERE (t1.""OwnerId"" = t2.""Id"") AND (EXISTS ( - SELECT 1 - FROM ""Tags"" AS t4 - WHERE (t3.""Id"" = t4.""TodoItemId"") AND (t4.""Name"" = @p1) - )) AND (t5.""LastName"" = @p2) AND (t3.""Description"" = @p3) -) -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE EXISTS ( + SELECT 1 + FROM "People" AS t2 + LEFT JOIN "TodoItems" AS t3 ON t2."Id" = t3."AssigneeId" + INNER JOIN "People" AS t5 ON t3."OwnerId" = t5."Id" + WHERE (t1."OwnerId" = t2."Id") AND (EXISTS ( + SELECT 1 + FROM "Tags" AS t4 + WHERE (t3."Id" = t4."TodoItemId") AND (t4."Name" = @p1) + )) AND (t5."LastName" = @p2) AND (t3."Description" = @p3) + ) + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "Personal"); @@ -1100,29 +1152,33 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1 -WHERE EXISTS ( - SELECT 1 - FROM ""TodoItems"" AS t2 - LEFT JOIN ""People"" AS t3 ON t2.""AssigneeId"" = t3.""Id"" - WHERE (t1.""Id"" = t2.""OwnerId"") AND (NOT (t3.""Id"" IS NULL)) AND (t3.""FirstName"" IS NULL) -)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + WHERE EXISTS ( + SELECT 1 + FROM "TodoItems" AS t2 + LEFT JOIN "People" AS t3 ON t2."AssigneeId" = t3."Id" + WHERE (t1."Id" = t2."OwnerId") AND (NOT (t3."Id" IS NULL)) AND (t3."FirstName" IS NULL) + ) + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE EXISTS ( - SELECT 1 - FROM ""TodoItems"" AS t2 - LEFT JOIN ""People"" AS t3 ON t2.""AssigneeId"" = t3.""Id"" - WHERE (t1.""Id"" = t2.""OwnerId"") AND (NOT (t3.""Id"" IS NULL)) AND (t3.""FirstName"" IS NULL) -) -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE EXISTS ( + SELECT 1 + FROM "TodoItems" AS t2 + LEFT JOIN "People" AS t3 ON t2."AssigneeId" = t3."Id" + WHERE (t1."Id" = t2."OwnerId") AND (NOT (t3."Id" IS NULL)) AND (t3."FirstName" IS NULL) + ) + ORDER BY t1."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -1185,9 +1241,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -WHERE (t1.""Description"" = @p1) AND ((t1.""Priority"" = @p2) OR (t1.""DurationInHours"" = @p3))")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + WHERE (t1."Description" = @p1) AND ((t1."Priority" = @p2) OR (t1."DurationInHours" = @p3)) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "1"); @@ -1197,11 +1255,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE (t1.""Description"" = @p1) AND ((t1.""Priority"" = @p2) OR (t1.""DurationInHours"" = @p3)) -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE (t1."Description" = @p1) AND ((t1."Priority" = @p2) OR (t1."DurationInHours" = @p3)) + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", "1"); diff --git a/test/DapperTests/IntegrationTests/QueryStrings/IncludeTests.cs b/test/DapperTests/IntegrationTests/QueryStrings/IncludeTests.cs index 153e028b01..09d307a256 100644 --- a/test/DapperTests/IntegrationTests/QueryStrings/IncludeTests.cs +++ b/test/DapperTests/IntegrationTests/QueryStrings/IncludeTests.cs @@ -148,22 +148,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"", t3.""Id"", t3.""FirstName"", t3.""LastName"", t4.""Id"", t4.""CreatedAt"", t4.""Description"", t4.""DurationInHours"", t4.""LastModifiedAt"", t4.""Priority"", t5.""Id"", t5.""Name"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -INNER JOIN ""People"" AS t3 ON t1.""OwnerId"" = t3.""Id"" -LEFT JOIN ""TodoItems"" AS t4 ON t3.""Id"" = t4.""AssigneeId"" -LEFT JOIN ""Tags"" AS t5 ON t1.""Id"" = t5.""TodoItemId"" -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC, t4.""Priority"", t4.""LastModifiedAt"" DESC, t5.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName", t3."Id", t3."FirstName", t3."LastName", t4."Id", t4."CreatedAt", t4."Description", t4."DurationInHours", t4."LastModifiedAt", t4."Priority", t5."Id", t5."Name" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + INNER JOIN "People" AS t3 ON t1."OwnerId" = t3."Id" + LEFT JOIN "TodoItems" AS t4 ON t3."Id" = t4."AssigneeId" + LEFT JOIN "Tags" AS t5 ON t1."Id" = t5."TodoItemId" + ORDER BY t1."Priority", t1."LastModifiedAt" DESC, t4."Priority", t4."LastModifiedAt" DESC, t5."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -213,20 +216,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""Name"", t3.""Id"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -LEFT JOIN ""RgbColors"" AS t3 ON t2.""Id"" = t3.""TagId"" -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC, t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."Name", t3."Id" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + LEFT JOIN "RgbColors" AS t3 ON t2."Id" = t3."TagId" + ORDER BY t1."Priority", t1."LastModifiedAt" DESC, t2."Id" + """)); command.Parameters.Should().BeEmpty(); }); diff --git a/test/DapperTests/IntegrationTests/QueryStrings/SortTests.cs b/test/DapperTests/IntegrationTests/QueryStrings/SortTests.cs index bdde400b84..33643519ce 100644 --- a/test/DapperTests/IntegrationTests/QueryStrings/SortTests.cs +++ b/test/DapperTests/IntegrationTests/QueryStrings/SortTests.cs @@ -60,18 +60,21 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -ORDER BY t1.""Description"" DESC, t1.""DurationInHours"", t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + ORDER BY t1."Description" DESC, t1."DurationInHours", t1."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -125,10 +128,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -136,13 +141,14 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"", t3.""Id"", t3.""Name"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -LEFT JOIN ""Tags"" AS t3 ON t2.""Id"" = t3.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY t2.""DurationInHours"" DESC, t3.""Name""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority", t3."Id", t3."Name" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + LEFT JOIN "Tags" AS t3 ON t2."Id" = t3."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY t2."DurationInHours" DESC, t3."Name" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -188,22 +194,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -ORDER BY ( - SELECT COUNT(*) - FROM ""Tags"" AS t2 - WHERE t1.""Id"" = t2.""TodoItemId"" -) DESC, t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + ORDER BY ( + SELECT COUNT(*) + FROM "Tags" AS t2 + WHERE t1."Id" = t2."TodoItemId" + ) DESC, t1."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -248,10 +257,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -259,16 +270,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -WHERE t1.""Id"" = @p1 -ORDER BY ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" -) DESC, t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + WHERE t1."Id" = @p1 + ORDER BY ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) DESC, t2."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -314,10 +326,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -325,17 +339,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"", t4.""Id"", t4.""Name"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -LEFT JOIN ""Tags"" AS t4 ON t2.""Id"" = t4.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" -) DESC, t2.""Id"", t4.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority", t4."Id", t4."Name" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + LEFT JOIN "Tags" AS t4 ON t2."Id" = t4."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) DESC, t2."Id", t4."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -386,23 +401,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -ORDER BY t1.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" -) DESC, t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + ORDER BY t1."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) DESC, t2."Id" + """)); command.Parameters.Should().BeEmpty(); }); diff --git a/test/DapperTests/IntegrationTests/QueryStrings/SparseFieldSets.cs b/test/DapperTests/IntegrationTests/QueryStrings/SparseFieldSets.cs index 719b3b2d36..e66616810e 100644 --- a/test/DapperTests/IntegrationTests/QueryStrings/SparseFieldSets.cs +++ b/test/DapperTests/IntegrationTests/QueryStrings/SparseFieldSets.cs @@ -88,20 +88,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""Description"", t1.""DurationInHours"", t2.""Id"", t2.""LastName"", t3.""Id"", t3.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -INNER JOIN ""People"" AS t3 ON t1.""OwnerId"" = t3.""Id"" -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Description", t1."DurationInHours", t2."Id", t2."LastName", t3."Id", t3."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + INNER JOIN "People" AS t3 ON t1."OwnerId" = t3."Id" + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -142,9 +145,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Description"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Description" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -192,10 +197,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""TodoItemId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."TodoItemId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -203,11 +210,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY t2."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -247,9 +256,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -289,9 +300,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -332,9 +345,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", person.Id); @@ -380,11 +395,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Description"", t2.""Id"", t2.""Name"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Description", t2."Id", t2."Name" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY t2."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/AddToToManyRelationshipTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/AddToToManyRelationshipTests.cs index 80206b0750..e6c49c1f62 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/AddToToManyRelationshipTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/AddToToManyRelationshipTests.cs @@ -80,9 +80,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""OwnerId"" = @p1 -WHERE ""Id"" IN (@p2, @p3)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "OwnerId" = @p1 + WHERE "Id" IN (@p2, @p3) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", existingPerson.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/FetchRelationshipTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/FetchRelationshipTests.cs index 22ebd01a4e..227bbdb755 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/FetchRelationshipTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/FetchRelationshipTests.cs @@ -56,10 +56,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -99,10 +101,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -146,10 +150,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""TodoItemId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."TodoItemId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -157,11 +163,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY t2."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/RemoveFromToManyRelationshipTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/RemoveFromToManyRelationshipTests.cs index c118d8ff59..f31a89c73e 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/RemoveFromToManyRelationshipTests.cs @@ -82,14 +82,16 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t3.""Id"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""AssigneeId"" - FROM ""TodoItems"" AS t2 - WHERE t2.""Id"" IN (@p2, @p3) -) AS t3 ON t1.""Id"" = t3.""AssigneeId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t3."Id" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."AssigneeId" + FROM "TodoItems" AS t2 + WHERE t2."Id" IN (@p2, @p3) + ) AS t3 ON t1."Id" = t3."AssigneeId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -99,9 +101,11 @@ LEFT JOIN ( store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" IN (@p1, @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "TodoItems" AS t1 + WHERE t1."Id" IN (@p1, @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.AssignedTodoItems.ElementAt(0).Id); @@ -110,9 +114,11 @@ LEFT JOIN ( store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" IN (@p2, @p3)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" IN (@p2, @p3) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", null); @@ -181,14 +187,16 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t3.""Id"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""OwnerId"" - FROM ""TodoItems"" AS t2 - WHERE t2.""Id"" IN (@p2, @p3) -) AS t3 ON t1.""Id"" = t3.""OwnerId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t3."Id" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."OwnerId" + FROM "TodoItems" AS t2 + WHERE t2."Id" IN (@p2, @p3) + ) AS t3 ON t1."Id" = t3."OwnerId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -198,9 +206,11 @@ LEFT JOIN ( store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" IN (@p1, @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "TodoItems" AS t1 + WHERE t1."Id" IN (@p1, @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.OwnedTodoItems.ElementAt(0).Id); @@ -209,8 +219,10 @@ LEFT JOIN ( store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""TodoItems"" -WHERE ""Id"" IN (@p1, @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "TodoItems" + WHERE "Id" IN (@p1, @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.OwnedTodoItems.ElementAt(0).Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/ReplaceToManyRelationshipTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/ReplaceToManyRelationshipTests.cs index e1bbcf1190..05b0710132 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/ReplaceToManyRelationshipTests.cs @@ -63,11 +63,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""AssigneeId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."AssigneeId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -75,9 +76,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" IN (@p2, @p3)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" IN (@p2, @p3) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", null); @@ -128,11 +131,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -140,8 +144,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""TodoItems"" -WHERE ""Id"" IN (@p1, @p2)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "TodoItems" + WHERE "Id" IN (@p1, @p2) + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.OwnedTodoItems.ElementAt(0).Id); @@ -207,11 +213,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""AssigneeId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."AssigneeId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -219,9 +226,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" IN (@p2, @p3)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" IN (@p2, @p3) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -283,11 +292,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""AssigneeId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."AssigneeId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -295,9 +305,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -306,9 +318,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -369,11 +383,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -381,8 +396,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""TodoItems"" -WHERE ""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "TodoItems" + WHERE "Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.OwnedTodoItems.ElementAt(0).Id); @@ -390,9 +407,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""OwnerId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "OwnerId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/UpdateToOneRelationshipTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/UpdateToOneRelationshipTests.cs index 5ed90caa2a..e42efaf2e1 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Relationships/UpdateToOneRelationshipTests.cs @@ -69,11 +69,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""People"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""AccountId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "People" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."AccountId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -81,9 +82,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -138,11 +141,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""LoginAccounts"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""Id"" = t2.""AccountId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."FirstName", t2."LastName" + FROM "LoginAccounts" AS t1 + LEFT JOIN "People" AS t2 ON t1."Id" = t2."AccountId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -150,9 +154,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -194,11 +200,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""LoginAccounts"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""Id"" = t2.""AccountId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."FirstName", t2."LastName" + FROM "LoginAccounts" AS t1 + LEFT JOIN "People" AS t2 ON t1."Id" = t2."AccountId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -245,11 +252,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""EmailAddress"", t2.""PhoneNumber"" -FROM ""LoginAccounts"" AS t1 -INNER JOIN ""AccountRecoveries"" AS t2 ON t1.""RecoveryId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."EmailAddress", t2."PhoneNumber" + FROM "LoginAccounts" AS t1 + INNER JOIN "AccountRecoveries" AS t2 ON t1."RecoveryId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -296,11 +304,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""EmailAddress"", t1.""PhoneNumber"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""AccountRecoveries"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""Id"" = t2.""RecoveryId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."EmailAddress", t1."PhoneNumber", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "AccountRecoveries" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."Id" = t2."RecoveryId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingAccountRecovery.Id); @@ -349,11 +358,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -361,9 +371,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -411,11 +423,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -470,11 +483,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""People"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""AccountId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "People" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."AccountId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -482,9 +496,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""AccountId"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "AccountId" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -493,9 +509,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -552,11 +570,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""LoginAccounts"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""Id"" = t2.""AccountId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."FirstName", t2."LastName" + FROM "LoginAccounts" AS t1 + LEFT JOIN "People" AS t2 ON t1."Id" = t2."AccountId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -564,9 +583,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingLoginAccount.Id); @@ -622,11 +643,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -634,9 +656,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson.Id); @@ -699,11 +723,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""People"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""AccountId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "People" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."AccountId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingPerson1.Id); @@ -711,9 +736,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""AccountId"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "AccountId" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -722,9 +749,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingPerson2.Account.Id); @@ -789,11 +818,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""LoginAccounts"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""Id"" = t2.""AccountId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."FirstName", t2."LastName" + FROM "LoginAccounts" AS t1 + LEFT JOIN "People" AS t2 ON t1."Id" = t2."AccountId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount1.Id); @@ -801,9 +831,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", null); @@ -812,9 +844,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingLoginAccount1.Id); @@ -877,11 +911,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"", t2.""Id"", t2.""EmailAddress"", t2.""PhoneNumber"" -FROM ""LoginAccounts"" AS t1 -INNER JOIN ""AccountRecoveries"" AS t2 ON t1.""RecoveryId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName", t2."Id", t2."EmailAddress", t2."PhoneNumber" + FROM "LoginAccounts" AS t1 + INNER JOIN "AccountRecoveries" AS t2 ON t1."RecoveryId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount1.Id); @@ -889,8 +924,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""LoginAccounts"" -WHERE ""RecoveryId"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "LoginAccounts" + WHERE "RecoveryId" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingLoginAccount2.Recovery.Id); @@ -898,9 +935,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""LoginAccounts"" -SET ""RecoveryId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "LoginAccounts" + SET "RecoveryId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingLoginAccount2.Recovery.Id); @@ -963,11 +1002,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""EmailAddress"", t1.""PhoneNumber"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""AccountRecoveries"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""Id"" = t2.""RecoveryId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."EmailAddress", t1."PhoneNumber", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "AccountRecoveries" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."Id" = t2."RecoveryId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingAccountRecovery1.Id); @@ -975,8 +1015,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""LoginAccounts"" -WHERE ""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "LoginAccounts" + WHERE "Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingAccountRecovery1.Account.Id); @@ -984,9 +1026,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""LoginAccounts"" -SET ""RecoveryId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "LoginAccounts" + SET "RecoveryId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingAccountRecovery1.Id); @@ -1045,11 +1089,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem1.Id); @@ -1057,9 +1102,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""AssigneeId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "AssigneeId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingTodoItem2.Assignee.Id); @@ -1116,11 +1163,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem1.Id); @@ -1128,9 +1176,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""OwnerId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "OwnerId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingTodoItem2.Owner.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Resources/CreateResourceTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Resources/CreateResourceTests.cs index 88ee185132..199c8641e6 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Resources/CreateResourceTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Resources/CreateResourceTests.cs @@ -137,10 +137,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"INSERT INTO ""TodoItems"" (""Description"", ""Priority"", ""DurationInHours"", ""CreatedAt"", ""LastModifiedAt"", ""OwnerId"", ""AssigneeId"") -VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "TodoItems" ("Description", "Priority", "DurationInHours", "CreatedAt", "LastModifiedAt", "OwnerId", "AssigneeId") + VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(7); command.Parameters.Should().Contain("@p1", newTodoItem.Description); @@ -154,9 +155,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""Tags"" -SET ""TodoItemId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "Tags" + SET "TodoItemId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -165,10 +168,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -265,10 +269,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"INSERT INTO ""TodoItems"" (""Description"", ""Priority"", ""DurationInHours"", ""CreatedAt"", ""LastModifiedAt"", ""OwnerId"", ""AssigneeId"") -VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "TodoItems" ("Description", "Priority", "DurationInHours", "CreatedAt", "LastModifiedAt", "OwnerId", "AssigneeId") + VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(7); command.Parameters.Should().Contain("@p1", newTodoItem.Description); @@ -282,10 +287,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newTodoItemId); @@ -435,8 +441,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""LoginAccounts"" -WHERE ""RecoveryId"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "LoginAccounts" + WHERE "RecoveryId" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingAccountRecovery.Id); @@ -444,9 +452,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""LoginAccounts"" (""UserName"", ""LastUsedAt"", ""RecoveryId"") -VALUES (@p1, @p2, @p3) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "LoginAccounts" ("UserName", "LastUsedAt", "RecoveryId") + VALUES (@p1, @p2, @p3) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", newUserName); @@ -456,9 +466,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""People"" -SET ""AccountId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "People" + SET "AccountId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newLoginAccountId); @@ -467,9 +479,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[3].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""LastUsedAt"", t1.""UserName"" -FROM ""LoginAccounts"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."LastUsedAt", t1."UserName" + FROM "LoginAccounts" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newLoginAccountId); @@ -528,9 +542,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""People"" (""FirstName"", ""LastName"", ""AccountId"") -VALUES (@p1, @p2, @p3) -RETURNING ""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "People" ("FirstName", "LastName", "AccountId") + VALUES (@p1, @p2, @p3) + RETURNING "Id" + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", newPerson.FirstName); @@ -540,9 +556,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"" -FROM ""People"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName" + FROM "People" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newPersonId); @@ -613,8 +631,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""RgbColors"" -WHERE ""TagId"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "RgbColors" + WHERE "TagId" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTag.Id); @@ -622,9 +642,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""RgbColors"" (""Id"", ""TagId"") -VALUES (@p1, @p2) -RETURNING ""Id""", true)); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "RgbColors" ("Id", "TagId") + VALUES (@p1, @p2) + RETURNING "Id" + """, true)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", newColor.Id); @@ -633,9 +655,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""RgbColors"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "RgbColors" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", newColor.Id); @@ -701,8 +725,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""RgbColors"" -WHERE ""TagId"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "RgbColors" + WHERE "TagId" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTag.Id); @@ -710,9 +736,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"INSERT INTO ""RgbColors"" (""Id"", ""TagId"") -VALUES (@p1, @p2) -RETURNING ""Id""", true)); + command.Statement.Should().Be(_testContext.AdaptSql(""" + INSERT INTO "RgbColors" ("Id", "TagId") + VALUES (@p1, @p2) + RETURNING "Id" + """, true)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingColor.Id); @@ -721,9 +749,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""RgbColors"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "RgbColors" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingColor.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Resources/DeleteResourceTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Resources/DeleteResourceTests.cs index 94f6d17b60..af81d138a6 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Resources/DeleteResourceTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Resources/DeleteResourceTests.cs @@ -66,8 +66,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""TodoItems"" -WHERE ""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "TodoItems" + WHERE "Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -103,8 +105,10 @@ public async Task Cannot_delete_unknown_resource() store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"DELETE FROM ""TodoItems"" -WHERE ""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + DELETE FROM "TodoItems" + WHERE "Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", unknownTodoItemId); @@ -112,9 +116,11 @@ public async Task Cannot_delete_unknown_resource() store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", unknownTodoItemId); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Resources/FetchResourceTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Resources/FetchResourceTests.cs index 327a0b3051..0027de1d38 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Resources/FetchResourceTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Resources/FetchResourceTests.cs @@ -74,18 +74,21 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + ORDER BY t1."Priority", t1."LastModifiedAt" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -131,10 +134,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -170,10 +174,11 @@ public async Task Cannot_get_unknown_primary_resource_by_ID() store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", unknownTodoItemId); @@ -223,10 +228,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""Tags"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""TodoItemId"" = t2.""Id"" -WHERE t2.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "Tags" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."TodoItemId" = t2."Id" + WHERE t2."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -234,11 +241,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"", t2.""Name"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""Tags"" AS t2 ON t1.""Id"" = t2.""TodoItemId"" -WHERE t1.""Id"" = @p1 -ORDER BY t2.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."Name" + FROM "TodoItems" AS t1 + LEFT JOIN "Tags" AS t2 ON t1."Id" = t2."TodoItemId" + WHERE t1."Id" = @p1 + ORDER BY t2."Id" + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -283,10 +292,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); @@ -325,10 +336,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t2.""Id"", t2.""FirstName"", t2.""LastName"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t2."Id", t2."FirstName", t2."LastName" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", todoItem.Id); diff --git a/test/DapperTests/IntegrationTests/ReadWrite/Resources/UpdateResourceTests.cs b/test/DapperTests/IntegrationTests/ReadWrite/Resources/UpdateResourceTests.cs index 7ac11df3c9..f51b7c6b52 100644 --- a/test/DapperTests/IntegrationTests/ReadWrite/Resources/UpdateResourceTests.cs +++ b/test/DapperTests/IntegrationTests/ReadWrite/Resources/UpdateResourceTests.cs @@ -77,9 +77,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTag.Id); @@ -87,9 +89,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT t1.""Id"", t1.""Name"" -FROM ""Tags"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."Name" + FROM "Tags" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTag.Id); @@ -181,10 +185,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -192,9 +197,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""Description"" = @p1, ""DurationInHours"" = @p2, ""LastModifiedAt"" = @p3 -WHERE ""Id"" = @p4")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "Description" = @p1, "DurationInHours" = @p2, "LastModifiedAt" = @p3 + WHERE "Id" = @p4 + """)); command.Parameters.ShouldHaveCount(4); command.Parameters.Should().Contain("@p1", newDescription); @@ -205,10 +212,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -334,13 +342,14 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"", t3.""Id"", t3.""FirstName"", t3.""LastName"", t4.""Id"", t4.""Name"" -FROM ""TodoItems"" AS t1 -LEFT JOIN ""People"" AS t2 ON t1.""AssigneeId"" = t2.""Id"" -INNER JOIN ""People"" AS t3 ON t1.""OwnerId"" = t3.""Id"" -LEFT JOIN ""Tags"" AS t4 ON t1.""Id"" = t4.""TodoItemId"" -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName", t3."Id", t3."FirstName", t3."LastName", t4."Id", t4."Name" + FROM "TodoItems" AS t1 + LEFT JOIN "People" AS t2 ON t1."AssigneeId" = t2."Id" + INNER JOIN "People" AS t3 ON t1."OwnerId" = t3."Id" + LEFT JOIN "Tags" AS t4 ON t1."Id" = t4."TodoItemId" + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -348,9 +357,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""TodoItems"" -SET ""Description"" = @p1, ""Priority"" = @p2, ""DurationInHours"" = @p3, ""LastModifiedAt"" = @p4, ""OwnerId"" = @p5, ""AssigneeId"" = @p6 -WHERE ""Id"" = @p7")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "TodoItems" + SET "Description" = @p1, "Priority" = @p2, "DurationInHours" = @p3, "LastModifiedAt" = @p4, "OwnerId" = @p5, "AssigneeId" = @p6 + WHERE "Id" = @p7 + """)); command.Parameters.ShouldHaveCount(7); command.Parameters.Should().Contain("@p1", newTodoItem.Description); @@ -364,9 +375,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[2].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""Tags"" -SET ""TodoItemId"" = @p1 -WHERE ""Id"" IN (@p2, @p3)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "Tags" + SET "TodoItemId" = @p1 + WHERE "Id" IN (@p2, @p3) + """)); command.Parameters.ShouldHaveCount(3); command.Parameters.Should().Contain("@p1", null); @@ -376,9 +389,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[3].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"UPDATE ""Tags"" -SET ""TodoItemId"" = @p1 -WHERE ""Id"" = @p2")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + UPDATE "Tags" + SET "TodoItemId" = @p1 + WHERE "Id" = @p2 + """)); command.Parameters.ShouldHaveCount(2); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); @@ -387,10 +402,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[4].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"" -FROM ""TodoItems"" AS t1 -WHERE t1.""Id"" = @p1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority" + FROM "TodoItems" AS t1 + WHERE t1."Id" = @p1 + """)); command.Parameters.ShouldHaveCount(1); command.Parameters.Should().Contain("@p1", existingTodoItem.Id); diff --git a/test/DapperTests/IntegrationTests/Sql/SubQueryInJoinTests.cs b/test/DapperTests/IntegrationTests/Sql/SubQueryInJoinTests.cs index 235ec91f2a..ed75d24d65 100644 --- a/test/DapperTests/IntegrationTests/Sql/SubQueryInJoinTests.cs +++ b/test/DapperTests/IntegrationTests/Sql/SubQueryInJoinTests.cs @@ -48,19 +48,22 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""LastUsedAt"", t2.""UserName"" -FROM ""People"" AS t1 -LEFT JOIN ""LoginAccounts"" AS t2 ON t1.""AccountId"" = t2.""Id"" -ORDER BY t1.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."LastUsedAt", t2."UserName" + FROM "People" AS t1 + LEFT JOIN "LoginAccounts" AS t2 ON t1."AccountId" = t2."Id" + ORDER BY t1."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -94,19 +97,22 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -ORDER BY t1.""Id"", t2.""Priority"", t2.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + ORDER BY t1."Id", t2."Priority", t2."LastModifiedAt" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -140,19 +146,22 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -ORDER BY t1.""Id"", t2.""Description""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + ORDER BY t1."Id", t2."Description" + """)); command.Parameters.Should().BeEmpty(); }); @@ -186,23 +195,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -ORDER BY t1.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" -)")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + ORDER BY t1."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) + """)); command.Parameters.Should().BeEmpty(); }); @@ -236,24 +248,27 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""Priority"", t4.""Id"", t4.""Name"" -FROM ""People"" AS t1 -LEFT JOIN ""TodoItems"" AS t2 ON t1.""Id"" = t2.""OwnerId"" -LEFT JOIN ""Tags"" AS t4 ON t2.""Id"" = t4.""TodoItemId"" -ORDER BY t1.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" -), t4.""Name"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."Priority", t4."Id", t4."Name" + FROM "People" AS t1 + LEFT JOIN "TodoItems" AS t2 ON t1."Id" = t2."OwnerId" + LEFT JOIN "Tags" AS t4 ON t2."Id" = t4."TodoItemId" + ORDER BY t1."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ), t4."Name" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -289,31 +304,34 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""TodoItems"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "TodoItems" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""CreatedAt"", t1.""Description"", t1.""DurationInHours"", t1.""LastModifiedAt"", t1.""Priority"", t2.""Id"", t2.""FirstName"", t2.""LastName"", t3.""Id"", t3.""CreatedAt"", t3.""Description"", t3.""DurationInHours"", t3.""LastModifiedAt"", t3.""Priority"", t5.""Id"", t5.""Name"", t6.""Id"", t6.""CreatedAt"", t6.""Description"", t6.""DurationInHours"", t6.""LastModifiedAt"", t6.""Priority"", t8.""Id"", t8.""Name"" -FROM ""TodoItems"" AS t1 -INNER JOIN ""People"" AS t2 ON t1.""OwnerId"" = t2.""Id"" -LEFT JOIN ""TodoItems"" AS t3 ON t2.""Id"" = t3.""AssigneeId"" -LEFT JOIN ""Tags"" AS t5 ON t3.""Id"" = t5.""TodoItemId"" -LEFT JOIN ""TodoItems"" AS t6 ON t2.""Id"" = t6.""OwnerId"" -LEFT JOIN ""Tags"" AS t8 ON t6.""Id"" = t8.""TodoItemId"" -ORDER BY t1.""Priority"", t1.""LastModifiedAt"" DESC, ( - SELECT COUNT(*) - FROM ""Tags"" AS t4 - WHERE t3.""Id"" = t4.""TodoItemId"" -), t5.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t7 - WHERE t6.""Id"" = t7.""TodoItemId"" -), t8.""Id""")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."CreatedAt", t1."Description", t1."DurationInHours", t1."LastModifiedAt", t1."Priority", t2."Id", t2."FirstName", t2."LastName", t3."Id", t3."CreatedAt", t3."Description", t3."DurationInHours", t3."LastModifiedAt", t3."Priority", t5."Id", t5."Name", t6."Id", t6."CreatedAt", t6."Description", t6."DurationInHours", t6."LastModifiedAt", t6."Priority", t8."Id", t8."Name" + FROM "TodoItems" AS t1 + INNER JOIN "People" AS t2 ON t1."OwnerId" = t2."Id" + LEFT JOIN "TodoItems" AS t3 ON t2."Id" = t3."AssigneeId" + LEFT JOIN "Tags" AS t5 ON t3."Id" = t5."TodoItemId" + LEFT JOIN "TodoItems" AS t6 ON t2."Id" = t6."OwnerId" + LEFT JOIN "Tags" AS t8 ON t6."Id" = t8."TodoItemId" + ORDER BY t1."Priority", t1."LastModifiedAt" DESC, ( + SELECT COUNT(*) + FROM "Tags" AS t4 + WHERE t3."Id" = t4."TodoItemId" + ), t5."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t7 + WHERE t6."Id" = t7."TodoItemId" + ), t8."Id" + """)); command.Parameters.Should().BeEmpty(); }); @@ -347,23 +365,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t3.""Id"", t3.""CreatedAt"", t3.""Description"", t3.""DurationInHours"", t3.""LastModifiedAt"", t3.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE t2.""Description"" = @p1 -) AS t3 ON t1.""Id"" = t3.""OwnerId"" -ORDER BY t1.""Id"", t3.""Priority"", t3.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t3."Id", t3."CreatedAt", t3."Description", t3."DurationInHours", t3."LastModifiedAt", t3."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + WHERE t2."Description" = @p1 + ) AS t3 ON t1."Id" = t3."OwnerId" + ORDER BY t1."Id", t3."Priority", t3."LastModifiedAt" DESC + """)); command.Parameters.Should().HaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -398,27 +419,30 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t4.""Id"", t4.""CreatedAt"", t4.""Description"", t4.""DurationInHours"", t4.""LastModifiedAt"", t4.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE EXISTS ( - SELECT 1 - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" - ) -) AS t4 ON t1.""Id"" = t4.""OwnerId"" -ORDER BY t1.""Id"", t4.""Priority"", t4.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t4."Id", t4."CreatedAt", t4."Description", t4."DurationInHours", t4."LastModifiedAt", t4."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + WHERE EXISTS ( + SELECT 1 + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) + ) AS t4 ON t1."Id" = t4."OwnerId" + ORDER BY t1."Id", t4."Priority", t4."LastModifiedAt" DESC + """)); command.Parameters.Should().BeEmpty(); }); @@ -452,27 +476,30 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t4.""Id"", t4.""CreatedAt"", t4.""Description"", t4.""DurationInHours"", t4.""LastModifiedAt"", t4.""Priority"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"" - FROM ""TodoItems"" AS t2 - WHERE ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t2.""Id"" = t3.""TodoItemId"" - ) > @p1 -) AS t4 ON t1.""Id"" = t4.""OwnerId"" -ORDER BY t1.""Id"", t4.""Priority"", t4.""LastModifiedAt"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t4."Id", t4."CreatedAt", t4."Description", t4."DurationInHours", t4."LastModifiedAt", t4."Priority" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority" + FROM "TodoItems" AS t2 + WHERE ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t2."Id" = t3."TodoItemId" + ) > @p1 + ) AS t4 ON t1."Id" = t4."OwnerId" + ORDER BY t1."Id", t4."Priority", t4."LastModifiedAt" DESC + """)); command.Parameters.Should().HaveCount(1); command.Parameters.Should().Contain("@p1", 0); @@ -508,28 +535,31 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t5.""Id"", t5.""CreatedAt"", t5.""Description"", t5.""DurationInHours"", t5.""LastModifiedAt"", t5.""Priority"", t5.Id0 AS Id, t5.""Name"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"", t4.""Id"" AS Id0, t4.""Name"" - FROM ""TodoItems"" AS t2 - LEFT JOIN ""Tags"" AS t4 ON t2.""Id"" = t4.""TodoItemId"" - WHERE t2.""Description"" = @p1 -) AS t5 ON t1.""Id"" = t5.""OwnerId"" -ORDER BY t1.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t5.""Id"" = t3.""TodoItemId"" -), t5.""Name"" DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t5."Id", t5."CreatedAt", t5."Description", t5."DurationInHours", t5."LastModifiedAt", t5."Priority", t5.Id0 AS Id, t5."Name" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority", t4."Id" AS Id0, t4."Name" + FROM "TodoItems" AS t2 + LEFT JOIN "Tags" AS t4 ON t2."Id" = t4."TodoItemId" + WHERE t2."Description" = @p1 + ) AS t5 ON t1."Id" = t5."OwnerId" + ORDER BY t1."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t5."Id" = t3."TodoItemId" + ), t5."Name" DESC + """)); command.Parameters.Should().HaveCount(1); command.Parameters.Should().Contain("@p1", "X"); @@ -566,33 +596,36 @@ await _testContext.RunOnDatabaseAsync(async dbContext => store.SqlCommands[0].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql(@"SELECT COUNT(*) -FROM ""People"" AS t1")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT COUNT(*) + FROM "People" AS t1 + """)); command.Parameters.Should().BeEmpty(); }); store.SqlCommands[1].With(command => { - command.Statement.Should().Be(_testContext.AdaptSql( - @"SELECT t1.""Id"", t1.""FirstName"", t1.""LastName"", t7.""Id"", t7.""CreatedAt"", t7.""Description"", t7.""DurationInHours"", t7.""LastModifiedAt"", t7.""Priority"", t7.Id00 AS Id, t7.""Name"" -FROM ""People"" AS t1 -LEFT JOIN ( - SELECT t2.""Id"", t2.""CreatedAt"", t2.""Description"", t2.""DurationInHours"", t2.""LastModifiedAt"", t2.""OwnerId"", t2.""Priority"", t4.""LastName"", t6.""Id"" AS Id00, t6.""Name"" - FROM ""TodoItems"" AS t2 - LEFT JOIN ""People"" AS t4 ON t2.""AssigneeId"" = t4.""Id"" - LEFT JOIN ( - SELECT t5.""Id"", t5.""Name"", t5.""TodoItemId"" - FROM ""Tags"" AS t5 - WHERE NOT (t5.""Name"" = @p2) - ) AS t6 ON t2.""Id"" = t6.""TodoItemId"" - WHERE NOT (t2.""Description"" = @p1) -) AS t7 ON t1.""Id"" = t7.""OwnerId"" -ORDER BY t1.""Id"", ( - SELECT COUNT(*) - FROM ""Tags"" AS t3 - WHERE t7.""Id"" = t3.""TodoItemId"" -), t7.""LastName"", t7.""Name"", t7.Id00 DESC")); + command.Statement.Should().Be(_testContext.AdaptSql(""" + SELECT t1."Id", t1."FirstName", t1."LastName", t7."Id", t7."CreatedAt", t7."Description", t7."DurationInHours", t7."LastModifiedAt", t7."Priority", t7.Id00 AS Id, t7."Name" + FROM "People" AS t1 + LEFT JOIN ( + SELECT t2."Id", t2."CreatedAt", t2."Description", t2."DurationInHours", t2."LastModifiedAt", t2."OwnerId", t2."Priority", t4."LastName", t6."Id" AS Id00, t6."Name" + FROM "TodoItems" AS t2 + LEFT JOIN "People" AS t4 ON t2."AssigneeId" = t4."Id" + LEFT JOIN ( + SELECT t5."Id", t5."Name", t5."TodoItemId" + FROM "Tags" AS t5 + WHERE NOT (t5."Name" = @p2) + ) AS t6 ON t2."Id" = t6."TodoItemId" + WHERE NOT (t2."Description" = @p1) + ) AS t7 ON t1."Id" = t7."OwnerId" + ORDER BY t1."Id", ( + SELECT COUNT(*) + FROM "Tags" AS t3 + WHERE t7."Id" = t3."TodoItemId" + ), t7."LastName", t7."Name", t7.Id00 DESC + """)); command.Parameters.Should().HaveCount(2); command.Parameters.Should().Contain("@p1", "X"); diff --git a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs index 14fe65bd22..a88646c7a7 100644 --- a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs +++ b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs @@ -7,7 +7,7 @@ internal sealed class SqlTextAdapter { private static readonly Dictionary SqlServerReplacements = new() { - [new Regex(@"""([^""]+)""", RegexOptions.Compiled)] = "[$+]", + [new Regex("\"([^\"]+)\"", RegexOptions.Compiled)] = "[$+]", [new Regex($@"(VALUES \([^)]*\)){Environment.NewLine}RETURNING \[Id\]", RegexOptions.Compiled)] = $"OUTPUT INSERTED.[Id]{Environment.NewLine}$1" }; diff --git a/test/DapperTests/UnitTests/RelationshipForeignKeyTests.cs b/test/DapperTests/UnitTests/RelationshipForeignKeyTests.cs index aadedc8c85..fe58b3b183 100644 --- a/test/DapperTests/UnitTests/RelationshipForeignKeyTests.cs +++ b/test/DapperTests/UnitTests/RelationshipForeignKeyTests.cs @@ -25,7 +25,9 @@ public void Can_format_foreign_key_for_ToOne_relationship() var foreignKey = new RelationshipForeignKey(DatabaseProvider.PostgreSql, parentRelationship, true, "ParentId", true); // Assert - foreignKey.ToString().Should().Be(@"TestResource.Parent => ""TestResources"".""ParentId""?"); + foreignKey.ToString().Should().Be(""" + TestResource.Parent => "TestResources"."ParentId"? + """); } [Fact] @@ -39,7 +41,9 @@ public void Can_format_foreign_key_for_ToMany_relationship() var foreignKey = new RelationshipForeignKey(DatabaseProvider.PostgreSql, childrenRelationship, false, "TestResourceId", false); // Assert - foreignKey.ToString().Should().Be(@"TestResource.Children => ""TestResources"".""TestResourceId"""); + foreignKey.ToString().Should().Be(""" + TestResource.Children => "TestResources"."TestResourceId" + """); } [UsedImplicitly] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicSerializationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicSerializationTests.cs index b59100dbd9..4f6a2f0a3c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicSerializationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicSerializationTests.cs @@ -89,42 +89,44 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""jsonapi"": { - ""version"": ""1.1"", - ""ext"": [ - ""https://jsonapi.org/ext/atomic"" - ] - }, - ""links"": { - ""self"": ""http://localhost/operations"" - }, - ""atomic:results"": [ - { - ""data"": null - }, - { - ""data"": { - ""type"": ""textLanguages"", - ""id"": """ + newLanguage.StringId + @""", - ""attributes"": { - ""isoCode"": """ + newLanguage.IsoCode + @" (changed)"" - }, - ""relationships"": { - ""lyrics"": { - ""links"": { - ""self"": ""http://localhost/textLanguages/" + newLanguage.StringId + @"/relationships/lyrics"", - ""related"": ""http://localhost/textLanguages/" + newLanguage.StringId + @"/lyrics"" + responseDocument.Should().BeJson($$""" + { + "jsonapi": { + "version": "1.1", + "ext": [ + "https://jsonapi.org/ext/atomic" + ] + }, + "links": { + "self": "http://localhost/operations" + }, + "atomic:results": [ + { + "data": null + }, + { + "data": { + "type": "textLanguages", + "id": "{{newLanguage.StringId}}", + "attributes": { + "isoCode": "{{newLanguage.IsoCode}} (changed)" + }, + "relationships": { + "lyrics": { + "links": { + "self": "http://localhost/textLanguages/{{newLanguage.StringId}}/relationships/lyrics", + "related": "http://localhost/textLanguages/{{newLanguage.StringId}}/lyrics" + } + } + }, + "links": { + "self": "http://localhost/textLanguages/{{newLanguage.StringId}}" + } + } + } + ] } - } - }, - ""links"": { - ""self"": ""http://localhost/textLanguages/" + newLanguage.StringId + @""" - } - } - } - ] -}"); + """); } [Fact] @@ -159,27 +161,29 @@ public async Task Includes_version_with_ext_on_error_at_operations_endpoint() string errorId = JsonApiStringConverter.ExtractErrorId(responseDocument); - responseDocument.Should().BeJson(@"{ - ""jsonapi"": { - ""version"": ""1.1"", - ""ext"": [ - ""https://jsonapi.org/ext/atomic"" - ] - }, - ""links"": { - ""self"": ""http://localhost/operations"" - }, - ""errors"": [ - { - ""id"": """ + errorId + @""", - ""status"": ""404"", - ""title"": ""The requested resource does not exist."", - ""detail"": ""Resource of type 'musicTracks' with ID '" + musicTrackId + @"' does not exist."", - ""source"": { - ""pointer"": ""/atomic:operations[0]"" - } - } - ] -}"); + responseDocument.Should().BeJson($$""" + { + "jsonapi": { + "version": "1.1", + "ext": [ + "https://jsonapi.org/ext/atomic" + ] + }, + "links": { + "self": "http://localhost/operations" + }, + "errors": [ + { + "id": "{{errorId}}", + "status": "404", + "title": "The requested resource does not exist.", + "detail": "Resource of type 'musicTracks' with ID '{{musicTrackId}}' does not exist.", + "source": { + "pointer": "/atomic:operations[0]" + } + } + ] + } + """); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs index 30099131ce..14e1e4fd61 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicTraceLoggingTests.cs @@ -120,196 +120,214 @@ await _testContext.RunOnDatabaseAsync(async dbContext => logLines.Should().BeEquivalentTo(new[] { - $@"[TRACE] Received POST request at 'http://localhost/operations' with body: <<{{ - ""atomic:operations"": [ - {{ - ""op"": ""update"", - ""data"": {{ - ""type"": ""musicTracks"", - ""id"": ""{existingTrack.StringId}"", - ""attributes"": {{ - ""genre"": ""{newGenre}"" - }}, - ""relationships"": {{ - ""lyric"": {{ - ""data"": {{ - ""type"": ""lyrics"", - ""id"": ""{existingLyric.StringId}"" - }} - }}, - ""ownedBy"": {{ - ""data"": {{ - ""type"": ""recordCompanies"", - ""id"": ""{existingCompany.StringId}"" - }} - }}, - ""performers"": {{ - ""data"": [ - {{ - ""type"": ""performers"", - ""id"": ""{existingPerformer.StringId}"" - }} - ] - }} - }} - }} - }} - ] -}}>>", - $@"[TRACE] Entering PostOperationsAsync(operations: [ - {{ - ""Resource"": {{ - ""Id"": ""{existingTrack.StringId}"", - ""Genre"": ""{newGenre}"", - ""ReleasedAt"": ""0001-01-01T00:00:00+00:00"", - ""Lyric"": {{ - ""CreatedAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingLyric.Id}, - ""StringId"": ""{existingLyric.StringId}"" - }}, - ""OwnedBy"": {{ - ""Tracks"": [], - ""Id"": {existingCompany.Id}, - ""StringId"": ""{existingCompany.StringId}"" - }}, - ""Performers"": [ - {{ - ""BornAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingPerformer.Id}, - ""StringId"": ""{existingPerformer.StringId}"" - }} - ], - ""OccursIn"": [], - ""StringId"": ""{existingTrack.StringId}"" - }}, - ""TargetedFields"": {{ - ""Attributes"": [ - ""genre"" - ], - ""Relationships"": [ - ""lyric"", - ""ownedBy"", - ""performers"" - ] - }}, - ""Request"": {{ - ""Kind"": ""AtomicOperations"", - ""PrimaryId"": ""{existingTrack.StringId}"", - ""PrimaryResourceType"": ""musicTracks"", - ""IsCollection"": false, - ""IsReadOnly"": false, - ""WriteOperation"": ""UpdateResource"" - }} - }} -])", - $@"[TRACE] Entering UpdateAsync(id: {existingTrack.StringId}, resource: {{ - ""Id"": ""{existingTrack.StringId}"", - ""Genre"": ""{newGenre}"", - ""ReleasedAt"": ""0001-01-01T00:00:00+00:00"", - ""Lyric"": {{ - ""CreatedAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingLyric.Id}, - ""StringId"": ""{existingLyric.StringId}"" - }}, - ""OwnedBy"": {{ - ""Tracks"": [], - ""Id"": {existingCompany.Id}, - ""StringId"": ""{existingCompany.StringId}"" - }}, - ""Performers"": [ - {{ - ""BornAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingPerformer.Id}, - ""StringId"": ""{existingPerformer.StringId}"" - }} - ], - ""OccursIn"": [], - ""StringId"": ""{existingTrack.StringId}"" -}})", - $@"[TRACE] Entering GetForUpdateAsync(queryLayer: QueryLayer -{{ - Include: lyric,ownedBy,performers - Filter: equals(id,'{existingTrack.StringId}') -}} -)", - $@"[TRACE] Entering GetAsync(queryLayer: QueryLayer -{{ - Include: lyric,ownedBy,performers - Filter: equals(id,'{existingTrack.StringId}') -}} -)", - $@"[TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer -{{ - Include: lyric,ownedBy,performers - Filter: equals(id,'{existingTrack.StringId}') -}} -)", - $@"[TRACE] Entering UpdateAsync(resourceFromRequest: {{ - ""Id"": ""{existingTrack.StringId}"", - ""Genre"": ""{newGenre}"", - ""ReleasedAt"": ""0001-01-01T00:00:00+00:00"", - ""Lyric"": {{ - ""CreatedAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingLyric.Id}, - ""StringId"": ""{existingLyric.StringId}"" - }}, - ""OwnedBy"": {{ - ""Tracks"": [], - ""Id"": {existingCompany.Id}, - ""StringId"": ""{existingCompany.StringId}"" - }}, - ""Performers"": [ - {{ - ""BornAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingPerformer.Id}, - ""StringId"": ""{existingPerformer.StringId}"" - }} - ], - ""OccursIn"": [], - ""StringId"": ""{existingTrack.StringId}"" -}}, resourceFromDatabase: {{ - ""Id"": ""{existingTrack.StringId}"", - ""Title"": ""{existingTrack.Title}"", - ""LengthInSeconds"": {JsonSerializer.Serialize(existingTrack.LengthInSeconds)}, - ""Genre"": ""{existingTrack.Genre}"", - ""ReleasedAt"": {JsonSerializer.Serialize(existingTrack.ReleasedAt)}, - ""Lyric"": {{ - ""Format"": ""{existingTrack.Lyric.Format}"", - ""Text"": {JsonSerializer.Serialize(existingTrack.Lyric.Text)}, - ""CreatedAt"": ""0001-01-01T00:00:00+00:00"", - ""Id"": {existingTrack.Lyric.Id}, - ""StringId"": ""{existingTrack.Lyric.StringId}"" - }}, - ""OwnedBy"": {{ - ""Name"": ""{existingTrack.OwnedBy.Name}"", - ""CountryOfResidence"": ""{existingTrack.OwnedBy.CountryOfResidence}"", - ""Tracks"": [ - null - ], - ""Id"": {existingTrack.OwnedBy.Id}, - ""StringId"": ""{existingTrack.OwnedBy.StringId}"" - }}, - ""Performers"": [ - {{ - ""ArtistName"": ""{existingTrack.Performers[0].ArtistName}"", - ""BornAt"": {JsonSerializer.Serialize(existingTrack.Performers[0].BornAt)}, - ""Id"": {existingTrack.Performers[0].Id}, - ""StringId"": ""{existingTrack.Performers[0].StringId}"" - }} - ], - ""OccursIn"": [], - ""StringId"": ""{existingTrack.StringId}"" -}})", - $@"[TRACE] Entering GetAsync(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingTrack.StringId}') -}} -)", - $@"[TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingTrack.StringId}') -}} -)" + $$""" + [TRACE] Received POST request at 'http://localhost/operations' with body: <<{ + "atomic:operations": [ + { + "op": "update", + "data": { + "type": "musicTracks", + "id": "{{existingTrack.StringId}}", + "attributes": { + "genre": "{{newGenre}}" + }, + "relationships": { + "lyric": { + "data": { + "type": "lyrics", + "id": "{{existingLyric.StringId}}" + } + }, + "ownedBy": { + "data": { + "type": "recordCompanies", + "id": "{{existingCompany.StringId}}" + } + }, + "performers": { + "data": [ + { + "type": "performers", + "id": "{{existingPerformer.StringId}}" + } + ] + } + } + } + } + ] + }>> + """, + $$""" + [TRACE] Entering PostOperationsAsync(operations: [ + { + "Resource": { + "Id": "{{existingTrack.StringId}}", + "Genre": "{{newGenre}}", + "ReleasedAt": "0001-01-01T00:00:00+00:00", + "Lyric": { + "CreatedAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingLyric.Id}}, + "StringId": "{{existingLyric.StringId}}" + }, + "OwnedBy": { + "Tracks": [], + "Id": {{existingCompany.Id}}, + "StringId": "{{existingCompany.StringId}}" + }, + "Performers": [ + { + "BornAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingPerformer.Id}}, + "StringId": "{{existingPerformer.StringId}}" + } + ], + "OccursIn": [], + "StringId": "{{existingTrack.StringId}}" + }, + "TargetedFields": { + "Attributes": [ + "genre" + ], + "Relationships": [ + "lyric", + "ownedBy", + "performers" + ] + }, + "Request": { + "Kind": "AtomicOperations", + "PrimaryId": "{{existingTrack.StringId}}", + "PrimaryResourceType": "musicTracks", + "IsCollection": false, + "IsReadOnly": false, + "WriteOperation": "UpdateResource" + } + } + ]) + """, + $$""" + [TRACE] Entering UpdateAsync(id: {{existingTrack.StringId}}, resource: { + "Id": "{{existingTrack.StringId}}", + "Genre": "{{newGenre}}", + "ReleasedAt": "0001-01-01T00:00:00+00:00", + "Lyric": { + "CreatedAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingLyric.Id}}, + "StringId": "{{existingLyric.StringId}}" + }, + "OwnedBy": { + "Tracks": [], + "Id": {{existingCompany.Id}}, + "StringId": "{{existingCompany.StringId}}" + }, + "Performers": [ + { + "BornAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingPerformer.Id}}, + "StringId": "{{existingPerformer.StringId}}" + } + ], + "OccursIn": [], + "StringId": "{{existingTrack.StringId}}" + }) + """, + $$""" + [TRACE] Entering GetForUpdateAsync(queryLayer: QueryLayer + { + Include: lyric,ownedBy,performers + Filter: equals(id,'{{existingTrack.StringId}}') + } + ) + """, + $$""" + [TRACE] Entering GetAsync(queryLayer: QueryLayer + { + Include: lyric,ownedBy,performers + Filter: equals(id,'{{existingTrack.StringId}}') + } + ) + """, + $$""" + [TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer + { + Include: lyric,ownedBy,performers + Filter: equals(id,'{{existingTrack.StringId}}') + } + ) + """, + $$""" + [TRACE] Entering UpdateAsync(resourceFromRequest: { + "Id": "{{existingTrack.StringId}}", + "Genre": "{{newGenre}}", + "ReleasedAt": "0001-01-01T00:00:00+00:00", + "Lyric": { + "CreatedAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingLyric.Id}}, + "StringId": "{{existingLyric.StringId}}" + }, + "OwnedBy": { + "Tracks": [], + "Id": {{existingCompany.Id}}, + "StringId": "{{existingCompany.StringId}}" + }, + "Performers": [ + { + "BornAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingPerformer.Id}}, + "StringId": "{{existingPerformer.StringId}}" + } + ], + "OccursIn": [], + "StringId": "{{existingTrack.StringId}}" + }, resourceFromDatabase: { + "Id": "{{existingTrack.StringId}}", + "Title": "{{existingTrack.Title}}", + "LengthInSeconds": {{JsonSerializer.Serialize(existingTrack.LengthInSeconds)}}, + "Genre": "{{existingTrack.Genre}}", + "ReleasedAt": {{JsonSerializer.Serialize(existingTrack.ReleasedAt)}}, + "Lyric": { + "Format": "{{existingTrack.Lyric.Format}}", + "Text": {{JsonSerializer.Serialize(existingTrack.Lyric.Text)}}, + "CreatedAt": "0001-01-01T00:00:00+00:00", + "Id": {{existingTrack.Lyric.Id}}, + "StringId": "{{existingTrack.Lyric.StringId}}" + }, + "OwnedBy": { + "Name": "{{existingTrack.OwnedBy.Name}}", + "CountryOfResidence": "{{existingTrack.OwnedBy.CountryOfResidence}}", + "Tracks": [ + null + ], + "Id": {{existingTrack.OwnedBy.Id}}, + "StringId": "{{existingTrack.OwnedBy.StringId}}" + }, + "Performers": [ + { + "ArtistName": "{{existingTrack.Performers[0].ArtistName}}", + "BornAt": {{JsonSerializer.Serialize(existingTrack.Performers[0].BornAt)}}, + "Id": {{existingTrack.Performers[0].Id}}, + "StringId": "{{existingTrack.Performers[0].StringId}}" + } + ], + "OccursIn": [], + "StringId": "{{existingTrack.StringId}}" + }) + """, + $$""" + [TRACE] Entering GetAsync(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingTrack.StringId}}') + } + ) + """, + $$""" + [TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingTrack.StringId}}') + } + ) + """ }, options => options.Using(IgnoreLineEndingsComparer.Instance).WithStrictOrdering()); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs index 3641e9e23d..06ad682591 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs @@ -94,7 +94,7 @@ public async Task Logs_and_produces_error_response_on_deserialization_failure() var loggerFactory = _testContext.Factory.Services.GetRequiredService(); loggerFactory.Logger.Clear(); - const string requestBody = @"{ ""data"": { ""type"": """" } }"; + const string requestBody = """{ "data": { "type": "" } }"""; const string route = "/consumerArticles"; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs index 81aca9c43e..cc56c3980f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingTests.cs @@ -161,58 +161,70 @@ await _testContext.RunOnDatabaseAsync(async dbContext => logLines.Should().BeEquivalentTo(new[] { - $@"[TRACE] Received POST request at 'http://localhost/fruitBowls/{existingBowl.StringId}/relationships/fruits' with body: <<{{ - ""data"": [ - {{ - ""type"": ""fruits"", - ""id"": ""{existingBanana.StringId}"" - }} - ] -}}>>", - $@"[TRACE] Entering PostRelationshipAsync(id: {existingBowl.StringId}, relationshipName: ""fruits"", rightResourceIds: [ - {{ - ""ClrType"": ""{typeof(Fruit).FullName}"", - ""StringId"": ""{existingBanana.StringId}"" - }} -])", - $@"[TRACE] Entering AddToToManyRelationshipAsync(leftId: {existingBowl.StringId}, relationshipName: ""fruits"", rightResourceIds: [ - {{ - ""ClrType"": ""{typeof(Fruit).FullName}"", - ""StringId"": ""{existingBanana.StringId}"" - }} -])", - $@"[TRACE] Entering GetAsync(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingBanana.Id}') - Selection - {{ - FieldSelectors - {{ - id - }} - }} -}} -)", - $@"[TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingBanana.Id}') - Selection - {{ - FieldSelectors - {{ - id - }} - }} -}} -)", - $@"[TRACE] Entering AddToToManyRelationshipAsync(leftResource: null, leftId: {existingBowl.Id}, rightResourceIds: [ - {{ - ""Color"": ""Yellow"", - ""LengthInCentimeters"": {existingBanana.LengthInCentimeters.ToString(CultureInfo.InvariantCulture)}, - ""Id"": {existingBanana.Id}, - ""StringId"": ""{existingBanana.StringId}"" - }} -])" + $$""" + [TRACE] Received POST request at 'http://localhost/fruitBowls/{{existingBowl.StringId}}/relationships/fruits' with body: <<{ + "data": [ + { + "type": "fruits", + "id": "{{existingBanana.StringId}}" + } + ] + }>> + """, + $$""" + [TRACE] Entering PostRelationshipAsync(id: {{existingBowl.StringId}}, relationshipName: "fruits", rightResourceIds: [ + { + "ClrType": "{{typeof(Fruit).FullName}}", + "StringId": "{{existingBanana.StringId}}" + } + ]) + """, + $$""" + [TRACE] Entering AddToToManyRelationshipAsync(leftId: {{existingBowl.StringId}}, relationshipName: "fruits", rightResourceIds: [ + { + "ClrType": "{{typeof(Fruit).FullName}}", + "StringId": "{{existingBanana.StringId}}" + } + ]) + """, + $$""" + [TRACE] Entering GetAsync(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingBanana.Id}}') + Selection + { + FieldSelectors + { + id + } + } + } + ) + """, + $$""" + [TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingBanana.Id}}') + Selection + { + FieldSelectors + { + id + } + } + } + ) + """, + $$""" + [TRACE] Entering AddToToManyRelationshipAsync(leftResource: null, leftId: {{existingBowl.Id}}, rightResourceIds: [ + { + "Color": "Yellow", + "LengthInCentimeters": {{existingBanana.LengthInCentimeters.ToString(CultureInfo.InvariantCulture)}}, + "Id": {{existingBanana.Id}}, + "StringId": "{{existingBanana.StringId}}" + } + ]) + """ }, options => options.Using(IgnoreLineEndingsComparer.Instance).WithStrictOrdering()); } @@ -259,62 +271,74 @@ await _testContext.RunOnDatabaseAsync(async dbContext => logLines.Should().BeEquivalentTo(new[] { - $@"[TRACE] Received POST request at 'http://localhost/fruitBowls/{existingBowl.StringId}/relationships/fruits' with body: <<{{ - ""data"": [ - {{ - ""type"": ""peaches"", - ""id"": ""{existingPeach.StringId}"" - }} - ] -}}>>", - $@"[TRACE] Entering PostRelationshipAsync(id: {existingBowl.StringId}, relationshipName: ""fruits"", rightResourceIds: [ - {{ - ""Color"": ""Red/Yellow"", - ""DiameterInCentimeters"": 0, - ""Id"": {existingPeach.Id}, - ""StringId"": ""{existingPeach.StringId}"" - }} -])", - $@"[TRACE] Entering AddToToManyRelationshipAsync(leftId: {existingBowl.StringId}, relationshipName: ""fruits"", rightResourceIds: [ - {{ - ""Color"": ""Red/Yellow"", - ""DiameterInCentimeters"": 0, - ""Id"": {existingPeach.Id}, - ""StringId"": ""{existingPeach.StringId}"" - }} -])", - $@"[TRACE] Entering GetAsync(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingPeach.Id}') - Selection - {{ - FieldSelectors - {{ - id - }} - }} -}} -)", - $@"[TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer -{{ - Filter: equals(id,'{existingPeach.Id}') - Selection - {{ - FieldSelectors - {{ - id - }} - }} -}} -)", - $@"[TRACE] Entering AddToToManyRelationshipAsync(leftResource: null, leftId: {existingBowl.Id}, rightResourceIds: [ - {{ - ""Color"": ""Red/Yellow"", - ""DiameterInCentimeters"": 0, - ""Id"": {existingPeach.Id}, - ""StringId"": ""{existingPeach.StringId}"" - }} -])" + $$""" + [TRACE] Received POST request at 'http://localhost/fruitBowls/{{existingBowl.StringId}}/relationships/fruits' with body: <<{ + "data": [ + { + "type": "peaches", + "id": "{{existingPeach.StringId}}" + } + ] + }>> + """, + $$""" + [TRACE] Entering PostRelationshipAsync(id: {{existingBowl.StringId}}, relationshipName: "fruits", rightResourceIds: [ + { + "Color": "Red/Yellow", + "DiameterInCentimeters": 0, + "Id": {{existingPeach.Id}}, + "StringId": "{{existingPeach.StringId}}" + } + ]) + """, + $$""" + [TRACE] Entering AddToToManyRelationshipAsync(leftId: {{existingBowl.StringId}}, relationshipName: "fruits", rightResourceIds: [ + { + "Color": "Red/Yellow", + "DiameterInCentimeters": 0, + "Id": {{existingPeach.Id}}, + "StringId": "{{existingPeach.StringId}}" + } + ]) + """, + $$""" + [TRACE] Entering GetAsync(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingPeach.Id}}') + Selection + { + FieldSelectors + { + id + } + } + } + ) + """, + $$""" + [TRACE] Entering ApplyQueryLayer(queryLayer: QueryLayer + { + Filter: equals(id,'{{existingPeach.Id}}') + Selection + { + FieldSelectors + { + id + } + } + } + ) + """, + $$""" + [TRACE] Entering AddToToManyRelationshipAsync(leftResource: null, leftId: {{existingBowl.Id}}, rightResourceIds: [ + { + "Color": "Red/Yellow", + "DiameterInCentimeters": 0, + "Id": {{existingPeach.Id}}, + "StringId": "{{existingPeach.StringId}}" + } + ]) + """ }, options => options.Using(IgnoreLineEndingsComparer.Instance).WithStrictOrdering()); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs index c96183dca0..472803c67d 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/ResponseMetaTests.cs @@ -39,22 +39,24 @@ public async Task Returns_top_level_meta() // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/supportTickets"", - ""first"": ""http://localhost/supportTickets"" - }, - ""data"": [], - ""meta"": { - ""license"": ""MIT"", - ""projectUrl"": ""https://github.com/json-api-dotnet/JsonApiDotNetCore/"", - ""versions"": [ - ""v4.0.0"", - ""v3.1.0"", - ""v2.5.2"", - ""v1.3.1"" - ] - } -}"); + responseDocument.Should().BeJson(""" + { + "links": { + "self": "http://localhost/supportTickets", + "first": "http://localhost/supportTickets" + }, + "data": [], + "meta": { + "license": "MIT", + "projectUrl": "https://github.com/json-api-dotnet/JsonApiDotNetCore/", + "versions": [ + "v4.0.0", + "v3.1.0", + "v2.5.2", + "v1.3.1" + ] + } + } + """); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs index 2e0417370c..6f830f873f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceReadTests.cs @@ -1403,616 +1403,618 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson($@"{{ - ""links"": {{ - ""self"": ""{route}"", - ""first"": ""{route}"" - }}, - ""data"": [ - {{ - ""type"": ""bikes"", - ""id"": ""{bike.StringId}"", - ""attributes"": {{ - ""requiresDriverLicense"": {bike.RequiresDriverLicense.ToString().ToLowerInvariant()}, - ""gearCount"": {bike.GearCount}, - ""weight"": {bike.Weight.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""cargoBox"": {{ - ""links"": {{ - ""self"": ""/bikes/{bike.StringId}/relationships/cargoBox"", - ""related"": ""/bikes/{bike.StringId}/cargoBox"" - }}, - ""data"": {{ - ""type"": ""boxes"", - ""id"": ""{bike.CargoBox.StringId}"" - }} - }}, - ""lights"": {{ - ""links"": {{ - ""self"": ""/bikes/{bike.StringId}/relationships/lights"", - ""related"": ""/bikes/{bike.StringId}/lights"" - }}, - ""data"": [ - {{ - ""type"": ""bicycleLights"", - ""id"": ""{bike.Lights.ElementAt(0).StringId}"" - }} - ] - }}, - ""manufacturer"": {{ - ""links"": {{ - ""self"": ""/bikes/{bike.StringId}/relationships/manufacturer"", - ""related"": ""/bikes/{bike.StringId}/manufacturer"" - }}, - ""data"": {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{bike.Manufacturer.StringId}"" - }} - }}, - ""wheels"": {{ - ""links"": {{ - ""self"": ""/bikes/{bike.StringId}/relationships/wheels"", - ""related"": ""/bikes/{bike.StringId}/wheels"" - }}, - ""data"": [ - {{ - ""type"": ""carbonWheels"", - ""id"": ""{bike.Wheels.OfType().ElementAt(0).StringId}"" - }} - ] - }} - }}, - ""links"": {{ - ""self"": ""/bikes/{bike.StringId}"" - }} - }}, - {{ - ""type"": ""cars"", - ""id"": ""{car.StringId}"", - ""attributes"": {{ - ""seatCount"": {car.SeatCount}, - ""requiresDriverLicense"": {car.RequiresDriverLicense.ToString().ToLowerInvariant()}, - ""licensePlate"": ""{car.LicensePlate}"", - ""weight"": {car.Weight.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""features"": {{ - ""links"": {{ - ""self"": ""/cars/{car.StringId}/relationships/features"", - ""related"": ""/cars/{car.StringId}/features"" - }}, - ""data"": [ - {{ - ""type"": ""genericFeatures"", - ""id"": ""{car.Features.ElementAt(0).StringId}"" - }} - ] - }}, - ""engine"": {{ - ""links"": {{ - ""self"": ""/cars/{car.StringId}/relationships/engine"", - ""related"": ""/cars/{car.StringId}/engine"" - }}, - ""data"": {{ - ""type"": ""gasolineEngines"", - ""id"": ""{car.Engine.StringId}"" - }} - }}, - ""navigationSystem"": {{ - ""links"": {{ - ""self"": ""/cars/{car.StringId}/relationships/navigationSystem"", - ""related"": ""/cars/{car.StringId}/navigationSystem"" - }}, - ""data"": {{ - ""type"": ""navigationSystems"", - ""id"": ""{car.NavigationSystem.StringId}"" - }} - }}, - ""manufacturer"": {{ - ""links"": {{ - ""self"": ""/cars/{car.StringId}/relationships/manufacturer"", - ""related"": ""/cars/{car.StringId}/manufacturer"" - }}, - ""data"": {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{car.Manufacturer.StringId}"" - }} - }}, - ""wheels"": {{ - ""links"": {{ - ""self"": ""/cars/{car.StringId}/relationships/wheels"", - ""related"": ""/cars/{car.StringId}/wheels"" - }}, - ""data"": [ - {{ - ""type"": ""carbonWheels"", - ""id"": ""{car.Wheels.OfType().ElementAt(0).StringId}"" - }} - ] - }} - }}, - ""links"": {{ - ""self"": ""/cars/{car.StringId}"" - }} - }}, - {{ - ""type"": ""tandems"", - ""id"": ""{tandem.StringId}"", - ""attributes"": {{ - ""passengerCount"": {tandem.PassengerCount}, - ""requiresDriverLicense"": {tandem.RequiresDriverLicense.ToString().ToLowerInvariant()}, - ""gearCount"": {tandem.GearCount}, - ""weight"": {tandem.Weight.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""features"": {{ - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}/relationships/features"", - ""related"": ""/tandems/{tandem.StringId}/features"" - }}, - ""data"": [ - {{ - ""type"": ""genericFeatures"", - ""id"": ""{tandem.Features.ElementAt(0).StringId}"" - }} - ] - }}, - ""cargoBox"": {{ - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}/relationships/cargoBox"", - ""related"": ""/tandems/{tandem.StringId}/cargoBox"" - }}, - ""data"": {{ - ""type"": ""boxes"", - ""id"": ""{tandem.CargoBox.StringId}"" - }} - }}, - ""lights"": {{ - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}/relationships/lights"", - ""related"": ""/tandems/{tandem.StringId}/lights"" - }}, - ""data"": [ - {{ - ""type"": ""bicycleLights"", - ""id"": ""{tandem.Lights.ElementAt(0).StringId}"" - }} - ] - }}, - ""manufacturer"": {{ - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}/relationships/manufacturer"", - ""related"": ""/tandems/{tandem.StringId}/manufacturer"" - }}, - ""data"": {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{tandem.Manufacturer.StringId}"" - }} - }}, - ""wheels"": {{ - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}/relationships/wheels"", - ""related"": ""/tandems/{tandem.StringId}/wheels"" - }}, - ""data"": [ - {{ - ""type"": ""chromeWheels"", - ""id"": ""{tandem.Wheels.ElementAt(0).StringId}"" - }} - ] - }} - }}, - ""links"": {{ - ""self"": ""/tandems/{tandem.StringId}"" - }} - }}, - {{ - ""type"": ""trucks"", - ""id"": ""{truck.StringId}"", - ""attributes"": {{ - ""loadingCapacity"": {truck.LoadingCapacity.ToString(CultureInfo.InvariantCulture)}, - ""requiresDriverLicense"": {truck.RequiresDriverLicense.ToString().ToLowerInvariant()}, - ""licensePlate"": ""{truck.LicensePlate}"", - ""weight"": {truck.Weight.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""sleepingArea"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/sleepingArea"", - ""related"": ""/trucks/{truck.StringId}/sleepingArea"" - }}, - ""data"": {{ - ""type"": ""boxes"", - ""id"": ""{truck.SleepingArea.StringId}"" - }} - }}, - ""features"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/features"", - ""related"": ""/trucks/{truck.StringId}/features"" - }}, - ""data"": [ - {{ - ""type"": ""genericFeatures"", - ""id"": ""{truck.Features.ElementAt(0).StringId}"" - }} - ] - }}, - ""engine"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/engine"", - ""related"": ""/trucks/{truck.StringId}/engine"" - }}, - ""data"": {{ - ""type"": ""dieselEngines"", - ""id"": ""{truck.Engine.StringId}"" - }} - }}, - ""navigationSystem"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/navigationSystem"", - ""related"": ""/trucks/{truck.StringId}/navigationSystem"" - }}, - ""data"": {{ - ""type"": ""navigationSystems"", - ""id"": ""{truck.NavigationSystem.StringId}"" - }} - }}, - ""manufacturer"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/manufacturer"", - ""related"": ""/trucks/{truck.StringId}/manufacturer"" - }}, - ""data"": {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{truck.Manufacturer.StringId}"" - }} - }}, - ""wheels"": {{ - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}/relationships/wheels"", - ""related"": ""/trucks/{truck.StringId}/wheels"" - }}, - ""data"": [ - {{ - ""type"": ""chromeWheels"", - ""id"": ""{truck.Wheels.ElementAt(0).StringId}"" - }} - ] - }} - }}, - ""links"": {{ - ""self"": ""/trucks/{truck.StringId}"" - }} - }} - ], - ""included"": [ - {{ - ""type"": ""boxes"", - ""id"": ""{bike.CargoBox.StringId}"", - ""attributes"": {{ - ""width"": {bike.CargoBox.Width.ToString(CultureInfo.InvariantCulture)}, - ""height"": {bike.CargoBox.Height.ToString(CultureInfo.InvariantCulture)}, - ""depth"": {bike.CargoBox.Depth.ToString(CultureInfo.InvariantCulture)} - }} - }}, - {{ - ""type"": ""bicycleLights"", - ""id"": ""{bike.Lights.ElementAt(0).StringId}"", - ""attributes"": {{ - ""color"": ""{bike.Lights.ElementAt(0).Color}"" - }} - }}, - {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{bike.Manufacturer.StringId}"", - ""attributes"": {{ - ""name"": ""{bike.Manufacturer.Name}"" - }} - }}, - {{ - ""type"": ""carbonWheels"", - ""id"": ""{bike.Wheels.ElementAt(0).StringId}"", - ""attributes"": {{ - ""hasTube"": {bike.Wheels.Cast().ElementAt(0).HasTube.ToString().ToLowerInvariant()}, - ""radius"": {bike.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""vehicle"": {{ - ""links"": {{ - ""self"": ""/carbonWheels/{bike.Wheels.ElementAt(0).StringId}/relationships/vehicle"", - ""related"": ""/carbonWheels/{bike.Wheels.ElementAt(0).StringId}/vehicle"" - }} - }} - }}, - ""links"": {{ - ""self"": ""/carbonWheels/{bike.Wheels.ElementAt(0).StringId}"" - }} - }}, - {{ - ""type"": ""genericFeatures"", - ""id"": ""{car.Features.ElementAt(0).StringId}"", - ""attributes"": {{ - ""description"": ""{car.Features.ElementAt(0).Description}"" - }}, - ""relationships"": {{ - ""properties"": {{ - ""data"": [ - {{ - ""type"": ""numberProperties"", - ""id"": ""{car.Features.ElementAt(0).Properties.ElementAt(0).StringId}"" - }} - ] - }} - }} - }}, - {{ - ""type"": ""numberProperties"", - ""id"": ""{car.Features.ElementAt(0).Properties.ElementAt(0).StringId}"", - ""attributes"": {{ - ""name"": ""{car.Features.ElementAt(0).Properties.ElementAt(0).Name}"" - }}, - ""relationships"": {{ - ""value"": {{ - ""data"": {{ - ""type"": ""numberValues"", - ""id"": ""{car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"" - }} - }} - }} - }}, - {{ - ""type"": ""numberValues"", - ""id"": ""{car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"", - ""attributes"": {{ - ""content"": {car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content.ToString(CultureInfo.InvariantCulture)} - }} - }}, - {{ - ""type"": ""gasolineEngines"", - ""id"": ""{car.Engine.StringId}"", - ""attributes"": {{ - ""isHydrocarbonBased"": {car.Engine.IsHydrocarbonBased.ToString().ToLowerInvariant()}, - ""serialCode"": ""{((GasolineEngine)car.Engine).SerialCode}"", - ""volatility"": {((GasolineEngine)car.Engine).Volatility.ToString(CultureInfo.InvariantCulture)}, - ""capacity"": {car.Engine.Capacity.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""cylinders"": {{ - ""links"": {{ - ""self"": ""/gasolineEngines/{car.Engine.StringId}/relationships/cylinders"", - ""related"": ""/gasolineEngines/{car.Engine.StringId}/cylinders"" - }}, - ""data"": [ - {{ - ""type"": ""cylinders"", - ""id"": ""{((GasolineEngine)car.Engine).Cylinders.ElementAt(0).StringId}"" - }} - ] - }} - }}, - ""links"": {{ - ""self"": ""/gasolineEngines/{car.Engine.StringId}"" - }} - }}, - {{ - ""type"": ""cylinders"", - ""id"": ""{((GasolineEngine)car.Engine).Cylinders.ElementAt(0).StringId}"", - ""attributes"": {{ - ""sparkPlugCount"": {((GasolineEngine)car.Engine).Cylinders.ElementAt(0).SparkPlugCount} - }} - }}, - {{ - ""type"": ""navigationSystems"", - ""id"": ""{car.NavigationSystem.StringId}"", - ""attributes"": {{ - ""modelType"": ""{car.NavigationSystem.ModelType}"" - }} - }}, - {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{car.Manufacturer.StringId}"", - ""attributes"": {{ - ""name"": ""{car.Manufacturer.Name}"" - }} - }}, - {{ - ""type"": ""carbonWheels"", - ""id"": ""{car.Wheels.ElementAt(0).StringId}"", - ""attributes"": {{ - ""hasTube"": {car.Wheels.OfType().ElementAt(0).HasTube.ToString().ToLowerInvariant()}, - ""radius"": {car.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""vehicle"": {{ - ""links"": {{ - ""self"": ""/carbonWheels/{car.Wheels.ElementAt(0).StringId}/relationships/vehicle"", - ""related"": ""/carbonWheels/{car.Wheels.ElementAt(0).StringId}/vehicle"" - }} - }} - }}, - ""links"": {{ - ""self"": ""/carbonWheels/{car.Wheels.ElementAt(0).StringId}"" - }} - }}, - {{ - ""type"": ""genericFeatures"", - ""id"": ""{tandem.Features.ElementAt(0).StringId}"", - ""attributes"": {{ - ""description"": ""{tandem.Features.ElementAt(0).Description}"" - }}, - ""relationships"": {{ - ""properties"": {{ - ""data"": [ - {{ - ""type"": ""stringProperties"", - ""id"": ""{tandem.Features.ElementAt(0).Properties.ElementAt(0).StringId}"" - }} - ] - }} - }} - }}, - {{ - ""type"": ""stringProperties"", - ""id"": ""{tandem.Features.ElementAt(0).Properties.ElementAt(0).StringId}"", - ""attributes"": {{ - ""name"": ""{tandem.Features.ElementAt(0).Properties.ElementAt(0).Name}"" - }}, - ""relationships"": {{ - ""value"": {{ - ""data"": {{ - ""type"": ""stringValues"", - ""id"": ""{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"" - }} - }} - }} - }}, - {{ - ""type"": ""stringValues"", - ""id"": ""{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"", - ""attributes"": {{ - ""content"": ""{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content}"" - }} - }}, - {{ - ""type"": ""boxes"", - ""id"": ""{tandem.CargoBox.StringId}"", - ""attributes"": {{ - ""width"": {tandem.CargoBox.Width.ToString(CultureInfo.InvariantCulture)}, - ""height"": {tandem.CargoBox.Height.ToString(CultureInfo.InvariantCulture)}, - ""depth"": {tandem.CargoBox.Depth.ToString(CultureInfo.InvariantCulture)} - }} - }}, - {{ - ""type"": ""bicycleLights"", - ""id"": ""{tandem.Lights.ElementAt(0).StringId}"", - ""attributes"": {{ - ""color"": ""{tandem.Lights.ElementAt(0).Color}"" - }} - }}, - {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{tandem.Manufacturer.StringId}"", - ""attributes"": {{ - ""name"": ""{tandem.Manufacturer.Name}"" - }} - }}, - {{ - ""type"": ""chromeWheels"", - ""id"": ""{tandem.Wheels.ElementAt(0).StringId}"", - ""attributes"": {{ - ""paintColor"": ""{tandem.Wheels.OfType().ElementAt(0).PaintColor}"", - ""radius"": {tandem.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""vehicle"": {{ - ""links"": {{ - ""self"": ""/chromeWheels/{tandem.Wheels.ElementAt(0).StringId}/relationships/vehicle"", - ""related"": ""/chromeWheels/{tandem.Wheels.ElementAt(0).StringId}/vehicle"" - }} - }} - }}, - ""links"": {{ - ""self"": ""/chromeWheels/{tandem.Wheels.ElementAt(0).StringId}"" - }} - }}, - {{ - ""type"": ""boxes"", - ""id"": ""{truck.SleepingArea.StringId}"", - ""attributes"": {{ - ""width"": {truck.SleepingArea.Width.ToString(CultureInfo.InvariantCulture)}, - ""height"": {truck.SleepingArea.Height.ToString(CultureInfo.InvariantCulture)}, - ""depth"": {truck.SleepingArea.Depth.ToString(CultureInfo.InvariantCulture)} - }} - }}, - {{ - ""type"": ""genericFeatures"", - ""id"": ""{truck.Features.ElementAt(0).StringId}"", - ""attributes"": {{ - ""description"": ""{truck.Features.ElementAt(0).Description}"" - }}, - ""relationships"": {{ - ""properties"": {{ - ""data"": [ - {{ - ""type"": ""stringProperties"", - ""id"": ""{truck.Features.ElementAt(0).Properties.ElementAt(0).StringId}"" - }} - ] - }} - }} - }}, - {{ - ""type"": ""stringProperties"", - ""id"": ""{truck.Features.ElementAt(0).Properties.ElementAt(0).StringId}"", - ""attributes"": {{ - ""name"": ""{truck.Features.ElementAt(0).Properties.ElementAt(0).Name}"" - }}, - ""relationships"": {{ - ""value"": {{ - ""data"": {{ - ""type"": ""stringValues"", - ""id"": ""{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"" - }} - }} - }} - }}, - {{ - ""type"": ""stringValues"", - ""id"": ""{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}"", - ""attributes"": {{ - ""content"": ""{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content}"" - }} - }}, - {{ - ""type"": ""dieselEngines"", - ""id"": ""{truck.Engine.StringId}"", - ""attributes"": {{ - ""isHydrocarbonBased"": {truck.Engine.IsHydrocarbonBased.ToString().ToLowerInvariant()}, - ""serialCode"": ""{((DieselEngine)truck.Engine).SerialCode}"", - ""viscosity"": {((DieselEngine)truck.Engine).Viscosity.ToString(CultureInfo.InvariantCulture)}, - ""capacity"": {truck.Engine.Capacity.ToString(CultureInfo.InvariantCulture)} - }}, - ""links"": {{ - ""self"": ""/dieselEngines/{truck.Engine.StringId}"" - }} - }}, - {{ - ""type"": ""navigationSystems"", - ""id"": ""{truck.NavigationSystem.StringId}"", - ""attributes"": {{ - ""modelType"": ""{truck.NavigationSystem.ModelType}"" - }} - }}, - {{ - ""type"": ""vehicleManufacturers"", - ""id"": ""{truck.Manufacturer.StringId}"", - ""attributes"": {{ - ""name"": ""{truck.Manufacturer.Name}"" - }} - }}, - {{ - ""type"": ""chromeWheels"", - ""id"": ""{truck.Wheels.ElementAt(0).StringId}"", - ""attributes"": {{ - ""paintColor"": ""{truck.Wheels.OfType().ElementAt(0).PaintColor}"", - ""radius"": {truck.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)} - }}, - ""relationships"": {{ - ""vehicle"": {{ - ""links"": {{ - ""self"": ""/chromeWheels/{truck.Wheels.ElementAt(0).StringId}/relationships/vehicle"", - ""related"": ""/chromeWheels/{truck.Wheels.ElementAt(0).StringId}/vehicle"" - }} - }} - }}, - ""links"": {{ - ""self"": ""/chromeWheels/{truck.Wheels.ElementAt(0).StringId}"" - }} - }} - ] -}}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "{{route}}", + "first": "{{route}}" + }, + "data": [ + { + "type": "bikes", + "id": "{{bike.StringId}}", + "attributes": { + "requiresDriverLicense": {{bike.RequiresDriverLicense.ToString().ToLowerInvariant()}}, + "gearCount": {{bike.GearCount}}, + "weight": {{bike.Weight.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "cargoBox": { + "links": { + "self": "/bikes/{{bike.StringId}}/relationships/cargoBox", + "related": "/bikes/{{bike.StringId}}/cargoBox" + }, + "data": { + "type": "boxes", + "id": "{{bike.CargoBox.StringId}}" + } + }, + "lights": { + "links": { + "self": "/bikes/{{bike.StringId}}/relationships/lights", + "related": "/bikes/{{bike.StringId}}/lights" + }, + "data": [ + { + "type": "bicycleLights", + "id": "{{bike.Lights.ElementAt(0).StringId}}" + } + ] + }, + "manufacturer": { + "links": { + "self": "/bikes/{{bike.StringId}}/relationships/manufacturer", + "related": "/bikes/{{bike.StringId}}/manufacturer" + }, + "data": { + "type": "vehicleManufacturers", + "id": "{{bike.Manufacturer.StringId}}" + } + }, + "wheels": { + "links": { + "self": "/bikes/{{bike.StringId}}/relationships/wheels", + "related": "/bikes/{{bike.StringId}}/wheels" + }, + "data": [ + { + "type": "carbonWheels", + "id": "{{bike.Wheels.OfType().ElementAt(0).StringId}}" + } + ] + } + }, + "links": { + "self": "/bikes/{{bike.StringId}}" + } + }, + { + "type": "cars", + "id": "{{car.StringId}}", + "attributes": { + "seatCount": {{car.SeatCount}}, + "requiresDriverLicense": {{car.RequiresDriverLicense.ToString().ToLowerInvariant()}}, + "licensePlate": "{{car.LicensePlate}}", + "weight": {{car.Weight.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "features": { + "links": { + "self": "/cars/{{car.StringId}}/relationships/features", + "related": "/cars/{{car.StringId}}/features" + }, + "data": [ + { + "type": "genericFeatures", + "id": "{{car.Features.ElementAt(0).StringId}}" + } + ] + }, + "engine": { + "links": { + "self": "/cars/{{car.StringId}}/relationships/engine", + "related": "/cars/{{car.StringId}}/engine" + }, + "data": { + "type": "gasolineEngines", + "id": "{{car.Engine.StringId}}" + } + }, + "navigationSystem": { + "links": { + "self": "/cars/{{car.StringId}}/relationships/navigationSystem", + "related": "/cars/{{car.StringId}}/navigationSystem" + }, + "data": { + "type": "navigationSystems", + "id": "{{car.NavigationSystem.StringId}}" + } + }, + "manufacturer": { + "links": { + "self": "/cars/{{car.StringId}}/relationships/manufacturer", + "related": "/cars/{{car.StringId}}/manufacturer" + }, + "data": { + "type": "vehicleManufacturers", + "id": "{{car.Manufacturer.StringId}}" + } + }, + "wheels": { + "links": { + "self": "/cars/{{car.StringId}}/relationships/wheels", + "related": "/cars/{{car.StringId}}/wheels" + }, + "data": [ + { + "type": "carbonWheels", + "id": "{{car.Wheels.OfType().ElementAt(0).StringId}}" + } + ] + } + }, + "links": { + "self": "/cars/{{car.StringId}}" + } + }, + { + "type": "tandems", + "id": "{{tandem.StringId}}", + "attributes": { + "passengerCount": {{tandem.PassengerCount}}, + "requiresDriverLicense": {{tandem.RequiresDriverLicense.ToString().ToLowerInvariant()}}, + "gearCount": {{tandem.GearCount}}, + "weight": {{tandem.Weight.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "features": { + "links": { + "self": "/tandems/{{tandem.StringId}}/relationships/features", + "related": "/tandems/{{tandem.StringId}}/features" + }, + "data": [ + { + "type": "genericFeatures", + "id": "{{tandem.Features.ElementAt(0).StringId}}" + } + ] + }, + "cargoBox": { + "links": { + "self": "/tandems/{{tandem.StringId}}/relationships/cargoBox", + "related": "/tandems/{{tandem.StringId}}/cargoBox" + }, + "data": { + "type": "boxes", + "id": "{{tandem.CargoBox.StringId}}" + } + }, + "lights": { + "links": { + "self": "/tandems/{{tandem.StringId}}/relationships/lights", + "related": "/tandems/{{tandem.StringId}}/lights" + }, + "data": [ + { + "type": "bicycleLights", + "id": "{{tandem.Lights.ElementAt(0).StringId}}" + } + ] + }, + "manufacturer": { + "links": { + "self": "/tandems/{{tandem.StringId}}/relationships/manufacturer", + "related": "/tandems/{{tandem.StringId}}/manufacturer" + }, + "data": { + "type": "vehicleManufacturers", + "id": "{{tandem.Manufacturer.StringId}}" + } + }, + "wheels": { + "links": { + "self": "/tandems/{{tandem.StringId}}/relationships/wheels", + "related": "/tandems/{{tandem.StringId}}/wheels" + }, + "data": [ + { + "type": "chromeWheels", + "id": "{{tandem.Wheels.ElementAt(0).StringId}}" + } + ] + } + }, + "links": { + "self": "/tandems/{{tandem.StringId}}" + } + }, + { + "type": "trucks", + "id": "{{truck.StringId}}", + "attributes": { + "loadingCapacity": {{truck.LoadingCapacity.ToString(CultureInfo.InvariantCulture)}}, + "requiresDriverLicense": {{truck.RequiresDriverLicense.ToString().ToLowerInvariant()}}, + "licensePlate": "{{truck.LicensePlate}}", + "weight": {{truck.Weight.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "sleepingArea": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/sleepingArea", + "related": "/trucks/{{truck.StringId}}/sleepingArea" + }, + "data": { + "type": "boxes", + "id": "{{truck.SleepingArea.StringId}}" + } + }, + "features": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/features", + "related": "/trucks/{{truck.StringId}}/features" + }, + "data": [ + { + "type": "genericFeatures", + "id": "{{truck.Features.ElementAt(0).StringId}}" + } + ] + }, + "engine": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/engine", + "related": "/trucks/{{truck.StringId}}/engine" + }, + "data": { + "type": "dieselEngines", + "id": "{{truck.Engine.StringId}}" + } + }, + "navigationSystem": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/navigationSystem", + "related": "/trucks/{{truck.StringId}}/navigationSystem" + }, + "data": { + "type": "navigationSystems", + "id": "{{truck.NavigationSystem.StringId}}" + } + }, + "manufacturer": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/manufacturer", + "related": "/trucks/{{truck.StringId}}/manufacturer" + }, + "data": { + "type": "vehicleManufacturers", + "id": "{{truck.Manufacturer.StringId}}" + } + }, + "wheels": { + "links": { + "self": "/trucks/{{truck.StringId}}/relationships/wheels", + "related": "/trucks/{{truck.StringId}}/wheels" + }, + "data": [ + { + "type": "chromeWheels", + "id": "{{truck.Wheels.ElementAt(0).StringId}}" + } + ] + } + }, + "links": { + "self": "/trucks/{{truck.StringId}}" + } + } + ], + "included": [ + { + "type": "boxes", + "id": "{{bike.CargoBox.StringId}}", + "attributes": { + "width": {{bike.CargoBox.Width.ToString(CultureInfo.InvariantCulture)}}, + "height": {{bike.CargoBox.Height.ToString(CultureInfo.InvariantCulture)}}, + "depth": {{bike.CargoBox.Depth.ToString(CultureInfo.InvariantCulture)}} + } + }, + { + "type": "bicycleLights", + "id": "{{bike.Lights.ElementAt(0).StringId}}", + "attributes": { + "color": "{{bike.Lights.ElementAt(0).Color}}" + } + }, + { + "type": "vehicleManufacturers", + "id": "{{bike.Manufacturer.StringId}}", + "attributes": { + "name": "{{bike.Manufacturer.Name}}" + } + }, + { + "type": "carbonWheels", + "id": "{{bike.Wheels.ElementAt(0).StringId}}", + "attributes": { + "hasTube": {{bike.Wheels.Cast().ElementAt(0).HasTube.ToString().ToLowerInvariant()}}, + "radius": {{bike.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "vehicle": { + "links": { + "self": "/carbonWheels/{{bike.Wheels.ElementAt(0).StringId}}/relationships/vehicle", + "related": "/carbonWheels/{{bike.Wheels.ElementAt(0).StringId}}/vehicle" + } + } + }, + "links": { + "self": "/carbonWheels/{{bike.Wheels.ElementAt(0).StringId}}" + } + }, + { + "type": "genericFeatures", + "id": "{{car.Features.ElementAt(0).StringId}}", + "attributes": { + "description": "{{car.Features.ElementAt(0).Description}}" + }, + "relationships": { + "properties": { + "data": [ + { + "type": "numberProperties", + "id": "{{car.Features.ElementAt(0).Properties.ElementAt(0).StringId}}" + } + ] + } + } + }, + { + "type": "numberProperties", + "id": "{{car.Features.ElementAt(0).Properties.ElementAt(0).StringId}}", + "attributes": { + "name": "{{car.Features.ElementAt(0).Properties.ElementAt(0).Name}}" + }, + "relationships": { + "value": { + "data": { + "type": "numberValues", + "id": "{{car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}" + } + } + } + }, + { + "type": "numberValues", + "id": "{{car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}", + "attributes": { + "content": {{car.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content.ToString(CultureInfo.InvariantCulture)}} + } + }, + { + "type": "gasolineEngines", + "id": "{{car.Engine.StringId}}", + "attributes": { + "isHydrocarbonBased": {{car.Engine.IsHydrocarbonBased.ToString().ToLowerInvariant()}}, + "serialCode": "{{((GasolineEngine)car.Engine).SerialCode}}", + "volatility": {{((GasolineEngine)car.Engine).Volatility.ToString(CultureInfo.InvariantCulture)}}, + "capacity": {{car.Engine.Capacity.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "cylinders": { + "links": { + "self": "/gasolineEngines/{{car.Engine.StringId}}/relationships/cylinders", + "related": "/gasolineEngines/{{car.Engine.StringId}}/cylinders" + }, + "data": [ + { + "type": "cylinders", + "id": "{{((GasolineEngine)car.Engine).Cylinders.ElementAt(0).StringId}}" + } + ] + } + }, + "links": { + "self": "/gasolineEngines/{{car.Engine.StringId}}" + } + }, + { + "type": "cylinders", + "id": "{{((GasolineEngine)car.Engine).Cylinders.ElementAt(0).StringId}}", + "attributes": { + "sparkPlugCount": {{((GasolineEngine)car.Engine).Cylinders.ElementAt(0).SparkPlugCount}} + } + }, + { + "type": "navigationSystems", + "id": "{{car.NavigationSystem.StringId}}", + "attributes": { + "modelType": "{{car.NavigationSystem.ModelType}}" + } + }, + { + "type": "vehicleManufacturers", + "id": "{{car.Manufacturer.StringId}}", + "attributes": { + "name": "{{car.Manufacturer.Name}}" + } + }, + { + "type": "carbonWheels", + "id": "{{car.Wheels.ElementAt(0).StringId}}", + "attributes": { + "hasTube": {{car.Wheels.OfType().ElementAt(0).HasTube.ToString().ToLowerInvariant()}}, + "radius": {{car.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "vehicle": { + "links": { + "self": "/carbonWheels/{{car.Wheels.ElementAt(0).StringId}}/relationships/vehicle", + "related": "/carbonWheels/{{car.Wheels.ElementAt(0).StringId}}/vehicle" + } + } + }, + "links": { + "self": "/carbonWheels/{{car.Wheels.ElementAt(0).StringId}}" + } + }, + { + "type": "genericFeatures", + "id": "{{tandem.Features.ElementAt(0).StringId}}", + "attributes": { + "description": "{{tandem.Features.ElementAt(0).Description}}" + }, + "relationships": { + "properties": { + "data": [ + { + "type": "stringProperties", + "id": "{{tandem.Features.ElementAt(0).Properties.ElementAt(0).StringId}}" + } + ] + } + } + }, + { + "type": "stringProperties", + "id": "{{tandem.Features.ElementAt(0).Properties.ElementAt(0).StringId}}", + "attributes": { + "name": "{{tandem.Features.ElementAt(0).Properties.ElementAt(0).Name}}" + }, + "relationships": { + "value": { + "data": { + "type": "stringValues", + "id": "{{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}" + } + } + } + }, + { + "type": "stringValues", + "id": "{{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}", + "attributes": { + "content": "{{tandem.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content}}" + } + }, + { + "type": "boxes", + "id": "{{tandem.CargoBox.StringId}}", + "attributes": { + "width": {{tandem.CargoBox.Width.ToString(CultureInfo.InvariantCulture)}}, + "height": {{tandem.CargoBox.Height.ToString(CultureInfo.InvariantCulture)}}, + "depth": {{tandem.CargoBox.Depth.ToString(CultureInfo.InvariantCulture)}} + } + }, + { + "type": "bicycleLights", + "id": "{{tandem.Lights.ElementAt(0).StringId}}", + "attributes": { + "color": "{{tandem.Lights.ElementAt(0).Color}}" + } + }, + { + "type": "vehicleManufacturers", + "id": "{{tandem.Manufacturer.StringId}}", + "attributes": { + "name": "{{tandem.Manufacturer.Name}}" + } + }, + { + "type": "chromeWheels", + "id": "{{tandem.Wheels.ElementAt(0).StringId}}", + "attributes": { + "paintColor": "{{tandem.Wheels.OfType().ElementAt(0).PaintColor}}", + "radius": {{tandem.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "vehicle": { + "links": { + "self": "/chromeWheels/{{tandem.Wheels.ElementAt(0).StringId}}/relationships/vehicle", + "related": "/chromeWheels/{{tandem.Wheels.ElementAt(0).StringId}}/vehicle" + } + } + }, + "links": { + "self": "/chromeWheels/{{tandem.Wheels.ElementAt(0).StringId}}" + } + }, + { + "type": "boxes", + "id": "{{truck.SleepingArea.StringId}}", + "attributes": { + "width": {{truck.SleepingArea.Width.ToString(CultureInfo.InvariantCulture)}}, + "height": {{truck.SleepingArea.Height.ToString(CultureInfo.InvariantCulture)}}, + "depth": {{truck.SleepingArea.Depth.ToString(CultureInfo.InvariantCulture)}} + } + }, + { + "type": "genericFeatures", + "id": "{{truck.Features.ElementAt(0).StringId}}", + "attributes": { + "description": "{{truck.Features.ElementAt(0).Description}}" + }, + "relationships": { + "properties": { + "data": [ + { + "type": "stringProperties", + "id": "{{truck.Features.ElementAt(0).Properties.ElementAt(0).StringId}}" + } + ] + } + } + }, + { + "type": "stringProperties", + "id": "{{truck.Features.ElementAt(0).Properties.ElementAt(0).StringId}}", + "attributes": { + "name": "{{truck.Features.ElementAt(0).Properties.ElementAt(0).Name}}" + }, + "relationships": { + "value": { + "data": { + "type": "stringValues", + "id": "{{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}" + } + } + } + }, + { + "type": "stringValues", + "id": "{{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.StringId}}", + "attributes": { + "content": "{{truck.Features.ElementAt(0).Properties.OfType().ElementAt(0).Value.Content}}" + } + }, + { + "type": "dieselEngines", + "id": "{{truck.Engine.StringId}}", + "attributes": { + "isHydrocarbonBased": {{truck.Engine.IsHydrocarbonBased.ToString().ToLowerInvariant()}}, + "serialCode": "{{((DieselEngine)truck.Engine).SerialCode}}", + "viscosity": {{((DieselEngine)truck.Engine).Viscosity.ToString(CultureInfo.InvariantCulture)}}, + "capacity": {{truck.Engine.Capacity.ToString(CultureInfo.InvariantCulture)}} + }, + "links": { + "self": "/dieselEngines/{{truck.Engine.StringId}}" + } + }, + { + "type": "navigationSystems", + "id": "{{truck.NavigationSystem.StringId}}", + "attributes": { + "modelType": "{{truck.NavigationSystem.ModelType}}" + } + }, + { + "type": "vehicleManufacturers", + "id": "{{truck.Manufacturer.StringId}}", + "attributes": { + "name": "{{truck.Manufacturer.Name}}" + } + }, + { + "type": "chromeWheels", + "id": "{{truck.Wheels.ElementAt(0).StringId}}", + "attributes": { + "paintColor": "{{truck.Wheels.OfType().ElementAt(0).PaintColor}}", + "radius": {{truck.Wheels.ElementAt(0).Radius.ToString(CultureInfo.InvariantCulture)}} + }, + "relationships": { + "vehicle": { + "links": { + "self": "/chromeWheels/{{truck.Wheels.ElementAt(0).StringId}}/relationships/vehicle", + "related": "/chromeWheels/{{truck.Wheels.ElementAt(0).StringId}}/vehicle" + } + } + }, + "links": { + "self": "/chromeWheels/{{truck.Wheels.ElementAt(0).StringId}}" + } + } + ] + } + """); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs index 00680558a7..fdac2bfc64 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs @@ -1,5 +1,7 @@ using System.Globalization; using System.Net; +using System.Text.Encodings.Web; +using System.Text.Json; using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; @@ -13,6 +15,11 @@ public sealed class SerializationTests : IClassFixture, SerializationDbContext> _testContext; private readonly SerializationFakers _fakers = new(); @@ -95,74 +102,76 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings?include=attendees"", - ""first"": ""http://localhost/meetings?include=attendees"", - ""last"": ""http://localhost/meetings?include=attendees"" - }, - ""data"": [ - { - ""type"": ""meetings"", - ""id"": """ + meeting.StringId + @""", - ""attributes"": { - ""title"": """ + meeting.Title + @""", - ""startTime"": """ + meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier) + @""", - ""duration"": """ + meeting.Duration + @""", - ""location"": { - ""lat"": " + meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @", - ""lng"": " + meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @" - } - }, - ""relationships"": { - ""attendees"": { - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"" - }, - ""data"": [ + responseDocument.Should().BeJson($$""" { - ""type"": ""meetingAttendees"", - ""id"": """ + meeting.Attendees[0].StringId + @""" + "links": { + "self": "http://localhost/meetings?include=attendees", + "first": "http://localhost/meetings?include=attendees", + "last": "http://localhost/meetings?include=attendees" + }, + "data": [ + { + "type": "meetings", + "id": "{{meeting.StringId}}", + "attributes": { + "title": "{{meeting.Title}}", + "startTime": "{{meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier)}}", + "duration": "{{meeting.Duration}}", + "location": { + "lat": {{meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture)}}, + "lng": {{meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture)}} + } + }, + "relationships": { + "attendees": { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{meeting.StringId}}/attendees" + }, + "data": [ + { + "type": "meetingAttendees", + "id": "{{meeting.Attendees[0].StringId}}" + } + ] + } + }, + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}" + } + } + ], + "included": [ + { + "type": "meetingAttendees", + "id": "{{meeting.Attendees[0].StringId}}", + "attributes": { + "displayName": {{JsonSerializer.Serialize(meeting.Attendees[0].DisplayName, UnicodeSerializerOptions)}}, + "homeAddress": { + "street": "{{meeting.Attendees[0].HomeAddress.Street}}", + "zipCode": "{{meeting.Attendees[0].HomeAddress.ZipCode}}", + "city": "{{meeting.Attendees[0].HomeAddress.City}}", + "country": "{{meeting.Attendees[0].HomeAddress.Country}}" + } + }, + "relationships": { + "meeting": { + "links": { + "self": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}/relationships/meeting", + "related": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}/meeting" + } + } + }, + "links": { + "self": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}" + } + } + ], + "meta": { + "total": 1 + } } - ] - } - }, - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @""" - } - } - ], - ""included"": [ - { - ""type"": ""meetingAttendees"", - ""id"": """ + meeting.Attendees[0].StringId + @""", - ""attributes"": { - ""displayName"": """ + meeting.Attendees[0].DisplayName + @""", - ""homeAddress"": { - ""street"": """ + meeting.Attendees[0].HomeAddress.Street + @""", - ""zipCode"": """ + meeting.Attendees[0].HomeAddress.ZipCode + @""", - ""city"": """ + meeting.Attendees[0].HomeAddress.City + @""", - ""country"": """ + meeting.Attendees[0].HomeAddress.Country + @""" - } - }, - ""relationships"": { - ""meeting"": { - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @"/relationships/meeting"", - ""related"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @"/meeting"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @""" - } - } - ], - ""meta"": { - ""total"": 1 - } -}"); + """); } [Fact] @@ -185,37 +194,39 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"?include=meeting"" - }, - ""data"": { - ""type"": ""meetingAttendees"", - ""id"": """ + attendee.StringId + @""", - ""attributes"": { - ""displayName"": """ + attendee.DisplayName + @""", - ""homeAddress"": { - ""street"": """ + attendee.HomeAddress.Street + @""", - ""zipCode"": """ + attendee.HomeAddress.ZipCode + @""", - ""city"": """ + attendee.HomeAddress.City + @""", - ""country"": """ + attendee.HomeAddress.Country + @""" - } - }, - ""relationships"": { - ""meeting"": { - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/relationships/meeting"", - ""related"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting"" - }, - ""data"": null - } - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @""" - } - }, - ""included"": [] -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}?include=meeting" + }, + "data": { + "type": "meetingAttendees", + "id": "{{attendee.StringId}}", + "attributes": { + "displayName": {{JsonSerializer.Serialize(attendee.DisplayName, UnicodeSerializerOptions)}}, + "homeAddress": { + "street": "{{attendee.HomeAddress.Street}}", + "zipCode": "{{attendee.HomeAddress.ZipCode}}", + "city": "{{attendee.HomeAddress.City}}", + "country": "{{attendee.HomeAddress.Country}}" + } + }, + "relationships": { + "meeting": { + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}/relationships/meeting", + "related": "http://localhost/meetingAttendees/{{attendee.StringId}}/meeting" + }, + "data": null + } + }, + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}" + } + }, + "included": [] + } + """); } [Fact] @@ -239,44 +250,46 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/?include=attendees"", - ""first"": ""http://localhost/meetings/?include=attendees"", - ""last"": ""http://localhost/meetings/?include=attendees"" - }, - ""data"": [ - { - ""type"": ""meetings"", - ""id"": """ + meeting.StringId + @""", - ""attributes"": { - ""title"": """ + meeting.Title + @""", - ""startTime"": """ + meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier) + @""", - ""duration"": """ + meeting.Duration + @""", - ""location"": { - ""lat"": " + meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @", - ""lng"": " + meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @" - } - }, - ""relationships"": { - ""attendees"": { - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"" - }, - ""data"": [] - } - }, - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @""" - } - } - ], - ""included"": [], - ""meta"": { - ""total"": 1 - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/?include=attendees", + "first": "http://localhost/meetings/?include=attendees", + "last": "http://localhost/meetings/?include=attendees" + }, + "data": [ + { + "type": "meetings", + "id": "{{meeting.StringId}}", + "attributes": { + "title": "{{meeting.Title}}", + "startTime": "{{meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier)}}", + "duration": "{{meeting.Duration}}", + "location": { + "lat": {{meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture)}}, + "lng": {{meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture)}} + } + }, + "relationships": { + "attendees": { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{meeting.StringId}}/attendees" + }, + "data": [] + } + }, + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}" + } + } + ], + "included": [], + "meta": { + "total": 1 + } + } + """); } [Fact] @@ -299,35 +312,37 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @""" - }, - ""data"": { - ""type"": ""meetings"", - ""id"": """ + meeting.StringId + @""", - ""attributes"": { - ""title"": """ + meeting.Title + @""", - ""startTime"": """ + meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier) + @""", - ""duration"": """ + meeting.Duration + @""", - ""location"": { - ""lat"": " + meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @", - ""lng"": " + meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @" - } - }, - ""relationships"": { - ""attendees"": { - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @""" - } - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}" + }, + "data": { + "type": "meetings", + "id": "{{meeting.StringId}}", + "attributes": { + "title": "{{meeting.Title}}", + "startTime": "{{meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier)}}", + "duration": "{{meeting.Duration}}", + "location": { + "lat": {{meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture)}}, + "lng": {{meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture)}} + } + }, + "relationships": { + "attendees": { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{meeting.StringId}}/attendees" + } + } + }, + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}" + } + } + } + """); } [Fact] @@ -346,19 +361,21 @@ public async Task Cannot_get_unknown_primary_resource_by_ID() string errorId = JsonApiStringConverter.ExtractErrorId(responseDocument); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/ffffffff-ffff-ffff-ffff-ffffffffffff"" - }, - ""errors"": [ - { - ""id"": """ + errorId + @""", - ""status"": ""404"", - ""title"": ""The requested resource does not exist."", - ""detail"": ""Resource of type 'meetings' with ID '" + meetingId + @"' does not exist."" - } - ] -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/ffffffff-ffff-ffff-ffff-ffffffffffff" + }, + "errors": [ + { + "id": "{{errorId}}", + "status": "404", + "title": "The requested resource does not exist.", + "detail": "Resource of type 'meetings' with ID '{{meetingId}}' does not exist." + } + ] + } + """); } [Fact] @@ -382,35 +399,37 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting"" - }, - ""data"": { - ""type"": ""meetings"", - ""id"": """ + attendee.Meeting.StringId + @""", - ""attributes"": { - ""title"": """ + attendee.Meeting.Title + @""", - ""startTime"": """ + attendee.Meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier) + @""", - ""duration"": """ + attendee.Meeting.Duration + @""", - ""location"": { - ""lat"": " + attendee.Meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @", - ""lng"": " + attendee.Meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @" - } - }, - ""relationships"": { - ""attendees"": { - ""links"": { - ""self"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @"/attendees"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetings/" + attendee.Meeting.StringId + @""" - } - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}/meeting" + }, + "data": { + "type": "meetings", + "id": "{{attendee.Meeting.StringId}}", + "attributes": { + "title": "{{attendee.Meeting.Title}}", + "startTime": "{{attendee.Meeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier)}}", + "duration": "{{attendee.Meeting.Duration}}", + "location": { + "lat": {{attendee.Meeting.Location.Latitude.ToString(CultureInfo.InvariantCulture)}}, + "lng": {{attendee.Meeting.Location.Longitude.ToString(CultureInfo.InvariantCulture)}} + } + }, + "relationships": { + "attendees": { + "links": { + "self": "http://localhost/meetings/{{attendee.Meeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{attendee.Meeting.StringId}}/attendees" + } + } + }, + "links": { + "self": "http://localhost/meetings/{{attendee.Meeting.StringId}}" + } + } + } + """); } [Fact] @@ -433,12 +452,14 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting"" - }, - ""data"": null -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}/meeting" + }, + "data": null + } + """); } [Fact] @@ -462,42 +483,44 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"", - ""first"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"", - ""last"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"" - }, - ""data"": [ - { - ""type"": ""meetingAttendees"", - ""id"": """ + meeting.Attendees[0].StringId + @""", - ""attributes"": { - ""displayName"": """ + meeting.Attendees[0].DisplayName + @""", - ""homeAddress"": { - ""street"": """ + meeting.Attendees[0].HomeAddress.Street + @""", - ""zipCode"": """ + meeting.Attendees[0].HomeAddress.ZipCode + @""", - ""city"": """ + meeting.Attendees[0].HomeAddress.City + @""", - ""country"": """ + meeting.Attendees[0].HomeAddress.Country + @""" - } - }, - ""relationships"": { - ""meeting"": { - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @"/relationships/meeting"", - ""related"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @"/meeting"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + meeting.Attendees[0].StringId + @""" - } - } - ], - ""meta"": { - ""total"": 1 - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/attendees", + "first": "http://localhost/meetings/{{meeting.StringId}}/attendees", + "last": "http://localhost/meetings/{{meeting.StringId}}/attendees" + }, + "data": [ + { + "type": "meetingAttendees", + "id": "{{meeting.Attendees[0].StringId}}", + "attributes": { + "displayName": {{JsonSerializer.Serialize(meeting.Attendees[0].DisplayName, UnicodeSerializerOptions)}}, + "homeAddress": { + "street": "{{meeting.Attendees[0].HomeAddress.Street}}", + "zipCode": "{{meeting.Attendees[0].HomeAddress.ZipCode}}", + "city": "{{meeting.Attendees[0].HomeAddress.City}}", + "country": "{{meeting.Attendees[0].HomeAddress.Country}}" + } + }, + "relationships": { + "meeting": { + "links": { + "self": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}/relationships/meeting", + "related": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}/meeting" + } + } + }, + "links": { + "self": "http://localhost/meetingAttendees/{{meeting.Attendees[0].StringId}}" + } + } + ], + "meta": { + "total": 1 + } + } + """); } [Fact] @@ -520,16 +543,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"", - ""first"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"" - }, - ""data"": [], - ""meta"": { - ""total"": 0 - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/attendees", + "first": "http://localhost/meetings/{{meeting.StringId}}/attendees" + }, + "data": [], + "meta": { + "total": 0 + } + } + """); } [Fact] @@ -553,16 +578,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/relationships/meeting"", - ""related"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting"" - }, - ""data"": { - ""type"": ""meetings"", - ""id"": """ + attendee.Meeting.StringId + @""" - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}/relationships/meeting", + "related": "http://localhost/meetingAttendees/{{attendee.StringId}}/meeting" + }, + "data": { + "type": "meetings", + "id": "{{attendee.Meeting.StringId}}" + } + } + """); } [Fact] @@ -588,27 +615,29 @@ await _testContext.RunOnDatabaseAsync(async dbContext => string[] meetingIds = [.. meeting.Attendees.Select(attendee => attendee.StringId!).OrderBy(id => id)]; - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + meeting.StringId + @"/attendees"", - ""first"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"", - ""last"": ""http://localhost/meetings/" + meeting.StringId + @"/relationships/attendees"" - }, - ""data"": [ - { - ""type"": ""meetingAttendees"", - ""id"": """ + meetingIds[0] + @""" - }, - { - ""type"": ""meetingAttendees"", - ""id"": """ + meetingIds[1] + @""" - } - ], - ""meta"": { - ""total"": 2 - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{meeting.StringId}}/attendees", + "first": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees", + "last": "http://localhost/meetings/{{meeting.StringId}}/relationships/attendees" + }, + "data": [ + { + "type": "meetingAttendees", + "id": "{{meetingIds[0]}}" + }, + { + "type": "meetingAttendees", + "id": "{{meetingIds[1]}}" + } + ], + "meta": { + "total": 2 + } + } + """); } [Fact] @@ -646,35 +675,37 @@ public async Task Can_create_resource_with_side_effects() // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.Created); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetings"" - }, - ""data"": { - ""type"": ""meetings"", - ""id"": """ + newMeeting.StringId + @""", - ""attributes"": { - ""title"": """ + newMeeting.Title + @""", - ""startTime"": """ + newMeeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier) + @""", - ""duration"": """ + newMeeting.Duration + @""", - ""location"": { - ""lat"": " + newMeeting.Location.Latitude.ToString(CultureInfo.InvariantCulture) + @", - ""lng"": " + newMeeting.Location.Longitude.ToString(CultureInfo.InvariantCulture) + @" - } - }, - ""relationships"": { - ""attendees"": { - ""links"": { - ""self"": ""http://localhost/meetings/" + newMeeting.StringId + @"/relationships/attendees"", - ""related"": ""http://localhost/meetings/" + newMeeting.StringId + @"/attendees"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetings/" + newMeeting.StringId + @""" - } - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetings" + }, + "data": { + "type": "meetings", + "id": "{{newMeeting.StringId}}", + "attributes": { + "title": "{{newMeeting.Title}}", + "startTime": "{{newMeeting.StartTime.ToString(JsonDateTimeOffsetFormatSpecifier)}}", + "duration": "{{newMeeting.Duration}}", + "location": { + "lat": {{newMeeting.Location.Latitude.ToString(CultureInfo.InvariantCulture)}}, + "lng": {{newMeeting.Location.Longitude.ToString(CultureInfo.InvariantCulture)}} + } + }, + "relationships": { + "attendees": { + "links": { + "self": "http://localhost/meetings/{{newMeeting.StringId}}/relationships/attendees", + "related": "http://localhost/meetings/{{newMeeting.StringId}}/attendees" + } + } + }, + "links": { + "self": "http://localhost/meetings/{{newMeeting.StringId}}" + } + } + } + """); } [Fact] @@ -710,35 +741,37 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @""" - }, - ""data"": { - ""type"": ""meetingAttendees"", - ""id"": """ + existingAttendee.StringId + @""", - ""attributes"": { - ""displayName"": """ + existingAttendee.DisplayName + @""", - ""homeAddress"": { - ""street"": """ + existingAttendee.HomeAddress.Street + @""", - ""zipCode"": """ + existingAttendee.HomeAddress.ZipCode + @""", - ""city"": """ + existingAttendee.HomeAddress.City + @""", - ""country"": """ + existingAttendee.HomeAddress.Country + @""" - } - }, - ""relationships"": { - ""meeting"": { - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"/relationships/meeting"", - ""related"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @"/meeting"" - } - } - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + existingAttendee.StringId + @""" - } - } -}"); + responseDocument.Should().BeJson($$""" + { + "links": { + "self": "http://localhost/meetingAttendees/{{existingAttendee.StringId}}" + }, + "data": { + "type": "meetingAttendees", + "id": "{{existingAttendee.StringId}}", + "attributes": { + "displayName": {{JsonSerializer.Serialize(existingAttendee.DisplayName, UnicodeSerializerOptions)}}, + "homeAddress": { + "street": "{{existingAttendee.HomeAddress.Street}}", + "zipCode": "{{existingAttendee.HomeAddress.ZipCode}}", + "city": "{{existingAttendee.HomeAddress.City}}", + "country": "{{existingAttendee.HomeAddress.Country}}" + } + }, + "relationships": { + "meeting": { + "links": { + "self": "http://localhost/meetingAttendees/{{existingAttendee.StringId}}/relationships/meeting", + "related": "http://localhost/meetingAttendees/{{existingAttendee.StringId}}/meeting" + } + } + }, + "links": { + "self": "http://localhost/meetingAttendees/{{existingAttendee.StringId}}" + } + } + } + """); } [Fact] @@ -810,15 +843,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK); - responseDocument.Should().BeJson(@"{ - ""jsonapi"": { - ""version"": ""1.1"" - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/" + attendee.StringId + @"/meeting"" - }, - ""data"": null -}"); + responseDocument.Should().BeJson($$""" + { + "jsonapi": { + "version": "1.1" + }, + "links": { + "self": "http://localhost/meetingAttendees/{{attendee.StringId}}/meeting" + }, + "data": null + } + """); } [Fact] @@ -840,21 +875,23 @@ public async Task Includes_version_on_error_at_resource_endpoint() string errorId = JsonApiStringConverter.ExtractErrorId(responseDocument); - responseDocument.Should().BeJson(@"{ - ""jsonapi"": { - ""version"": ""1.1"" - }, - ""links"": { - ""self"": ""http://localhost/meetingAttendees/ffffffff-ffff-ffff-ffff-ffffffffffff"" - }, - ""errors"": [ - { - ""id"": """ + errorId + @""", - ""status"": ""404"", - ""title"": ""The requested resource does not exist."", - ""detail"": ""Resource of type 'meetingAttendees' with ID '" + attendeeId + @"' does not exist."" - } - ] -}"); + responseDocument.Should().BeJson($$""" + { + "jsonapi": { + "version": "1.1" + }, + "links": { + "self": "http://localhost/meetingAttendees/ffffffff-ffff-ffff-ffff-ffffffffffff" + }, + "errors": [ + { + "id": "{{errorId}}", + "status": "404", + "title": "The requested resource does not exist.", + "detail": "Resource of type 'meetingAttendees' with ID '{{attendeeId}}' does not exist." + } + ] + } + """); } } diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/ResponseModelAdapterTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/ResponseModelAdapterTests.cs index e5c97abdb5..2d2e07e600 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/ResponseModelAdapterTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/ResponseModelAdapterTests.cs @@ -30,121 +30,130 @@ public void Resources_in_deeply_nested_circular_chain_are_written_in_relationshi article.Author.FavoriteFood = fakers.Food.Generate(); article.Author.Blogs.ElementAt(1).Reviewer.FavoriteFood = fakers.Food.Generate(); - IJsonApiOptions options = new JsonApiOptions(); + IJsonApiOptions options = new JsonApiOptions + { + SerializerOptions = + { + WriteIndented = true + } + }; + ResponseModelAdapter responseModelAdapter = CreateAdapter(options, article.StringId, "author.blogs.reviewer.favoriteFood"); // Act Document document = responseModelAdapter.Convert(article); // Assert - string text = JsonSerializer.Serialize(document, new JsonSerializerOptions(options.SerializerWriteOptions)); + string text = JsonSerializer.Serialize(document, options.SerializerWriteOptions); // ReSharper disable StringLiteralTypo - text.Should().BeJson(@"{ - ""data"": { - ""type"": ""articles"", - ""id"": ""1"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - }, - ""included"": [ - { - ""type"": ""people"", - ""id"": ""2"", - ""attributes"": { - ""name"": ""Ernestine Runte"" - }, - ""relationships"": { - ""blogs"": { - ""data"": [ - { - ""type"": ""blogs"", - ""id"": ""3"" - }, + text.Should().BeJson(""" { - ""type"": ""blogs"", - ""id"": ""4"" + "data": { + "type": "articles", + "id": "1", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "author": { + "data": { + "type": "people", + "id": "2" + } + } + } + }, + "included": [ + { + "type": "people", + "id": "2", + "attributes": { + "name": "Ernestine Runte" + }, + "relationships": { + "blogs": { + "data": [ + { + "type": "blogs", + "id": "3" + }, + { + "type": "blogs", + "id": "4" + } + ] + }, + "favoriteFood": { + "data": { + "type": "foods", + "id": "6" + } + } + } + }, + { + "type": "blogs", + "id": "3", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "2" + } + } + } + }, + { + "type": "blogs", + "id": "4", + "attributes": { + "title": "I'll connect the mobile ADP card, that should card the ADP card!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "5" + } + } + } + }, + { + "type": "people", + "id": "5", + "attributes": { + "name": "Doug Shields" + }, + "relationships": { + "favoriteFood": { + "data": { + "type": "foods", + "id": "7" + } + } + } + }, + { + "type": "foods", + "id": "7", + "attributes": { + "dish": "Nostrum totam harum totam voluptatibus." + } + }, + { + "type": "foods", + "id": "6", + "attributes": { + "dish": "Illum assumenda iste quia natus et dignissimos reiciendis." + } + } + ] } - ] - }, - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""6"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""3"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""4"", - ""attributes"": { - ""title"": ""I'll connect the mobile ADP card, that should card the ADP card!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""5"" - } - } - } - }, - { - ""type"": ""people"", - ""id"": ""5"", - ""attributes"": { - ""name"": ""Doug Shields"" - }, - ""relationships"": { - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""7"" - } - } - } - }, - { - ""type"": ""foods"", - ""id"": ""7"", - ""attributes"": { - ""dish"": ""Nostrum totam harum totam voluptatibus."" - } - }, - { - ""type"": ""foods"", - ""id"": ""6"", - ""attributes"": { - ""dish"": ""Illum assumenda iste quia natus et dignissimos reiciendis."" - } - } - ] -}"); + """); // ReSharper restore StringLiteralTypo } @@ -165,7 +174,14 @@ public void Resources_in_deeply_nested_circular_chains_are_written_in_relationsh Article article2 = fakers.Article.Generate(); article2.Author = article1.Author; - IJsonApiOptions options = new JsonApiOptions(); + IJsonApiOptions options = new JsonApiOptions + { + SerializerOptions = + { + WriteIndented = true + } + }; + ResponseModelAdapter responseModelAdapter = CreateAdapter(options, article1.StringId, "author.blogs.reviewer.favoriteFood"); // Act @@ -176,131 +192,133 @@ public void Resources_in_deeply_nested_circular_chains_are_written_in_relationsh }); // Assert - string text = JsonSerializer.Serialize(document, new JsonSerializerOptions(options.SerializerWriteOptions)); + string text = JsonSerializer.Serialize(document, options.SerializerWriteOptions); // ReSharper disable StringLiteralTypo - text.Should().BeJson(@"{ - ""data"": [ - { - ""type"": ""articles"", - ""id"": ""1"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - }, - { - ""type"": ""articles"", - ""id"": ""8"", - ""attributes"": { - ""title"": ""I'll connect the mobile ADP card, that should card the ADP card!"" - }, - ""relationships"": { - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - } - ], - ""included"": [ - { - ""type"": ""people"", - ""id"": ""2"", - ""attributes"": { - ""name"": ""Ernestine Runte"" - }, - ""relationships"": { - ""blogs"": { - ""data"": [ - { - ""type"": ""blogs"", - ""id"": ""3"" - }, + text.Should().BeJson(""" { - ""type"": ""blogs"", - ""id"": ""4"" + "data": [ + { + "type": "articles", + "id": "1", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "author": { + "data": { + "type": "people", + "id": "2" + } + } + } + }, + { + "type": "articles", + "id": "8", + "attributes": { + "title": "I'll connect the mobile ADP card, that should card the ADP card!" + }, + "relationships": { + "author": { + "data": { + "type": "people", + "id": "2" + } + } + } + } + ], + "included": [ + { + "type": "people", + "id": "2", + "attributes": { + "name": "Ernestine Runte" + }, + "relationships": { + "blogs": { + "data": [ + { + "type": "blogs", + "id": "3" + }, + { + "type": "blogs", + "id": "4" + } + ] + }, + "favoriteFood": { + "data": { + "type": "foods", + "id": "6" + } + } + } + }, + { + "type": "blogs", + "id": "3", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "2" + } + } + } + }, + { + "type": "blogs", + "id": "4", + "attributes": { + "title": "I'll connect the mobile ADP card, that should card the ADP card!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "5" + } + } + } + }, + { + "type": "people", + "id": "5", + "attributes": { + "name": "Doug Shields" + }, + "relationships": { + "favoriteFood": { + "data": { + "type": "foods", + "id": "7" + } + } + } + }, + { + "type": "foods", + "id": "7", + "attributes": { + "dish": "Nostrum totam harum totam voluptatibus." + } + }, + { + "type": "foods", + "id": "6", + "attributes": { + "dish": "Illum assumenda iste quia natus et dignissimos reiciendis." + } + } + ] } - ] - }, - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""6"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""3"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""4"", - ""attributes"": { - ""title"": ""I'll connect the mobile ADP card, that should card the ADP card!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""5"" - } - } - } - }, - { - ""type"": ""people"", - ""id"": ""5"", - ""attributes"": { - ""name"": ""Doug Shields"" - }, - ""relationships"": { - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""7"" - } - } - } - }, - { - ""type"": ""foods"", - ""id"": ""7"", - ""attributes"": { - ""dish"": ""Nostrum totam harum totam voluptatibus."" - } - }, - { - ""type"": ""foods"", - ""id"": ""6"", - ""attributes"": { - ""dish"": ""Illum assumenda iste quia natus et dignissimos reiciendis."" - } - } - ] -}"); + """); // ReSharper restore StringLiteralTypo } @@ -327,7 +345,13 @@ public void Resources_in_overlapping_deeply_nested_circular_chains_are_written_i article.Author.Blogs.ElementAt(1).Reviewer.FavoriteSong = fakers.Song.Generate(); article.Reviewer.FavoriteSong = fakers.Song.Generate(); - IJsonApiOptions options = new JsonApiOptions(); + IJsonApiOptions options = new JsonApiOptions + { + SerializerOptions = + { + WriteIndented = true + } + }; ResponseModelAdapter responseModelAdapter = CreateAdapter(options, article.StringId, "author.blogs.reviewer.favoriteFood,reviewer.blogs.author.favoriteSong"); @@ -336,188 +360,190 @@ public void Resources_in_overlapping_deeply_nested_circular_chains_are_written_i Document document = responseModelAdapter.Convert(article); // Assert - string text = JsonSerializer.Serialize(document, new JsonSerializerOptions(options.SerializerWriteOptions)); + string text = JsonSerializer.Serialize(document, options.SerializerWriteOptions); // ReSharper disable StringLiteralTypo - text.Should().BeJson(@"{ - ""data"": { - ""type"": ""articles"", - ""id"": ""1"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""8"" - } - }, - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - } - } - }, - ""included"": [ - { - ""type"": ""people"", - ""id"": ""8"", - ""attributes"": { - ""name"": ""Nettie Howell"" - }, - ""relationships"": { - ""blogs"": { - ""data"": [ - { - ""type"": ""blogs"", - ""id"": ""9"" - }, + text.Should().BeJson(""" { - ""type"": ""blogs"", - ""id"": ""3"" + "data": { + "type": "articles", + "id": "1", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "8" + } + }, + "author": { + "data": { + "type": "people", + "id": "2" + } + } + } + }, + "included": [ + { + "type": "people", + "id": "8", + "attributes": { + "name": "Nettie Howell" + }, + "relationships": { + "blogs": { + "data": [ + { + "type": "blogs", + "id": "9" + }, + { + "type": "blogs", + "id": "3" + } + ] + }, + "favoriteSong": { + "data": { + "type": "songs", + "id": "11" + } + } + } + }, + { + "type": "blogs", + "id": "9", + "attributes": { + "title": "The RSS bus is down, parse the mobile bus so we can parse the RSS bus!" + }, + "relationships": { + "author": { + "data": { + "type": "people", + "id": "8" + } + } + } + }, + { + "type": "blogs", + "id": "3", + "attributes": { + "title": "The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "2" + } + }, + "author": { + "data": { + "type": "people", + "id": "5" + } + } + } + }, + { + "type": "people", + "id": "2", + "attributes": { + "name": "Ernestine Runte" + }, + "relationships": { + "blogs": { + "data": [ + { + "type": "blogs", + "id": "3" + }, + { + "type": "blogs", + "id": "4" + } + ] + }, + "favoriteFood": { + "data": { + "type": "foods", + "id": "6" + } + } + } + }, + { + "type": "blogs", + "id": "4", + "attributes": { + "title": "I'll connect the mobile ADP card, that should card the ADP card!" + }, + "relationships": { + "reviewer": { + "data": { + "type": "people", + "id": "5" + } + } + } + }, + { + "type": "people", + "id": "5", + "attributes": { + "name": "Doug Shields" + }, + "relationships": { + "favoriteFood": { + "data": { + "type": "foods", + "id": "7" + } + }, + "favoriteSong": { + "data": { + "type": "songs", + "id": "10" + } + } + } + }, + { + "type": "foods", + "id": "7", + "attributes": { + "dish": "Nostrum totam harum totam voluptatibus." + } + }, + { + "type": "songs", + "id": "10", + "attributes": { + "title": "Illum assumenda iste quia natus et dignissimos reiciendis." + } + }, + { + "type": "foods", + "id": "6", + "attributes": { + "dish": "Illum assumenda iste quia natus et dignissimos reiciendis." + } + }, + { + "type": "songs", + "id": "11", + "attributes": { + "title": "Nostrum totam harum totam voluptatibus." + } + } + ] } - ] - }, - ""favoriteSong"": { - ""data"": { - ""type"": ""songs"", - ""id"": ""11"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""9"", - ""attributes"": { - ""title"": ""The RSS bus is down, parse the mobile bus so we can parse the RSS bus!"" - }, - ""relationships"": { - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""8"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""3"", - ""attributes"": { - ""title"": ""The SAS microchip is down, quantify the 1080p microchip so we can quantify the SAS microchip!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""2"" - } - }, - ""author"": { - ""data"": { - ""type"": ""people"", - ""id"": ""5"" - } - } - } - }, - { - ""type"": ""people"", - ""id"": ""2"", - ""attributes"": { - ""name"": ""Ernestine Runte"" - }, - ""relationships"": { - ""blogs"": { - ""data"": [ - { - ""type"": ""blogs"", - ""id"": ""3"" - }, - { - ""type"": ""blogs"", - ""id"": ""4"" - } - ] - }, - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""6"" - } - } - } - }, - { - ""type"": ""blogs"", - ""id"": ""4"", - ""attributes"": { - ""title"": ""I'll connect the mobile ADP card, that should card the ADP card!"" - }, - ""relationships"": { - ""reviewer"": { - ""data"": { - ""type"": ""people"", - ""id"": ""5"" - } - } - } - }, - { - ""type"": ""people"", - ""id"": ""5"", - ""attributes"": { - ""name"": ""Doug Shields"" - }, - ""relationships"": { - ""favoriteFood"": { - ""data"": { - ""type"": ""foods"", - ""id"": ""7"" - } - }, - ""favoriteSong"": { - ""data"": { - ""type"": ""songs"", - ""id"": ""10"" - } - } - } - }, - { - ""type"": ""foods"", - ""id"": ""7"", - ""attributes"": { - ""dish"": ""Nostrum totam harum totam voluptatibus."" - } - }, - { - ""type"": ""songs"", - ""id"": ""10"", - ""attributes"": { - ""title"": ""Illum assumenda iste quia natus et dignissimos reiciendis."" - } - }, - { - ""type"": ""foods"", - ""id"": ""6"", - ""attributes"": { - ""dish"": ""Illum assumenda iste quia natus et dignissimos reiciendis."" - } - }, - { - ""type"": ""songs"", - ""id"": ""11"", - ""attributes"": { - ""title"": ""Nostrum totam harum totam voluptatibus."" - } - } - ] -}"); + """); // ReSharper restore StringLiteralTypo } diff --git a/test/SourceGeneratorTests/ControllerGenerationTests.cs b/test/SourceGeneratorTests/ControllerGenerationTests.cs index c1d56d12dd..8f24b882a0 100644 --- a/test/SourceGeneratorTests/ControllerGenerationTests.cs +++ b/test/SourceGeneratorTests/ControllerGenerationTests.cs @@ -24,13 +24,14 @@ public void Can_generate_for_default_controller() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -51,25 +52,27 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using ExampleApi.Models; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using ExampleApi.Models; -namespace ExampleApi.Controllers; + namespace ExampleApi.Controllers; -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, resourceGraph, loggerFactory, resourceService) + { + } + } + + """); } [Fact] @@ -86,13 +89,14 @@ public void Can_generate_for_read_only_controller() .WithNamespaceImportFor(typeof(ResourceAttribute)) .WithNamespaceImportFor(typeof(JsonApiEndpoints)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource(GenerateControllerEndpoints = JsonApiEndpoints.Query)] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -113,25 +117,27 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using ExampleApi.Models; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using ExampleApi.Models; -namespace ExampleApi.Controllers; + namespace ExampleApi.Controllers; -public sealed partial class ItemsController : JsonApiQueryController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceQueryService queryService) - : base(options, resourceGraph, loggerFactory, queryService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiQueryController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceQueryService queryService) + : base(options, resourceGraph, loggerFactory, queryService) + { + } + } + + """); } [Fact] @@ -148,13 +154,14 @@ public void Can_generate_for_write_only_controller() .WithNamespaceImportFor(typeof(ResourceAttribute)) .WithNamespaceImportFor(typeof(JsonApiEndpoints)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource(GenerateControllerEndpoints = JsonApiEndpoints.Command)] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -175,25 +182,27 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using ExampleApi.Models; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using ExampleApi.Models; -namespace ExampleApi.Controllers; + namespace ExampleApi.Controllers; -public sealed partial class ItemsController : JsonApiCommandController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceCommandService commandService) - : base(options, resourceGraph, loggerFactory, commandService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiCommandController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceCommandService commandService) + : base(options, resourceGraph, loggerFactory, commandService) + { + } + } + + """); } [Fact] @@ -210,16 +219,17 @@ public void Can_generate_for_mixed_controller() .WithNamespaceImportFor(typeof(ResourceAttribute)) .WithNamespaceImportFor(typeof(JsonApiEndpoints)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource(GenerateControllerEndpoints = NoRelationshipEndpoints)] public sealed class Item : Identifiable { private const JsonApiEndpoints NoRelationshipEndpoints = JsonApiEndpoints.GetCollection | JsonApiEndpoints.GetSingle | JsonApiEndpoints.Post | JsonApiEndpoints.Patch | JsonApiEndpoints.Delete; - + [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -240,34 +250,36 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// - -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using ExampleApi.Models; - -namespace ExampleApi.Controllers; + runResult.Should().HaveProducedSourceCode(""" + // + + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using ExampleApi.Models; + + namespace ExampleApi.Controllers; + + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IGetAllService getAll, + IGetByIdService getById, + ICreateService create, + IUpdateService update, + IDeleteService delete) + : base(options, resourceGraph, loggerFactory, + getAll: getAll, + getById: getById, + create: create, + update: update, + delete: delete) + { + } + } -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IGetAllService getAll, - IGetByIdService getById, - ICreateService create, - IUpdateService update, - IDeleteService delete) - : base(options, resourceGraph, loggerFactory, - getAll: getAll, - getById: getById, - create: create, - update: update, - delete: delete) - { - } -} -"); + """); } [Fact] @@ -283,12 +295,13 @@ public void Skips_for_resource_without_ResourceAttribute() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(AttrAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -325,13 +338,14 @@ public void Skips_for_resource_with_no_endpoints() .WithNamespaceImportFor(typeof(ResourceAttribute)) .WithNamespaceImportFor(typeof(JsonApiEndpoints)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource(GenerateControllerEndpoints = JsonApiEndpoints.None)] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -365,7 +379,7 @@ public void Skips_for_missing_dependency_on_JsonApiDotNetCore() string source = new SourceCodeBuilder() .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" public abstract class Identifiable { } @@ -383,7 +397,8 @@ public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -421,13 +436,14 @@ public void Skips_for_missing_dependency_on_LoggerFactory() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -464,13 +480,14 @@ public void Warns_for_resource_that_does_not_implement_IIdentifiable() string source = new SourceCodeBuilder() .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" [Resource] public sealed class Item { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -491,7 +508,7 @@ public sealed class Item GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().HaveSingleDiagnostic( - "(6,17): warning JADNC001: Type 'Item' must implement IIdentifiable when using ResourceAttribute to auto-generate ASP.NET controllers"); + "(5,1): warning JADNC001: Type 'Item' must implement IIdentifiable when using ResourceAttribute to auto-generate ASP.NET controllers"); runResult.Should().NotHaveProducedSourceCode(); } @@ -509,7 +526,7 @@ public void Adds_nullable_enable_for_nullable_reference_ID_type() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" + .WithCode(""" #nullable enable [Resource] @@ -517,7 +534,8 @@ public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -554,13 +572,14 @@ public void Can_generate_for_custom_namespace() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi.Models") - .WithCode(@" - [Resource(ControllerNamespace = ""Some.Path.To.Generate.Code.In"")] + .WithCode(""" + [Resource(ControllerNamespace = "Some.Path.To.Generate.Code.In")] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -581,25 +600,27 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using ExampleApi.Models; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using ExampleApi.Models; -namespace Some.Path.To.Generate.Code.In; + namespace Some.Path.To.Generate.Code.In; -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, resourceGraph, loggerFactory, resourceService) + { + } + } + + """); } [Fact] @@ -615,13 +636,14 @@ public void Can_generate_for_top_level_namespace() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("TopLevel") - .WithCode(@" + .WithCode(""" [Resource] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -642,25 +664,27 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; -using TopLevel; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; + using TopLevel; -namespace Controllers; + namespace Controllers; -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, resourceGraph, loggerFactory, resourceService) + { + } + } + + """); } [Fact] @@ -675,13 +699,14 @@ public void Can_generate_for_global_namespace() string source = new SourceCodeBuilder() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) - .WithCode(@" + .WithCode(""" [Resource] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -702,22 +727,24 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, resourceGraph, loggerFactory, resourceService) + { + } + } + + """); } [Fact] @@ -733,13 +760,14 @@ public void Can_generate_for_shared_namespace() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) .InNamespace("ExampleApi") - .WithCode(@" - [Resource(ControllerNamespace = ""ExampleApi"")] + .WithCode(""" + [Resource(ControllerNamespace = "ExampleApi")] public sealed class Item : Identifiable { [Attr] public int Value { get; set; } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() @@ -760,24 +788,26 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCode(@"// + runResult.Should().HaveProducedSourceCode(""" + // -using Microsoft.Extensions.Logging; -using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Services; + using Microsoft.Extensions.Logging; + using JsonApiDotNetCore.Configuration; + using JsonApiDotNetCore.Controllers; + using JsonApiDotNetCore.Services; -namespace ExampleApi; + namespace ExampleApi; -public sealed partial class ItemsController : JsonApiController -{ - public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} -"); + public sealed partial class ItemsController : JsonApiController + { + public ItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, resourceGraph, loggerFactory, resourceService) + { + } + } + + """); } [Fact] @@ -792,7 +822,7 @@ public void Generates_unique_file_names_for_duplicate_resource_name_in_different string source = new SourceCodeBuilder() .WithNamespaceImportFor(typeof(IIdentifiable)) .WithNamespaceImportFor(typeof(ResourceAttribute)) - .WithCode(@" + .WithCode(""" namespace The.First.One { [Resource] @@ -811,7 +841,8 @@ public sealed class Item : Identifiable [Attr] public int Value { get; set; } } - }") + } + """) .Build(); Compilation inputCompilation = new CompilationBuilder() From 2aecb1755735069c3447c8a9eca814c63aecf203 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:26:54 +0100 Subject: [PATCH 09/16] Resharper: convert to switch expression --- .../CollectionConverter.cs | 33 +++++-------------- .../QueryableBuilding/WhereClauseBuilder.cs | 30 ++++++----------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs b/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs index 6edce84335..645b5329b7 100644 --- a/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs +++ b/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs @@ -68,32 +68,15 @@ private Type ToConcreteCollectionType(Type collectionType) /// public IReadOnlyCollection ExtractResources(object? value) { - if (value is List resourceList) + return value switch { - return resourceList; - } - - if (value is HashSet resourceSet) - { - return resourceSet; - } - - if (value is IReadOnlyCollection resourceCollection) - { - return resourceCollection; - } - - if (value is IEnumerable resources) - { - return resources.ToList(); - } - - if (value is IIdentifiable resource) - { - return resource.AsArray(); - } - - return Array.Empty(); + List resourceList => resourceList, + HashSet resourceSet => resourceSet, + IReadOnlyCollection resourceCollection => resourceCollection, + IEnumerable resources => resources.ToList(), + IIdentifiable resource => resource.AsArray(), + _ => Array.Empty() + }; } /// diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs index 981b2da1a3..fa8e69d8a5 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs @@ -100,17 +100,12 @@ public override Expression VisitMatchText(MatchTextExpression expression, QueryC Expression text = Visit(expression.TextValue, context); - if (expression.MatchKind == TextMatchKind.StartsWith) + return expression.MatchKind switch { - return Expression.Call(property, "StartsWith", null, text); - } - - if (expression.MatchKind == TextMatchKind.EndsWith) - { - return Expression.Call(property, "EndsWith", null, text); - } - - return Expression.Call(property, "Contains", null, text); + TextMatchKind.StartsWith => Expression.Call(property, "StartsWith", null, text), + TextMatchKind.EndsWith => Expression.Call(property, "EndsWith", null, text), + _ => Expression.Call(property, "Contains", null, text) + }; } public override Expression VisitAny(AnyExpression expression, QueryClauseBuilderContext context) @@ -137,17 +132,12 @@ public override Expression VisitLogical(LogicalExpression expression, QueryClaus { var termQueue = new Queue(expression.Terms.Select(filter => Visit(filter, context))); - if (expression.Operator == LogicalOperator.And) - { - return Compose(termQueue, Expression.AndAlso); - } - - if (expression.Operator == LogicalOperator.Or) + return expression.Operator switch { - return Compose(termQueue, Expression.OrElse); - } - - throw new InvalidOperationException($"Unknown logical operator '{expression.Operator}'."); + LogicalOperator.And => Compose(termQueue, Expression.AndAlso), + LogicalOperator.Or => Compose(termQueue, Expression.OrElse), + _ => throw new InvalidOperationException($"Unknown logical operator '{expression.Operator}'.") + }; } private static BinaryExpression Compose(Queue argumentQueue, Func applyOperator) From 1c2ba5ab538ab5f30ce4b58ed9ee9d3efc8b6343 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:35:19 +0100 Subject: [PATCH 10/16] Update to Resharper 2023.3-EAP8 (required to enable analysis on .NET 8 RTM) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6dc2459ae5..6491f7d142 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2023.2.3", + "version": "2023.3.0-eap08", "commands": [ "jb" ] From 8ef0987e5abe7918fa2229ad0d39ea9fc82ca84e Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 22:17:12 +0100 Subject: [PATCH 11/16] Add workaround for Resharper bug "Property can be made init-only" --- .../Configuration/DependencyContainerRegistrationTests.cs | 3 +++ .../FieldChains/FieldChainPatternInheritanceMatchTests.cs | 3 +++ .../UnitTests/FieldChains/FieldChainPatternMatchTests.cs | 3 +++ .../UnitTests/Middleware/JsonApiMiddlewareTests.cs | 3 +++ .../ModelStateValidation/ModelStateValidationTests.cs | 3 +++ .../ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs | 3 +++ .../UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs | 3 +++ .../Serialization/Response/IncompleteResourceGraphTests.cs | 3 +++ test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs | 3 +++ 9 files changed, 27 insertions(+) diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs index 0289585dfb..9e96bc718a 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs @@ -15,6 +15,9 @@ using TestBuildingBlocks; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace JsonApiDotNetCoreTests.UnitTests.Configuration; public sealed class DependencyContainerRegistrationTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs index 6036bfc6d4..fece0100f8 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs @@ -11,6 +11,9 @@ using Xunit; using Xunit.Abstractions; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + // ReSharper disable InconsistentNaming #pragma warning disable AV1706 // Identifier contains an abbreviation or is too short diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs index 052ec4a44f..cfffac4e2c 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs @@ -11,6 +11,9 @@ using Xunit; using Xunit.Abstractions; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + // ReSharper disable InconsistentNaming #pragma warning disable AV1706 // Identifier contains an abbreviation or is too short diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs index d11eb53a19..4293a894df 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -13,6 +13,9 @@ using TestBuildingBlocks; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + #pragma warning disable AV1561 // Signature contains too many parameters namespace JsonApiDotNetCoreTests.UnitTests.Middleware; diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs index 34bbc16d17..a1daade80a 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs @@ -10,6 +10,9 @@ using TestBuildingBlocks; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace JsonApiDotNetCoreTests.UnitTests.ModelStateValidation; public sealed class ModelStateValidationTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs index 337940b75c..bedb5398f8 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs @@ -11,6 +11,9 @@ using TestBuildingBlocks; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace JsonApiDotNetCoreTests.UnitTests.ResourceDefinitions; public sealed class CreateSortExpressionFromLambdaTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs index ebce906b9d..0f270ddfeb 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs @@ -10,6 +10,9 @@ using TestBuildingBlocks; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace JsonApiDotNetCoreTests.UnitTests.ResourceGraph; public sealed class ResourceGraphBuilderTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs index 85329874ea..5d6551e2ad 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs @@ -10,6 +10,9 @@ using Microsoft.Extensions.Logging.Abstractions; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace JsonApiDotNetCoreTests.UnitTests.Serialization.Response; public sealed class IncompleteResourceGraphTests diff --git a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs index e8fe1585ca..27a52c0732 100644 --- a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs +++ b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs @@ -6,6 +6,9 @@ using NoEntityFrameworkExample; using Xunit; +// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. +// ReSharper disable PropertyCanBeMadeInitOnly.Local + namespace NoEntityFrameworkTests; public sealed class NullSafeExpressionRewriterTests From f1194d16bf089a000ef8c1c4418d7bd8138f5147 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 21:42:23 +0100 Subject: [PATCH 12/16] Add workaround for Resharper cleanup bug --- test/UnitTests/Internal/ErrorObjectTests.cs | 27 ++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/test/UnitTests/Internal/ErrorObjectTests.cs b/test/UnitTests/Internal/ErrorObjectTests.cs index 7deea9831c..bb8c4e3bcc 100644 --- a/test/UnitTests/Internal/ErrorObjectTests.cs +++ b/test/UnitTests/Internal/ErrorObjectTests.cs @@ -7,13 +7,28 @@ namespace UnitTests.Internal; public sealed class ErrorObjectTests { - // @formatter:wrap_array_initializer_style wrap_if_long + // Formatting below is broken due to Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494897/Formatter-directive-broken-in-2023.3-EAP7. + // This no longer works: @formatter:wrap_array_initializer_style wrap_if_long [Theory] - [InlineData(new[] { HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] - [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] - [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.Unauthorized }, HttpStatusCode.BadRequest)] - [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.BadGateway }, HttpStatusCode.InternalServerError)] - // @formatter:wrap_array_initializer_style restore + [InlineData(new[] + { + HttpStatusCode.UnprocessableEntity + }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] + { + HttpStatusCode.UnprocessableEntity, + HttpStatusCode.UnprocessableEntity + }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] + { + HttpStatusCode.UnprocessableEntity, + HttpStatusCode.Unauthorized + }, HttpStatusCode.BadRequest)] + [InlineData(new[] + { + HttpStatusCode.UnprocessableEntity, + HttpStatusCode.BadGateway + }, HttpStatusCode.InternalServerError)] public void ErrorDocument_GetErrorStatusCode_IsCorrect(HttpStatusCode[] errorCodes, HttpStatusCode expected) { // Arrange From aeae31bce2c697988a0247a52b03ac322460eb12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 02:47:03 +0000 Subject: [PATCH 13/16] Bump docfx from 2.72.1 to 2.74.0 Bumps [docfx](https://github.com/dotnet/docfx) from 2.72.1 to 2.74.0. - [Release notes](https://github.com/dotnet/docfx/releases) - [Changelog](https://github.com/dotnet/docfx/blob/main/RELEASENOTE.md) - [Commits](https://github.com/dotnet/docfx/compare/v2.72.1...v2.74.0) --- updated-dependencies: - dependency-name: docfx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6491f7d142..c8c97435a8 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -21,7 +21,7 @@ ] }, "docfx": { - "version": "2.72.1", + "version": "2.74.0", "commands": [ "docfx" ] From 215df7483ddb6c6bb73ecc59f5412d21612b1b6a Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 21 Nov 2023 22:38:50 +0100 Subject: [PATCH 14/16] Remove ArrayFactory.Create --- .../QueryString/QueryStringParserBenchmarks.cs | 11 ++++++++--- src/JsonApiDotNetCore/ArrayFactory.cs | 12 ------------ .../Configuration/ServiceDiscoveryFacade.cs | 8 +++++--- .../Errors/InvalidModelStateException.cs | 7 ++++++- .../Queries/QueryableBuilding/OrderClauseBuilder.cs | 7 ++++++- .../Queries/QueryableBuilding/SelectClauseBuilder.cs | 7 ++++++- src/JsonApiDotNetCore/Resources/ResourceFactory.cs | 2 +- .../Serialization/Response/ETagGenerator.cs | 8 +++++++- .../Relationships/ReplaceToManyRelationshipTests.cs | 3 +-- .../Resources/ReplaceToManyRelationshipTests.cs | 2 +- .../ResourceTypeCapturingDefinition.cs | 2 +- 11 files changed, 42 insertions(+), 27 deletions(-) delete mode 100644 src/JsonApiDotNetCore/ArrayFactory.cs diff --git a/benchmarks/QueryString/QueryStringParserBenchmarks.cs b/benchmarks/QueryString/QueryStringParserBenchmarks.cs index 2f466a3fcb..0b2f88134a 100644 --- a/benchmarks/QueryString/QueryStringParserBenchmarks.cs +++ b/benchmarks/QueryString/QueryStringParserBenchmarks.cs @@ -1,7 +1,6 @@ using System.ComponentModel.Design; using BenchmarkDotNet.Attributes; using Benchmarks.Tools; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Queries.Parsing; @@ -55,8 +54,14 @@ public QueryStringParserBenchmarks() var paginationParser = new PaginationParser(); var paginationReader = new PaginationQueryStringParameterReader(paginationParser, request, resourceGraph, options); - IQueryStringParameterReader[] readers = ArrayFactory.Create(includeReader, filterReader, sortReader, - sparseFieldSetReader, paginationReader); + IQueryStringParameterReader[] readers = + [ + includeReader, + filterReader, + sortReader, + sparseFieldSetReader, + paginationReader + ]; _queryStringReader = new QueryStringReader(options, _queryStringAccessor, readers, NullLoggerFactory.Instance); } diff --git a/src/JsonApiDotNetCore/ArrayFactory.cs b/src/JsonApiDotNetCore/ArrayFactory.cs deleted file mode 100644 index 6ad678c64d..0000000000 --- a/src/JsonApiDotNetCore/ArrayFactory.cs +++ /dev/null @@ -1,12 +0,0 @@ -#pragma warning disable AV1008 // Class should not be static -#pragma warning disable AV1130 // Return type in method signature should be an interface to an unchangeable collection - -namespace JsonApiDotNetCore; - -internal static class ArrayFactory -{ - public static T[] Create(params T[] items) - { - return items; - } -} diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index 5d2ac7190b..01f9ecc7cb 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -152,9 +152,11 @@ private void AddResourceDefinitions(Assembly assembly, ResourceDescriptor resour private void RegisterImplementations(Assembly assembly, Type interfaceType, ResourceDescriptor resourceDescriptor) { - Type[] typeArguments = interfaceType.GetTypeInfo().GenericTypeParameters.Length == 2 - ? ArrayFactory.Create(resourceDescriptor.ResourceClrType, resourceDescriptor.IdClrType) - : ArrayFactory.Create(resourceDescriptor.ResourceClrType); + Type[] typeArguments = + [ + resourceDescriptor.ResourceClrType, + resourceDescriptor.IdClrType + ]; (Type implementationType, Type serviceInterface)? result = _typeLocator.GetContainerRegistrationFromAssembly(assembly, interfaceType, typeArguments); diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index b5805e15dc..ce8ab8a1b0 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -207,7 +207,12 @@ private abstract class ModelStateKeySegment private const char Dot = '.'; private const char BracketOpen = '['; private const char BracketClose = ']'; - private static readonly char[] KeySegmentStartTokens = ArrayFactory.Create(Dot, BracketOpen); + + private static readonly char[] KeySegmentStartTokens = + [ + Dot, + BracketOpen + ]; // The right part of the full key, which nested segments are produced from. private readonly string _nextKey; diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/OrderClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/OrderClauseBuilder.cs index 09f0c5326e..93dd7c53d1 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/OrderClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/OrderClauseBuilder.cs @@ -57,7 +57,12 @@ private static string GetOperationName(bool isAscending, QueryClauseBuilderConte private static Expression ExtensionMethodCall(Expression source, string operationName, Type keyType, LambdaExpression keySelector, QueryClauseBuilderContext context) { - Type[] typeArguments = ArrayFactory.Create(context.LambdaScope.Parameter.Type, keyType); + Type[] typeArguments = + [ + context.LambdaScope.Parameter.Type, + keyType + ]; + return Expression.Call(context.ExtensionType, operationName, typeArguments, source, keySelector); } } diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs index 3f23013d7c..43d82d77ce 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs @@ -247,7 +247,12 @@ private static Expression CopyCollectionExtensionMethodCall(Expression source, s private static Expression SelectExtensionMethodCall(Type extensionType, Expression source, Type elementType, Expression selectBody) { - Type[] typeArguments = ArrayFactory.Create(elementType, elementType); + Type[] typeArguments = + [ + elementType, + elementType + ]; + return Expression.Call(extensionType, "Select", typeArguments, source, selectBody); } diff --git a/src/JsonApiDotNetCore/Resources/ResourceFactory.cs b/src/JsonApiDotNetCore/Resources/ResourceFactory.cs index b803544bec..9d282b4938 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceFactory.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceFactory.cs @@ -50,7 +50,7 @@ private static IIdentifiable CreateWrapperForAbstractType(Type resourceClrType) Type wrapperClrType = typeof(AbstractResourceWrapper<>).MakeGenericType(descriptor.IdClrType); ConstructorInfo constructor = wrapperClrType.GetConstructors().Single(); - object resource = constructor.Invoke(ArrayFactory.Create(resourceClrType)); + object resource = constructor.Invoke([resourceClrType]); return (IIdentifiable)resource; } diff --git a/src/JsonApiDotNetCore/Serialization/Response/ETagGenerator.cs b/src/JsonApiDotNetCore/Serialization/Response/ETagGenerator.cs index 7a22cf5a60..d5aefb1fee 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/ETagGenerator.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/ETagGenerator.cs @@ -17,7 +17,13 @@ public ETagGenerator(IFingerprintGenerator fingerprintGenerator) /// public EntityTagHeaderValue Generate(string requestUrl, string responseBody) { - string fingerprint = _fingerprintGenerator.Generate(ArrayFactory.Create(requestUrl, responseBody)); + string[] elements = + [ + requestUrl, + responseBody + ]; + + string fingerprint = _fingerprintGenerator.Generate(elements); string eTagValue = $"\"{fingerprint}\""; return EntityTagHeaderValue.Parse(eTagValue); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index d3aa61afaf..431bf89396 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -1,6 +1,5 @@ using System.Net; using FluentAssertions; -using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using Microsoft.EntityFrameworkCore; using TestBuildingBlocks; @@ -880,7 +879,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => dbContext.WorkItems.Add(existingWorkItem); await dbContext.SaveChangesAsync(); - existingWorkItem.RelatedFrom = ArrayFactory.Create(existingWorkItem); + existingWorkItem.RelatedFrom = [existingWorkItem]; await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index 0cee60ef86..9b9f96ddce 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -965,7 +965,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => dbContext.WorkItems.Add(existingWorkItem); await dbContext.SaveChangesAsync(); - existingWorkItem.RelatedFrom = ArrayFactory.Create(existingWorkItem); + existingWorkItem.RelatedFrom = [existingWorkItem]; await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceTypeCapturingDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceTypeCapturingDefinition.cs index 3b92b278da..e2754968a7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceTypeCapturingDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceTypeCapturingDefinition.cs @@ -82,7 +82,7 @@ public override Task OnWriteSucceededAsync(TResource resource, WriteOperationKin private void EnsureSnapshot(TResource leftType, IIdentifiable? rightResourceId = null) { - IIdentifiable[] rightResourceIds = rightResourceId != null ? ArrayFactory.Create(rightResourceId) : Array.Empty(); + IIdentifiable[] rightResourceIds = rightResourceId != null ? [rightResourceId] : Array.Empty(); EnsureSnapshot(leftType, rightResourceIds); } From 9546bcb97146434af73eae1a3b3ff91c83c4d92c Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:48:06 +0100 Subject: [PATCH 15/16] Use char overload instead of passing a single-char string --- src/JsonApiDotNetCore.Annotations/TypeExtensions.cs | 2 +- .../QueryStrings/FilterQueryStringParameterReader.cs | 2 +- .../QueryStrings/SortQueryStringParameterReader.cs | 2 +- .../QueryStrings/SparseFieldSetQueryStringParameterReader.cs | 2 +- .../IntegrationTests/IdObfuscation/HexadecimalCodec.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/JsonApiDotNetCore.Annotations/TypeExtensions.cs b/src/JsonApiDotNetCore.Annotations/TypeExtensions.cs index b31f82d48e..785dff030a 100644 --- a/src/JsonApiDotNetCore.Annotations/TypeExtensions.cs +++ b/src/JsonApiDotNetCore.Annotations/TypeExtensions.cs @@ -48,7 +48,7 @@ public static string GetFriendlyTypeName(this Type type) if (type.IsGenericType) { string typeArguments = type.GetGenericArguments().Select(GetFriendlyTypeName).Aggregate((firstType, secondType) => $"{firstType}, {secondType}"); - return $"{type.Name[..type.Name.IndexOf("`", StringComparison.Ordinal)]}<{typeArguments}>"; + return $"{type.Name[..type.Name.IndexOf('`')]}<{typeArguments}>"; } return type.Name; diff --git a/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs index 3c8d16a3f0..6ebdd4fd29 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FilterQueryStringParameterReader.cs @@ -52,7 +52,7 @@ public virtual bool CanRead(string parameterName) { ArgumentGuard.NotNullNorEmpty(parameterName); - bool isNested = parameterName.StartsWith("filter[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); + bool isNested = parameterName.StartsWith("filter[", StringComparison.Ordinal) && parameterName.EndsWith(']'); return parameterName == "filter" || isNested; } diff --git a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs index 4362f95ed5..d068ae7ce2 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs @@ -45,7 +45,7 @@ public virtual bool CanRead(string parameterName) { ArgumentGuard.NotNullNorEmpty(parameterName); - bool isNested = parameterName.StartsWith("sort[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); + bool isNested = parameterName.StartsWith("sort[", StringComparison.Ordinal) && parameterName.EndsWith(']'); return parameterName == "sort" || isNested; } diff --git a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs index 9757383c39..18d2926931 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs @@ -50,7 +50,7 @@ public virtual bool CanRead(string parameterName) { ArgumentGuard.NotNullNorEmpty(parameterName); - return parameterName.StartsWith("fields[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); + return parameterName.StartsWith("fields[", StringComparison.Ordinal) && parameterName.EndsWith(']'); } /// diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs index aa12e5ceb3..a3feb15b9e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs @@ -15,7 +15,7 @@ public int Decode(string? value) return 0; } - if (!value.StartsWith("x", StringComparison.Ordinal)) + if (!value.StartsWith('x')) { throw new JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { From dea63fdba818ed0b6e8dd49c0252363d08d71bba Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:12:58 +0100 Subject: [PATCH 16/16] Remove ObjectExtensions.AsEnumerable/AsArray/AsList --- .../Builders/SelectStatementBuilder.cs | 4 ++-- .../UpdateClearOneToOneStatementBuilder.cs | 2 +- .../CollectionConverter.cs | 2 +- .../ObjectExtensions.cs | 15 ------------ .../ServiceCollectionExtensions.cs | 2 +- .../Errors/JsonApiException.cs | 2 +- .../Middleware/ExceptionHandler.cs | 24 ++++++++++++------- .../Middleware/JsonApiMiddleware.cs | 2 +- .../Queries/Parsing/IncludeParser.cs | 2 +- .../Queries/QueryLayerComposer.cs | 8 +++---- .../QueryableBuilding/IncludeClauseBuilder.cs | 2 +- .../QueryableBuilding/SelectClauseBuilder.cs | 2 +- .../SkipTakeClauseBuilder.cs | 2 +- .../QueryableBuilding/WhereClauseBuilder.cs | 8 +++---- .../IncludeQueryStringParameterReader.cs | 2 +- ...parseFieldSetQueryStringParameterReader.cs | 2 +- .../Response/ResponseModelAdapter.cs | 2 +- .../CompositeKeys/CarExpressionRewriter.cs | 3 +-- .../Sum/SumWhereClauseBuilder.cs | 3 +-- .../ReplaceToManyRelationshipTests.cs | 3 +-- .../FieldChainPatternInheritanceMatchTests.cs | 3 +-- .../FieldChainPatternMatchTests.cs | 3 +-- test/TestBuildingBlocks/TestableDbContext.cs | 3 +-- 23 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs index cd97a63d32..8bebc3f01f 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/SelectStatementBuilder.cs @@ -106,8 +106,8 @@ private void TrackPrimaryTable(TableAccessorNode tableAccessor) _selectorsPerTable[tableAccessor] = _selectShape switch { SelectShape.Columns => Array.Empty(), - SelectShape.Count => new CountSelectorNode(null).AsArray(), - _ => new OneSelectorNode(null).AsArray() + SelectShape.Count => [new CountSelectorNode(null)], + _ => [new OneSelectorNode(null)] }; } diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs index 152e14991c..4ccc5fec9a 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs @@ -29,7 +29,7 @@ public UpdateNode Build(ResourceType resourceType, string setColumnName, string ColumnNode whereColumn = table.GetColumn(whereColumnName, null, table.Alias); WhereNode where = GetWhere(whereColumn, whereValue); - return new UpdateNode(table, columnAssignment.AsList(), where); + return new UpdateNode(table, [columnAssignment], where); } private WhereNode GetWhere(ColumnNode column, object? value) diff --git a/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs b/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs index 645b5329b7..e95d306329 100644 --- a/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs +++ b/src/JsonApiDotNetCore.Annotations/CollectionConverter.cs @@ -74,7 +74,7 @@ public IReadOnlyCollection ExtractResources(object? value) HashSet resourceSet => resourceSet, IReadOnlyCollection resourceCollection => resourceCollection, IEnumerable resources => resources.ToList(), - IIdentifiable resource => resource.AsArray(), + IIdentifiable resource => [resource], _ => Array.Empty() }; } diff --git a/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs b/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs index 2e8f9acfc6..8aa1e6c165 100644 --- a/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs +++ b/src/JsonApiDotNetCore.Annotations/ObjectExtensions.cs @@ -4,21 +4,6 @@ namespace JsonApiDotNetCore; internal static class ObjectExtensions { - public static IEnumerable AsEnumerable(this T element) - { - yield return element; - } - - public static T[] AsArray(this T element) - { - return [element]; - } - - public static List AsList(this T element) - { - return [element]; - } - public static HashSet AsHashSet(this T element) { return [element]; diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs index 7ea42a2470..b25c208086 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs @@ -36,7 +36,7 @@ public static IServiceCollection AddJsonApi(this IServiceCollection Action? discovery = null, Action? resources = null, IMvcCoreBuilder? mvcBuilder = null) where TDbContext : DbContext { - return AddJsonApi(services, options, discovery, resources, mvcBuilder, typeof(TDbContext).AsArray()); + return AddJsonApi(services, options, discovery, resources, mvcBuilder, [typeof(TDbContext)]); } private static void SetupApplicationBuilder(IServiceCollection services, Action? configureOptions, diff --git a/src/JsonApiDotNetCore/Errors/JsonApiException.cs b/src/JsonApiDotNetCore/Errors/JsonApiException.cs index 4571843e8d..097b972089 100644 --- a/src/JsonApiDotNetCore/Errors/JsonApiException.cs +++ b/src/JsonApiDotNetCore/Errors/JsonApiException.cs @@ -26,7 +26,7 @@ public JsonApiException(ErrorObject error, Exception? innerException = null) { ArgumentGuard.NotNull(error); - Errors = error.AsArray(); + Errors = [error]; } public JsonApiException(IEnumerable errors, Exception? innerException = null) diff --git a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs index 7f7479975a..816c5ffbb7 100644 --- a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs +++ b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs @@ -74,15 +74,21 @@ protected virtual IReadOnlyList CreateErrorResponse(Exception excep IReadOnlyList errors = exception switch { JsonApiException jsonApiException => jsonApiException.Errors, - OperationCanceledException => new ErrorObject((HttpStatusCode)499) - { - Title = "Request execution was canceled." - }.AsArray(), - _ => new ErrorObject(HttpStatusCode.InternalServerError) - { - Title = "An unhandled error occurred while processing this request.", - Detail = exception.Message - }.AsArray() + OperationCanceledException => + [ + new ErrorObject((HttpStatusCode)499) + { + Title = "Request execution was canceled." + } + ], + _ => + [ + new ErrorObject(HttpStatusCode.InternalServerError) + { + Title = "An unhandled error occurred while processing this request.", + Detail = exception.Message + } + ] }; if (_options.IncludeExceptionStackTraceInErrors && exception is not InvalidModelStateException) diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 40a784d25c..7cd2573727 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -205,7 +205,7 @@ private static async Task FlushResponseAsync(HttpResponse httpResponse, JsonSeri var errorDocument = new Document { - Errors = error.AsList() + Errors = [error] }; await JsonSerializer.SerializeAsync(httpResponse.Body, errorDocument, serializerOptions); diff --git a/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs b/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs index 79f286da91..1ab0e61326 100644 --- a/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Parsing/IncludeParser.cs @@ -86,7 +86,7 @@ private void ParseRelationshipChain(string source, IncludeTreeNode treeRoot) // that there's currently no way to include Products without Articles. We could add such optional upcast syntax // in the future, if desired. - ICollection children = ParseRelationshipName(source, treeRoot.AsList()); + ICollection children = ParseRelationshipName(source, [treeRoot]); while (TokenStack.TryPeek(out Token? nextToken) && nextToken.Kind == TokenKind.Period) { diff --git a/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs index d5fac60c71..8e0c97e6c0 100644 --- a/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/QueryLayerComposer.cs @@ -272,7 +272,7 @@ public QueryLayer ComposeForGetById(TId id, ResourceType primaryResourceTyp QueryLayer queryLayer = ComposeFromConstraints(primaryResourceType); queryLayer.Sort = null; queryLayer.Pagination = null; - queryLayer.Filter = CreateFilterByIds(id.AsArray(), idAttribute, queryLayer.Filter); + queryLayer.Filter = CreateFilterByIds([id], idAttribute, queryLayer.Filter); if (fieldSelection == TopFieldSelection.OnlyIdAttribute) { @@ -342,7 +342,7 @@ public QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, return new QueryLayer(primaryResourceType) { Include = RewriteIncludeForSecondaryEndpoint(innerInclude, relationship), - Filter = CreateFilterByIds(primaryId.AsArray(), primaryIdAttribute, primaryFilter), + Filter = CreateFilterByIds([primaryId], primaryIdAttribute, primaryFilter), Selection = primarySelection }; } @@ -390,7 +390,7 @@ public QueryLayer ComposeForUpdate(TId id, ResourceType primaryResourceType primaryLayer.Include = includeElements.Any() ? new IncludeExpression(includeElements) : IncludeExpression.Empty; primaryLayer.Sort = null; primaryLayer.Pagination = null; - primaryLayer.Filter = CreateFilterByIds(id.AsArray(), primaryIdAttribute, primaryLayer.Filter); + primaryLayer.Filter = CreateFilterByIds([id], primaryIdAttribute, primaryLayer.Filter); primaryLayer.Selection = null; return primaryLayer; @@ -449,7 +449,7 @@ public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, T AttrAttribute rightIdAttribute = GetIdAttribute(hasManyRelationship.RightType); HashSet rightTypedIds = rightResourceIds.Select(resource => resource.GetTypedId()).ToHashSet(); - FilterExpression? leftFilter = CreateFilterByIds(leftId.AsArray(), leftIdAttribute, null); + FilterExpression? leftFilter = CreateFilterByIds([leftId], leftIdAttribute, null); FilterExpression? rightFilter = CreateFilterByIds(rightTypedIds, rightIdAttribute, null); var secondarySelection = new FieldSelection(); diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs index 81a0db533e..3bd19eb21f 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/IncludeClauseBuilder.cs @@ -75,6 +75,6 @@ private static Expression IncludeExtensionMethodCall(Expression source, Type ent { Expression navigationExpression = Expression.Constant(navigationPropertyPath); - return Expression.Call(typeof(EntityFrameworkQueryableExtensions), "Include", entityType.AsArray(), source, navigationExpression); + return Expression.Call(typeof(EntityFrameworkQueryableExtensions), "Include", [entityType], source, navigationExpression); } } diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs index 43d82d77ce..858532d7c2 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SelectClauseBuilder.cs @@ -242,7 +242,7 @@ private static Expression TestForNull(Expression expressionToTest, Expression if private static Expression CopyCollectionExtensionMethodCall(Expression source, string operationName, Type elementType) { - return Expression.Call(typeof(Enumerable), operationName, elementType.AsArray(), source); + return Expression.Call(typeof(Enumerable), operationName, [elementType], source); } private static Expression SelectExtensionMethodCall(Type extensionType, Expression source, Type elementType, Expression selectBody) diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SkipTakeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SkipTakeClauseBuilder.cs index 2eb2823aca..b48fa696db 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/SkipTakeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/SkipTakeClauseBuilder.cs @@ -38,6 +38,6 @@ private static Expression ExtensionMethodCall(Expression source, string operatio { Expression constant = value.CreateTupleAccessExpressionForConstant(typeof(int)); - return Expression.Call(context.ExtensionType, operationName, context.LambdaScope.Parameter.Type.AsArray(), source, constant); + return Expression.Call(context.ExtensionType, operationName, [context.LambdaScope.Parameter.Type], source, constant); } } diff --git a/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs index fa8e69d8a5..f14d795f7b 100644 --- a/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/QueryableBuilding/WhereClauseBuilder.cs @@ -33,7 +33,7 @@ private LambdaExpression GetPredicateLambda(FilterExpression filter, QueryClause private static Expression WhereExtensionMethodCall(LambdaExpression predicate, QueryClauseBuilderContext context) { - return Expression.Call(context.ExtensionType, "Where", context.LambdaScope.Parameter.Type.AsArray(), context.Source, predicate); + return Expression.Call(context.ExtensionType, "Where", [context.LambdaScope.Parameter.Type], context.Source, predicate); } public override Expression VisitHas(HasExpression expression, QueryClauseBuilderContext context) @@ -67,8 +67,8 @@ public override Expression VisitHas(HasExpression expression, QueryClauseBuilder private static MethodCallExpression AnyExtensionMethodCall(Type elementType, Expression source, Expression? predicate) { return predicate != null - ? Expression.Call(typeof(Enumerable), "Any", elementType.AsArray(), source, predicate) - : Expression.Call(typeof(Enumerable), "Any", elementType.AsArray(), source); + ? Expression.Call(typeof(Enumerable), "Any", [elementType], source, predicate) + : Expression.Call(typeof(Enumerable), "Any", [elementType], source); } public override Expression VisitIsType(IsTypeExpression expression, QueryClauseBuilderContext context) @@ -125,7 +125,7 @@ public override Expression VisitAny(AnyExpression expression, QueryClauseBuilder private static Expression ContainsExtensionMethodCall(Expression collection, Expression value) { - return Expression.Call(typeof(Enumerable), "Contains", value.Type.AsArray(), collection, value); + return Expression.Call(typeof(Enumerable), "Contains", [value.Type], collection, value); } public override Expression VisitLogical(LogicalExpression expression, QueryClauseBuilderContext context) diff --git a/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs index de144de7c5..76bcc4a7b4 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs @@ -72,6 +72,6 @@ public virtual IReadOnlyCollection GetConstraints() ? new ExpressionInScope(null, _includeExpression) : new ExpressionInScope(null, IncludeExpression.Empty); - return expressionInScope.AsArray(); + return [expressionInScope]; } } diff --git a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs index 18d2926931..559da09f38 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs @@ -100,7 +100,7 @@ private SparseFieldSetExpression GetSparseFieldSet(string parameterValue, Resour public virtual IReadOnlyCollection GetConstraints() { return _sparseFieldTableBuilder.Any() - ? new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTableBuilder.ToImmutable())).AsArray() + ? [new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTableBuilder.ToImmutable()))] : Array.Empty(); } } diff --git a/src/JsonApiDotNetCore/Serialization/Response/ResponseModelAdapter.cs b/src/JsonApiDotNetCore/Serialization/Response/ResponseModelAdapter.cs index 4bd6844335..9457b05502 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/ResponseModelAdapter.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/ResponseModelAdapter.cs @@ -107,7 +107,7 @@ public Document Convert(object? model) } else if (model is ErrorObject errorObject) { - document.Errors = errorObject.AsArray(); + document.Errors = [errorObject]; } else { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs index 6d887a3e9e..c85a2b2a31 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs @@ -1,6 +1,5 @@ using System.Collections.Immutable; using System.Reflection; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -42,7 +41,7 @@ public CarExpressionRewriter(IResourceGraph resourceGraph) } string carStringId = (string)rightConstant.TypedValue; - return RewriteFilterOnCarStringIds(leftChain, carStringId.AsEnumerable()); + return RewriteFilterOnCarStringIds(leftChain, [carStringId]); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumWhereClauseBuilder.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumWhereClauseBuilder.cs index a732490123..b14150e793 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumWhereClauseBuilder.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumWhereClauseBuilder.cs @@ -1,5 +1,4 @@ using System.Linq.Expressions; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Queries.QueryableBuilding; @@ -42,6 +41,6 @@ private LambdaExpression GetSelectorLambda(QueryExpression expression, QueryClau private static Expression SumExtensionMethodCall(LambdaExpression selector, QueryClauseBuilderContext context) { - return Expression.Call(context.ExtensionType, "Sum", context.LambdaScope.Parameter.Type.AsArray(), context.Source, selector); + return Expression.Call(context.ExtensionType, "Sum", [context.LambdaScope.Parameter.Type], context.Source, selector); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index 9b9f96ddce..32560b2ad9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -1,6 +1,5 @@ using System.Net; using FluentAssertions; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; using Microsoft.EntityFrameworkCore; @@ -916,7 +915,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => dbContext.WorkItems.Add(existingWorkItem); await dbContext.SaveChangesAsync(); - existingWorkItem.Children = existingWorkItem.AsList(); + existingWorkItem.Children = [existingWorkItem]; await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs index fece0100f8..f308b40d2d 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using JetBrains.Annotations; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.QueryStrings.FieldChains; using JsonApiDotNetCore.Resources; @@ -47,7 +46,7 @@ public sealed class FieldChainPatternInheritanceMatchTests public FieldChainPatternInheritanceMatchTests(ITestOutputHelper testOutputHelper) { var loggerProvider = new XUnitLoggerProvider(testOutputHelper, null, LogOutputFields.Message); - _loggerFactory = new LoggerFactory(loggerProvider.AsEnumerable()); + _loggerFactory = new LoggerFactory([loggerProvider]); var options = new JsonApiOptions(); _resourceGraph = new ResourceGraphBuilder(options, NullLoggerFactory.Instance).Add().Add().Add().Build(); diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs index cfffac4e2c..dec0e7c33d 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using JetBrains.Annotations; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.QueryStrings.FieldChains; using JsonApiDotNetCore.Resources; @@ -33,7 +32,7 @@ public sealed class FieldChainPatternMatchTests public FieldChainPatternMatchTests(ITestOutputHelper testOutputHelper) { var loggerProvider = new XUnitLoggerProvider(testOutputHelper, null, LogOutputFields.Message); - _loggerFactory = new LoggerFactory(loggerProvider.AsEnumerable()); + _loggerFactory = new LoggerFactory([loggerProvider]); var options = new JsonApiOptions(); IResourceGraph resourceGraph = new ResourceGraphBuilder(options, NullLoggerFactory.Instance).Add().Build(); diff --git a/test/TestBuildingBlocks/TestableDbContext.cs b/test/TestBuildingBlocks/TestableDbContext.cs index b92f6be261..65cb8872be 100644 --- a/test/TestBuildingBlocks/TestableDbContext.cs +++ b/test/TestBuildingBlocks/TestableDbContext.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using JsonApiDotNetCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.Logging; @@ -21,7 +20,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder builder) [Conditional("DEBUG")] private static void WriteSqlStatementsToOutputWindow(DbContextOptionsBuilder builder) { - builder.LogTo(message => Debug.WriteLine(message), DbLoggerCategory.Database.Name.AsArray(), LogLevel.Information); + builder.LogTo(message => Debug.WriteLine(message), [DbLoggerCategory.Database.Name], LogLevel.Information); } protected override void OnModelCreating(ModelBuilder builder)