module PostgresTests open Expecto open BitBadger.Documents open BitBadger.Documents.Postgres open BitBadger.Documents.Tests (** UNIT TESTS **) /// Unit tests for the Parameters module of the PostgreSQL library let parametersTests = testList "Parameters" [ testList "idParam" [ // NOTE: these tests also exercise all branches of the internal parameterFor function test "succeeds for byte ID" { Expect.equal (idParam (sbyte 7)) ("@id", Sql.int8 (sbyte 7)) "Byte ID parameter not constructed correctly" } test "succeeds for unsigned byte ID" { Expect.equal (idParam (byte 7)) ("@id", Sql.int8 (int8 (byte 7))) "Unsigned byte ID parameter not constructed correctly" } test "succeeds for short ID" { Expect.equal (idParam (int16 44)) ("@id", Sql.int16 (int16 44)) "Short ID parameter not constructed correctly" } test "succeeds for unsigned short ID" { Expect.equal (idParam (uint16 64)) ("@id", Sql.int16 (int16 64)) "Unsigned short ID parameter not constructed correctly" } test "succeeds for integer ID" { Expect.equal (idParam 88) ("@id", Sql.int 88) "Int ID parameter not constructed correctly" } test "succeeds for unsigned integer ID" { Expect.equal (idParam (uint 889)) ("@id", Sql.int 889) "Unsigned int ID parameter not constructed correctly" } test "succeeds for long ID" { Expect.equal (idParam (int64 123)) ("@id", Sql.int64 (int64 123)) "Long ID parameter not constructed correctly" } test "succeeds for unsigned long ID" { Expect.equal (idParam (uint64 6464)) ("@id", Sql.int64 (int64 6464)) "Unsigned long ID parameter not constructed correctly" } test "succeeds for decimal ID" { Expect.equal (idParam (decimal 4.56)) ("@id", Sql.decimal (decimal 4.56)) "Decimal ID parameter not constructed correctly" } test "succeeds for single ID" { Expect.equal (idParam (single 5.67)) ("@id", Sql.double (double (single 5.67))) "Single ID parameter not constructed correctly" } test "succeeds for double ID" { Expect.equal (idParam (double 6.78)) ("@id", Sql.double (double 6.78)) "Double ID parameter not constructed correctly" } test "succeeds for string ID" { 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" } Expect.equal (idParam target) ("@id", Sql.string "ToString was called") "Non-numeric, non-string parameter not constructed correctly" } ] test "jsonParam succeeds" { Expect.equal (jsonParam "@test" {| Something = "good" |}) ("@test", Sql.jsonb """{"Something":"good"}""") "JSON parameter not constructed correctly" } testList "addFieldParams" [ test "succeeds when a parameter is added" { let paramList = addFieldParams [ Field.Where "it" (Equal "242") ] [] Expect.hasLength paramList 1 "There should have been a parameter added" let name, value = Seq.head paramList Expect.equal name "@field0" "Field parameter name not correct" Expect.equal value (Sql.string "242") "Parameter value not correct" } test "succeeds when multiple independent parameters are added" { let paramList = addFieldParams [ Field.Equal "me" "you"; Field.Greater "us" "them" ] [ idParam 14 ] Expect.hasLength paramList 3 "There should have been 2 parameters added" let p = Array.ofSeq paramList Expect.equal (fst p[0]) "@id" "First field parameter name not correct" Expect.equal (snd p[0]) (Sql.int 14) "First parameter value not correct" Expect.equal (fst p[1]) "@field0" "Second field parameter name not correct" Expect.equal (snd p[1]) (Sql.string "you") "Second parameter value not correct" Expect.equal (fst p[2]) "@field1" "Third parameter name not correct" Expect.equal (snd p[2]) (Sql.string "them") "Third parameter value not correct" } test "succeeds when a parameter is not added" { let paramList = addFieldParams [ Field.Exists "tacos" ] [] Expect.isEmpty paramList "There should not have been any parameters added" } test "succeeds when two parameters are added for one field" { let paramList = addFieldParams [ { Field.Between "that" "eh" "zed" with ParameterName = Some "@test" } ] [] Expect.hasLength paramList 2 "There should have been 2 parameters added" let name, value = Seq.head paramList Expect.equal name "@testmin" "Minimum field name not correct" Expect.equal value (Sql.string "eh") "Minimum parameter value not correct" let name, value = paramList |> Seq.skip 1 |> Seq.head Expect.equal name "@testmax" "Maximum field name not correct" Expect.equal value (Sql.string "zed") "Maximum parameter value not correct" } ] testList "fieldNameParams" [ test "succeeds for one name" { let name, value = fieldNameParams [ "bob" ] Expect.equal name "@name" "The parameter name was incorrect" Expect.equal value (Sql.string "bob") "The parameter value was incorrect" } test "succeeds for multiple names" { let name, value = fieldNameParams [ "bob"; "tom"; "mike" ] Expect.equal name "@name" "The parameter name was incorrect" Expect.equal value (Sql.stringArray [| "bob"; "tom"; "mike" |]) "The parameter value was incorrect" } ] test "noParams succeeds" { Expect.isEmpty noParams "The no-params sequence should be empty" } ] /// Unit tests for the Query module of the PostgreSQL library let queryTests = testList "Query" [ testList "whereByFields" [ test "succeeds for a single field when a logical comparison is passed" { Expect.equal (Query.whereByFields Any [ { Field.Greater "theField" "0" with ParameterName = Some "@test" } ]) "data->>'theField' > @test" "WHERE clause not correct" } test "succeeds for a single field when an existence comparison is passed" { Expect.equal (Query.whereByFields Any [ Field.NotExists "thatField" ]) "data->>'thatField' IS NULL" "WHERE clause not correct" } test "succeeds for a single field when a between comparison is passed with numeric values" { Expect.equal (Query.whereByFields All [ { Field.Between "aField" 50 99 with ParameterName = Some "@range" } ]) "(data->>'aField')::numeric BETWEEN @rangemin AND @rangemax" "WHERE clause not correct" } test "succeeds for a single field when a between comparison is passed with non-numeric values" { Expect.equal (Query.whereByFields Any [ { Field.Between "field0" "a" "b" with ParameterName = Some "@alpha" } ]) "data->>'field0' BETWEEN @alphamin AND @alphamax" "WHERE clause not correct" } test "succeeds for all multiple fields with logical comparisons" { Expect.equal (Query.whereByFields All [ Field.Equal "theFirst" "1"; Field.Equal "numberTwo" "2" ]) "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1" "WHERE clause not correct" } test "succeeds for any multiple fields with an existence comparisons" { Expect.equal (Query.whereByFields Any [ Field.NotExists "thatField"; Field.GreaterOrEqual "thisField" 18 ]) "data->>'thatField' IS NULL OR (data->>'thisField')::numeric >= @field0" "WHERE clause not correct" } test "succeeds for all multiple fields with between comparisons" { Expect.equal (Query.whereByFields All [ Field.Between "aField" 50 99; Field.Between "anotherField" "a" "b" ]) "(data->>'aField')::numeric BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max" "WHERE clause not correct" } test "succeeds for a field with an In comparison with alphanumeric values" { Expect.equal (Query.whereByFields All [ Field.In "this" [ "a"; "b"; "c" ] ]) "data->>'this' IN (@field0_0, @field0_1, @field0_2)" "WHERE clause not correct" } test "succeeds for a field with an In comparison with numeric values" { Expect.equal (Query.whereByFields All [ Field.In "this" [ 7; 14; 21 ] ]) "(data->>'this')::numeric IN (@field0_0, @field0_1, @field0_2)" "WHERE clause not correct" } test "succeeds for a field with an InArray comparison" { Expect.equal (Query.whereByFields All [ Field.InArray "theField" "the_table" [ "q", "r" ] ]) "data->'theField' ?| @field0" "WHERE clause not correct" } ] testList "whereById" [ test "succeeds for numeric ID" { Expect.equal (Query.whereById 18) "(data->>'Id')::numeric = @id" "WHERE clause not correct" } test "succeeds for string ID" { Expect.equal (Query.whereById "18") "data->>'Id' = @id" "WHERE clause not correct" } test "succeeds for non-numeric non-string ID" { Expect.equal (Query.whereById (System.Uri "https://example.com")) "data->>'Id' = @id" "WHERE clause not correct" } ] testList "Definition" [ test "ensureTable succeeds" { Expect.equal (Query.Definition.ensureTable PostgresDb.TableName) $"CREATE TABLE IF NOT EXISTS {PostgresDb.TableName} (data JSONB NOT NULL)" "CREATE TABLE statement not constructed correctly" } test "ensureDocumentIndex succeeds for full index" { Expect.equal (Query.Definition.ensureDocumentIndex "schema.tbl" Full) "CREATE INDEX IF NOT EXISTS idx_tbl_document ON schema.tbl USING GIN (data)" "CREATE INDEX statement not constructed correctly" } test "ensureDocumentIndex succeeds for JSONB Path Ops index" { Expect.equal (Query.Definition.ensureDocumentIndex PostgresDb.TableName Optimized) (sprintf "CREATE INDEX IF NOT EXISTS idx_%s_document ON %s USING GIN (data jsonb_path_ops)" PostgresDb.TableName PostgresDb.TableName) "CREATE INDEX statement not constructed correctly" } ] test "whereDataContains succeeds" { Expect.equal (Query.whereDataContains "@test") "data @> @test" "WHERE clause not correct" } test "whereJsonPathMatches succeeds" { Expect.equal (Query.whereJsonPathMatches "@path") "data @? @path::jsonpath" "WHERE clause not correct" } test "patch succeeds" { Expect.equal (Query.patch PostgresDb.TableName) $"UPDATE {PostgresDb.TableName} SET data = data || @data" "Patch query not correct" } test "removeFields succeeds" { Expect.equal (Query.removeFields PostgresDb.TableName) $"UPDATE {PostgresDb.TableName} SET data = data - @name" "Field removal query not correct" } test "byId succeeds" { Expect.equal (Query.byId "test" "14") "test WHERE data->>'Id' = @id" "By-ID query not correct" } test "byFields succeeds" { Expect.equal (Query.byFields "unit" Any [ Field.Greater "That" 14 ]) "unit WHERE (data->>'That')::numeric > @field0" "By-Field query not correct" } test "byContains succeeds" { Expect.equal (Query.byContains "exam") "exam WHERE data @> @criteria" "By-Contains query not correct" } test "byPathMach succeeds" { Expect.equal (Query.byPathMatch "verify") "verify WHERE data @? @path::jsonpath" "By-JSON Path query not correct" } ] (** INTEGRATION TESTS **) open ThrowawayDb.Postgres open Types /// Load the test documents into the database let loadDocs () = backgroundTask { for doc in testDocuments do do! insert PostgresDb.TableName doc } /// Integration tests for the Configuration module of the PostgreSQL library let configurationTests = testList "Configuration" [ test "useDataSource disposes existing source" { use db1 = ThrowawayDatabase.Create PostgresDb.ConnStr.Value let source = PostgresDb.MkDataSource db1.ConnectionString Configuration.useDataSource source use db2 = ThrowawayDatabase.Create PostgresDb.ConnStr.Value Configuration.useDataSource (PostgresDb.MkDataSource db2.ConnectionString) Expect.throws (fun () -> source.OpenConnection() |> ignore) "Data source should have been disposed" } test "dataSource returns configured data source" { use db = ThrowawayDatabase.Create PostgresDb.ConnStr.Value let source = PostgresDb.MkDataSource db.ConnectionString Configuration.useDataSource source Expect.isTrue (obj.ReferenceEquals(source, Configuration.dataSource ())) "Data source should have been the same" } ] /// Integration tests for the Custom module of the PostgreSQL library let customTests = testList "Custom" [ testList "list" [ testTask "succeeds when data is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Custom.list (Query.find PostgresDb.TableName) [] fromData Expect.hasLength docs 5 "There should have been 5 documents returned" } testTask "succeeds when data is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Custom.list $"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath" [ "@path", Sql.string "$.NumValue ? (@ > 100)" ] fromData Expect.isEmpty docs "There should have been no documents returned" } ] testList "single" [ testTask "succeeds when a row is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Custom.single $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id" [ "@id", Sql.string "one"] fromData Expect.isSome doc "There should have been a document returned" Expect.equal doc.Value.Id "one" "The incorrect document was returned" } testTask "succeeds when a row is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Custom.single $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id" [ "@id", Sql.string "eighty" ] fromData Expect.isNone doc "There should not have been a document returned" } ] testList "nonQuery" [ testTask "succeeds when operating on data" { use db = PostgresDb.BuildDb() do! loadDocs () do! Custom.nonQuery $"DELETE FROM {PostgresDb.TableName}" [] let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 0 "There should be no documents remaining in the table" } testTask "succeeds when no data matches where clause" { use db = PostgresDb.BuildDb() do! loadDocs () do! Custom.nonQuery $"DELETE FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath" [ "@path", Sql.string "$.NumValue ? (@ > 100)" ] let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 5 "There should be 5 documents remaining in the table" } ] testTask "scalar succeeds" { use db = PostgresDb.BuildDb() let! nbr = Custom.scalar "SELECT 5 AS test_value" [] (fun row -> row.int "test_value") Expect.equal nbr 5 "The query should have returned the number 5" } ] /// Integration tests for the Definition module of the PostgreSQL library let definitionTests = testList "Definition" [ testTask "ensureTable succeeds" { use db = PostgresDb.BuildDb() let tableExists () = Custom.scalar "SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'ensured') AS it" [] toExists 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" Expect.isFalse alsoExists "The key index should not exist already" do! Definition.ensureTable "ensured" let! exists' = tableExists () let! alsoExists' = keyExists () Expect.isTrue exists' "The table should now exist" Expect.isTrue alsoExists' "The key index should now exist" } testTask "ensureDocumentIndex succeeds" { use db = PostgresDb.BuildDb() 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" do! Definition.ensureTable "ensured" do! Definition.ensureDocumentIndex "ensured" Optimized let! exists' = indexExists () Expect.isTrue exists' "The index should now exist" } testTask "ensureFieldIndex succeeds" { 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" do! Definition.ensureTable "ensured" do! Definition.ensureFieldIndex "ensured" "test" [ "Id"; "Category" ] let! exists' = indexExists () Expect.isTrue exists' "The index should now exist" } ] /// Integration tests for the (auto-opened) Document module of the PostgreSQL library let documentTests = testList "Document" [ testList "insert" [ testTask "succeeds" { use db = PostgresDb.BuildDb() let! before = Find.all PostgresDb.TableName Expect.equal before [] "There should be no documents in the table" let testDoc = { emptyDoc with Id = "turkey"; Sub = Some { Foo = "gobble"; Bar = "gobble" } } do! insert PostgresDb.TableName testDoc let! after = Find.all PostgresDb.TableName Expect.equal after [ testDoc ] "There should have been one document inserted" } testTask "fails for duplicate key" { use db = PostgresDb.BuildDb() do! insert PostgresDb.TableName { emptyDoc with Id = "test" } Expect.throws (fun () -> insert PostgresDb.TableName {emptyDoc with Id = "test" } |> Async.AwaitTask |> Async.RunSynchronously) "An exception should have been raised for duplicate document ID insert" } testTask "succeeds when adding a numeric auto ID" { try Configuration.useAutoIdStrategy Number Configuration.useIdField "Key" 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 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" finally Configuration.useAutoIdStrategy Disabled Configuration.useIdField "Id" } testTask "succeeds when adding a GUID auto ID" { try Configuration.useAutoIdStrategy Guid 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 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" Expect.hasCountOf after 1u (fun doc -> doc.Id = "abc123") "The provided ID should have been used as-is" finally Configuration.useAutoIdStrategy Disabled } testTask "succeeds when adding a RandomString auto ID" { try Configuration.useAutoIdStrategy RandomString Configuration.useIdStringLength 44 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 PostgresDb.TableName Expect.hasLength after 4 "There should have been 4 documents returned" Expect.hasCountOf after 3u (fun doc -> doc.Id.Length = 44) "Three of the IDs should have been 44-character random strings" Expect.hasCountOf after 1u (fun doc -> doc.Id = "abc123") "The provided ID should have been used as-is" finally Configuration.useAutoIdStrategy Disabled Configuration.useIdStringLength 16 } ] testList "save" [ testTask "succeeds when a document is inserted" { use db = PostgresDb.BuildDb() let! before = Find.all PostgresDb.TableName Expect.equal before [] "There should be no documents in the table" let testDoc = { emptyDoc with Id = "test"; Sub = Some { Foo = "a"; Bar = "b" } } do! save PostgresDb.TableName testDoc let! after = Find.all PostgresDb.TableName Expect.equal after [ testDoc ] "There should have been one document inserted" } testTask "succeeds when a document is updated" { use db = PostgresDb.BuildDb() let testDoc = { emptyDoc with Id = "test"; Sub = Some { Foo = "a"; Bar = "b" } } do! insert PostgresDb.TableName testDoc let! before = Find.byId PostgresDb.TableName "test" Expect.isSome before "There should have been a document returned" Expect.equal before.Value testDoc "The document is not correct" let upd8Doc = { testDoc with Sub = Some { Foo = "c"; Bar = "d" } } do! save PostgresDb.TableName upd8Doc let! after = Find.byId PostgresDb.TableName "test" Expect.isSome after "There should have been a document returned post-update" Expect.equal after.Value upd8Doc "The updated document is not correct" } ] ] /// Integration tests for the Count module of the PostgreSQL library let countTests = testList "Count" [ testTask "all succeeds" { use db = PostgresDb.BuildDb() do! loadDocs () let! theCount = Count.all PostgresDb.TableName Expect.equal theCount 5 "There should have been 5 matching documents" } testList "byFields" [ 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" } 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" } ] testTask "byContains succeeds" { use db = PostgresDb.BuildDb() do! loadDocs () let! theCount = Count.byContains PostgresDb.TableName {| Value = "purple" |} Expect.equal theCount 2 "There should have been 2 matching documents" } testTask "byJsonPath succeeds" { use db = PostgresDb.BuildDb() do! loadDocs () let! theCount = Count.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 5)" Expect.equal theCount 3 "There should have been 3 matching documents" } ] /// Integration tests for the Exists module of the PostgreSQL library let existsTests = testList "Exists" [ testList "byId" [ testTask "succeeds when a document exists" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byId PostgresDb.TableName "three" Expect.isTrue exists "There should have been an existing document" } testTask "succeeds when a document does not exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byId PostgresDb.TableName "seven" Expect.isFalse exists "There should not have been an existing document" } ] testList "byFields" [ testTask "succeeds when documents exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byFields PostgresDb.TableName Any [ Field.Exists "Sub"; Field.Exists "Boo" ] Expect.isTrue exists "There should have been existing documents" } testTask "succeeds when documents do not exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byFields PostgresDb.TableName All [ Field.Equal "NumValue" "six"; Field.Exists "Nope" ] Expect.isFalse exists "There should not have been existing documents" } ] testList "byContains" [ testTask "succeeds when documents exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byContains PostgresDb.TableName {| NumValue = 10 |} Expect.isTrue exists "There should have been existing documents" } testTask "succeeds when no matching documents exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byContains PostgresDb.TableName {| Nothing = "none" |} Expect.isFalse exists "There should not have been any existing documents" } ] testList "byJsonPath" [ testTask "succeeds when documents exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byJsonPath PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" Expect.isTrue exists "There should have been existing documents" } testTask "succeeds when no matching documents exist" { use db = PostgresDb.BuildDb() do! loadDocs () let! exists = Exists.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 1000)" Expect.isFalse exists "There should not have been any existing documents" } ] ] /// Integration tests for the Find module of the PostgreSQL library let findTests = testList "Find" [ testList "all" [ testTask "succeeds when there is data" { use db = PostgresDb.BuildDb() do! insert PostgresDb.TableName { Foo = "one"; Bar = "two" } do! insert PostgresDb.TableName { Foo = "three"; Bar = "four" } do! insert PostgresDb.TableName { Foo = "five"; Bar = "six" } let! results = Find.all PostgresDb.TableName Expect.equal results [ { Foo = "one"; Bar = "two" }; { Foo = "three"; Bar = "four" }; { Foo = "five"; Bar = "six" } ] "There should have been 3 documents returned" } testTask "succeeds when there is no data" { use db = PostgresDb.BuildDb() let! results = Find.all PostgresDb.TableName Expect.equal results [] "There should have been no documents returned" } ] testList "allOrdered" [ testTask "succeeds when ordering numerically" { use db = PostgresDb.BuildDb() do! loadDocs () let! results = Find.allOrdered PostgresDb.TableName [ Field.Named "n:NumValue" ] Expect.hasLength results 5 "There should have been 5 documents returned" Expect.equal (results |> List.map _.Id |> String.concat "|") "one|three|two|four|five" "The documents were not ordered correctly" } testTask "succeeds when ordering numerically descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! results = Find.allOrdered PostgresDb.TableName [ Field.Named "n:NumValue DESC" ] Expect.hasLength results 5 "There should have been 5 documents returned" Expect.equal (results |> List.map _.Id |> String.concat "|") "five|four|two|three|one" "The documents were not ordered correctly" } testTask "succeeds when ordering alphabetically" { use db = PostgresDb.BuildDb() do! loadDocs () let! results = Find.allOrdered PostgresDb.TableName [ Field.Named "Id DESC" ] Expect.hasLength results 5 "There should have been 5 documents returned" Expect.equal (results |> List.map _.Id |> String.concat "|") "two|three|one|four|five" "The documents were not ordered correctly" } ] testList "byId" [ testTask "succeeds when a document is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.byId PostgresDb.TableName "two" Expect.isSome doc "There should have been a document returned" Expect.equal doc.Value.Id "two" "The incorrect document was returned" } testTask "succeeds when a document is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.byId PostgresDb.TableName "three hundred eighty-seven" Expect.isNone doc "There should not have been a document returned" } ] testList "byFields" [ testTask "succeeds when documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byFields PostgresDb.TableName All [ Field.In "Value" [ "purple"; "blue" ]; Field.Exists "Sub" ] Expect.hasLength docs 1 "There should have been one document returned" } testTask "succeeds when documents are found using IN with numeric field" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byFields PostgresDb.TableName All [ Field.In "NumValue" [ 2; 4; 6; 8 ] ] Expect.hasLength docs 1 "There should have been one document returned" } testTask "succeeds when documents are not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byFields PostgresDb.TableName All [ Field.Equal "Value" "mauve"; Field.NotEqual "NumValue" 40 ] Expect.isEmpty docs "There should have been no documents returned" } 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! docs = Find.byFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "c" ] ] Expect.hasLength docs 2 "There should have been two documents returned" } 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 let! docs = Find.byFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ] Expect.isEmpty docs "There should have been no documents returned" } ] testList "byFieldsOrdered" [ testTask "succeeds when sorting ascending" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byFieldsOrdered PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] Expect.hasLength docs 2 "There should have been two documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "five|four" "Documents not ordered correctly" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byFieldsOrdered PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] Expect.hasLength docs 2 "There should have been two documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "four|five" "Documents not ordered correctly" } ] testList "byContains" [ testTask "succeeds when documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |} Expect.equal (List.length docs) 2 "There should have been two documents returned" } testTask "succeeds when documents are not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byContains PostgresDb.TableName {| Value = "mauve" |} Expect.isEmpty docs "There should have been no documents returned" } ] testList "byContainsOrdered" [ // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red testTask "succeeds when sorting ascending" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar" ] Expect.hasLength docs 2 "There should have been two documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "two|four" "Documents not ordered correctly" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar DESC" ] Expect.hasLength docs 2 "There should have been two documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "four|two" "Documents not ordered correctly" } ] testList "byJsonPath" [ testTask "succeeds when documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 15)" Expect.equal (List.length docs) 3 "There should have been 3 documents returned" } testTask "succeeds when documents are not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" Expect.isEmpty docs "There should have been no documents returned" } ] 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 () let! docs = Find.byJsonPathOrdered PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue" ] Expect.hasLength docs 3 "There should have been 3 documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "one|three|two" "Documents not ordered correctly" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! docs = Find.byJsonPathOrdered PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue DESC" ] Expect.hasLength docs 3 "There should have been 3 documents returned" Expect.equal (docs |> List.map _.Id |> String.concat "|") "two|three|one" "Documents not ordered correctly" } ] testList "firstByFields" [ testTask "succeeds when a document is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "another" ] Expect.isSome doc "There should have been a document returned" Expect.equal doc.Value.Id "two" "The incorrect document was returned" } testTask "succeeds when multiple documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] Expect.isSome doc "There should have been a document returned" Expect.contains [ "five"; "four" ] doc.Value.Id "An incorrect document was returned" } testTask "succeeds when a document is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByFields PostgresDb.TableName Any [ Field.Equal "Value" "absent" ] Expect.isNone doc "There should not have been a document returned" } ] testList "firstByFieldsOrdered" [ testTask "succeeds when sorting ascending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByFieldsOrdered PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] Expect.isSome doc "There should have been a document returned" Expect.equal "five" doc.Value.Id "An incorrect document was returned" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByFieldsOrdered PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] Expect.isSome doc "There should have been a document returned" Expect.equal "four" doc.Value.Id "An incorrect document was returned" } ] testList "firstByContains" [ testTask "succeeds when a document is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByContains PostgresDb.TableName {| Value = "another" |} Expect.isSome doc "There should have been a document returned" Expect.equal doc.Value.Id "two" "The incorrect document was returned" } testTask "succeeds when multiple documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |} Expect.isSome doc "There should have been a document returned" Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned" } testTask "succeeds when a document is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByContains PostgresDb.TableName {| Value = "absent" |} Expect.isNone doc "There should not have been a document returned" } ] testList "firstByContainsOrdered" [ testTask "succeeds when sorting ascending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value" ] Expect.isSome doc "There should have been a document returned" Expect.equal "two" doc.Value.Id "An incorrect document was returned" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByContainsOrdered PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value DESC" ] Expect.isSome doc "There should have been a document returned" Expect.equal "four" doc.Value.Id "An incorrect document was returned" } ] testList "firstByJsonPath" [ testTask "succeeds when a document is found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByJsonPath PostgresDb.TableName """$.Value ? (@ == "FIRST!")""" Expect.isSome doc "There should have been a document returned" Expect.equal doc.Value.Id "one" "The incorrect document was returned" } testTask "succeeds when multiple documents are found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByJsonPath PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" Expect.isSome doc "There should have been a document returned" Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned" } testTask "succeeds when a document is not found" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByJsonPath PostgresDb.TableName """$.Id ? (@ == "nope")""" Expect.isNone doc "There should not have been a document returned" } ] testList "firstByJsonPathOrdered" [ testTask "succeeds when sorting ascending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByJsonPathOrdered PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar" ] Expect.isSome doc "There should have been a document returned" Expect.equal "two" doc.Value.Id "An incorrect document was returned" } testTask "succeeds when sorting descending" { use db = PostgresDb.BuildDb() do! loadDocs () let! doc = Find.firstByJsonPathOrdered PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar DESC" ] Expect.isSome doc "There should have been a document returned" Expect.equal "four" doc.Value.Id "An incorrect document was returned" } ] ] /// Integration tests for the Update module of the PostgreSQL library let updateTests = testList "Update" [ testList "byId" [ testTask "succeeds when a document is updated" { use db = PostgresDb.BuildDb() do! loadDocs () let testDoc = { emptyDoc with Id = "one"; Sub = Some { Foo = "blue"; Bar = "red" } } do! Update.byId PostgresDb.TableName "one" testDoc let! after = Find.byId PostgresDb.TableName "one" Expect.isSome after "There should have been a document returned post-update" Expect.equal after.Value testDoc "The updated document is not correct" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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" } } } ] testList "byFunc" [ testTask "succeeds when a document is updated" { use db = PostgresDb.BuildDb() do! loadDocs () do! Update.byFunc PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None } let! after = Find.byId PostgresDb.TableName "one" Expect.isSome after "There should have been a document returned post-update" Expect.equal after.Value { Id = "one"; Value = "le un"; NumValue = 1; Sub = None } "The updated document is not correct" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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 } } ] ] /// Integration tests for the Patch module of the PostgreSQL library let patchTests = testList "Patch" [ testList "byId" [ 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 PostgresDb.TableName "one" Expect.isSome after "There should have been a document returned post-update" Expect.equal after.Value.NumValue 44 "The updated document is not correct" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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" |} } ] testList "byFields" [ 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" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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" |} } ] testList "byContains" [ 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" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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" |} } ] testList "byJsonPath" [ 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" } testTask "succeeds when no document is updated" { use db = PostgresDb.BuildDb() 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" |} } ] ] /// Integration tests for the RemoveFields module of the PostgreSQL library let removeFieldsTests = testList "RemoveFields" [ testList "byId" [ testTask "succeeds when multiple fields are removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byId PostgresDb.TableName "two" [ "Sub"; "Value" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 1 "There should be 1 document without Value fields" } testTask "succeeds when a single field is removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byId PostgresDb.TableName "two" [ "Sub" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 0 "There should be no documents without Value fields" } 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" ] } ] testList "byFields" [ testTask "succeeds when multiple fields are removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byFields PostgresDb.TableName Any [ Field.Equal "NumValue" 17 ] [ "Sub"; "Value" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 1 "There should be 1 document without Value fields" } testTask "succeeds when a single field is removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byFields PostgresDb.TableName Any [ Field.Equal "NumValue" 17 ] [ "Sub" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 0 "There should be no documents without Value fields" } 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" ] } ] testList "byContains" [ testTask "succeeds when multiple fields are removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byContains PostgresDb.TableName {| NumValue = 17 |} [ "Sub"; "Value" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 1 "There should be 1 document without Value fields" } testTask "succeeds when a single field is removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byContains PostgresDb.TableName {| NumValue = 17 |} [ "Sub" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 0 "There should be no documents without Value fields" } 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" ] } ] testList "byJsonPath" [ testTask "succeeds when multiple fields are removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byJsonPath PostgresDb.TableName "$.NumValue ? (@ == 17)" [ "Sub"; "Value" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 1 "There should be 1 document without Value fields" } testTask "succeeds when a single field is removed" { use db = PostgresDb.BuildDb() do! loadDocs () do! RemoveFields.byJsonPath PostgresDb.TableName "$.NumValue ? (@ == 17)" [ "Sub" ] let! noSubs = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Sub" ] Expect.equal noSubs 4 "There should now be 4 documents without Sub fields" let! noValue = Count.byFields PostgresDb.TableName Any [ Field.NotExists "Value" ] Expect.equal noValue 0 "There should be no documents without Value fields" } 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" ] } ] ] /// Integration tests for the Delete module of the PostgreSQL library let deleteTests = testList "Delete" [ testList "byId" [ testTask "succeeds when a document is deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byId PostgresDb.TableName "four" let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 4 "There should have been 4 documents remaining" } testTask "succeeds when a document is not deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byId PostgresDb.TableName "thirty" let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 5 "There should have been 5 documents remaining" } ] testList "byFields" [ testTask "succeeds when documents are deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 3 "There should have been 3 documents remaining" } testTask "succeeds when documents are not deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byFields PostgresDb.TableName Any [ Field.Equal "Value" "crimson" ] let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 5 "There should have been 5 documents remaining" } ] testList "byContains" [ testTask "succeeds when documents are deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byContains PostgresDb.TableName {| Value = "purple" |} let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 3 "There should have been 3 documents remaining" } testTask "succeeds when documents are not deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byContains PostgresDb.TableName {| Value = "crimson" |} let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 5 "There should have been 5 documents remaining" } ] testList "byJsonPath" [ testTask "succeeds when documents are deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byJsonPath PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 3 "There should have been 3 documents remaining" } testTask "succeeds when documents are not deleted" { use db = PostgresDb.BuildDb() do! loadDocs () do! Delete.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 100)" let! remaining = Count.all PostgresDb.TableName Expect.equal remaining 5 "There should have been 5 documents remaining" } ] ] /// All tests for the PostgreSQL library let all = testList "Postgres" [ testList "Unit" [ parametersTests; queryTests ] testSequenced <| testList "Integration" [ configurationTests customTests definitionTests documentTests countTests existsTests findTests updateTests patchTests removeFieldsTests deleteTests ] ]