| 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 { consumeGraphicsRecoveryArg, GRAPHICS_RECOVERY_ARG, 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("compatibility launch leaves the saved preference untouched and can explicitly persist off", async () => { |
| 18 | const root = home(); |
| 19 | const boot = loadGraphicsBootstrap(root, {}, [GRAPHICS_RECOVERY_ARG]); |
| 20 | assert.equal(boot.shouldDisable, true); |
| 21 | assert.equal(boot.state.hardwareAcceleration, true); |
| 22 | const argv = ["app", GRAPHICS_RECOVERY_ARG, "--workspace=test", GRAPHICS_RECOVERY_ARG]; |
| 23 | assert.equal(consumeGraphicsRecoveryArg(argv), true); |
| 24 | assert.deepEqual(argv, ["app", "--workspace=test"]); |
| 25 | assert.equal(consumeGraphicsRecoveryArg(argv), false); |
| 26 | assert.equal(loadGraphicsBootstrap(root, {}, []).shouldDisable, false); |
| 27 | await new GraphicsSettingsStore(boot.configPath, boot).setHardwareAcceleration(false); |
| 28 | assert.equal(loadGraphicsBootstrap(root, {}, []).shouldDisable, true); |
| 29 | }); |
| 30 | |
| 31 | test("environment and command-line overrides disable without changing the saved preference", async () => { |
| 32 | const root = home(); |
| 33 | const b = loadGraphicsBootstrap(root, {}, []); |
| 34 | const store = new GraphicsSettingsStore(b.configPath, b); |
| 35 | await store.setHardwareAcceleration(true); |
| 36 | const overridden = loadGraphicsBootstrap(root, { REASONIX_DISABLE_GPU: "1" }, []); |
| 37 | assert.equal(overridden.state.override, "environment"); |
| 38 | assert.equal(overridden.state.startupEnabled, false); |
| 39 | assert.equal(loadGraphicsBootstrap(root, {}, ["--disable-gpu"]).state.override, "command-line"); |
| 40 | assert.equal(JSON.parse(readFileSync(overridden.configPath, "utf8")).hardwareAcceleration, true); |
| 41 | }); |
| 42 | |
| 43 | test("preserves unknown fields and rejects unknown versions", async () => { |
| 44 | const root = home(); |
| 45 | const path = join(root, "graphics.json"); |
| 46 | const b = loadGraphicsBootstrap(root, {}, []); |
| 47 | const store = new GraphicsSettingsStore(path, b); |
| 48 | await store.setHardwareAcceleration(false); |
| 49 | writeFileSync(path, JSON.stringify({ version: 1, hardwareAcceleration: false, future: { keep: true } })); |
| 50 | const reread = loadGraphicsBootstrap(root, {}, []); |
| 51 | const next = new GraphicsSettingsStore(path, reread); |
| 52 | await next.setHardwareAcceleration(true); |
| 53 | assert.deepEqual(JSON.parse(readFileSync(path, "utf8")).future, { keep: true }); |
| 54 | writeFileSync(path, JSON.stringify({ version: 9, hardwareAcceleration: false })); |
| 55 | const unknown = loadGraphicsBootstrap(root, {}, []); |
| 56 | assert.equal(unknown.state.writable, false); |
| 57 | await assert.rejects(() => new GraphicsSettingsStore(path, unknown).setHardwareAcceleration(true)); |
| 58 | }); |
| 59 | |
| 60 | test("backs up repeated invalid files with unique names before recovery", async () => { |
| 61 | const root = home(); |
| 62 | const path = join(root, "graphics.json"); |
| 63 | writeFileSync(path, "not json"); |
| 64 | const first = loadGraphicsBootstrap(root, {}, []); |
| 65 | await new GraphicsSettingsStore(path, first).setHardwareAcceleration(false); |
| 66 | writeFileSync(path, "still not json"); |
| 67 | const second = loadGraphicsBootstrap(root, {}, []); |
| 68 | await new GraphicsSettingsStore(path, second).setHardwareAcceleration(true); |
| 69 | const backups = readdirSync(root).filter((name) => name.startsWith("graphics.json.invalid")); |
| 70 | assert.equal(backups.length, 2); |
| 71 | assert.equal(JSON.parse(readFileSync(path, "utf8")).hardwareAcceleration, true); |
| 72 | }); |
| 73 |