[fabric/sqlite-store] Add QueryBuilder tests and implement assertNone method
This commit is contained in:
parent
ce1f0a04f3
commit
4cc3324b46
101
packages/fabric/sqlite-store/state/query-builder.test.ts
Normal file
101
packages/fabric/sqlite-store/state/query-builder.test.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import {
|
||||
AlreadyExistsError,
|
||||
Field,
|
||||
isLike,
|
||||
Model,
|
||||
NotFoundError,
|
||||
} from "@fabric/domain";
|
||||
import { UUIDGeneratorMock } from "@fabric/domain/mocks";
|
||||
import { afterEach, beforeEach, describe, expect, test } from "@fabric/testing";
|
||||
import { SQLiteStateStore } from "./state-store.ts";
|
||||
|
||||
describe("QueryBuilder", () => {
|
||||
const models = [
|
||||
Model.entityFrom("test", {
|
||||
name: Field.string(),
|
||||
}),
|
||||
];
|
||||
|
||||
let stateStore = new SQLiteStateStore(":memory:", models);
|
||||
|
||||
beforeEach(async () => {
|
||||
stateStore = new SQLiteStateStore(":memory:", models);
|
||||
await stateStore.migrate().unwrapOrThrow();
|
||||
await stateStore.insertInto("test", {
|
||||
id: UUIDGeneratorMock.generate(),
|
||||
name: "test1",
|
||||
}).unwrapOrThrow();
|
||||
await stateStore.insertInto("test", {
|
||||
id: UUIDGeneratorMock.generate(),
|
||||
name: "test2",
|
||||
}).unwrapOrThrow();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await stateStore.close().unwrapOrThrow();
|
||||
});
|
||||
|
||||
test("select() after a where() should return valid results", async () => {
|
||||
const result = await stateStore.from("test").where({
|
||||
name: isLike("test%"),
|
||||
})
|
||||
.select().unwrapOrThrow();
|
||||
expect(result).toEqual([{
|
||||
id: expect.any(String),
|
||||
name: "test1",
|
||||
}, {
|
||||
id: expect.any(String),
|
||||
name: "test2",
|
||||
}]);
|
||||
});
|
||||
|
||||
test("selectOneOrFail() should return a single result", async () => {
|
||||
const result = await stateStore.from("test").where({ name: "test1" })
|
||||
.selectOneOrFail().unwrapOrThrow();
|
||||
expect(result).toEqual({
|
||||
id: expect.any(String),
|
||||
name: "test1",
|
||||
});
|
||||
});
|
||||
|
||||
test("selectOneOrFail() should fail if no results are found", async () => {
|
||||
const error = await stateStore.from("test").where({ name: "not-found" })
|
||||
.selectOneOrFail().unwrapErrorOrThrow();
|
||||
|
||||
expect(error).toBeInstanceOf(NotFoundError);
|
||||
});
|
||||
|
||||
test("selectOne() should return a single result", async () => {
|
||||
const result = await stateStore.from("test")
|
||||
.selectOne().unwrapOrThrow();
|
||||
|
||||
expect(result).toEqual({
|
||||
id: expect.any(String),
|
||||
name: "test1",
|
||||
});
|
||||
});
|
||||
|
||||
test("selectOne() should return undefined if no results are found", async () => {
|
||||
const result = await stateStore.from("test").where({
|
||||
name: "not-found",
|
||||
})
|
||||
.selectOne().unwrapOrThrow();
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
test("assertNone() should succeed if no results are found", async () => {
|
||||
const result = await stateStore.from("test").where({
|
||||
name: "not-found",
|
||||
}).assertNone().unwrapOrThrow();
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
test("assertNone() should fail if results are found", async () => {
|
||||
const error = await stateStore.from("test").where({ name: "test1" })
|
||||
.assertNone().unwrapErrorOrThrow();
|
||||
|
||||
expect(error).toBeInstanceOf(AlreadyExistsError);
|
||||
});
|
||||
});
|
||||
@ -1,6 +1,7 @@
|
||||
// deno-lint-ignore-file no-explicit-any
|
||||
import { AsyncResult, Keyof, Optional } from "@fabric/core";
|
||||
import {
|
||||
AlreadyExistsError,
|
||||
FilterOptions,
|
||||
Model,
|
||||
type ModelSchema,
|
||||
@ -112,18 +113,43 @@ export class QueryBuilder<T> implements StoreQuery<T> {
|
||||
limit: 1,
|
||||
},
|
||||
);
|
||||
const result = await this.db.onePrepared(
|
||||
return await this.db.onePrepared(
|
||||
stmt,
|
||||
params,
|
||||
transformRow(this.schema[this.query.from]!),
|
||||
);
|
||||
if (!result) {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
return result;
|
||||
},
|
||||
(err) => new StoreQueryError(err.message),
|
||||
);
|
||||
).flatMap((result) => {
|
||||
if (!result) {
|
||||
return AsyncResult.failWith(new NotFoundError());
|
||||
}
|
||||
return AsyncResult.ok(result);
|
||||
});
|
||||
}
|
||||
|
||||
assertNone(): AsyncResult<void, StoreQueryError | AlreadyExistsError> {
|
||||
return AsyncResult.tryFrom(
|
||||
async () => {
|
||||
const [stmt, params] = getSelectStatement(
|
||||
this.schema[this.query.from]!,
|
||||
{
|
||||
...this.query,
|
||||
limit: 1,
|
||||
},
|
||||
);
|
||||
return await this.db.onePrepared(
|
||||
stmt,
|
||||
params,
|
||||
);
|
||||
},
|
||||
(err) => new StoreQueryError(err.message),
|
||||
).flatMap((result) => {
|
||||
if (result) {
|
||||
return AsyncResult.failWith(new AlreadyExistsError());
|
||||
}
|
||||
return AsyncResult.ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user