1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5import { describe, test, expect, beforeEach, afterEach } from "bun:test";
6import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from "node:fs";
7import { tmpdir } from "node:os";
8import { join } from "node:path";
9import { ConfigError } from "../src/util/errors.js";
10import { loadConfig } from "../src/config/loader.js";
11
12describe("loadConfig - ConfigError rethrown directly (issue #10)", () => {
13 let configDir: string;
14 let configPath: string;
15 const originalEnv = { ...process.env };
16
17 beforeEach(() => {
18 configDir = mkdtempSync(join(tmpdir(), "rumilo-cfg-test10-"));
19 const xdgBase = join(configDir, "xdg");
20 const rumiloDir = join(xdgBase, "rumilo");
21 mkdirSync(rumiloDir, { recursive: true });
22 configPath = join(rumiloDir, "config.toml");
23 process.env["XDG_CONFIG_HOME"] = xdgBase;
24 });
25
26 afterEach(() => {
27 process.env = { ...originalEnv };
28 try {
29 rmSync(configDir, { recursive: true, force: true });
30 } catch {}
31 });
32
33 test("ConfigError from validation is rethrown with original message and stack", async () => {
34 // Write invalid config that triggers ConfigError from validatePartialConfig
35 writeFileSync(configPath, `[defaults]\nmodel = 42\n`);
36 try {
37 await loadConfig();
38 throw new Error("should have thrown");
39 } catch (e: any) {
40 expect(e).toBeInstanceOf(ConfigError);
41 // The original message should include the validation details, not be re-wrapped
42 expect(e.message).toContain("/defaults/model");
43 // Stack should reference the validation function, not be a generic re-wrap
44 expect(e.stack).toBeDefined();
45 }
46 });
47
48 test("TOML parse error is wrapped as ConfigError with original message", async () => {
49 writeFileSync(configPath, `[invalid toml !!!`);
50 try {
51 await loadConfig();
52 throw new Error("should have thrown");
53 } catch (e: any) {
54 expect(e).toBeInstanceOf(ConfigError);
55 // Should contain the original TOML parse error message
56 expect(e.message.length).toBeGreaterThan(0);
57 }
58 });
59});