diff --git a/.github/workflows/publish-test-results.yml b/.github/workflows/publish-test-results.yml new file mode 100644 index 00000000..5de1f3a1 --- /dev/null +++ b/.github/workflows/publish-test-results.yml @@ -0,0 +1,61 @@ +name: Publish Test Results + +on: + workflow_run: + workflows: ["Build and Test"] + types: + - completed + +permissions: {} + +jobs: + test-results: + if: github.event.workflow_run.conclusion != 'skipped' && github.event.workflow_run.event == 'pull_request' + name: Test Results + runs-on: ubuntu-latest + + permissions: + actions: read + checks: write + pull-requests: write + + steps: + - name: Download event file + uses: dawidd6/action-download-artifact@v6 + with: + run_id: ${{ github.event.workflow_run.id }} + path: artifacts + name: EventFile + + - name: Download test results + uses: dawidd6/action-download-artifact@v6 + with: + run_id: ${{ github.event.workflow_run.id }} + path: test-results + name: ^test-results-.* + name_is_regexp: true + if_no_artifact_found: warn + + - name: Resolve event file path + id: event_file + shell: pwsh + run: | + $eventFilePath = + Get-ChildItem -Path artifacts -Filter event.json -Recurse | + Select-Object -First 1 -ExpandProperty FullName + + if ($null -eq $eventFilePath) { + throw "event.json file was not found in downloaded artifacts" + } + + "path=$eventFilePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + + - name: Publish test results + if: ${{ hashFiles('test-results/**/*.trx') != '' }} + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + commit: ${{ github.event.workflow_run.head_sha }} + comment_mode: always + event_file: ${{ steps.event_file.outputs.path }} + event_name: ${{ github.event.workflow_run.event }} + files: "test-results/**/*.trx" diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 3397e91f..228084b6 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -14,8 +14,25 @@ env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 DOTNET_NOLOGO: true +permissions: {} + jobs: + event_file: + if: github.event_name == 'pull_request' + name: Publish event file + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Upload event file + uses: actions/upload-artifact@v4 + with: + name: EventFile + path: ${{ github.event_path }} + build: + permissions: + contents: read strategy: fail-fast: false @@ -50,3 +67,10 @@ jobs: - name: Build and run integration tests run: dotnet run --project build/Build.fsproj --launch-profile BuildAndTest + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.os }} + path: test-results diff --git a/build/Program.fs b/build/Program.fs index 517ece4b..b5b73573 100644 --- a/build/Program.fs +++ b/build/Program.fs @@ -98,12 +98,17 @@ let startGraphQLServer (project : string) port (streamRef : DataRef) = System.Threading.Thread.Sleep (2000) -let runTests (project : string) (args : string) = +let runTests (project : string) = + let projectName = Path.GetFileNameWithoutExtension project + let resultsFileName = $"{projectName}.trx" + DotNet.test (fun options -> { options with NoBuild = true + Logger = Some $"trx;LogFileName={resultsFileName}" + ResultsDirectory = Some "test-results" Framework = Some DotNetMoniker Configuration = configuration MSBuildParams = { @@ -164,18 +169,36 @@ let integrationTestsProjectPath = let [] UpdateIntrospectionFileTarget = "UpdateIntrospectionFile" Target.create UpdateIntrospectionFileTarget <| fun _ -> - integrationTestsProjectPath - |> DotNet.test (fun options -> { - options with - Framework = Some DotNetMoniker - Configuration = configuration - Common = { DotNetCli.setVersion options.Common with CustomParams = Some "--filter FullyQualifiedName~IntrospectionUpdateTests" } - MSBuildParams = { - options.MSBuildParams with - DisableInternalBinLog = true - Verbosity = Some Normal + let projectName = Path.GetFileNameWithoutExtension integrationTestsProjectPath + let resultsFileName = $"{projectName}.trx" + + DotNet.test + (fun options -> + { + options with + NoBuild = true + Logger = Some $"trx;LogFileName={resultsFileName}" + ResultsDirectory = Some "test-results" + Framework = Some DotNetMoniker + Configuration = configuration + Common = { + options.Common with + CustomParams = Some "--filter FullyQualifiedName~IntrospectionUpdateTests" + } + MSBuildParams = { + options.MSBuildParams with + DisableInternalBinLog = true + Verbosity = Some Normal + Properties = [ + if embedAll then + ("DebugType", "embedded") + ("EmbedAllSources", "true") + ] + } } - }) + |> _.WithRedirectOutput(true) + |> _.WithCommon(DotNetCli.setVersion)) + integrationTestsProjectPath let unitTestsProjectPath = "tests" @@ -184,7 +207,7 @@ let unitTestsProjectPath = let [] RunUnitTestsTarget = "RunUnitTests" Target.create RunUnitTestsTarget <| fun _ -> - runTests unitTestsProjectPath "" + runTests unitTestsProjectPath let prepareDocGen () = Shell.rm "docs/release-notes.md" diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests/IntrospectionUpdateTests.fs b/tests/FSharp.Data.GraphQL.IntegrationTests/IntrospectionUpdateTests.fs index c3931b29..ce0e7eae 100644 --- a/tests/FSharp.Data.GraphQL.IntegrationTests/IntrospectionUpdateTests.fs +++ b/tests/FSharp.Data.GraphQL.IntegrationTests/IntrospectionUpdateTests.fs @@ -20,9 +20,9 @@ let normalizeJsonDocument options (document : JsonDocument) = JsonDocument.Parse buffer let parseAndNormalizeJsonAsync ct options stream = task { - let! document = JsonDocument.ParseAsync (stream, cancellationToken = ct) - return normalizeJsonDocument options document -} + let! document = JsonDocument.ParseAsync (stream, cancellationToken = ct) + return normalizeJsonDocument options document + } let areSchemasEqual (document1 : JsonDocument) (document2 : JsonDocument) = let schema1 = document1.RootElement.GetProperty("data").GetProperty ("__schema") @@ -30,56 +30,56 @@ let areSchemasEqual (document1 : JsonDocument) (document2 : JsonDocument) = schema1.GetRawText () = schema2.GetRawText () let readDestinationDocumentAsync ct (stream : FileStream) = task { - try - let! document = JsonDocument.ParseAsync (stream, cancellationToken = ct) - return ValueSome document - with :? JsonException -> - return ValueNone -} + try + let! document = JsonDocument.ParseAsync (stream, cancellationToken = ct) + return ValueSome document + with :? JsonException -> + return ValueNone + } let updateIntrospectionFileAsync ct sourceStream = task { - use destinationStream = - new FileStream (introspectionFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read) + use destinationStream = + new FileStream (introspectionFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read) let options = JsonWriterOptions (Indented = true) - let! sourceDocument = parseAndNormalizeJsonAsync ct options sourceStream - destinationStream.Seek (0L, SeekOrigin.Begin) |> ignore - let! destinationDocument = readDestinationDocumentAsync ct destinationStream + let! sourceDocument = parseAndNormalizeJsonAsync ct options sourceStream + destinationStream.Seek (0L, SeekOrigin.Begin) |> ignore + let! destinationDocument = readDestinationDocumentAsync ct destinationStream - let shouldUpdate = - match destinationDocument with - | ValueNone -> true - | ValueSome document -> not (areSchemasEqual document sourceDocument) + let shouldUpdate = + match destinationDocument with + | ValueNone -> true + | ValueSome document -> not (areSchemasEqual document sourceDocument) - if shouldUpdate then - destinationStream.Seek (0L, SeekOrigin.Begin) |> ignore - destinationStream.SetLength 0 - use writer = new Utf8JsonWriter (destinationStream, options) - sourceDocument.WriteTo writer - writer.Flush () + if shouldUpdate then + destinationStream.Seek (0L, SeekOrigin.Begin) |> ignore + destinationStream.SetLength 0 + use writer = new Utf8JsonWriter (destinationStream, options) + sourceDocument.WriteTo writer + writer.Flush () - return shouldUpdate -} + return shouldUpdate + } [] let ``Get GraphQL introspection response returns schema`` () = task { - use httpClient = TestHosts.createIntegrationHttpClient () + use httpClient = TestHosts.createIntegrationHttpClient () let! response = httpClient.GetFromJsonAsync ("/", CancellationToken.None) let schema = response.GetProperty("data").GetProperty ("__schema") Assert.NotEqual (Unchecked.defaultof, schema) - let hasErrors, _ = response.TryGetProperty "errors" - Assert.False hasErrors -} + let hasErrors, _ = response.TryGetProperty "errors" + Assert.False hasErrors + } [] let ``Update integration introspection file when schema changes`` () = task { - use httpClient = TestHosts.createIntegrationHttpClient () + use httpClient = TestHosts.createIntegrationHttpClient () let! sourceStream = httpClient.GetStreamAsync ("/") - let! wasUpdated = updateIntrospectionFileAsync CancellationToken.None sourceStream + let! wasUpdated = updateIntrospectionFileAsync CancellationToken.None sourceStream Assert.True (File.Exists introspectionFilePath) - if wasUpdated then + if wasUpdated then let! sourceStreamSecondRun = httpClient.GetStreamAsync ("/") - use sourceStreamForVerification = sourceStreamSecondRun - let! wasUpdatedSecondRun = updateIntrospectionFileAsync CancellationToken.None sourceStreamForVerification - Assert.False wasUpdatedSecondRun -} + use sourceStreamForVerification = sourceStreamSecondRun + let! wasUpdatedSecondRun = updateIntrospectionFileAsync CancellationToken.None sourceStreamForVerification + Assert.False wasUpdatedSecondRun + } diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs index d1a7381f..587a274d 100644 --- a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs +++ b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs @@ -5,10 +5,8 @@ open System.Threading.Tasks open FSharp.Data.GraphQL open Helpers -[] -let IntrospectionPath = "integration-introspection.json" -[] -let EmptyGuidAsString = "00000000-0000-0000-0000-000000000000" +let [] IntrospectionPath = "integration-introspection.json" +let [] EmptyGuidAsString = "00000000-0000-0000-0000-000000000000" type Provider = GraphQLProvider // type FileProvider = GraphQLProvider @@ -236,22 +234,14 @@ module SingleRequiredUploadOperation = [] let ``Should be able to execute a single required upload`` () = - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - SingleRequiredUploadOperation.operation.Run (context, file.MakeUpload ()) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + SingleRequiredUploadOperation.operation.Run(context, file.MakeUpload()) |> SingleRequiredUploadOperation.validateResult file [] let ``Should be able to execute a single required upload asynchronously`` () : Task = task { - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - let! result = SingleRequiredUploadOperation.operation.AsyncRun (context, file.MakeUpload ()) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + let! result = SingleRequiredUploadOperation.operation.AsyncRun(context, file.MakeUpload()) result |> SingleRequiredUploadOperation.validateResult file } @@ -283,24 +273,15 @@ module SingleOptionalUploadOperation = [] let ``Should be able to execute a single optional upload by passing a file`` () = - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - SingleOptionalUploadOperation.operation.Run (context, file.MakeUpload ()) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + SingleOptionalUploadOperation.operation.Run(context, file.MakeUpload()) |> SingleOptionalUploadOperation.validateResult (Some file) -[] +[] let ``Should be able to execute a single optional upload by passing a file, asynchronously`` () : Task = task { - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - let! result = SingleOptionalUploadOperation.operation.AsyncRun (context, file.MakeUpload ()) - result - |> SingleOptionalUploadOperation.validateResult (Some file) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + let! result = SingleOptionalUploadOperation.operation.AsyncRun(context, file.MakeUpload()) + result |> SingleOptionalUploadOperation.validateResult (Some file) } [] @@ -340,38 +321,19 @@ module RequiredMultipleUploadOperation = [] let ``Should be able to execute a multiple required upload`` () = - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - RequiredMultipleUploadOperation.operation.Run (context, files |> Array.map (fun f -> f.MakeUpload ())) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + RequiredMultipleUploadOperation.operation.Run(context, files |> Array.map (fun f -> f.MakeUpload())) |> RequiredMultipleUploadOperation.validateResult files [] let ``Should be able to execute a multiple required upload asynchronously`` () : Task = task { - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = RequiredMultipleUploadOperation.operation.AsyncRun (context, files |> Array.map (fun f -> f.MakeUpload ())) - result - |> RequiredMultipleUploadOperation.validateResult files + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = RequiredMultipleUploadOperation.operation.AsyncRun(context, files |> Array.map (fun f -> f.MakeUpload())) + result |> RequiredMultipleUploadOperation.validateResult files } module OptionalMultipleUploadOperation = @@ -402,38 +364,19 @@ module OptionalMultipleUploadOperation = [] let ``Should be able to execute a multiple upload`` () = - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - OptionalMultipleUploadOperation.operation.Run (context, files |> Array.map (fun f -> f.MakeUpload ())) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + OptionalMultipleUploadOperation.operation.Run(context, files |> Array.map (fun f -> f.MakeUpload())) |> OptionalMultipleUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple upload asynchronously`` () : Task = task { - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = OptionalMultipleUploadOperation.operation.AsyncRun (context, files |> Array.map (fun f -> f.MakeUpload ())) - result - |> OptionalMultipleUploadOperation.validateResult (Some files) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = OptionalMultipleUploadOperation.operation.AsyncRun(context, files |> Array.map (fun f -> f.MakeUpload())) + result |> OptionalMultipleUploadOperation.validateResult (Some files) } [] @@ -478,38 +421,19 @@ module OptionalMultipleOptionalUploadOperation = [] let ``Should be able to execute a multiple optional upload`` () = - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - OptionalMultipleOptionalUploadOperation.operation.Run (context, files |> Array.map (Option.map (fun f -> f.MakeUpload ()))) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + OptionalMultipleOptionalUploadOperation.operation.Run(context, files |> Array.map (Option.map (fun f -> f.MakeUpload()))) |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple optional upload asynchronously`` () : Task = task { - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun (context, files |> Array.map (Option.map (fun f -> f.MakeUpload ()))) - result - |> (OptionalMultipleOptionalUploadOperation.validateResult (Some files)) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun(context, files |> Array.map (Option.map (fun f -> f.MakeUpload()))) + result |> (OptionalMultipleOptionalUploadOperation.validateResult (Some files)) } [] @@ -526,42 +450,23 @@ let ``Should be able to execute a multiple optional upload asynchronously by sen [] let ``Should be able to execute a multiple optional upload by sending some uploads`` () = - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - None - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - None - |] - OptionalMultipleOptionalUploadOperation.operation.Run (context, files |> Array.map (Option.map (fun f -> f.MakeUpload ()))) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + None + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } + None |] + OptionalMultipleOptionalUploadOperation.operation.Run(context, files |> Array.map (Option.map (fun f -> f.MakeUpload()))) |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple optional upload asynchronously by sending some uploads`` () : Task = task { - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - None - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - None - |] - let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun (context, files |> Array.map (Option.map (fun f -> f.MakeUpload ()))) - result - |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + None + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } + None |] + let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun(context, files |> Array.map (Option.map (fun f -> f.MakeUpload()))) + result |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) } module UploadRequestOperation = @@ -675,13 +580,9 @@ module UploadComplexOperation = [] let ``Should be able to upload file using complex input object`` () = - let file = { - Name = "complex.txt" - ContentType = "text/plain" - Content = "Complex input object file content" - } - let input = UploadComplexOperation.InputFile (file = file.MakeUpload ()) - UploadComplexOperation.operation.Run (context, input) + let file = { Name = "complex.txt"; ContentType = "text/plain"; Content = "Complex input object file content" } + let input = UploadComplexOperation.InputFile(file = file.MakeUpload()) + UploadComplexOperation.operation.Run(context, input) |> UploadComplexOperation.validateResult file [] @@ -697,13 +598,9 @@ let ``Should be able to upload file using complex input object with context`` () [] let ``Should be able to upload file using complex input object asynchronously`` () : Task = task { - let file = { - Name = "complex_async.txt" - ContentType = "text/plain" - Content = "Complex input object async file content" - } - let input = UploadComplexOperation.InputFile (file = file.MakeUpload ()) - let! result = UploadComplexOperation.operation.AsyncRun (context, input) + let file = { Name = "complex_async.txt"; ContentType = "text/plain"; Content = "Complex input object async file content" } + let input = UploadComplexOperation.InputFile(file = file.MakeUpload()) + let! result = UploadComplexOperation.operation.AsyncRun(context, input) result |> UploadComplexOperation.validateResult file } diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderWithOptionalParametersOnlyTests.fs b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderWithOptionalParametersOnlyTests.fs index b0a0221a..36b07b71 100644 --- a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderWithOptionalParametersOnlyTests.fs +++ b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderWithOptionalParametersOnlyTests.fs @@ -5,10 +5,8 @@ open System.Threading.Tasks open FSharp.Data.GraphQL open Helpers -[] -let IntrospectionPath = "integration-introspection.json" -[] -let EmptyGuidAsString = "00000000-0000-0000-0000-000000000000" +let [] IntrospectionPath = "integration-introspection.json" +let [] EmptyGuidAsString = "00000000-0000-0000-0000-000000000000" type Provider = GraphQLProvider @@ -235,22 +233,14 @@ module SingleRequiredUploadOperation = [] let ``Should be able to execute a single required upload`` () = - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - SingleRequiredUploadOperation.operation.Run (context, file.MakeUpload (file.Name)) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + SingleRequiredUploadOperation.operation.Run(context, file.MakeUpload(file.Name)) |> SingleRequiredUploadOperation.validateResult file [] let ``Should be able to execute a single required upload asynchronously`` () : Task = task { - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - let! result = SingleRequiredUploadOperation.operation.AsyncRun (context, file.MakeUpload ()) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + let! result = SingleRequiredUploadOperation.operation.AsyncRun(context, file.MakeUpload()) result |> SingleRequiredUploadOperation.validateResult file } @@ -281,24 +271,15 @@ module SingleOptionalUploadOperation = [] let ``Should be able to execute a single optional upload by passing a file`` () = - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - SingleOptionalUploadOperation.operation.Run (context, file.MakeUpload () |> Some) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + SingleOptionalUploadOperation.operation.Run(context, file.MakeUpload() |> Some) |> SingleOptionalUploadOperation.validateResult (Some file) [] let ``Should be able to execute a single optional upload by passing a file, asynchronously`` () : Task = task { - let file = { - Name = "file.txt" - ContentType = "text/plain" - Content = "Sample text file contents" - } - let! result = SingleOptionalUploadOperation.operation.AsyncRun (context, file.MakeUpload ("test") |> Some) - result - |> SingleOptionalUploadOperation.validateResult (Some file) + let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" } + let! result = SingleOptionalUploadOperation.operation.AsyncRun(context, file.MakeUpload("test") |> Some) + result |> SingleOptionalUploadOperation.validateResult (Some file) } [] @@ -338,38 +319,19 @@ module RequiredMultipleUploadOperation = [] let ``Should be able to execute a multiple required upload`` () = - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - RequiredMultipleUploadOperation.operation.Run (context, files |> Array.map (fun f -> f.MakeUpload ())) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + RequiredMultipleUploadOperation.operation.Run(context, files |> Array.map (fun f -> f.MakeUpload())) |> RequiredMultipleUploadOperation.validateResult files [] let ``Should be able to execute a multiple required upload asynchronously`` () : Task = task { - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = RequiredMultipleUploadOperation.operation.AsyncRun (context, files |> Array.map (fun f -> f.MakeUpload ())) - result - |> RequiredMultipleUploadOperation.validateResult files + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = RequiredMultipleUploadOperation.operation.AsyncRun(context, files |> Array.map (fun f -> f.MakeUpload())) + result |> RequiredMultipleUploadOperation.validateResult files } module OptionalMultipleUploadOperation = @@ -400,38 +362,19 @@ module OptionalMultipleUploadOperation = [] let ``Should be able to execute a multiple upload`` () = - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - OptionalMultipleUploadOperation.operation.Run (context, files |> Array.map (fun f -> f.MakeUpload ()) |> Some) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + OptionalMultipleUploadOperation.operation.Run(context, files |> Array.map (fun f -> f.MakeUpload()) |> Some) |> OptionalMultipleUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple upload asynchronously`` () : Task = task { - let files = [| - { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = OptionalMultipleUploadOperation.operation.AsyncRun (context, (files |> Array.map _.MakeUpload()) |> Some) - result - |> OptionalMultipleUploadOperation.validateResult (Some files) + let files = + [| { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = OptionalMultipleUploadOperation.operation.AsyncRun(context, (files |> Array.map _.MakeUpload()) |> Some) + result |> OptionalMultipleUploadOperation.validateResult (Some files) } [] @@ -476,38 +419,19 @@ module OptionalMultipleOptionalUploadOperation = [] let ``Should be able to execute a multiple optional upload`` () = - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - OptionalMultipleOptionalUploadOperation.operation.Run (context, (files |> Array.map (Option.map _.MakeUpload())) |> Some) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + OptionalMultipleOptionalUploadOperation.operation.Run(context, (files |> Array.map (Option.map _.MakeUpload())) |> Some) |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple optional upload asynchronously`` () : Task = task { - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - |] - let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun (context, (files |> Array.map (Option.map _.MakeUpload())) |> Some) - result - |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } |] + let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun(context, (files |> Array.map (Option.map _.MakeUpload())) |> Some) + result |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) } [] @@ -524,42 +448,23 @@ let ``Should be able to execute a multiple optional upload asynchronously by sen [] let ``Should be able to execute a multiple optional upload by sending some uploads`` () = - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - None - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - None - |] - OptionalMultipleOptionalUploadOperation.operation.Run (context, files |> Array.map (Option.map _.MakeUpload()) |> Some) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + None + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } + None |] + OptionalMultipleOptionalUploadOperation.operation.Run(context, files |> Array.map (Option.map _.MakeUpload()) |> Some) |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) [] let ``Should be able to execute a multiple optional upload asynchronously by sending some uploads`` () : Task = task { - let files = [| - Some { - Name = "file1.txt" - ContentType = "text/plain" - Content = "Sample text file contents 1" - } - None - Some { - Name = "file2.txt" - ContentType = "text/plain" - Content = "Sample text file contents 2" - } - None - |] - let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun (context, files |> Array.map (Option.map _.MakeUpload()) |> Some) - result - |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) + let files = + [| Some { Name = "file1.txt"; ContentType = "text/plain"; Content = "Sample text file contents 1" } + None + Some { Name = "file2.txt"; ContentType = "text/plain"; Content = "Sample text file contents 2" } + None |] + let! result = OptionalMultipleOptionalUploadOperation.operation.AsyncRun(context, files |> Array.map (Option.map _.MakeUpload()) |> Some) + result |> OptionalMultipleOptionalUploadOperation.validateResult (Some files) } module UploadRequestOperation = @@ -672,13 +577,9 @@ module UploadComplexOperation = [] let ``Should be able to upload file using complex input object`` () = - let file = { - Name = "complex.txt" - ContentType = "text/plain" - Content = "Complex input object file content" - } - let input = UploadComplexOperation.InputFile (file = file.MakeUpload ()) - UploadComplexOperation.operation.Run (context, input) + let file = { Name = "complex.txt"; ContentType = "text/plain"; Content = "Complex input object file content" } + let input = UploadComplexOperation.InputFile(file = file.MakeUpload()) + UploadComplexOperation.operation.Run(context, input) |> UploadComplexOperation.validateResult file [] @@ -694,13 +595,9 @@ let ``Should be able to upload file using complex input object with context`` () [] let ``Should be able to upload file using complex input object asynchronously`` () : Task = task { - let file = { - Name = "complex_async.txt" - ContentType = "text/plain" - Content = "Complex input object async file content" - } - let input = UploadComplexOperation.InputFile (file = file.MakeUpload ()) - let! result = UploadComplexOperation.operation.AsyncRun (context, input) + let file = { Name = "complex_async.txt"; ContentType = "text/plain"; Content = "Complex input object async file content" } + let input = UploadComplexOperation.InputFile(file = file.MakeUpload()) + let! result = UploadComplexOperation.operation.AsyncRun(context, input) result |> UploadComplexOperation.validateResult file } diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.InputAsOutput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.InputAsOutput.fsx index d39472e9..7f7b5f4b 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.InputAsOutput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.InputAsOutput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let inputOnlyType = - Define.InputObject (name = "InputOnlyType", fields = [ Define.Input ("value", IntType) ]) + Define.InputObject( + name = "InputOnlyType", + fields = [ Define.Input("value", IntType) ] + ) // This should fail: InputDef cannot be assigned to OutputDef let _ : OutputDef = ListOf inputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.OutputAsInput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.OutputAsInput.fsx index dd330762..ca8e4761 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.OutputAsInput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/ListOf.OutputAsInput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let outputOnlyType = - Define.Object (name = "OutputOnlyType", fields = [ Define.Field ("value", IntType, fun _ x -> x.Value) ]) + Define.Object( + name = "OutputOnlyType", + fields = [ Define.Field("value", IntType, fun _ x -> x.Value) ] + ) // This should fail: OutputDef cannot be assigned to InputDef let _ : InputDef = ListOf outputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.InputAsOutput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.InputAsOutput.fsx index cb37d0e3..281b09c4 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.InputAsOutput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.InputAsOutput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let inputOnlyType = - Define.InputObject (name = "InputOnlyType", fields = [ Define.Input ("value", IntType) ]) + Define.InputObject( + name = "InputOnlyType", + fields = [ Define.Input("value", IntType) ] + ) // This should fail: InputDef cannot be assigned to OutputDef let _ : OutputDef = Nullable inputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.OutputAsInput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.OutputAsInput.fsx index faa94e83..07d81e83 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.OutputAsInput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Nullable.OutputAsInput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let outputOnlyType = - Define.Object (name = "OutputOnlyType", fields = [ Define.Field ("value", IntType, fun _ x -> x.Value) ]) + Define.Object( + name = "OutputOnlyType", + fields = [ Define.Field("value", IntType, fun _ x -> x.Value) ] + ) // This should fail: OutputDef cannot be assigned to InputDef let _ : InputDef = Nullable outputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.InputAsOutput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.InputAsOutput.fsx index 1d112345..c8f13613 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.InputAsOutput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.InputAsOutput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let inputOnlyType = - Define.InputObject (name = "InputOnlyType", fields = [ Define.Input ("value", IntType) ]) + Define.InputObject( + name = "InputOnlyType", + fields = [ Define.Input("value", IntType) ] + ) // This should fail: InputDef cannot be assigned to OutputDef let _ : OutputDef = StructNullable inputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.OutputAsInput.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.OutputAsInput.fsx index e83c7e01..c06d6d49 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.OutputAsInput.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/StructNullable.OutputAsInput.fsx @@ -6,7 +6,10 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let outputOnlyType = - Define.Object (name = "OutputOnlyType", fields = [ Define.Field ("value", IntType, fun _ x -> x.Value) ]) + Define.Object( + name = "OutputOnlyType", + fields = [ Define.Field("value", IntType, fun _ x -> x.Value) ] + ) // This should fail: OutputDef cannot be assigned to InputDef let _ : InputDef = StructNullable outputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Valid.fsx b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Valid.fsx index 662d580f..f03aa65c 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Valid.fsx +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafety/Valid.fsx @@ -6,15 +6,21 @@ type InputOnly = { Value : int } type OutputOnly = { Value : int } let inputOnlyType = - Define.InputObject (name = "InputOnlyType", fields = [ Define.Input ("value", IntType) ]) + Define.InputObject( + name = "InputOnlyType", + fields = [ Define.Input("value", IntType) ] + ) let outputOnlyType = - Define.Object (name = "OutputOnlyType", fields = [ Define.Field ("value", IntType, fun _ x -> x.Value) ]) + Define.Object( + name = "OutputOnlyType", + fields = [ Define.Field("value", IntType, fun _ x -> x.Value) ] + ) // These are all valid assignments and must compile successfully -let _inputList : InputDef = ListOf inputOnlyType -let _outputList : OutputDef = ListOf outputOnlyType -let _inputNullable : InputDef = Nullable inputOnlyType +let _inputList : InputDef = ListOf inputOnlyType +let _outputList : OutputDef = ListOf outputOnlyType +let _inputNullable : InputDef = Nullable inputOnlyType let _outputNullable : OutputDef = Nullable outputOnlyType -let _inputStruct : InputDef = StructNullable inputOnlyType +let _inputStruct : InputDef = StructNullable inputOnlyType let _outputStruct : OutputDef = StructNullable outputOnlyType diff --git a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafetyTests.fs b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafetyTests.fs index 50bc6884..57e43ed1 100644 --- a/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafetyTests.fs +++ b/tests/FSharp.Data.GraphQL.Tests/TypeWrappersKindSafetyTests.fs @@ -62,14 +62,14 @@ type TypeWrappersKindSafetyFixture () = interface IAsyncLifetime with member this.InitializeAsync () : Task = task { - IO.Directory.CreateDirectory (scriptsDir) |> ignore - IO.Directory.CreateDirectory (sourceScriptsDir) |> ignore + IO.Directory.CreateDirectory (scriptsDir) |> ignore + IO.Directory.CreateDirectory (sourceScriptsDir) |> ignore - let content = this.ReferencesContent + let content = this.ReferencesContent - do! ensureFileContentAsync referencesPath content - do! ensureFileContentAsync sourceReferencesPath content - } + do! ensureFileContentAsync referencesPath content + do! ensureFileContentAsync sourceReferencesPath content + } member _.DisposeAsync () = Task.CompletedTask @@ -78,63 +78,63 @@ type TypeWrappersKindSafetyTests (fixture : TypeWrappersKindSafetyFixture) = [] member _.``ListOf keeps input-output direction`` () : Task = task { - let inputList : InputDef = ListOf InputOnlyType - let outputList : OutputDef = ListOf OutputOnlyType - Assert.Equal ("[InputOnlyType!]!", inputList.ToString ()) - Assert.Equal ("[OutputOnlyType!]!", outputList.ToString ()) - } + let inputList : InputDef = ListOf InputOnlyType + let outputList : OutputDef = ListOf OutputOnlyType + Assert.Equal ("[InputOnlyType!]!", inputList.ToString ()) + Assert.Equal ("[OutputOnlyType!]!", outputList.ToString ()) + } [] member _.``Nullable keeps input-output direction`` () : Task = task { - let nullableInput : InputDef = Nullable InputOnlyType - let nullableOutput : OutputDef = Nullable OutputOnlyType - Assert.Equal ("InputOnlyType", nullableInput.ToString ()) - Assert.Equal ("OutputOnlyType", nullableOutput.ToString ()) - } + let nullableInput : InputDef = Nullable InputOnlyType + let nullableOutput : OutputDef = Nullable OutputOnlyType + Assert.Equal ("InputOnlyType", nullableInput.ToString ()) + Assert.Equal ("OutputOnlyType", nullableOutput.ToString ()) + } [] member _.``StructNullable keeps input-output direction`` () : Task = task { - let nullableInput : InputDef = StructNullable InputOnlyType - let nullableOutput : OutputDef = StructNullable OutputOnlyType - Assert.Equal ("InputOnlyType", nullableInput.ToString ()) - Assert.Equal ("OutputOnlyType", nullableOutput.ToString ()) - } + let nullableInput : InputDef = StructNullable InputOnlyType + let nullableOutput : OutputDef = StructNullable OutputOnlyType + Assert.Equal ("InputOnlyType", nullableInput.ToString ()) + Assert.Equal ("OutputOnlyType", nullableOutput.ToString ()) + } [] member _.``Valid script compiles successfully`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Valid.fsx")) - Assert.Equal (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Valid.fsx")) + Assert.Equal (0, exitCode) + } [] member _.``ListOf rejects output type as input at compile time`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("ListOf.OutputAsInput.fsx")) - Assert.NotEqual (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("ListOf.OutputAsInput.fsx")) + Assert.NotEqual (0, exitCode) + } [] member _.``ListOf rejects input type as output at compile time`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("ListOf.InputAsOutput.fsx")) - Assert.NotEqual (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("ListOf.InputAsOutput.fsx")) + Assert.NotEqual (0, exitCode) + } [] member _.``Nullable rejects output type as input at compile time`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Nullable.OutputAsInput.fsx")) - Assert.NotEqual (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Nullable.OutputAsInput.fsx")) + Assert.NotEqual (0, exitCode) + } [] member _.``Nullable rejects input type as output at compile time`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Nullable.InputAsOutput.fsx")) - Assert.NotEqual (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("Nullable.InputAsOutput.fsx")) + Assert.NotEqual (0, exitCode) + } [] member _.``StructNullable rejects output type as input at compile time`` () : Task = task { - let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("StructNullable.OutputAsInput.fsx")) - Assert.NotEqual (0, exitCode) - } + let! exitCode = fixture.RunFsiCheckAsync (fixture.ScriptPath ("StructNullable.OutputAsInput.fsx")) + Assert.NotEqual (0, exitCode) + } [] member _.``StructNullable rejects input type as output at compile time`` () : Task = task {