using Expecto.CSharp; using Expecto; using Microsoft.FSharp.Core; using BitBadger.Documents.Sqlite; namespace BitBadger.Documents.Tests.CSharp; using static Runner; /// /// C# tests for the SQLite implementation of BitBadger.Documents /// public static class SqliteCSharpTests { /// /// Unit tests for the Query module of the SQLite library /// private static readonly Test QueryTests = TestList("Query", [ TestList("WhereByFields", [ TestCase("succeeds for a single field when a logical operator is passed", () => { Expect.equal( Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.GT("theField", 0).WithParameterName("@test")]), "data->>'theField' > @test", "WHERE clause not correct"); }), TestCase("succeeds for a single field when an existence operator is passed", () => { Expect.equal(Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField")]), "data->>'thatField' IS NULL", "WHERE clause not correct"); }), TestCase("succeeds for a single field when a between operator is passed", () => { Expect.equal( Sqlite.Query.WhereByFields(FieldMatch.All, [Field.BT("aField", 50, 99).WithParameterName("@range")]), "data->>'aField' BETWEEN @rangemin AND @rangemax", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with logical operators", () => { Expect.equal( Sqlite.Query.WhereByFields(FieldMatch.All, [Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")]), "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct"); }), TestCase("succeeds for any multiple fields with an existence operator", () => { Expect.equal( Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField"), Field.GE("thisField", 18)]), "data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with between operators", () => { Expect.equal( Sqlite.Query.WhereByFields(FieldMatch.All, [Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")]), "data->>'aField' BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max", "WHERE clause not correct"); }) ]), TestCase("WhereById succeeds", () => { Expect.equal(Sqlite.Query.WhereById("@id"), "data->>'Id' = @id", "WHERE clause not correct"); }), TestCase("Patch succeeds", () => { Expect.equal(Sqlite.Query.Patch(SqliteDb.TableName), $"UPDATE {SqliteDb.TableName} SET data = json_patch(data, json(@data))", "Patch query not correct"); }), TestCase("RemoveFields succeeds", () => { Expect.equal(Sqlite.Query.RemoveFields(SqliteDb.TableName, [new("@a", "a"), new("@b", "b")]), $"UPDATE {SqliteDb.TableName} SET data = json_remove(data, @a, @b)", "Field removal query not correct"); }), TestCase("ById succeeds", () => { Expect.equal(Sqlite.Query.ById("test", "14"), "test WHERE data->>'Id' = @id", "By-ID query not correct"); }), TestCase("ByFields succeeds", () => { Expect.equal(Sqlite.Query.ByFields("unit", FieldMatch.Any, [Field.GT("That", 14)]), "unit WHERE data->>'That' > @field0", "By-Field query not correct"); }), TestCase("Definition.EnsureTable succeeds", () => { Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"), "CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)", "CREATE TABLE statement not correct"); }) ]); /// /// Unit tests for the Parameters module of the SQLite library /// private static readonly Test ParametersTests = TestList("Parameters", [ TestCase("Id succeeds", () => { var theParam = Parameters.Id(7); Expect.equal(theParam.ParameterName, "@id", "The parameter name is incorrect"); Expect.equal(theParam.Value, "7", "The parameter value is incorrect"); }), TestCase("Json succeeds", () => { var theParam = Parameters.Json("@test", new { Nice = "job" }); Expect.equal(theParam.ParameterName, "@test", "The parameter name is incorrect"); Expect.equal(theParam.Value, "{\"Nice\":\"job\"}", "The parameter value is incorrect"); }), #pragma warning disable CS0618 TestCase("AddField succeeds when adding a parameter", () => { var paramList = Parameters.AddField("@field", Field.EQ("it", 99), []).ToList(); Expect.hasLength(paramList, 1, "There should have been a parameter added"); var theParam = paramList[0]; Expect.equal(theParam.ParameterName, "@field", "The parameter name is incorrect"); Expect.equal(theParam.Value, 99, "The parameter value is incorrect"); }), TestCase("AddField succeeds when not adding a parameter", () => { var paramSeq = Parameters.AddField("@it", Field.EX("Coffee"), []); Expect.isEmpty(paramSeq, "There should not have been any parameters added"); }), #pragma warning restore CS0618 TestCase("None succeeds", () => { Expect.isEmpty(Parameters.None, "The parameter list should have been empty"); }) ]); // Results are exhaustively executed in the context of other tests /// /// Documents used for integration tests /// private static readonly List TestDocuments = [ new() { Id = "one", Value = "FIRST!", NumValue = 0 }, new() { Id = "two", Value = "another", NumValue = 10, Sub = new() { Foo = "green", Bar = "blue" } }, new() { Id = "three", Value = "", NumValue = 4 }, new() { Id = "four", Value = "purple", NumValue = 17, Sub = new() { Foo = "green", Bar = "red" } }, new() { Id = "five", Value = "purple", NumValue = 18 } ]; /// /// Add the test documents to the database /// internal static async Task LoadDocs() { foreach (var doc in TestDocuments) await Document.Insert(SqliteDb.TableName, doc); } /// /// Integration tests for the Configuration module of the SQLite library /// private static readonly Test ConfigurationTests = TestCase("Configuration.UseConnectionString succeeds", () => { try { Sqlite.Configuration.UseConnectionString("Data Source=test.db"); Expect.equal(Sqlite.Configuration.connectionString, new FSharpOption("Data Source=test.db;Foreign Keys=True"), "Connection string incorrect"); } finally { Sqlite.Configuration.UseConnectionString("Data Source=:memory:"); } }); /// /// Integration tests for the Custom module of the SQLite library /// private static readonly Test CustomTests = TestList("Custom", [ TestList("Single", [ TestCase("succeeds when a row is found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Custom.Single($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id", [Parameters.Id("one")], Results.FromData); Expect.isNotNull(doc, "There should have been a document returned"); Expect.equal(doc!.Id, "one", "The incorrect document was returned"); }), TestCase("succeeds when a row is not found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Custom.Single($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id", [Parameters.Id("eighty")], Results.FromData); Expect.isNull(doc, "There should not have been a document returned"); }) ]), TestList("List", [ TestCase("succeeds when data is found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var docs = await Custom.List(Query.Find(SqliteDb.TableName), Parameters.None, Results.FromData); Expect.equal(docs.Count, 5, "There should have been 5 documents returned"); }), TestCase("succeeds when data is not found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var docs = await Custom.List( $"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value", [new("@value", 100)], Results.FromData); Expect.isEmpty(docs, "There should have been no documents returned"); }) ]), TestList("NonQuery", [ TestCase("succeeds when operating on data", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Custom.NonQuery($"DELETE FROM {SqliteDb.TableName}", Parameters.None); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 0L, "There should be no documents remaining in the table"); }), TestCase("succeeds when no data matches where clause", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Custom.NonQuery($"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value", [new("@value", 100)]); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 5L, "There should be 5 documents remaining in the table"); }) ]), TestCase("Scalar succeeds", async () => { await using var db = await SqliteDb.BuildDb(); var nbr = await Custom.Scalar("SELECT 5 AS test_value", Parameters.None, rdr => rdr.GetInt32(0)); Expect.equal(nbr, 5, "The query should have returned the number 5"); }) ]); /// /// Integration tests for the Definition module of the SQLite library /// private static readonly Test DefinitionTests = TestList("Definition", [ TestCase("EnsureTable succeeds", async () => { await using var db = await SqliteDb.BuildDb(); var exists = await ItExists("ensured"); var alsoExists = await ItExists("idx_ensured_key"); Expect.isFalse(exists, "The table should not exist already"); Expect.isFalse(alsoExists, "The key index should not exist already"); await Definition.EnsureTable("ensured"); exists = await ItExists("ensured"); alsoExists = await ItExists("idx_ensured_key"); Expect.isTrue(exists, "The table should now exist"); Expect.isTrue(alsoExists, "The key index should now exist"); return; async ValueTask ItExists(string name) { return await Custom.Scalar($"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it", [new("@name", name)], Results.ToExists); } }), TestCase("EnsureFieldIndex succeeds", async () => { await using var db = await SqliteDb.BuildDb(); var exists = await IndexExists(); Expect.isFalse(exists, "The index should not exist already"); await Definition.EnsureTable("ensured"); await Definition.EnsureFieldIndex("ensured", "test", ["Id", "Category"]); exists = await IndexExists(); Expect.isTrue(exists, "The index should now exist"); return; Task IndexExists() => Custom.Scalar( $"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it", Parameters.None, Results.ToExists); }) ]); /// /// Integration tests for the Document module of the SQLite library /// private static readonly Test DocumentTests = TestList("Document", [ TestList("Insert", [ TestCase("succeeds", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should be no documents in the table"); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "turkey", Sub = new() { Foo = "gobble", Bar = "gobble" } }); var after = await Find.All(SqliteDb.TableName); Expect.equal(after.Count, 1, "There should have been one document inserted"); }), TestCase("fails for duplicate key", async () => { await using var db = await SqliteDb.BuildDb(); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" }); try { await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" }); Expect.isTrue(false, "An exception should have been raised for duplicate document ID insert"); } catch (Exception) { // This is what is supposed to happen } }) ]), TestList("Document.Save", [ TestCase("succeeds when a document is inserted", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should be no documents in the table"); await Document.Save(SqliteDb.TableName, new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } }); var after = await Find.All(SqliteDb.TableName); Expect.equal(after.Count, 1, "There should have been one document inserted"); }), TestCase("succeeds when a document is updated", async () => { await using var db = await SqliteDb.BuildDb(); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } }); var before = await Find.ById(SqliteDb.TableName, "test"); Expect.isNotNull(before, "There should have been a document returned"); Expect.equal(before!.Id, "test", "The document is not correct"); Expect.isNotNull(before.Sub, "There should have been a sub-document"); Expect.equal(before.Sub!.Foo, "a", "The document is not correct"); Expect.equal(before.Sub.Bar, "b", "The document is not correct"); await Document.Save(SqliteDb.TableName, new JsonDocument { Id = "test" }); var after = await Find.ById(SqliteDb.TableName, "test"); Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.equal(after!.Id, "test", "The updated document is not correct"); Expect.isNull(after.Sub, "There should not have been a sub-document in the updated document"); }) ]) ]); /// /// Integration tests for the Count module of the SQLite library /// private static readonly Test CountTests = TestList("Count", [ TestCase("All succeeds", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var theCount = await Count.All(SqliteDb.TableName); Expect.equal(theCount, 5L, "There should have been 5 matching documents"); }), TestList("ByFields", [ TestCase("succeeds for numeric range", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var theCount = await Count.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.BT("NumValue", 10, 20)]); Expect.equal(theCount, 3L, "There should have been 3 matching documents"); }), TestCase("succeeds for non-numeric range", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var theCount = await Count.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.BT("Value", "aardvark", "apple")]); Expect.equal(theCount, 1L, "There should have been 1 matching document"); }) ]) ]); /// /// Integration tests for the Exists module of the SQLite library /// private static readonly Test ExistsTests = TestList("Exists", [ TestList("ById", [ TestCase("succeeds when a document exists", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var exists = await Exists.ById(SqliteDb.TableName, "three"); Expect.isTrue(exists, "There should have been an existing document"); }), TestCase("succeeds when a document does not exist", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var exists = await Exists.ById(SqliteDb.TableName, "seven"); Expect.isFalse(exists, "There should not have been an existing document"); }) ]), TestList("ByFields", [ TestCase("succeeds when documents exist", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var exists = await Exists.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.GE("NumValue", 10)]); Expect.isTrue(exists, "There should have been existing documents"); }), TestCase("succeeds when no matching documents exist", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var exists = await Exists.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Nothing", "none")]); Expect.isFalse(exists, "There should not have been any existing documents"); }) ]) ]); /// /// Integration tests for the Find module of the SQLite library /// private static readonly Test FindTests = TestList("Find", [ TestList("All", [ TestCase("succeeds when there is data", async () => { await using var db = await SqliteDb.BuildDb(); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "one", Value = "two" }); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "three", Value = "four" }); await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "five", Value = "six" }); var results = await Find.All(SqliteDb.TableName); Expect.equal(results.Count, 3, "There should have been 3 documents returned"); }), TestCase("succeeds when there is no data", async () => { await using var db = await SqliteDb.BuildDb(); var results = await Find.All(SqliteDb.TableName); Expect.isEmpty(results, "There should have been no documents returned"); }) ]), TestList("ById", [ TestCase("succeeds when a document is found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Find.ById(SqliteDb.TableName, "two"); Expect.isNotNull(doc, "There should have been a document returned"); Expect.equal(doc!.Id, "two", "The incorrect document was returned"); }), TestCase("succeeds when a document is not found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Find.ById(SqliteDb.TableName, "twenty two"); Expect.isNull(doc, "There should not have been a document returned"); }) ]), TestList("ByFields", [ TestCase("succeeds when documents are found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var docs = await Find.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.GT("NumValue", 15)]); Expect.equal(docs.Count, 2, "There should have been two documents returned"); }), TestCase("succeeds when documents are not found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var docs = await Find.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "mauve")]); Expect.isEmpty(docs, "There should have been no documents returned"); }) ]), TestList("FirstByFields", [ TestCase("succeeds when a document is found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Find.FirstByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "another")]); Expect.isNotNull(doc, "There should have been a document returned"); Expect.equal(doc!.Id, "two", "The incorrect document was returned"); }), TestCase("succeeds when multiple documents are found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Find.FirstByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Sub.Foo", "green")]); Expect.isNotNull(doc, "There should have been a document returned"); Expect.contains(["two", "four"], doc!.Id, "An incorrect document was returned"); }), TestCase("succeeds when a document is not found", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var doc = await Find.FirstByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "absent")]); Expect.isNull(doc, "There should not have been a document returned"); }) ]) ]); /// /// Integration tests for the Update module of the SQLite library /// private static readonly Test UpdateTests = TestList("Update", [ TestList("ById", [ TestCase("succeeds when a document is updated", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); var testDoc = new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } }; await Update.ById(SqliteDb.TableName, "one", testDoc); var after = await Find.ById(SqliteDb.TableName, "one"); Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.equal(after!.Id, "one", "The updated document is not correct"); Expect.isNotNull(after.Sub, "The updated document should have had a sub-document"); Expect.equal(after.Sub!.Foo, "blue", "The updated sub-document is not correct"); Expect.equal(after.Sub.Bar, "red", "The updated sub-document is not correct"); }), TestCase("succeeds when no document is updated", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should have been no documents returned"); // This not raising an exception is the test await Update.ById(SqliteDb.TableName, "test", new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } }); }) ]), TestList("ByFunc", [ TestCase("succeeds when a document is updated", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Update.ByFunc(SqliteDb.TableName, doc => doc.Id, new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); var after = await Find.ById(SqliteDb.TableName, "one"); Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.equal(after!.Id, "one", "The updated document is incorrect"); Expect.equal(after.Value, "le un", "The updated document is incorrect"); Expect.equal(after.NumValue, 1, "The updated document is incorrect"); Expect.isNull(after.Sub, "The updated document should not have a sub-document"); }), TestCase("succeeds when no document is updated", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should have been no documents returned"); // This not raising an exception is the test await Update.ByFunc(SqliteDb.TableName, doc => doc.Id, new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); }) ]), ]); /// /// Integration tests for the Patch module of the SQLite library /// private static readonly Test PatchTests = TestList("Patch", [ TestList("ById", [ TestCase("succeeds when a document is updated", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Patch.ById(SqliteDb.TableName, "one", new { NumValue = 44 }); var after = await Find.ById(SqliteDb.TableName, "one"); Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.equal(after!.Id, "one", "The updated document is not correct"); Expect.equal(after.NumValue, 44, "The updated document is not correct"); }), TestCase("succeeds when no document is updated", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should have been no documents returned"); // This not raising an exception is the test await Patch.ById(SqliteDb.TableName, "test", new { Foo = "green" }); }) ]), TestList("ByFields", [ TestCase("succeeds when a document is updated", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Patch.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "purple")], new { NumValue = 77 }); var after = await Count.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 77)]); Expect.equal(after, 2L, "There should have been 2 documents returned"); }), TestCase("succeeds when no document is updated", async () => { await using var db = await SqliteDb.BuildDb(); var before = await Find.All(SqliteDb.TableName); Expect.isEmpty(before, "There should have been no documents returned"); // This not raising an exception is the test await Patch.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "burgundy")], new { Foo = "green" }); }) ]) ]); /// /// Integration tests for the RemoveFields module of the SQLite library /// private static readonly Test RemoveFieldsTests = TestList("RemoveFields", [ TestList("ById", [ TestCase("succeeds when fields are removed", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await RemoveFields.ById(SqliteDb.TableName, "two", ["Sub", "Value"]); var updated = await Find.ById(SqliteDb.TableName, "two"); Expect.isNotNull(updated, "The updated document should have been retrieved"); Expect.equal(updated.Value, "", "The string value should have been removed"); Expect.isNull(updated.Sub, "The sub-document should have been removed"); }), TestCase("succeeds when a field is not removed", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); // This not raising an exception is the test await RemoveFields.ById(SqliteDb.TableName, "two", ["AFieldThatIsNotThere"]); }), TestCase("succeeds when no document is matched", async () => { await using var db = await SqliteDb.BuildDb(); // This not raising an exception is the test await RemoveFields.ById(SqliteDb.TableName, "two", ["Value"]); }) ]), TestList("ByFields", [ TestCase("succeeds when a field is removed", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await RemoveFields.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 17)], ["Sub"]); var updated = await Find.ById(SqliteDb.TableName, "four"); Expect.isNotNull(updated, "The updated document should have been retrieved"); Expect.isNull(updated.Sub, "The sub-document should have been removed"); }), TestCase("succeeds when a field is not removed", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); // This not raising an exception is the test await RemoveFields.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 17)], ["Nothing"]); }), TestCase("succeeds when no document is matched", async () => { await using var db = await SqliteDb.BuildDb(); // This not raising an exception is the test await RemoveFields.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.NE("Abracadabra", "apple")], ["Value"]); }) ]) ]); /// /// Integration tests for the Delete module of the SQLite library /// private static readonly Test DeleteTests = TestList("Delete", [ TestList("ById", [ TestCase("succeeds when a document is deleted", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Delete.ById(SqliteDb.TableName, "four"); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 4L, "There should have been 4 documents remaining"); }), TestCase("succeeds when a document is not deleted", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Delete.ById(SqliteDb.TableName, "thirty"); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 5L, "There should have been 5 documents remaining"); }) ]), TestList("ByFields", [ TestCase("succeeds when documents are deleted", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Delete.ByFields(SqliteDb.TableName, FieldMatch.Any, [Field.NE("Value", "purple")]); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 2L, "There should have been 2 documents remaining"); }), TestCase("succeeds when documents are not deleted", async () => { await using var db = await SqliteDb.BuildDb(); await LoadDocs(); await Delete.ByFields(SqliteDb.TableName, FieldMatch.All, [Field.EQ("Value", "crimson")]); var remaining = await Count.All(SqliteDb.TableName); Expect.equal(remaining, 5L, "There should have been 5 documents remaining"); }) ]) ]); /// /// All tests for SQLite C# functions and methods /// [Tests] public static readonly Test All = TestList("Sqlite.C#", [ TestList("Unit", [QueryTests, ParametersTests]), TestSequenced(TestList("Integration", [ ConfigurationTests, CustomTests, DefinitionTests, DocumentTests, CountTests, ExistsTests, FindTests, UpdateTests, PatchTests, RemoveFieldsTests, DeleteTests, TestCase("Clean up database", () => Sqlite.Configuration.UseConnectionString("data source=:memory:")) ])) ]); }