|
| 1 | +import { invariant } from '@zenstackhq/common-helpers'; |
1 | 2 | import { loadDocument } from '@zenstackhq/language'; |
2 | 3 | import { TsSchemaGenerator } from '@zenstackhq/sdk'; |
3 | 4 | import type { SchemaDef } from '@zenstackhq/sdk/schema'; |
4 | 5 | import { execSync } from 'node:child_process'; |
| 6 | +import crypto from 'node:crypto'; |
5 | 7 | import fs from 'node:fs'; |
| 8 | +import os from 'node:os'; |
6 | 9 | import path from 'node:path'; |
7 | 10 | import { match } from 'ts-pattern'; |
| 11 | +import { expect } from 'vitest'; |
8 | 12 | import { createTestProject } from './project'; |
9 | 13 |
|
10 | 14 | function makePrelude(provider: 'sqlite' | 'postgresql', dbUrl?: string) { |
@@ -86,3 +90,44 @@ export async function generateTsSchemaInPlace(schemaPath: string) { |
86 | 90 | await generator.generate(result.model, workDir); |
87 | 91 | return compileAndLoad(workDir); |
88 | 92 | } |
| 93 | + |
| 94 | +export async function loadSchema(schema: string) { |
| 95 | + if (!schema.includes('datasource ')) { |
| 96 | + schema = `${makePrelude('sqlite')}\n\n${schema}`; |
| 97 | + } |
| 98 | + |
| 99 | + // create a temp file |
| 100 | + const tempFile = path.join(os.tmpdir(), `zenstack-schema-${crypto.randomUUID()}.zmodel`); |
| 101 | + fs.writeFileSync(tempFile, schema); |
| 102 | + const r = await loadDocument(tempFile); |
| 103 | + expect(r).toSatisfy( |
| 104 | + (r) => r.success, |
| 105 | + `Failed to load schema: ${(r as any).errors?.map((e: any) => e.toString()).join(', ')}`, |
| 106 | + ); |
| 107 | + invariant(r.success); |
| 108 | + return r.model; |
| 109 | +} |
| 110 | + |
| 111 | +export async function loadSchemaWithError(schema: string, error: string | RegExp) { |
| 112 | + if (!schema.includes('datasource ')) { |
| 113 | + schema = `${makePrelude('sqlite')}\n\n${schema}`; |
| 114 | + } |
| 115 | + |
| 116 | + // create a temp file |
| 117 | + const tempFile = path.join(os.tmpdir(), `zenstack-schema-${crypto.randomUUID()}.zmodel`); |
| 118 | + fs.writeFileSync(tempFile, schema); |
| 119 | + const r = await loadDocument(tempFile); |
| 120 | + expect(r.success).toBe(false); |
| 121 | + invariant(!r.success); |
| 122 | + if (typeof error === 'string') { |
| 123 | + expect(r).toSatisfy( |
| 124 | + (r) => r.errors.some((e: any) => e.toString().toLowerCase().includes(error.toLowerCase())), |
| 125 | + `Expected error message to include "${error}" but got: ${r.errors.map((e: any) => e.toString()).join(', ')}`, |
| 126 | + ); |
| 127 | + } else { |
| 128 | + expect(r).toSatisfy( |
| 129 | + (r) => r.errors.some((e: any) => error.test(e)), |
| 130 | + `Expected error message to match "${error}" but got: ${r.errors.map((e: any) => e.toString()).join(', ')}`, |
| 131 | + ); |
| 132 | + } |
| 133 | +} |
0 commit comments