| 1 | import assert from "node:assert/strict"; |
| 2 | import { mkdtempSync, readFileSync, writeFileSync, existsSync, readdirSync } from "node:fs"; |
| 3 | import { tmpdir } from "node:os"; |
| 4 | import { join } from "node:path"; |
| 5 | import { test } from "node:test"; |
| 6 | import { GraphicsSettingsStore, loadGraphicsBootstrap } from "./graphics.js"; |
| 7 | |
| 8 | const home = () => mkdtempSync(join(tmpdir(), "reasonix-graphics-")); |
| 9 | |
| 10 | test("defaults to enabled without creating a config", () => { |
| 11 | const b = loadGraphicsBootstrap(home(), {}, []); |
| 12 | assert.equal(b.state.hardwareAcceleration, true); |
| 13 | assert.equal(b.shouldDisable, false); |
| 14 | assert.equal(existsSync(b.configPath), false); |
| 15 | }); |
| 16 | |
| 17 | test("environment and command-line overrides disable without changing the saved preference", async () => { |
| 18 | const root = home(); |
| 19 | const b = loadGraphicsBootstrap(root, {}, []); |
| 20 | const store = new GraphicsSettingsStore(b.configPath, b); |
| 21 | await store.setHardwareAcceleration(true); |
| 22 | const overridden = loadGraphicsBootstrap(root, { REASONIX_DISABLE_GPU: "1" }, []); |
| 23 | assert.equal(overridden.state.override, "environment"); |
| 24 | assert.equal(overridden.state.startupEnabled, false); |
| 25 | assert.equal(loadGraphicsBootstrap(root, {}, ["--disable-gpu"]).state.override, "command-line"); |
| 26 | assert.equal(JSON.parse(readFileSync(overridden.configPath, "utf8")).hardwareAcceleration, true); |
| 27 | }); |
| 28 | |
| 29 | test("preserves unknown fields and rejects unknown versions", async () => { |
| 30 | const root = home(); |
| 31 | const path = join(root, "graphics.json"); |
| 32 | const b = loadGraphicsBootstrap(root, {}, []); |
| 33 | const store = new GraphicsSettingsStore(path, b); |
| 34 | await store.setHardwareAcceleration(false); |
| 35 | writeFileSync(path, JSON.stringify({ version: 1, hardwareAcceleration: false, future: { keep: true } })); |
| 36 | const reread = loadGraphicsBootstrap(root, {}, []); |
| 37 | const next = new GraphicsSettingsStore(path, reread); |
| 38 | await next.setHardwareAcceleration(true); |
| 39 | assert.deepEqual(JSON.parse(readFileSync(path, "utf8")).future, { keep: true }); |
| 40 | writeFileSync(path, JSON.stringify({ version: 9, hardwareAcceleration: false })); |
| 41 | const unknown = loadGraphicsBootstrap(root, {}, []); |
| 42 | assert.equal(unknown.state.writable, false); |
| 43 | await assert.rejects(() => new GraphicsSettingsStore(path, unknown).setHardwareAcceleration(true)); |
| 44 | }); |
| 45 | |
| 46 | test("backs up repeated invalid files with unique names before recovery", async () => { |
| 47 | const root = home(); |
| 48 | const path = join(root, "graphics.json"); |
| 49 | writeFileSync(path, "not json"); |
| 50 | const first = loadGraphicsBootstrap(root, {}, []); |
| 51 | await new GraphicsSettingsStore(path, first).setHardwareAcceleration(false); |
| 52 | writeFileSync(path, "still not json"); |
| 53 | const second = loadGraphicsBootstrap(root, {}, []); |
| 54 | await new GraphicsSettingsStore(path, second).setHardwareAcceleration(true); |
| 55 | const backups = readdirSync(root).filter((name) => name.startsWith("graphics.json.invalid")); |
| 56 | assert.equal(backups.length, 2); |
| 57 | assert.equal(JSON.parse(readFileSync(path, "utf8")).hardwareAcceleration, true); |
| 58 | }); |
| 59 |