@@ -0,0 +1,76 @@
1+import { describe, it, expect, beforeAll } from "vitest";
2+import { execSync } from "child_process";
3+import { readdirSync, readFileSync } from "fs";
4+import { join } from "path";
6+const casesDir = join(__dirname, "cases");
7+const outputDir = "output-compile-fail";
9+function getSourceGlobs() {
10+ const raw = execSync("npx spago sources", {
12+ cwd: join(__dirname, ".."),
13+ stdio: ["pipe", "pipe", "pipe"],
17+ .filter((l) => l.trim() && !l.startsWith("test/"))
18+ .map((g) => `"${g}"`)
25+ sourceGlobs = getSourceGlobs();
28+ `npx purs compile --output ${outputDir} ${sourceGlobs}`,
30+ cwd: join(__dirname, ".."),
32+ stdio: ["pipe", "pipe", "pipe"],
36+ // Warming cache - ignore errors
40+const cases = readdirSync(casesDir)
41+ .filter((f) => f.endsWith(".purs"))
44+describe("Compile-fail tests", () => {
45+ for (const file of cases) {
46+ const filePath = join(casesDir, file);
47+ const firstLine = readFileSync(filePath, "utf-8").split("\n")[0];
48+ const expectMatch = firstLine.match(/^-- EXPECT:\s*(.+)/);
49+ const expectedSubstring = expectMatch ? expectMatch[1].trim() : null;
50+ const testName = file.replace(".purs", "");
57+ `npx purs compile --output ${outputDir} ${sourceGlobs} "${filePath}"`,
59+ cwd: join(__dirname, ".."),
61+ stdio: ["pipe", "pipe", "pipe"],
65+ exitCode = err.status;
66+ output = (err.stdout || "") + (err.stderr || "");
69+ expect(exitCode, `Expected ${file} to fail compilation but it succeeded`).not.toBe(0);
71+ if (expectedSubstring) {
72+ expect(output, `Expected error to contain "${expectedSubstring}"`).toContain(expectedSubstring);