History

Fix the test to use it.effect() and some lints

Griffin Evans committed 6 months ago

Commit ddaab4b1 parent 66420b81 file · +81 −111Browse files

Unified · Split

apps/local/src/server/executor-schema-compat.test.ts+81−111
@@ -3,6 +3,7 @@ import { mkdtempSync, rmSync } from "node:fs"; · 2 unmodified lines
3import { tmpdir } from "node:os";3import { tmpdir } from "node:os";
4import { join } from "node:path";4import { join } from "node:path";
5import { afterEach, describe, expect, it } from "@effect/vitest";5import { afterEach, describe, expect, it } from "@effect/vitest";
6import { Effect } from "effect";
6import { drizzle } from "drizzle-orm/bun-sqlite";7import { drizzle } from "drizzle-orm/bun-sqlite";
7import { migrate } from "drizzle-orm/bun-sqlite/migrator";8import { migrate } from "drizzle-orm/bun-sqlite/migrator";
8 9
@@ -17,12 +18,15 @@ import { · 8 unmodified lines
17const MIGRATIONS_FOLDER = join(import.meta.dirname, "../../drizzle");18const MIGRATIONS_FOLDER = join(import.meta.dirname, "../../drizzle");
18 19
19const workDirs: string[] = [];20const workDirs: string[] = [];
21const openDbs: Database[] = [];
20 22
21const tempDb = (): { db: Database; path: string } => {23const tempDb = (): { db: Database; path: string } => {
22 const dir = mkdtempSync(join(tmpdir(), "executor-schema-compat-"));24 const dir = mkdtempSync(join(tmpdir(), "executor-schema-compat-"));
23 workDirs.push(dir);25 workDirs.push(dir);
24 const path = join(dir, "data.db");26 const path = join(dir, "data.db");
25 return { db: new Database(path), path };27 const db = new Database(path);
28 openDbs.push(db);
29 return { db, path };
26};30};
27 31
28const createMigrationTable = (db: Database): void => {32const createMigrationTable = (db: Database): void => {
@@ -43,139 +47,105 @@ const insertMigrationHashes = (db: Database, hashes: ReadonlyArray<string>): voi · 14 unmodified lines
43};47};
44 48
45afterEach(() => {49afterEach(() => {
50 for (const db of openDbs.splice(0)) {
51 db.close();
52 }
46 for (const dir of workDirs.splice(0)) {53 for (const dir of workDirs.splice(0)) {
47 rmSync(dir, { recursive: true, force: true });54 rmSync(dir, { recursive: true, force: true });
48 }55 }
49});56});
50 57
51describe("Drizzle migration compatibility preflight", () => {58describe("Drizzle migration compatibility preflight", () => {
52 it("allows a fresh DB without __drizzle_migrations", () => {59 it.effect("allows a fresh DB without __drizzle_migrations", () =>
53 const { db, path } = tempDb();60 Effect.gen(function* () {
54 try {61 const { db, path } = tempDb();
55 expect(() =>62
56 checkDrizzleMigrationCompatibility({63 yield* checkDrizzleMigrationCompatibility({
57 sqlite: db,64 sqlite: db,
58 dbPath: path,65 dbPath: path,
59 migrationsFolder: MIGRATIONS_FOLDER,66 migrationsFolder: MIGRATIONS_FOLDER,
60 }),67 });
61 ).not.toThrow();68 }),
62 } finally {69 );
63 db.close();70
64 }71 it.effect("allows an existing but empty __drizzle_migrations table", () =>
65 });72 Effect.gen(function* () {
66 73 const { db, path } = tempDb();
67 it("allows an existing but empty __drizzle_migrations table", () => {
68 const { db, path } = tempDb();
69 try {
70 createMigrationTable(db);74 createMigrationTable(db);
71 75
72 expect(() =>76 yield* checkDrizzleMigrationCompatibility({
73 checkDrizzleMigrationCompatibility({77 sqlite: db,
74 sqlite: db,78 dbPath: path,
75 dbPath: path,79 migrationsFolder: MIGRATIONS_FOLDER,
76 migrationsFolder: MIGRATIONS_FOLDER,80 });
77 }),81 }),
78 ).not.toThrow();82 );
79 } finally {
80 db.close();
81 }
82 });
83 83
84 it("computes bundled hashes that exactly match hashes written by Drizzle", () => {84 it("computes bundled hashes that exactly match hashes written by Drizzle", () => {
85 const { db } = tempDb();85 const { db } = tempDb();
86 try {86 migrate(drizzle(db), { migrationsFolder: MIGRATIONS_FOLDER });
87 migrate(drizzle(db), { migrationsFolder: MIGRATIONS_FOLDER });87
88 88 expect(readAppliedDrizzleMigrationHashes(db)).toEqual(
89 expect(readAppliedDrizzleMigrationHashes(db)).toEqual(89 readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER),
90 readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER),90 );
91 );
92 } finally {
93 db.close();
94 }
95 });91 });
96 92
97 it("throws LocalDatabaseSchemaTooNew when the DB has more migrations than the binary", () => {93 it.effect("fails with LocalDatabaseSchemaTooNew when the DB has more migrations", () =>
98 const { db, path } = tempDb();94 Effect.gen(function* () {
99 try {95 const { db, path } = tempDb();
100 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);96 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);
101 createMigrationTable(db);97 createMigrationTable(db);
102 insertMigrationHashes(db, [...bundled, "future-migration-hash"]);98 insertMigrationHashes(db, [...bundled, "future-migration-hash"]);
103 99
104 expect(() =>100 const error = yield* checkDrizzleMigrationCompatibility({
105 checkDrizzleMigrationCompatibility({101 sqlite: db,
106 sqlite: db,102 dbPath: path,
107 dbPath: path,103 migrationsFolder: MIGRATIONS_FOLDER,
108 migrationsFolder: MIGRATIONS_FOLDER,104 }).pipe(Effect.flip);
109 }),105
110 ).toThrow(LocalDatabaseSchemaTooNew);106 expect(error).toBeInstanceOf(LocalDatabaseSchemaTooNew);
111 107 expect(error).toMatchObject({
112 try {108 message: expect.stringContaining("This Executor binary is older than the schema"),
113 checkDrizzleMigrationCompatibility({109 });
114 sqlite: db,110 expect(error).toMatchObject({
115 dbPath: path,111 message: expect.stringContaining("Use a newer Executor binary"),
116 migrationsFolder: MIGRATIONS_FOLDER,112 });
117 });113 }),
118 } catch (error) {114 );
119 expect(error).toBeInstanceOf(LocalDatabaseSchemaTooNew);115
120 expect((error as Error).message).toContain(116 it.effect("fails with LocalDatabaseMigrationHistoryMismatch when hashes diverge", () =>
121 "This Executor binary is older than the schema",117 Effect.gen(function* () {
122 );118 const { db, path } = tempDb();
123 expect((error as Error).message).toContain("Use a newer Executor binary");
124 }
125 } finally {
126 db.close();
127 }
128 });
129
130 it("throws LocalDatabaseMigrationHistoryMismatch when hashes diverge", () => {
131 const { db, path } = tempDb();
132 try {
133 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);119 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);
134 createMigrationTable(db);120 createMigrationTable(db);
135 insertMigrationHashes(db, ["different-migration-hash", ...bundled.slice(1)]);121 insertMigrationHashes(db, ["different-migration-hash", ...bundled.slice(1)]);
136 122
137 expect(() =>123 const error = yield* checkDrizzleMigrationCompatibility({
138 checkDrizzleMigrationCompatibility({124 sqlite: db,
139 sqlite: db,125 dbPath: path,
140 dbPath: path,126 migrationsFolder: MIGRATIONS_FOLDER,
141 migrationsFolder: MIGRATIONS_FOLDER,127 }).pipe(Effect.flip);
142 }),128
143 ).toThrow(LocalDatabaseMigrationHistoryMismatch);129 expect(error).toBeInstanceOf(LocalDatabaseMigrationHistoryMismatch);
144 130 expect(error).toMatchObject({
145 try {131 message: expect.stringContaining("does not match this Executor build"),
146 checkDrizzleMigrationCompatibility({132 });
147 sqlite: db,133 expect(error).toMatchObject({ message: expect.stringContaining("restore a backup") });
148 dbPath: path,134 }),
149 migrationsFolder: MIGRATIONS_FOLDER,135 );
150 });136
151 } catch (error) {137 it.effect("allows an older DB whose migration history is a bundled prefix", () =>
152 expect(error).toBeInstanceOf(LocalDatabaseMigrationHistoryMismatch);138 Effect.gen(function* () {
153 expect((error as Error).message).toContain(139 const { db, path } = tempDb();
154 "does not match this Executor build",
155 );
156 expect((error as Error).message).toContain("restore a backup");
157 }
158 } finally {
159 db.close();
160 }
161 });
162
163 it("allows an older DB whose migration history is a bundled prefix", () => {
164 const { db, path } = tempDb();
165 try {
166 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);140 const bundled = readBundledDrizzleMigrationHashes(MIGRATIONS_FOLDER);
167 createMigrationTable(db);141 createMigrationTable(db);
168 insertMigrationHashes(db, bundled.slice(0, 1));142 insertMigrationHashes(db, bundled.slice(0, 1));
169 143
170 expect(() =>144 yield* checkDrizzleMigrationCompatibility({
171 checkDrizzleMigrationCompatibility({145 sqlite: db,
172 sqlite: db,146 dbPath: path,
173 dbPath: path,147 migrationsFolder: MIGRATIONS_FOLDER,
174 migrationsFolder: MIGRATIONS_FOLDER,148 });
175 }),149 }),
176 ).not.toThrow();150 );
177 } finally {
178 db.close();
179 }
180 });
181});151});