Skip to content

Commit ed9ddd2

Browse files
committed
Add tests for createQuery type inference
Introduces tests to verify that createQuery infers correct types for various query scenarios, including selectAll, specific columns, foreign keys, different tables, and usage of $narrowType. Ensures that both user-defined and system columns are properly typed in query results.
1 parent 6df3ba9 commit ed9ddd2

1 file changed

Lines changed: 101 additions & 14 deletions

File tree

packages/common/test/local-first/Evolu.test.ts

Lines changed: 101 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -315,22 +315,16 @@ test("init", async () => {
315315
},
316316
"dbSchema": {
317317
"indexes": [],
318-
"tables": [
319-
{
320-
"columns": [
321-
"title",
322-
"isCompleted",
323-
"categoryId",
324-
],
325-
"name": "todo",
318+
"tables": {
319+
"todo": Set {
320+
"title",
321+
"isCompleted",
322+
"categoryId",
326323
},
327-
{
328-
"columns": [
329-
"name",
330-
],
331-
"name": "todoCategory",
324+
"todoCategory": Set {
325+
"name",
332326
},
333-
],
327+
},
334328
},
335329
"type": "init",
336330
},
@@ -1257,3 +1251,96 @@ describe("useOwner", () => {
12571251
expect(postMessageCalls[0]).toEqual(ownerMessage(testOwner, false));
12581252
});
12591253
});
1254+
1255+
describe("createQuery type inference", () => {
1256+
test("Query.Row infers correct types for simple selectAll", async () => {
1257+
const { evolu } = await testCreateEvolu();
1258+
1259+
const _allTodosQuery = evolu.createQuery((db) =>
1260+
db.selectFrom("todo").selectAll(),
1261+
);
1262+
1263+
type AllTodosRow = typeof _allTodosQuery.Row;
1264+
1265+
// Verify the Row type has the correct shape including user-defined columns
1266+
expectTypeOf<AllTodosRow>().toExtend<{
1267+
readonly id: TodoId;
1268+
readonly title: NonEmptyString50 | null;
1269+
readonly isCompleted: SqliteBoolean | null;
1270+
readonly categoryId: TodoCategoryId | null;
1271+
}>();
1272+
1273+
// Verify system columns are included
1274+
expectTypeOf<AllTodosRow>().toHaveProperty("createdAt");
1275+
expectTypeOf<AllTodosRow>().toHaveProperty("updatedAt");
1276+
expectTypeOf<AllTodosRow>().toHaveProperty("isDeleted");
1277+
expectTypeOf<AllTodosRow>().toHaveProperty("ownerId");
1278+
});
1279+
1280+
test("Query.Row infers correct types for select with specific columns", async () => {
1281+
const { evolu } = await testCreateEvolu();
1282+
1283+
const _todoTitlesQuery = evolu.createQuery((db) =>
1284+
db.selectFrom("todo").select(["id", "title"]),
1285+
);
1286+
1287+
type TodoTitlesRow = typeof _todoTitlesQuery.Row;
1288+
1289+
// Should only have selected columns
1290+
expectTypeOf<TodoTitlesRow["id"]>().toEqualTypeOf<TodoId>();
1291+
expectTypeOf<
1292+
TodoTitlesRow["title"]
1293+
>().toEqualTypeOf<NonEmptyString50 | null>();
1294+
});
1295+
1296+
test("Query.Row infers correct types for table with foreign key", async () => {
1297+
const { evolu } = await testCreateEvolu();
1298+
1299+
const _todosWithCategoryQuery = evolu.createQuery((db) =>
1300+
db.selectFrom("todo").select(["id", "title", "categoryId"]),
1301+
);
1302+
1303+
type TodosWithCategoryRow = typeof _todosWithCategoryQuery.Row;
1304+
1305+
expectTypeOf<TodosWithCategoryRow["id"]>().toEqualTypeOf<TodoId>();
1306+
expectTypeOf<
1307+
TodosWithCategoryRow["title"]
1308+
>().toEqualTypeOf<NonEmptyString50 | null>();
1309+
expectTypeOf<
1310+
TodosWithCategoryRow["categoryId"]
1311+
>().toEqualTypeOf<TodoCategoryId | null>();
1312+
});
1313+
1314+
test("Query.Row infers correct types for different table", async () => {
1315+
const { evolu } = await testCreateEvolu();
1316+
1317+
const _categoriesQuery = evolu.createQuery((db) =>
1318+
db.selectFrom("todoCategory").select(["id", "name"]),
1319+
);
1320+
1321+
type CategoriesRow = typeof _categoriesQuery.Row;
1322+
1323+
expectTypeOf<CategoriesRow["id"]>().toEqualTypeOf<TodoCategoryId>();
1324+
expectTypeOf<
1325+
CategoriesRow["name"]
1326+
>().toEqualTypeOf<NonEmptyString50 | null>();
1327+
});
1328+
1329+
test("Query.Row infers correct types with $narrowType", async () => {
1330+
const { evolu } = await testCreateEvolu();
1331+
1332+
const _nonNullTitlesQuery = evolu.createQuery((db) =>
1333+
db
1334+
.selectFrom("todo")
1335+
.select(["id", "title"])
1336+
.where("title", "is not", null)
1337+
.$narrowType<{ title: NonEmptyString50 }>(),
1338+
);
1339+
1340+
type NonNullTitlesRow = typeof _nonNullTitlesQuery.Row;
1341+
1342+
// After $narrowType, title should not be nullable
1343+
expectTypeOf<NonNullTitlesRow["id"]>().toEqualTypeOf<TodoId>();
1344+
expectTypeOf<NonNullTitlesRow["title"]>().toEqualTypeOf<NonEmptyString50>();
1345+
});
1346+
});

0 commit comments

Comments
 (0)