Add Custom Json tests

This commit is contained in:
2025-04-04 23:28:10 -04:00
parent a363370342
commit 0e489617f7
5 changed files with 237 additions and 61 deletions

View File

@@ -1,5 +1,6 @@
module PostgresTests
open System.IO
open Expecto
open BitBadger.Documents
open BitBadger.Documents.Postgres
@@ -68,7 +69,7 @@ let parametersTests = testList "Parameters" [
Expect.equal (idParam "99") ("@id", Sql.string "99") "String ID parameter not constructed correctly"
}
test "succeeds for non-numeric non-string ID" {
let target = { new obj() with override _.ToString() = "ToString was called" }
let target = { new obj() with override _.ToString() = "ToString was called" }
Expect.equal
(idParam target)
("@id", Sql.string "ToString was called")
@@ -275,6 +276,19 @@ let loadDocs () = backgroundTask {
for doc in testDocuments do do! insert PostgresDb.TableName doc
}
/// Set up a stream writer for a test
let writeStream (stream: Stream) =
let writer = new StreamWriter(stream)
writer.AutoFlush <- true
writer
/// Get the text of the given stream
let streamText (stream: Stream) =
stream.Position <- 0L
use reader = new StreamReader(stream)
reader.ReadToEnd()
/// Integration tests for the Configuration module of the PostgreSQL library
let configurationTests = testList "Configuration" [
test "useDataSource disposes existing source" {
@@ -317,6 +331,57 @@ let customTests = testList "Custom" [
Expect.isEmpty docs "There should have been no documents returned"
}
]
testList "jsonArray" [
testTask "succeeds when data is found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let docs = Custom.jsonArray (Query.find PostgresDb.TableName) [] jsonFromData
Expect.stringStarts docs "[" "The JSON array should have started with `[`"
Expect.hasLength (docs.Split "{\"Id\":") 6 "There should have been 5 documents returned"
Expect.stringEnds docs "]" "The JSON array should have ended with `[`"
}
testTask "succeeds when data is not found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let docs =
Custom.jsonArray
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
[ "@path", Sql.string "$.NumValue ? (@ > 100)" ]
jsonFromData
Expect.equal docs "[]" "There should have been no documents returned"
}
]
testList "writeJsonArray" [
testTask "succeeds when data is found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
use stream = new MemoryStream()
use writer = writeStream stream
Custom.writeJsonArray (Query.find PostgresDb.TableName) [] writer jsonFromData
let docs = streamText stream
Expect.stringStarts docs "[" "The JSON array should have started with `[`"
Expect.hasLength (docs.Split "{\"Id\":") 6 "There should have been 5 documents returned"
Expect.stringEnds docs "]" "The JSON array should have ended with `[`"
}
testTask "succeeds when data is not found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
use stream = new MemoryStream()
use writer = writeStream stream
Custom.writeJsonArray
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
[ "@path", Sql.string "$.NumValue ? (@ > 100)" ]
writer
jsonFromData
Expect.equal (streamText stream) "[]" "There should have been no documents returned"
}
]
testList "single" [
testTask "succeeds when a row is found" {
use db = PostgresDb.BuildDb()
@@ -342,6 +407,32 @@ let customTests = testList "Custom" [
Expect.isNone doc "There should not have been a document returned"
}
]
testList "jsonSingle" [
testTask "succeeds when a row is found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let doc =
Custom.jsonSingle
$"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id"
[ "@id", Sql.string "one"]
jsonFromData
Expect.stringStarts doc "{" "The document should have started with an open brace"
Expect.stringContains doc "\"Id\": \"one\"" "An incorrect document was returned"
Expect.stringEnds doc "}" "The document should have ended with a closing brace"
}
testTask "succeeds when a row is not found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let doc =
Custom.jsonSingle
$"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id"
[ "@id", Sql.string "eighty" ]
jsonFromData
Expect.equal doc "{}" "There should not have been a document returned"
}
]
testList "nonQuery" [
testTask "succeeds when operating on data" {
use db = PostgresDb.BuildDb()
@@ -380,7 +471,7 @@ let definitionTests = testList "Definition" [
let keyExists () =
Custom.scalar
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_key') AS it" [] toExists
let! exists = tableExists ()
let! alsoExists = keyExists ()
Expect.isFalse exists "The table should not exist already"
@@ -397,7 +488,7 @@ let definitionTests = testList "Definition" [
let indexExists () =
Custom.scalar
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_document') AS it" [] toExists
let! exists = indexExists ()
Expect.isFalse exists "The index should not exist already"
@@ -410,7 +501,7 @@ let definitionTests = testList "Definition" [
use db = PostgresDb.BuildDb()
let indexExists () =
Custom.scalar "SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_test') AS it" [] toExists
let! exists = indexExists ()
Expect.isFalse exists "The index should not exist already"
@@ -451,12 +542,12 @@ let documentTests = testList "Document" [
use db = PostgresDb.BuildDb()
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should be no documents in the table"
do! insert PostgresDb.TableName { Key = 0; Text = "one" }
do! insert PostgresDb.TableName { Key = 0; Text = "two" }
do! insert PostgresDb.TableName { Key = 77; Text = "three" }
do! insert PostgresDb.TableName { Key = 0; Text = "four" }
let! after = Find.allOrdered<NumIdDocument> PostgresDb.TableName [ Field.Named "n:Key" ]
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.equal (after |> List.map _.Key) [ 1; 2; 77; 78 ] "The IDs were not generated correctly"
@@ -470,12 +561,12 @@ let documentTests = testList "Document" [
use db = PostgresDb.BuildDb()
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should be no documents in the table"
do! insert PostgresDb.TableName { emptyDoc with Value = "one" }
do! insert PostgresDb.TableName { emptyDoc with Value = "two" }
do! insert PostgresDb.TableName { emptyDoc with Id = "abc123"; Value = "three" }
do! insert PostgresDb.TableName { emptyDoc with Value = "four" }
let! after = Find.all<JsonDocument> PostgresDb.TableName
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.hasCountOf after 3u (fun doc -> doc.Id.Length = 32) "Three of the IDs should have been GUIDs"
@@ -490,12 +581,12 @@ let documentTests = testList "Document" [
use db = PostgresDb.BuildDb()
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should be no documents in the table"
do! insert PostgresDb.TableName { emptyDoc with Value = "one" }
do! insert PostgresDb.TableName { emptyDoc with Value = "two" }
do! insert PostgresDb.TableName { emptyDoc with Id = "abc123"; Value = "three" }
do! insert PostgresDb.TableName { emptyDoc with Value = "four" }
let! after = Find.all<JsonDocument> PostgresDb.TableName
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.hasCountOf
@@ -549,7 +640,7 @@ let countTests = testList "Count" [
testTask "succeeds when items are found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! theCount =
Count.byFields PostgresDb.TableName Any [ Field.Between "NumValue" 15 20; Field.Equal "NumValue" 0 ]
Expect.equal theCount 3 "There should have been 3 matching documents"
@@ -557,7 +648,7 @@ let countTests = testList "Count" [
testTask "succeeds when items are not found" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! theCount = Count.byFields PostgresDb.TableName All [ Field.Exists "Sub"; Field.Greater "NumValue" 100 ]
Expect.equal theCount 0 "There should have been no matching documents"
}
@@ -672,7 +763,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering numerically" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> PostgresDb.TableName [ Field.Named "n:NumValue" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -683,7 +774,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering numerically descending" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> PostgresDb.TableName [ Field.Named "n:NumValue DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -694,7 +785,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering alphabetically" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> PostgresDb.TableName [ Field.Named "Id DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -750,7 +841,7 @@ let findTests = testList "Find" [
use db = PostgresDb.BuildDb()
do! Definition.ensureTable PostgresDb.TableName
for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc
let! docs =
Find.byFields<ArrayDocument>
PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "c" ] ]
@@ -760,7 +851,7 @@ let findTests = testList "Find" [
use db = PostgresDb.BuildDb()
do! Definition.ensureTable PostgresDb.TableName
for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc
let! docs =
Find.byFields<ArrayDocument>
PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ]
@@ -1034,7 +1125,7 @@ let updateTests = testList "Update" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Update.byId
PostgresDb.TableName "test" { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } }
@@ -1045,7 +1136,7 @@ let updateTests = testList "Update" [
use db = PostgresDb.BuildDb()
do! loadDocs ()
do! Update.byFunc PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
do! Update.byFunc PostgresDb.TableName _.Id { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update"
Expect.equal
@@ -1058,9 +1149,9 @@ let updateTests = testList "Update" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Update.byFunc PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
do! Update.byFunc PostgresDb.TableName _.Id { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
}
]
]
@@ -1071,7 +1162,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
do! Patch.byId PostgresDb.TableName "one" {| NumValue = 44 |}
let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update"
@@ -1082,7 +1173,7 @@ let patchTests = testList "Patch" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byId PostgresDb.TableName "test" {| Foo = "green" |}
}
@@ -1091,7 +1182,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
do! Patch.byFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] {| NumValue = 77 |}
let! after = Count.byFields PostgresDb.TableName Any [ Field.Equal "NumValue" 77 ]
Expect.equal after 2 "There should have been 2 documents returned"
@@ -1101,7 +1192,7 @@ let patchTests = testList "Patch" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byFields PostgresDb.TableName Any [ Field.Equal "Value" "burgundy" ] {| Foo = "green" |}
}
@@ -1110,7 +1201,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
do! Patch.byContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |}
let! after = Count.byContains PostgresDb.TableName {| NumValue = 77 |}
Expect.equal after 2 "There should have been 2 documents returned"
@@ -1120,7 +1211,7 @@ let patchTests = testList "Patch" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
}
@@ -1129,7 +1220,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
do! Patch.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |}
let! after = Count.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)"
Expect.equal after 2 "There should have been 2 documents returned"
@@ -1139,7 +1230,7 @@ let patchTests = testList "Patch" [
let! before = Count.all PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
}
@@ -1172,13 +1263,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byId PostgresDb.TableName "two" [ "AFieldThatIsNotThere" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byId PostgresDb.TableName "two" [ "Value" ]
}
@@ -1207,13 +1298,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byFields PostgresDb.TableName Any [ Field.Equal "NumValue" 17 ] [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byFields PostgresDb.TableName Any [ Field.NotEqual "Abracadabra" "apple" ] [ "Value" ]
}
@@ -1242,13 +1333,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byContains PostgresDb.TableName {| NumValue = 17 |} [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byContains PostgresDb.TableName {| Abracadabra = "apple" |} [ "Value" ]
}
@@ -1277,13 +1368,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byJsonPath PostgresDb.TableName "$.NumValue ? (@ == 17)" [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byJsonPath PostgresDb.TableName "$.Abracadabra ? (@ == \"apple\")" [ "Value" ]
}