From 8c1d534d7a2c0c5bc1743a81d8669e04115c576b Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sat, 5 Apr 2025 16:05:06 -0400 Subject: [PATCH] Add F# string-returning Json tests --- src/Tests/PostgresTests.fs | 321 +++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) diff --git a/src/Tests/PostgresTests.fs b/src/Tests/PostgresTests.fs index 9bde8d3..46d9a2d 100644 --- a/src/Tests/PostgresTests.fs +++ b/src/Tests/PostgresTests.fs @@ -1107,6 +1107,326 @@ let findTests = testList "Find" [ ] ] +/// Verify a JSON array begins with "[" and ends with "]" +let private verifyBeginEnd json = + Expect.stringStarts json "[" "The array should have started with `[`" + Expect.stringEnds json "]" "The array should have ended with `]`" + +/// Verify the presence of a document by its ID +let private verifyDocById docId json = + Expect.stringContains json $"{{\"Id\": \"%s{docId}\"," $"Document `{docId}` not present" + +/// Verify the presence of a document by its ID +let private verifySingleById docId json = + verifyBeginEnd json + Expect.stringContains json $"{{\"Id\": \"%s{docId}\"," $"Document `{docId}` not present" + +/// Verify the presence of any of the given document IDs in the given JSON +let private verifyAnyById (docIds: string list) (json: string) = + match docIds |> List.tryFind (fun it -> json.Contains $"{{\"Id\": \"{it}\"") with + | Some _ -> () + | None -> + let ids = docIds |> String.concat ", " + Expect.isTrue false $"Could not find any of IDs {ids} in {json}" + +/// Verify the JSON for `all` returning data +let private verifyAllData json = + verifyBeginEnd json + for docId in [ "one"; "two"; "three"; "four"; "five" ] do verifyDocById docId json + +/// Verify an empty JSON array +let private verifyEmpty json = + Expect.equal json "[]" "There should be no documents returned" + +/// Verify an empty JSON document +let private verifyNoDoc json = + Expect.equal json "{}" "There should be no document returned" + +/// Verify the JSON for an ordered query +let private verifyExpectedOrder idFirst idSecond idThird idFourth idFifth (json: string) = + let firstIdx = json.IndexOf $"{{\"Id\": \"%s{idFirst}\"," + let secondIdx = json.IndexOf $"{{\"Id\": \"%s{idSecond}\"," + verifyBeginEnd json + Expect.isGreaterThan secondIdx firstIdx $"`{idSecond}` should have been after `{idFirst}`" + match idThird with + | Some id3 -> + let thirdIdx = json.IndexOf $"{{\"Id\": \"%s{id3}\"," + Expect.isGreaterThan thirdIdx secondIdx $"`{id3}` should have been after `{idSecond}`" + match idFourth with + | Some id4 -> + let fourthIdx = json.IndexOf $"{{\"Id\": \"%s{id4}\"," + Expect.isGreaterThan fourthIdx thirdIdx $"`{id4}` should have been after `{id3}`" + match idFifth with + | Some id5 -> + let fifthIdx = json.IndexOf $"{{\"Id\": \"%s{id5}\"," + Expect.isGreaterThan fifthIdx fourthIdx $"`{id5}` should have been after `{id4}`" + | None -> () + | None -> () + | None -> () + Expect.stringEnds json "]" "The array should have ended with `]`" + +/// Integration tests for the Json module of the PostgreSQL library +let jsonTests = testList "Json" [ + testList "all" [ + testTask "succeeds when there is data" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.all PostgresDb.TableName |> verifyAllData + } + testTask "succeeds when there is no data" { + use db = PostgresDb.BuildDb() + Json.all PostgresDb.TableName |> verifyEmpty + } + ] + testList "allOrdered" [ + testTask "succeeds when ordering numerically" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.allOrdered PostgresDb.TableName [ Field.Named "n:NumValue" ] + |> verifyExpectedOrder "one" "three" (Some "two") (Some "four") (Some "five") + } + testTask "succeeds when ordering numerically descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.allOrdered PostgresDb.TableName [ Field.Named "n:NumValue DESC" ] + |> verifyExpectedOrder "five" "four" (Some "two") (Some "three") (Some "one") + } + testTask "succeeds when ordering alphabetically" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.allOrdered PostgresDb.TableName [ Field.Named "Id DESC" ] + |> verifyExpectedOrder "two" "three" (Some "one") (Some "four") (Some "five") + } + ] + testList "byId" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + let json = Json.byId PostgresDb.TableName "two" + Expect.stringStarts json """{"Id": "two",""" "An incorrect document was returned" + Expect.stringEnds json "}" "JSON should have ended with this document" + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byId PostgresDb.TableName "three hundred eighty-seven" |> verifyNoDoc + } + ] + testList "byFields" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byFields PostgresDb.TableName All [ Field.In "Value" [ "purple"; "blue" ]; Field.Exists "Sub" ] + |> verifySingleById "four" + } + testTask "succeeds when documents are found using IN with numeric field" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byFields PostgresDb.TableName All [ Field.In "NumValue" [ 2; 4; 6; 8 ] ] |> verifySingleById "three" + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byFields PostgresDb.TableName All [ Field.Equal "Value" "mauve"; Field.NotEqual "NumValue" 40 ] + |> verifyEmpty + } + testTask "succeeds for InArray when matching documents exist" { + use db = PostgresDb.BuildDb() + do! Definition.ensureTable PostgresDb.TableName + for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc + + let json = Json.byFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "c" ] ] + verifyBeginEnd json + verifyDocById "first" json + verifyDocById "second" json + } + testTask "succeeds for InArray when no matching documents exist" { + use db = PostgresDb.BuildDb() + do! Definition.ensureTable PostgresDb.TableName + for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc + Json.byFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ] + |> verifyEmpty + } + ] + testList "byFieldsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byFieldsOrdered PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] + |> verifyExpectedOrder "five" "four" None None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byFieldsOrdered PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] + |> verifyExpectedOrder "four" "five" None None None + } + ] + testList "byContains" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + let json = Json.byContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |} + verifyBeginEnd json + verifyDocById "two" json + verifyDocById "four" json + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byContains PostgresDb.TableName {| Value = "mauve" |} |> verifyEmpty + } + ] + testList "byContainsOrdered" [ + // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar" ] + |> verifyExpectedOrder "two" "four" None None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar DESC" ] + |> verifyExpectedOrder "four" "two" None None None + } + ] + testList "byJsonPath" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + let json = Json.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 15)" + verifyBeginEnd json + verifyDocById "one" json + verifyDocById "two" json + verifyDocById "three" json + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" |> verifyEmpty + } + ] + testList "byJsonPathOrdered" [ + // Id = one, NumValue = 0; Id = two, NumValue = 10; Id = three, NumValue = 4 + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byJsonPathOrdered PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue" ] + |> verifyExpectedOrder "one" "three" (Some "two") None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.byJsonPathOrdered PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue DESC" ] + |> verifyExpectedOrder "two" "three" (Some "one") None None + } + ] + testList "firstByFields" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "another" ] + |> verifyDocById "two" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] + |> verifyAnyById [ "five"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "absent" ] |> verifyNoDoc + } + ] + testList "firstByFieldsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByFieldsOrdered PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] + |> verifyDocById "five" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByFieldsOrdered + PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] + |> verifyDocById "four" + } + ] + testList "firstByContains" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByContains PostgresDb.TableName {| Value = "another" |} |> verifyDocById "two" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |} |> verifyAnyById [ "two"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByContains PostgresDb.TableName {| Value = "absent" |} |> verifyNoDoc + } + ] + testList "firstByContainsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value" ] + |> verifyDocById "two" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByContainsOrdered + PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value DESC" ] + |> verifyDocById "four" + } + ] + testList "firstByJsonPath" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByJsonPath PostgresDb.TableName """$.Value ? (@ == "FIRST!")""" |> verifyDocById "one" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByJsonPath PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" + |> verifyAnyById [ "two"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByJsonPath PostgresDb.TableName """$.Id ? (@ == "nope")""" |> verifyNoDoc + } + ] + testList "firstByJsonPathOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByJsonPathOrdered PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar" ] + |> verifyDocById "two" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + Json.firstByJsonPathOrdered + PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar DESC" ] + |> verifyDocById "four" + } + ] +] + /// Integration tests for the Update module of the PostgreSQL library let updateTests = testList "Update" [ testList "byId" [ @@ -1468,6 +1788,7 @@ let all = testList "Postgres" [ countTests existsTests findTests + jsonTests updateTests patchTests removeFieldsTests