Finish Postgres C# tests
- Rename *JsonIndex to *DocumentIndex
This commit is contained in:
parent
a1559ad29e
commit
18ec31d16b
|
@ -18,11 +18,13 @@ module Configuration =
|
|||
let mutable private dataSourceValue : NpgsqlDataSource option = None
|
||||
|
||||
/// Register a data source to use for query execution (disposes the current one if it exists)
|
||||
[<CompiledName "UseDataSource">]
|
||||
let useDataSource source =
|
||||
if Option.isSome dataSourceValue then dataSourceValue.Value.Dispose()
|
||||
dataSourceValue <- Some source
|
||||
|
||||
/// Retrieve the currently configured data source
|
||||
[<CompiledName "DataSource">]
|
||||
let dataSource () =
|
||||
match dataSourceValue with
|
||||
| Some source -> source
|
||||
|
@ -85,8 +87,8 @@ module Query =
|
|||
Query.Definition.ensureTableFor name "JSONB"
|
||||
|
||||
/// SQL statement to create an index on JSON documents in the specified table
|
||||
[<CompiledName "EnsureJsonIndex">]
|
||||
let ensureJsonIndex (name: string) idxType =
|
||||
[<CompiledName "EnsureDocumentIndex">]
|
||||
let ensureDocumentIndex (name: string) idxType =
|
||||
let extraOps = match idxType with Full -> "" | Optimized -> " jsonb_path_ops"
|
||||
let tableName = name.Split '.' |> Array.last
|
||||
$"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})"
|
||||
|
@ -266,9 +268,9 @@ module WithProps =
|
|||
}
|
||||
|
||||
/// Create an index on documents in the specified table
|
||||
[<CompiledName "EnsureJsonIndex">]
|
||||
let ensureJsonIndex name idxType sqlProps =
|
||||
Custom.nonQuery (Query.Definition.ensureJsonIndex name idxType) [] sqlProps
|
||||
[<CompiledName "EnsureDocumentIndex">]
|
||||
let ensureDocumentIndex name idxType sqlProps =
|
||||
Custom.nonQuery (Query.Definition.ensureDocumentIndex name idxType) [] sqlProps
|
||||
|
||||
/// Create an index on field(s) within documents in the specified table
|
||||
[<CompiledName "EnsureFieldIndex">]
|
||||
|
@ -549,9 +551,9 @@ module Definition =
|
|||
WithProps.Definition.ensureTable name (fromDataSource ())
|
||||
|
||||
/// Create an index on documents in the specified table
|
||||
[<CompiledName "EnsureJsonIndex">]
|
||||
let ensureJsonIndex name idxType =
|
||||
WithProps.Definition.ensureJsonIndex name idxType (fromDataSource ())
|
||||
[<CompiledName "EnsureDocumentIndex">]
|
||||
let ensureDocumentIndex name idxType =
|
||||
WithProps.Definition.ensureDocumentIndex name idxType (fromDataSource ())
|
||||
|
||||
/// Create an index on field(s) within documents in the specified table
|
||||
[<CompiledName "EnsureFieldIndex">]
|
||||
|
|
|
@ -23,8 +23,7 @@ public static class CommonCSharpTests
|
|||
/// Unit tests
|
||||
/// </summary>
|
||||
[Tests]
|
||||
public static Test Unit =
|
||||
TestList("Common.C# Unit", new[]
|
||||
public static readonly Test Unit = TestList("Common.C# Unit", new[]
|
||||
{
|
||||
TestSequenced(
|
||||
TestList("Configuration", new[]
|
||||
|
@ -177,8 +176,7 @@ public static class CommonCSharpTests
|
|||
{
|
||||
TestCase("All succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Count.All("tbl"), "SELECT COUNT(*) AS it FROM tbl",
|
||||
"Count query not correct");
|
||||
Expect.equal(Query.Count.All("tbl"), "SELECT COUNT(*) AS it FROM tbl", "Count query not correct");
|
||||
}),
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using Expecto.CSharp;
|
||||
using Expecto;
|
||||
using BitBadger.Documents.Postgres;
|
||||
using Npgsql.FSharp;
|
||||
using ThrowawayDb.Postgres;
|
||||
|
||||
namespace BitBadger.Documents.Tests.CSharp;
|
||||
|
||||
using static CommonExtensionsAndTypesForNpgsqlFSharp;
|
||||
using static Runner;
|
||||
|
||||
/// <summary>
|
||||
|
@ -12,24 +13,33 @@ using static Runner;
|
|||
/// </summary>
|
||||
public class PostgresCSharpTests
|
||||
{
|
||||
public static Test Unit =
|
||||
TestList("Unit", new[]
|
||||
/// <summary>
|
||||
/// Tests which do not hit the database
|
||||
/// </summary>
|
||||
private static readonly Test Unit = TestList("Unit", new[]
|
||||
{
|
||||
TestList("Parameters", new[]
|
||||
{
|
||||
TestCase("Id succeeds", () => {
|
||||
Expect.equal(Parameters.Id(88).Item1, "@id", "ID parameter not constructed correctly");
|
||||
TestCase("Id succeeds", () =>
|
||||
{
|
||||
var it = Parameters.Id(88);
|
||||
Expect.equal(it.Item1, "@id", "ID parameter not constructed correctly");
|
||||
Expect.equal(it.Item2, Sql.@string("88"), "ID parameter value incorrect");
|
||||
}),
|
||||
TestCase("Json succeeds", () =>
|
||||
{
|
||||
Expect.equal(Parameters.Json("@test", new { Something = "good" }).Item1, "@test",
|
||||
"JSON parameter not constructed correctly");
|
||||
var it = Parameters.Json("@test", new { Something = "good" });
|
||||
Expect.equal(it.Item1, "@test", "JSON parameter not constructed correctly");
|
||||
Expect.equal(it.Item2, Sql.jsonb("{\"Something\":\"good\"}"), "JSON parameter value incorrect");
|
||||
}),
|
||||
TestCase("Field succeeds", () =>
|
||||
{
|
||||
Expect.equal(Parameters.Field(242).Item1, "@field", "Field parameter not constructed correctly");
|
||||
var it = Parameters.Field(242);
|
||||
Expect.equal(it.Item1, "@field", "Field parameter not constructed correctly");
|
||||
Expect.isTrue(it.Item2.IsParameter, "Field parameter value incorrect");
|
||||
}),
|
||||
TestCase("None succeeds", () => {
|
||||
TestCase("None succeeds", () =>
|
||||
{
|
||||
Expect.isEmpty(Parameters.None, "The no-params sequence should be empty");
|
||||
})
|
||||
}),
|
||||
|
@ -43,16 +53,16 @@ public class PostgresCSharpTests
|
|||
$"CREATE TABLE IF NOT EXISTS {PostgresDb.TableName} (data JSONB NOT NULL)",
|
||||
"CREATE TABLE statement not constructed correctly");
|
||||
}),
|
||||
TestCase("EnsureJsonIndex succeeds for full index", () =>
|
||||
TestCase("EnsureDocumentIndex succeeds for full index", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Definition.EnsureJsonIndex("schema.tbl", DocumentIndex.Full),
|
||||
Expect.equal(Postgres.Query.Definition.EnsureDocumentIndex("schema.tbl", DocumentIndex.Full),
|
||||
"CREATE INDEX IF NOT EXISTS idx_tbl_document ON schema.tbl USING GIN (data)",
|
||||
"CREATE INDEX statement not constructed correctly");
|
||||
}),
|
||||
TestCase("EnsureJsonIndex succeeds for JSONB Path Ops index", () =>
|
||||
TestCase("EnsureDocumentIndex succeeds for JSONB Path Ops index", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Postgres.Query.Definition.EnsureJsonIndex(PostgresDb.TableName, DocumentIndex.Optimized),
|
||||
Postgres.Query.Definition.EnsureDocumentIndex(PostgresDb.TableName, DocumentIndex.Optimized),
|
||||
string.Format(
|
||||
"CREATE INDEX IF NOT EXISTS idx_{0}_document ON {0} USING GIN (data jsonb_path_ops)",
|
||||
PostgresDb.TableName),
|
||||
|
@ -168,13 +178,794 @@ public class PostgresCSharpTests
|
|||
new() { Id = "five", Value = "purple", NumValue = 18 }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Add the test documents to the database
|
||||
/// </summary>
|
||||
internal static async Task LoadDocs()
|
||||
{
|
||||
foreach (var doc in TestDocuments) await Document.Insert(SqliteDb.TableName, doc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for the PostgreSQL library
|
||||
/// </summary>
|
||||
private static readonly Test Integration = TestList("Integration", new[]
|
||||
{
|
||||
TestList("Configuration", new[]
|
||||
{
|
||||
TestCase("UseDataSource disposes existing source", () =>
|
||||
{
|
||||
using var db1 = ThrowawayDatabase.Create(PostgresDb.ConnStr.Value);
|
||||
var source = PostgresDb.MkDataSource(db1.ConnectionString);
|
||||
Postgres.Configuration.UseDataSource(source);
|
||||
|
||||
using var db2 = ThrowawayDatabase.Create(PostgresDb.ConnStr.Value);
|
||||
Postgres.Configuration.UseDataSource(PostgresDb.MkDataSource(db2.ConnectionString));
|
||||
try
|
||||
{
|
||||
_ = source.OpenConnection();
|
||||
Expect.isTrue(false, "Data source should have been disposed");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// This is what should have happened
|
||||
}
|
||||
}),
|
||||
TestCase("DataSource returns configured data source", () =>
|
||||
{
|
||||
using var db = ThrowawayDatabase.Create(PostgresDb.ConnStr.Value);
|
||||
var source = PostgresDb.MkDataSource(db.ConnectionString);
|
||||
Postgres.Configuration.UseDataSource(source);
|
||||
|
||||
Expect.isTrue(ReferenceEquals(source, Postgres.Configuration.DataSource()),
|
||||
"Data source should have been the same");
|
||||
})
|
||||
}),
|
||||
TestList("Custom", new[]
|
||||
{
|
||||
TestList("List", new[]
|
||||
{
|
||||
TestCase("succeeds when data is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Custom.List(Query.SelectFromTable(PostgresDb.TableName), Parameters.None,
|
||||
Results.FromData<JsonDocument>);
|
||||
Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
|
||||
}),
|
||||
TestCase("succeeds when data is not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Custom.List(
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
|
||||
new[] { Tuple.Create("@path", Sql.@string("$.NumValue ? (@ > 100)")) },
|
||||
Results.FromData<JsonDocument>);
|
||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||
})
|
||||
}),
|
||||
TestList("Single", new[]
|
||||
{
|
||||
TestCase("succeeds when a row is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Custom.Single($"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Tuple.Create("@id", Sql.@string("one")) }, Results.FromData<JsonDocument>);
|
||||
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 = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Custom.Single($"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Tuple.Create("@id", Sql.@string("eighty")) }, Results.FromData<JsonDocument>);
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
}),
|
||||
TestList("NonQuery", new[]
|
||||
{
|
||||
TestCase("succeeds when operating on data", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Custom.NonQuery($"DELETE FROM {PostgresDb.TableName}", Parameters.None);
|
||||
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 0, "There should be no documents remaining in the table");
|
||||
}),
|
||||
TestCase("succeeds when no data matches where clause", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Custom.NonQuery($"DELETE FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
|
||||
new[] { Tuple.Create("@path", Sql.@string("$.NumValue ? (@ > 100)")) });
|
||||
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 5, "There should be 5 documents remaining in the table");
|
||||
})
|
||||
}),
|
||||
TestCase("Scalar succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var nbr = await Custom.Scalar("SELECT 5 AS test_value", Parameters.None, row => row.@int("test_value"));
|
||||
Expect.equal(nbr, 5, "The query should have returned the number 5");
|
||||
})
|
||||
}),
|
||||
TestList("Definition", new[]
|
||||
{
|
||||
TestCase("EnsureTable succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
var tableExists = () => Custom.Scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'ensured') AS it", Parameters.None,
|
||||
Results.ToExists);
|
||||
var keyExists = () => Custom.Scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_key') AS it", Parameters.None,
|
||||
Results.ToExists);
|
||||
|
||||
var exists = await tableExists();
|
||||
var alsoExists = await keyExists();
|
||||
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 tableExists();
|
||||
alsoExists = await keyExists();
|
||||
Expect.isTrue(exists, "The table should now exist");
|
||||
Expect.isTrue(alsoExists, "The key index should now exist");
|
||||
}),
|
||||
TestCase("EnsureDocumentIndex succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
var indexExists = () => Custom.Scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_document') AS it",
|
||||
Parameters.None, Results.ToExists);
|
||||
|
||||
var exists = await indexExists();
|
||||
Expect.isFalse(exists, "The index should not exist already");
|
||||
|
||||
await Definition.EnsureTable("ensured");
|
||||
await Definition.EnsureDocumentIndex("ensured", DocumentIndex.Optimized);
|
||||
exists = await indexExists();
|
||||
Expect.isTrue(exists, "The index should now exist");
|
||||
}),
|
||||
TestCase("EnsureFieldIndex succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
var indexExists = () => Custom.Scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_test') AS it", Parameters.None,
|
||||
Results.ToExists);
|
||||
|
||||
var exists = await indexExists();
|
||||
Expect.isFalse(exists, "The index should not exist already");
|
||||
|
||||
await Definition.EnsureTable("ensured");
|
||||
await Definition.EnsureFieldIndex("ensured", "test", new[] { "Id", "Category" });
|
||||
exists = await indexExists();
|
||||
Expect.isTrue(exists, "The index should now exist");
|
||||
})
|
||||
}),
|
||||
TestList("Document", new[]
|
||||
{
|
||||
TestList("Insert", new[]
|
||||
{
|
||||
TestCase("succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should be no documents in the table");
|
||||
|
||||
await Document.Insert(PostgresDb.TableName,
|
||||
new JsonDocument { Id = "turkey", Sub = new() { Foo = "gobble", Bar = "gobble" } });
|
||||
var after = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(after, 1, "There should have been one document inserted");
|
||||
}),
|
||||
TestCase("fails for duplicate key", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await Document.Insert(PostgresDb.TableName, new JsonDocument { Id = "test" });
|
||||
try
|
||||
{
|
||||
await Document.Insert(PostgresDb.TableName, new JsonDocument { Id = "test" });
|
||||
Expect.isTrue(false, "An exception should have been raised for duplicate document ID insert");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// This is what should have happened
|
||||
}
|
||||
})
|
||||
}),
|
||||
TestList("Save", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is inserted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should be no documents in the table");
|
||||
|
||||
await Document.Save(PostgresDb.TableName,
|
||||
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
||||
var after = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(after, 1, "There should have been one document inserted");
|
||||
}),
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await Document.Insert(PostgresDb.TableName,
|
||||
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
||||
|
||||
var before = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "test");
|
||||
Expect.isNotNull(before, "There should have been a document returned");
|
||||
Expect.equal(before.Id, "test", "The document is not correct");
|
||||
|
||||
before.Sub = new() { Foo = "c", Bar = "d" };
|
||||
await Document.Save(PostgresDb.TableName, before);
|
||||
var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "test");
|
||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||
Expect.equal(after.Id, "test", "The document is not correct");
|
||||
Expect.equal(after.Sub!.Foo, "c", "The updated document is not correct");
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Count", new[]
|
||||
{
|
||||
TestCase("All succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var theCount = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(theCount, 5, "There should have been 5 matching documents");
|
||||
}),
|
||||
TestCase("ByField succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var theCount = await Count.ByField(PostgresDb.TableName, "Value", Op.EQ, "purple");
|
||||
Expect.equal(theCount, 2, "There should have been 2 matching documents");
|
||||
}),
|
||||
TestCase("ByContains succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var theCount = await Count.ByContains(PostgresDb.TableName, new { Value = "purple" });
|
||||
Expect.equal(theCount, 2, "There should have been 2 matching documents");
|
||||
}),
|
||||
TestCase("ByJsonPath succeeds", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var theCount = await Count.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 5)");
|
||||
Expect.equal(theCount, 3, "There should have been 3 matching documents");
|
||||
})
|
||||
}),
|
||||
TestList("Exists", new[]
|
||||
{
|
||||
TestList("ById", new[]
|
||||
{
|
||||
TestCase("succeeds when a document exists", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ById(PostgresDb.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 = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ById(PostgresDb.TableName, "seven");
|
||||
Expect.isFalse(exists, "There should not have been an existing document");
|
||||
})
|
||||
}),
|
||||
TestList("ByField", new[]
|
||||
{
|
||||
TestCase("succeeds when documents exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByField(PostgresDb.TableName, "Sub", Op.NEX, "");
|
||||
Expect.isTrue(exists, "There should have been existing documents");
|
||||
}),
|
||||
TestCase("succeeds when documents do not exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByField(PostgresDb.TableName, "NumValue", Op.EQ, "six");
|
||||
Expect.isFalse(exists, "There should not have been existing documents");
|
||||
})
|
||||
}),
|
||||
TestList("ByContains", new[]
|
||||
{
|
||||
TestCase("succeeds when documents exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByContains(PostgresDb.TableName, new { NumValue = 10 });
|
||||
Expect.isTrue(exists, "There should have been existing documents");
|
||||
}),
|
||||
TestCase("succeeds when no matching documents exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByContains(PostgresDb.TableName, new { Nothing = "none" });
|
||||
Expect.isFalse(exists, "There should not have been any existing documents");
|
||||
})
|
||||
}),
|
||||
TestList("ByJsonPath", new[] {
|
||||
TestCase("succeeds when documents exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByJsonPath(PostgresDb.TableName, "$.Sub.Foo ? (@ == \"green\")");
|
||||
Expect.isTrue(exists, "There should have been existing documents");
|
||||
}),
|
||||
TestCase("succeeds when no matching documents exist", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var exists = await Exists.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 1000)");
|
||||
Expect.isFalse(exists, "There should not have been any existing documents");
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Find", new[]
|
||||
{
|
||||
TestList("All", new[]
|
||||
{
|
||||
TestCase("succeeds when there is data", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
await Document.Insert(PostgresDb.TableName, new SubDocument { Foo = "one", Bar = "two" });
|
||||
await Document.Insert(PostgresDb.TableName, new SubDocument { Foo = "three", Bar = "four" });
|
||||
await Document.Insert(PostgresDb.TableName, new SubDocument { Foo = "five", Bar = "six" });
|
||||
|
||||
var results = await Find.All<SubDocument>(PostgresDb.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 = PostgresDb.BuildDb();
|
||||
var results = await Find.All<SubDocument>(PostgresDb.TableName);
|
||||
Expect.isEmpty(results, "There should have been no documents returned");
|
||||
})
|
||||
}),
|
||||
TestList("ById", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.ById<string, JsonDocument>(PostgresDb.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 = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "three hundred eighty-seven");
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
}),
|
||||
TestList("ByField", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByField<JsonDocument>(PostgresDb.TableName, "Value", Op.EQ, "another");
|
||||
Expect.equal(docs.Count, 1, "There should have been one document returned");
|
||||
}),
|
||||
TestCase("succeeds when documents are not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByField<JsonDocument>(PostgresDb.TableName, "Value", Op.EQ, "mauve");
|
||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||
})
|
||||
}),
|
||||
TestList("ByContains", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByContains<JsonDocument>(PostgresDb.TableName,
|
||||
new { Sub = new { Foo = "green" } });
|
||||
Expect.equal(docs.Count, 2, "There should have been two documents returned");
|
||||
}),
|
||||
TestCase("succeeds when documents are not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByContains<JsonDocument>(PostgresDb.TableName, new { Value = "mauve" });
|
||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||
})
|
||||
}),
|
||||
TestList("ByJsonPath", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByJsonPath<JsonDocument>(PostgresDb.TableName, "$.NumValue ? (@ < 15)");
|
||||
Expect.equal(docs.Count, 3, "There should have been 3 documents returned");
|
||||
}),
|
||||
TestCase("succeeds when documents are not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var docs = await Find.ByJsonPath<JsonDocument>(PostgresDb.TableName, "$.NumValue ? (@ < 0)");
|
||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||
})
|
||||
}),
|
||||
TestList("FirstByField", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByField<JsonDocument>(PostgresDb.TableName, "Value", Op.EQ, "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 = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByField<JsonDocument>(PostgresDb.TableName, "Value", Op.EQ, "purple");
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.contains(new[] { "five", "four" }, doc.Id, "An incorrect document was returned");
|
||||
}),
|
||||
TestCase("succeeds when a document is not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByField<JsonDocument>(PostgresDb.TableName, "Value", Op.EQ, "absent");
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
}),
|
||||
TestList("FirstByContains", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByContains<JsonDocument>(PostgresDb.TableName, new { 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 = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByContains<JsonDocument>(PostgresDb.TableName,
|
||||
new { Sub = new { Foo = "green" } });
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.contains(new[] { "two", "four" }, doc.Id, "An incorrect document was returned");
|
||||
}),
|
||||
TestCase("succeeds when a document is not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByContains<JsonDocument>(PostgresDb.TableName, new { Value = "absent" });
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
}),
|
||||
TestList("FirstByJsonPath", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByJsonPath<JsonDocument>(PostgresDb.TableName,
|
||||
"$.Value ? (@ == \"FIRST!\")");
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.equal(doc.Id, "one", "The incorrect document was returned");
|
||||
}),
|
||||
TestCase("succeeds when multiple documents are found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByJsonPath<JsonDocument>(PostgresDb.TableName,
|
||||
"$.Sub.Foo ? (@ == \"green\")");
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.contains(new[] { "two", "four" }, doc.Id, "An incorrect document was returned");
|
||||
}),
|
||||
TestCase("succeeds when a document is not found", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Find.FirstByJsonPath<JsonDocument>(PostgresDb.TableName, "$.Id ? (@ == \"nope\")");
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Update", new[]
|
||||
{
|
||||
TestList("Full", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.Full(PostgresDb.TableName, "one",
|
||||
new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } });
|
||||
var after = await Find.ById<string, JsonDocument>(PostgresDb.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 (ID)");
|
||||
Expect.equal(after.Value, "", "The updated document is not correct (Value)");
|
||||
Expect.equal(after.NumValue, 0, "The updated document is not correct (NumValue)");
|
||||
Expect.isNotNull(after.Sub, "The updated document should have had a sub-document");
|
||||
Expect.equal(after.Sub!.Foo, "blue", "The updated document is not correct (Sub.Foo)");
|
||||
Expect.equal(after.Sub.Bar, "red", "The updated document is not correct (Sub.Bar)");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.Full(PostgresDb.TableName, "test",
|
||||
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
|
||||
})
|
||||
}),
|
||||
TestList("FullFunc", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.FullFunc(PostgresDb.TableName, doc => doc.Id,
|
||||
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
||||
var after = await Find.ById<string, JsonDocument>(PostgresDb.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 (ID)");
|
||||
Expect.equal(after.Value, "le un", "The updated document is not correct (Value)");
|
||||
Expect.equal(after.NumValue, 1, "The updated document is not correct (NumValue)");
|
||||
Expect.isNull(after.Sub, "The updated document should not have had a sub-document");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.FullFunc(PostgresDb.TableName, doc => doc.Id,
|
||||
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
||||
})
|
||||
}),
|
||||
TestList("PartialById", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.PartialById(PostgresDb.TableName, "one", new { NumValue = 44 });
|
||||
var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one");
|
||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||
Expect.equal(after.NumValue, 44, "The updated document is not correct");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.PartialById(PostgresDb.TableName, "test", new { Foo = "green" });
|
||||
})
|
||||
}),
|
||||
TestList("PartialByField", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.PartialByField(PostgresDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
|
||||
var after = await Count.ByField(PostgresDb.TableName, "NumValue", Op.EQ, "77");
|
||||
Expect.equal(after, 2, "There should have been 2 documents returned");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.PartialByField(PostgresDb.TableName, "Value", Op.EQ, "burgundy",
|
||||
new { Foo = "green" });
|
||||
})
|
||||
}),
|
||||
TestList("PartialByContains", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.PartialByContains(PostgresDb.TableName, new { Value = "purple" },
|
||||
new { NumValue = 77 });
|
||||
var after = await Count.ByContains(PostgresDb.TableName, new { NumValue = 77 });
|
||||
Expect.equal(after, 2, "There should have been 2 documents returned");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.PartialByContains(PostgresDb.TableName, new { Value = "burgundy" },
|
||||
new { Foo = "green" });
|
||||
})
|
||||
}),
|
||||
TestList("PartialByJsonPath", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Update.PartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)",
|
||||
new { NumValue = 1000 });
|
||||
var after = await Count.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)");
|
||||
Expect.equal(after, 2, "There should have been 2 documents returned");
|
||||
}),
|
||||
TestCase("succeeds when no document is updated", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
|
||||
var before = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(before, 0, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await Update.PartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" });
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Delete", new[]
|
||||
{
|
||||
TestList("ById", new[]
|
||||
{
|
||||
TestCase("succeeds when a document is deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ById(PostgresDb.TableName, "four");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 4, "There should have been 4 documents remaining");
|
||||
}),
|
||||
TestCase("succeeds when a document is not deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ById(PostgresDb.TableName, "thirty");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 5, "There should have been 5 documents remaining");
|
||||
})
|
||||
}),
|
||||
TestList("ByField", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByField(PostgresDb.TableName, "Value", Op.EQ, "purple");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 3, "There should have been 3 documents remaining");
|
||||
}),
|
||||
TestCase("succeeds when documents are not deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByField(PostgresDb.TableName, "Value", Op.EQ, "crimson");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 5, "There should have been 5 documents remaining");
|
||||
})
|
||||
}),
|
||||
TestList("ByContains", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByContains(PostgresDb.TableName, new { Value = "purple" });
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 3, "There should have been 3 documents remaining");
|
||||
}),
|
||||
TestCase("succeeds when documents are not deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByContains(PostgresDb.TableName, new { Value = "crimson" });
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 5, "There should have been 5 documents remaining");
|
||||
})
|
||||
}),
|
||||
TestList("ByJsonPath", new[]
|
||||
{
|
||||
TestCase("succeeds when documents are deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByJsonPath(PostgresDb.TableName, "$.Sub.Foo ? (@ == \"green\")");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 3, "There should have been 3 documents remaining");
|
||||
}),
|
||||
TestCase("succeeds when documents are not deleted", async () =>
|
||||
{
|
||||
await using var db = PostgresDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Delete.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 100)");
|
||||
var remaining = await Count.All(PostgresDb.TableName);
|
||||
Expect.equal(remaining, 5, "There should have been 5 documents remaining");
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// All Postgres C# tests
|
||||
/// </summary>
|
||||
public static Test All = TestList("Postgres.C#", new[] { Unit });
|
||||
[Tests]
|
||||
public static readonly Test All = TestList("Postgres.C#", new[] { Unit, TestSequenced(Integration) });
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ public static class PostgresDb
|
|||
Sql.executeNonQuery(Sql.query(Postgres.Query.Definition.EnsureTable(TableName), sqlProps));
|
||||
Sql.executeNonQuery(Sql.query(Query.Definition.EnsureKey(TableName), sqlProps));
|
||||
|
||||
Postgres.Configuration.useDataSource(MkDataSource(database.ConnectionString));
|
||||
Postgres.Configuration.UseDataSource(MkDataSource(database.ConnectionString));
|
||||
|
||||
return new ThrowawayPostgresDb(database);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,11 @@ public static class SqliteCSharpExtensionTests
|
|||
{
|
||||
private static Task LoadDocs() => SqliteCSharpTests.LoadDocs();
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for the SQLite extension methods
|
||||
/// </summary>
|
||||
[Tests]
|
||||
public static Test Integration =
|
||||
TestList("Extensions", new[]
|
||||
public static readonly Test Integration = TestList("Extensions", new[]
|
||||
{
|
||||
TestList("CustomSingle", new[]
|
||||
{
|
||||
|
@ -26,8 +28,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await conn.CustomSingle(
|
||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Parameters.Id("one") }, Results.FromData<JsonDocument>);
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.equal(doc!.Id, "one", "The incorrect document was returned");
|
||||
|
@ -38,8 +39,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await conn.CustomSingle(
|
||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Parameters.Id("eighty") }, Results.FromData<JsonDocument>);
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
|
@ -87,8 +87,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
await conn.CustomNonQuery(
|
||||
$"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||
await conn.CustomNonQuery($"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||
new[] { new SqliteParameter("@value", 100) });
|
||||
|
||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||
|
@ -325,8 +324,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ,
|
||||
"another");
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "another");
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
|
||||
}),
|
||||
|
@ -336,8 +334,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ,
|
||||
"green");
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green");
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
|
||||
}),
|
||||
|
@ -347,8 +344,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ,
|
||||
"absent");
|
||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "absent");
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
}),
|
||||
|
@ -443,8 +439,7 @@ public static class SqliteCSharpExtensionTests
|
|||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
await LoadDocs();
|
||||
|
||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "purple",
|
||||
new { NumValue = 77 });
|
||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
|
||||
var after = await conn.CountByField(SqliteDb.TableName, "NumValue", Op.EQ, 77);
|
||||
Expect.equal(after, 2L, "There should have been 2 documents returned");
|
||||
}),
|
||||
|
@ -456,8 +451,7 @@ public static class SqliteCSharpExtensionTests
|
|||
Expect.isEmpty(before, "There should have been no documents returned");
|
||||
|
||||
// This not raising an exception is the test
|
||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy",
|
||||
new { Foo = "green" });
|
||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
|
||||
})
|
||||
}),
|
||||
TestList("DeleteById", new[]
|
||||
|
|
|
@ -16,9 +16,7 @@ public static class SqliteCSharpTests
|
|||
/// <summary>
|
||||
/// Unit tests for the SQLite library
|
||||
/// </summary>
|
||||
[Tests]
|
||||
public static Test Unit =
|
||||
TestList("Unit", new[]
|
||||
private static readonly Test Unit = TestList("Unit", new[]
|
||||
{
|
||||
TestList("Query", new[]
|
||||
{
|
||||
|
@ -80,14 +78,15 @@ public static class SqliteCSharpTests
|
|||
new() { Id = "five", Value = "purple", NumValue = 18 }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Add the test documents to the database
|
||||
/// </summary>
|
||||
internal static async Task LoadDocs()
|
||||
{
|
||||
foreach (var doc in TestDocuments) await Document.Insert(SqliteDb.TableName, doc);
|
||||
}
|
||||
|
||||
[Tests]
|
||||
public static Test Integration =
|
||||
TestList("Integration", new[]
|
||||
private static readonly Test Integration = TestList("Integration", new[]
|
||||
{
|
||||
TestCase("Configuration.UseConnectionString succeeds", () =>
|
||||
{
|
||||
|
@ -95,8 +94,7 @@ public static class SqliteCSharpTests
|
|||
{
|
||||
Sqlite.Configuration.UseConnectionString("Data Source=test.db");
|
||||
Expect.equal(Sqlite.Configuration.connectionString,
|
||||
new FSharpOption<string>("Data Source=test.db;Foreign Keys=True"),
|
||||
"Connection string incorrect");
|
||||
new FSharpOption<string>("Data Source=test.db;Foreign Keys=True"), "Connection string incorrect");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -105,15 +103,14 @@ public static class SqliteCSharpTests
|
|||
}),
|
||||
TestList("Custom", new[]
|
||||
{
|
||||
TestList("Single", new []
|
||||
TestList("Single", new[]
|
||||
{
|
||||
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",
|
||||
var doc = await Custom.Single($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Parameters.Id("one") }, Results.FromData<JsonDocument>);
|
||||
Expect.isNotNull(doc, "There should have been a document returned");
|
||||
Expect.equal(doc!.Id, "one", "The incorrect document was returned");
|
||||
|
@ -123,8 +120,7 @@ public static class SqliteCSharpTests
|
|||
await using var db = await SqliteDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
var doc = await Custom.Single(
|
||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
var doc = await Custom.Single($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||
new[] { Parameters.Id("eighty") }, Results.FromData<JsonDocument>);
|
||||
Expect.isNull(doc, "There should not have been a document returned");
|
||||
})
|
||||
|
@ -168,8 +164,7 @@ public static class SqliteCSharpTests
|
|||
await using var db = await SqliteDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await Custom.NonQuery(
|
||||
$"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||
await Custom.NonQuery($"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||
new[] { new SqliteParameter("@value", 100) });
|
||||
|
||||
var remaining = await Count.All(SqliteDb.TableName);
|
||||
|
@ -207,8 +202,7 @@ public static class SqliteCSharpTests
|
|||
{
|
||||
var result = await Custom.Scalar(
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
|
||||
new SqliteParameter[] { new("@name", name) },
|
||||
rdr => rdr.GetInt64(0));
|
||||
new SqliteParameter[] { new("@name", name) }, rdr => rdr.GetInt64(0));
|
||||
return result > 0L;
|
||||
}
|
||||
})
|
||||
|
@ -582,5 +576,6 @@ public static class SqliteCSharpTests
|
|||
/// <summary>
|
||||
/// All tests for SQLite C# functions and methods
|
||||
/// </summary>
|
||||
[Tests]
|
||||
public static readonly Test All = TestList("Sqlite.C#", new[] { Unit, TestSequenced(Integration) });
|
||||
}
|
||||
|
|
|
@ -39,15 +39,15 @@ let unitTests =
|
|||
$"CREATE TABLE IF NOT EXISTS {PostgresDb.TableName} (data JSONB NOT NULL)"
|
||||
"CREATE TABLE statement not constructed correctly"
|
||||
}
|
||||
test "ensureJsonIndex succeeds for full index" {
|
||||
test "ensureDocumentIndex succeeds for full index" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureJsonIndex "schema.tbl" Full)
|
||||
(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 "ensureJsonIndex succeeds for JSONB Path Ops index" {
|
||||
test "ensureDocumentIndex succeeds for JSONB Path Ops index" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureJsonIndex PostgresDb.TableName Optimized)
|
||||
(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"
|
||||
|
@ -266,7 +266,7 @@ let integrationTests =
|
|||
Expect.isTrue exists' "The table should now exist"
|
||||
Expect.isTrue alsoExists' "The key index should now exist"
|
||||
}
|
||||
testTask "ensureJsonIndex succeeds" {
|
||||
testTask "ensureDocumentIndex succeeds" {
|
||||
use db = PostgresDb.BuildDb()
|
||||
let indexExists () =
|
||||
Custom.scalar
|
||||
|
@ -278,7 +278,7 @@ let integrationTests =
|
|||
Expect.isFalse exists "The index should not exist already"
|
||||
|
||||
do! Definition.ensureTable "ensured"
|
||||
do! Definition.ensureJsonIndex "ensured" Optimized
|
||||
do! Definition.ensureDocumentIndex "ensured" Optimized
|
||||
let! exists' = indexExists ()
|
||||
Expect.isTrue exists' "The index should now exist"
|
||||
}
|
||||
|
@ -730,7 +730,7 @@ let integrationTests =
|
|||
Expect.equal before 0 "There should have been no documents returned"
|
||||
|
||||
// This not raising an exception is the test
|
||||
do! Update.partialByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
|
||||
do! Update.partialByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue
Block a user