aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/assistant/test_config.js
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/assistant/test_config.js')
-rw-r--r--desktop/modules/assistant/test_config.js89
1 files changed, 89 insertions, 0 deletions
diff --git a/desktop/modules/assistant/test_config.js b/desktop/modules/assistant/test_config.js
new file mode 100644
index 0000000..cc610a8
--- /dev/null
+++ b/desktop/modules/assistant/test_config.js
@@ -0,0 +1,89 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Run: node desktop/modules/assistant/test_config.js
+// Config.js is a QML library, so its .pragma line is stripped before node
+// evaluates it.
+
+const fs = require("fs");
+const assert = require("assert");
+
+const src = fs.readFileSync(__dirname + "/Config.js", "utf8")
+ .replace(/^\.pragma library$/m, "");
+const C = new Function(src + "\nreturn { scalars, setScalar, env, setEnv, quote };")();
+
+const KEYS = ["llm", "system", "tool_rounds", "temperature", "thinking"];
+const file = [
+ "# desktop-assistant configuration.",
+ "# Style name = weight; prose with an equals sign",
+ "",
+ '# llm = "http://localhost:8181/v1" # llama-server, OpenAI API',
+ '# system = "You are a voice assistant. ..."',
+ "temperature = 0.6 # per request; unset = the preset's",
+ "",
+ "# [whisper]",
+ "# port = 8182",
+ "",
+ "[env]",
+ 'SEARXNG_URL = "http://search.example.org" # a # inside a comment',
+ 'MD_EDITOR = "typora"',
+ '# WEATHER_ENV = "/home/you/x"',
+ "",
+].join("\n");
+
+// Only active keys have values; prose and commented keys do not.
+assert.deepStrictEqual(C.scalars(file, KEYS), { temperature: 0.6 });
+assert.deepStrictEqual(C.env(file), [
+ { key: "SEARXNG_URL", value: "http://search.example.org" },
+ { key: "MD_EDITOR", value: "typora" },
+]);
+
+// Setting an active key keeps its inline comment.
+let t = C.setScalar(file, "temperature", "0.2");
+assert.strictEqual(t.split("\n")[5], "temperature = 0.2 # per request; unset = the preset's");
+// Unsetting comments it out in place, and it reads as unset.
+t = C.setScalar(file, "temperature", null);
+assert.strictEqual(t.split("\n")[5], "# temperature = 0.6 # per request; unset = the preset's");
+assert.deepStrictEqual(C.scalars(t, KEYS), {});
+// Setting a commented key activates its line rather than adding one.
+t = C.setScalar(file, "llm", C.quote("http://box:8080/v1"));
+assert.strictEqual(t.split("\n")[3], 'llm = "http://box:8080/v1" # llama-server, OpenAI API');
+assert.strictEqual(t.split("\n").length, file.split("\n").length);
+// A key nowhere in the file lands before the first table, not inside it.
+t = C.setScalar(file, "thinking", "false");
+const lines = t.split("\n");
+assert.ok(lines.indexOf("thinking = false") < lines.indexOf("[env]"));
+assert.strictEqual(C.scalars(t, KEYS).thinking, false);
+// The prose line with "=" is never treated as a key.
+assert.strictEqual(C.setScalar(file, "name", null), file);
+
+// Strings round-trip with quotes, backslashes and newlines.
+const tricky = 'Say "hi"\\now\nline two\ttab';
+t = C.setScalar(file, "system", C.quote(tricky));
+assert.strictEqual(C.scalars(t, KEYS).system, tricky);
+assert.strictEqual(t.split("\n").length, file.split("\n").length);
+
+// env: replace, remove, add after the last active entry.
+t = C.setEnv(file, "MD_EDITOR", "xdg-open");
+assert.deepStrictEqual(C.env(t)[1], { key: "MD_EDITOR", value: "xdg-open" });
+t = C.setEnv(file, "SEARXNG_URL", null);
+assert.deepStrictEqual(C.env(t).map(e => e.key), ["MD_EDITOR"]);
+t = C.setEnv(file, "CALENDAR_DIR", "/home/you/cal");
+assert.deepStrictEqual(C.env(t).map(e => e.key), ["SEARXNG_URL", "MD_EDITOR", "CALENDAR_DIR"]);
+assert.strictEqual(t.split("\n")[13], 'CALENDAR_DIR = "/home/you/cal"');
+// No [env] table yet: one is appended.
+t = C.setEnv("temperature = 0.6\n", "X", "1");
+assert.deepStrictEqual(C.env(t), [{ key: "X", value: "1" }]);
+assert.ok(/\n\[env\]\nX = "1"\n$/.test(t), JSON.stringify(t));
+// An env key in another table is not the env one.
+assert.deepStrictEqual(C.env('[voice]\nlang = "it"\n'), []);
+
+console.log("test_config: ok");