Skip to content

Commit 83bdcf4

Browse files
dmealingclaude
andcommitted
fix(migrate-ts): green typecheck — add checks:[] to legacy test descriptor literals
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 73adf9f commit 83bdcf4

8 files changed

Lines changed: 43 additions & 35 deletions

File tree

server/typescript/packages/migrate-ts/test/check/e2e-check.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { buildExpectedSchema } from "../../src/expected-schema.js";
1111
import { diff } from "../../src/diff/index.js";
1212
import { emit } from "../../src/emit/index.js";
1313
import { baselineFromMetadata, planOffline } from "../../src/snapshot/plan.js";
14-
import type { Dialect } from "../../src/types.js";
14+
import type { Dialect, SchemaSnapshot } from "../../src/types.js";
1515

1616
async function load(json: string): Promise<MetaData> {
1717
return (await new MetaDataLoader().load([new InMemoryStringSource(json)])).root;
@@ -28,7 +28,7 @@ const META = JSON.stringify({
2828
}] },
2929
});
3030

31-
const EMPTY = { tables: [], views: [] } as const;
31+
const EMPTY: SchemaSnapshot = { tables: [], views: [] };
3232

3333
describe("CHECK constraints — end-to-end (enum → CHECK)", () => {
3434
test("(a) new postgres table inlines the CHECK exactly once, no ADD CONSTRAINT", async () => {

server/typescript/packages/migrate-ts/test/diff-schema-aware.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function makeOrdersTable(schema: string | undefined): TableDescriptor {
1515
indexes: [],
1616
foreignKeys: [],
1717
primaryKey: ["id"],
18+
checks: [],
1819
};
1920
if (schema !== undefined) t.schema = schema;
2021
return t;

server/typescript/packages/migrate-ts/test/unit/diff-rename-heuristic.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function tableWithCols(cols: { name: string; type?: "text" | "integer"; nullable
1515
indexes: [],
1616
foreignKeys: [],
1717
primaryKey: [],
18+
checks: [],
1819
};
1920
}
2021

@@ -99,6 +100,7 @@ describe("rename-heuristic — table", () => {
99100
indexes: [],
100101
foreignKeys: [],
101102
primaryKey: ["id"],
103+
checks: [],
102104
};
103105
}
104106

@@ -128,7 +130,7 @@ describe("rename-heuristic — table", () => {
128130
{ name: "x", sqlType: { kind: "integer" as const, bits: 32 as const }, nullable: true },
129131
{ name: "y", sqlType: { kind: "real" as const }, nullable: true },
130132
],
131-
indexes: [], foreignKeys: [], primaryKey: [],
133+
indexes: [], foreignKeys: [], primaryKey: [], checks: [],
132134
}],
133135
views: [],
134136
};

server/typescript/packages/migrate-ts/test/unit/diff-status.test.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,65 +11,66 @@ function snap(tables: SchemaSnapshot["tables"]): SchemaSnapshot {
1111

1212
describe("diff — status enforcement", () => {
1313
test("drop-column blocked by default", async () => {
14-
const e = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
15-
const a = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 }), col("legacy", { kind: "text" })], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
14+
const e = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
15+
const a = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 }), col("legacy", { kind: "text" })], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
1616
const r = await diff(e, a);
1717
const dropCol = r.changes.find((c) => c.kind === "drop-column");
1818
expect(dropCol?.status.state).toBe("blocked");
1919
expect(r.blocked).toContain(dropCol!);
2020
});
2121

2222
test("drop-column allowed with allow.dropColumn", async () => {
23-
const e = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
24-
const a = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 }), col("legacy", { kind: "text" })], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
23+
const e = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
24+
const a = snap([{ name: "u", columns: [col("id", { kind: "integer", bits: 64 }), col("legacy", { kind: "text" })], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
2525
const r = await diff(e, a, { allow: { dropColumn: true } });
2626
expect(r.blocked).toHaveLength(0);
2727
expect(r.changes.find((c) => c.kind === "drop-column")?.status.state).toBe("allowed");
2828
});
2929

3030
test("drop-table blocked by default; allowed with allow.dropTable", async () => {
3131
const e = snap([]);
32-
const a = snap([{ name: "legacy", columns: [], indexes: [], foreignKeys: [], primaryKey: [] }]);
32+
const a = snap([{ name: "legacy", columns: [], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
3333
expect((await diff(e, a)).blocked).toHaveLength(1);
3434
expect((await diff(e, a, { allow: { dropTable: true } })).blocked).toHaveLength(0);
3535
});
3636

3737
test("change-column-type widening (int32→int64) allowed without flag", async () => {
38-
const e = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: [] }]);
39-
const a = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 32 })], indexes: [], foreignKeys: [], primaryKey: [] }]);
38+
const e = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
39+
const a = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 32 })], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
4040
const r = await diff(e, a);
4141
const c = r.changes.find((c) => c.kind === "change-column-type");
4242
expect(c?.status.state).toBe("allowed");
4343
});
4444

4545
test("change-column-type narrowing (int64→int32) blocked", async () => {
46-
const e = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 32 })], indexes: [], foreignKeys: [], primaryKey: [] }]);
47-
const a = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: [] }]);
46+
const e = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 32 })], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
47+
const a = snap([{ name: "t", columns: [col("n", { kind: "integer", bits: 64 })], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
4848
expect((await diff(e, a)).blocked.some((c) => c.kind === "change-column-type")).toBe(true);
4949
expect((await diff(e, a, { allow: { typeChange: true } })).blocked).toHaveLength(0);
5050
});
5151

5252
test("change-column-nullable: notnull→nullable allowed", async () => {
53-
const e = snap([{ name: "t", columns: [col("c", { kind: "text" }, true)], indexes: [], foreignKeys: [], primaryKey: [] }]);
54-
const a = snap([{ name: "t", columns: [col("c", { kind: "text" }, false)], indexes: [], foreignKeys: [], primaryKey: [] }]);
53+
const e = snap([{ name: "t", columns: [col("c", { kind: "text" }, true)], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
54+
const a = snap([{ name: "t", columns: [col("c", { kind: "text" }, false)], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
5555
const r = await diff(e, a);
5656
expect(r.changes.find((c) => c.kind === "change-column-nullable")?.status.state).toBe("allowed");
5757
});
5858

5959
test("change-column-nullable: nullable→notnull blocked without flag", async () => {
60-
const e = snap([{ name: "t", columns: [col("c", { kind: "text" }, false)], indexes: [], foreignKeys: [], primaryKey: [] }]);
61-
const a = snap([{ name: "t", columns: [col("c", { kind: "text" }, true)], indexes: [], foreignKeys: [], primaryKey: [] }]);
60+
const e = snap([{ name: "t", columns: [col("c", { kind: "text" }, false)], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
61+
const a = snap([{ name: "t", columns: [col("c", { kind: "text" }, true)], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
6262
expect((await diff(e, a)).blocked.some((c) => c.kind === "change-column-nullable")).toBe(true);
6363
expect((await diff(e, a, { allow: { nullableToNotNull: true } })).blocked).toHaveLength(0);
6464
});
6565

6666
test("drop-index / drop-fk blocked by default", async () => {
67-
const e = snap([{ name: "t", columns: [], indexes: [], foreignKeys: [], primaryKey: [] }]);
67+
const e = snap([{ name: "t", columns: [], indexes: [], foreignKeys: [], primaryKey: [], checks: [] }]);
6868
const a = snap([{
6969
name: "t", columns: [],
7070
indexes: [{ name: "old_idx", columns: ["x"], unique: false }],
7171
foreignKeys: [{ name: "old_fk", columns: ["x"], refTable: "y", refColumns: ["id"] }],
7272
primaryKey: [],
73+
checks: [],
7374
}]);
7475
const r = await diff(e, a);
7576
expect(r.blocked.some((c) => c.kind === "drop-index")).toBe(true);

server/typescript/packages/migrate-ts/test/unit/diff.test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ describe("diff — table-level", () => {
2222
});
2323

2424
test("expected table not in actual → create-table", async () => {
25-
const expected = snapshot([{ name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
25+
const expected = snapshot([{ name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
2626
const r = await diff(expected, empty);
2727
expect(r.changes).toHaveLength(1);
2828
expect(r.changes[0]?.kind).toBe("create-table");
2929
});
3030

3131
test("actual table not in expected → drop-table", async () => {
32-
const actual = snapshot([{ name: "legacy", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"] }]);
32+
const actual = snapshot([{ name: "legacy", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] }]);
3333
const r = await diff(empty, actual);
3434
expect(r.changes).toHaveLength(1);
3535
expect(r.changes[0]?.kind).toBe("drop-table");
@@ -38,57 +38,57 @@ describe("diff — table-level", () => {
3838

3939
describe("diff — per-table column-level", () => {
4040
test("expected column not in actual → add-column", async () => {
41-
const tableE = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
42-
const tableA = { name: "users", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
41+
const tableE = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
42+
const tableA = { name: "users", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
4343
const r = await diff(snapshot([tableE]), snapshot([tableA]));
4444
expect(r.changes).toHaveLength(1);
4545
expect(r.changes[0]).toMatchObject({ kind: "add-column", table: "users" });
4646
});
4747

4848
test("actual column not in expected → drop-column", async () => {
49-
const tableE = { name: "users", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
50-
const tableA = { name: "users", columns: [col("id", "integer"), col("legacy_field")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
49+
const tableE = { name: "users", columns: [col("id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
50+
const tableA = { name: "users", columns: [col("id", "integer"), col("legacy_field")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
5151
const r = await diff(snapshot([tableE]), snapshot([tableA]));
5252
expect(r.changes).toHaveLength(1);
5353
expect(r.changes[0]).toMatchObject({ kind: "drop-column", table: "users", column: "legacy_field" });
5454
});
5555

5656
test("type mismatch → change-column-type", async () => {
57-
const tableE = { name: "users", columns: [{ ...col("count"), sqlType: { kind: "integer" as const, bits: 64 as const } }], indexes: [], foreignKeys: [], primaryKey: [] };
58-
const tableA = { name: "users", columns: [col("count", "text")], indexes: [], foreignKeys: [], primaryKey: [] };
57+
const tableE = { name: "users", columns: [{ ...col("count"), sqlType: { kind: "integer" as const, bits: 64 as const } }], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
58+
const tableA = { name: "users", columns: [col("count", "text")], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
5959
const r = await diff(snapshot([tableE]), snapshot([tableA]));
6060
const c = r.changes.find((x) => x.kind === "change-column-type");
6161
expect(c).toBeDefined();
6262
});
6363

6464
test("nullable mismatch → change-column-nullable", async () => {
65-
const tableE = { name: "users", columns: [{ ...col("note"), nullable: true }], indexes: [], foreignKeys: [], primaryKey: [] };
66-
const tableA = { name: "users", columns: [{ ...col("note"), nullable: false }], indexes: [], foreignKeys: [], primaryKey: [] };
65+
const tableE = { name: "users", columns: [{ ...col("note"), nullable: true }], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
66+
const tableA = { name: "users", columns: [{ ...col("note"), nullable: false }], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
6767
const r = await diff(snapshot([tableE]), snapshot([tableA]));
6868
const c = r.changes.find((x) => x.kind === "change-column-nullable");
6969
expect(c).toBeDefined();
7070
expect(c).toMatchObject({ from: false, to: true });
7171
});
7272

7373
test("default mismatch → change-column-default", async () => {
74-
const tableE = { name: "users", columns: [{ ...col("flag", "boolean"), default: { kind: "literal" as const, value: "true" } }], indexes: [], foreignKeys: [], primaryKey: [] };
75-
const tableA = { name: "users", columns: [col("flag", "boolean")], indexes: [], foreignKeys: [], primaryKey: [] };
74+
const tableE = { name: "users", columns: [{ ...col("flag", "boolean"), default: { kind: "literal" as const, value: "true" } }], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
75+
const tableA = { name: "users", columns: [col("flag", "boolean")], indexes: [], foreignKeys: [], primaryKey: [], checks: [] };
7676
const r = await diff(snapshot([tableE]), snapshot([tableA]));
7777
expect(r.changes.find((x) => x.kind === "change-column-default")).toBeDefined();
7878
});
7979
});
8080

8181
describe("diff — per-table index/FK", () => {
8282
test("expected index not in actual → add-index", async () => {
83-
const tableE = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [{ name: "users_email_idx", columns: ["email"], unique: true }], foreignKeys: [], primaryKey: ["id"] };
84-
const tableA = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
83+
const tableE = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [{ name: "users_email_idx", columns: ["email"], unique: true }], foreignKeys: [], primaryKey: ["id"], checks: [] };
84+
const tableA = { name: "users", columns: [col("id", "integer"), col("email")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
8585
const r = await diff(snapshot([tableE]), snapshot([tableA]));
8686
expect(r.changes.find((x) => x.kind === "add-index")).toBeDefined();
8787
});
8888

8989
test("actual FK not in expected → drop-fk", async () => {
90-
const tableE = { name: "weeks", columns: [col("id", "integer"), col("program_id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"] };
91-
const tableA = { name: "weeks", columns: [col("id", "integer"), col("program_id", "integer")], indexes: [], foreignKeys: [{ name: "weeks_program_id_fk", columns: ["program_id"], refTable: "programs", refColumns: ["id"] }], primaryKey: ["id"] };
90+
const tableE = { name: "weeks", columns: [col("id", "integer"), col("program_id", "integer")], indexes: [], foreignKeys: [], primaryKey: ["id"], checks: [] };
91+
const tableA = { name: "weeks", columns: [col("id", "integer"), col("program_id", "integer")], indexes: [], foreignKeys: [{ name: "weeks_program_id_fk", columns: ["program_id"], refTable: "programs", refColumns: ["id"] }], primaryKey: ["id"], checks: [] };
9292
const r = await diff(snapshot([tableE]), snapshot([tableA]));
9393
expect(r.changes.find((x) => x.kind === "drop-fk")).toBeDefined();
9494
});

server/typescript/packages/migrate-ts/test/unit/emit-d1.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ describe("emit(dialect: 'd1')", () => {
1616
indexes: [],
1717
foreignKeys: [],
1818
primaryKey: ["id"],
19+
checks: [],
1920
},
2021
}];
2122
const expected: SchemaSnapshot = { tables: [], views: [] };
@@ -38,6 +39,7 @@ describe("emit(dialect: 'd1')", () => {
3839
indexes: [],
3940
foreignKeys: [],
4041
primaryKey: ["id"],
42+
checks: [],
4143
},
4244
}];
4345
const expected: SchemaSnapshot = { tables: [], views: [] };
@@ -66,6 +68,7 @@ describe("emit(dialect: 'd1')", () => {
6668
indexes: [],
6769
foreignKeys: [],
6870
primaryKey: ["id"],
71+
checks: [],
6972
}],
7073
views: [],
7174
};

server/typescript/packages/migrate-ts/test/unit/emit-postgres.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Change, ColumnDescriptor, TableDescriptor } from "../../src/types.
55
const ALLOWED = { state: "allowed" as const };
66

77
function table(name: string, cols: ColumnDescriptor[], pk: string[] = []): TableDescriptor {
8-
return { name, columns: cols, indexes: [], foreignKeys: [], primaryKey: pk };
8+
return { name, columns: cols, indexes: [], foreignKeys: [], primaryKey: pk, checks: [] };
99
}
1010

1111
function norm(s: string): string {

server/typescript/packages/migrate-ts/test/unit/emit-sqlite.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Change, ColumnDescriptor, TableDescriptor, SchemaSnapshot, Snapsho
55
const ALLOWED = { state: "allowed" as const };
66

77
function table(name: string, cols: ColumnDescriptor[], pk: string[] = []): TableDescriptor {
8-
return { name, columns: cols, indexes: [], foreignKeys: [], primaryKey: pk };
8+
return { name, columns: cols, indexes: [], foreignKeys: [], primaryKey: pk, checks: [] };
99
}
1010
function norm(s: string): string {
1111
return s.trim().split("\n").map((l) => l.trim()).filter((l) => l.length > 0).join("\n");
@@ -253,6 +253,7 @@ describe("renderSqlite — add-fk / drop-fk via recreate", () => {
253253
name: "weeks", columns: newCols, primaryKey: ["id"],
254254
indexes: [],
255255
foreignKeys: [{ name: "weeks_program_id_fk", columns: ["program_id"], refTable: "programs", refColumns: ["id"] }],
256+
checks: [],
256257
};
257258
const expectedSchema: SchemaSnapshot = { tables: [newTable], views: [] };
258259
const { up } = emit(

0 commit comments

Comments
 (0)