aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/sbbuilder/test_toml.js
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/sbbuilder/test_toml.js')
-rw-r--r--desktop/modules/sbbuilder/test_toml.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/desktop/modules/sbbuilder/test_toml.js b/desktop/modules/sbbuilder/test_toml.js
new file mode 100644
index 0000000..bb230e9
--- /dev/null
+++ b/desktop/modules/sbbuilder/test_toml.js
@@ -0,0 +1,95 @@
+// 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/sbbuilder/test_toml.js
+// Toml.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 + "/Toml.js", "utf8")
+ .replace(/^\.pragma library$/m, "");
+const T = new Function(src + "\nreturn { entries, get, set, remove };")();
+
+const file = [
+ "# helper config",
+ "# Every key is optional.",
+ "",
+ 'state_dir = "/var/lib/x"',
+ 'overlays = ["one", "two"] # searched in order',
+ "# upstream_branch = 'current'",
+ "",
+ "# bundled deps: package = its deps list URL",
+ "[manifests]",
+ 'neovim = "https://example.org/v{VERSION}/deps.txt"',
+ '"gtk+3" = "https://example.org/gtk"',
+ "",
+ "[refresh]",
+ "jobs = 5",
+ "on = true",
+ "",
+].join("\n");
+
+// Top-level keys are section "".
+assert.strictEqual(T.get(file, "", "state_dir"), "/var/lib/x");
+assert.deepStrictEqual(T.get(file, "", "overlays"), ["one", "two"]);
+assert.strictEqual(T.get(file, "", "upstream_branch"), undefined);
+assert.strictEqual(T.get(file, "refresh", "jobs"), 5);
+assert.strictEqual(T.get(file, "refresh", "on"), true);
+// A quoted key reads unquoted; a commented line with = is not a key.
+assert.deepStrictEqual(T.entries(file, "manifests").map(e => e.key), ["neovim", "gtk+3"]);
+assert.deepStrictEqual(T.entries(file, "").map(e => e.key), ["state_dir", "overlays"]);
+
+// Replacing keeps the padding-free form, the inline comment and the line count.
+let t = T.set(file, "", "overlays", ["a"]);
+assert.strictEqual(t.split("\n")[4], 'overlays = ["a"] # searched in order');
+assert.strictEqual(t.split("\n").length, file.split("\n").length);
+// Setting a commented key activates its line, single-quoted or not.
+t = T.set(file, "", "upstream_branch", "main");
+assert.strictEqual(t.split("\n")[5], 'upstream_branch = "main"');
+// Unsetting comments a key out in place, and it reads back as unset.
+t = T.set(file, "refresh", "jobs", null);
+assert.strictEqual(t.split("\n")[13], "# jobs = 5");
+assert.strictEqual(T.get(t, "refresh", "jobs"), undefined);
+// ...and setting it again reactivates that line.
+assert.strictEqual(T.set(t, "refresh", "jobs", 9).split("\n")[13], "jobs = 9");
+// A new top-level key lands after the last top-level key, not after the
+// [manifests] comment, which belongs to its section.
+t = T.set(file, "", "genreprc", "/root/.genreprc");
+assert.strictEqual(t.split("\n")[5], 'genreprc = "/root/.genreprc"');
+assert.strictEqual(T.get(t, "", "genreprc"), "/root/.genreprc");
+// A new key in a file with only comments goes after the leading comments.
+t = T.set("# head\n# more\n", "", "x", 1);
+assert.strictEqual(t, "# head\n# more\nx = 1\n");
+// A new key in a section lands after that section's last key.
+t = T.set(file, "manifests", "foo.bar", "u");
+assert.strictEqual(t.split("\n")[11], '"foo.bar" = "u"');
+assert.strictEqual(T.get(t, "manifests", "foo.bar"), "u");
+// A missing section is appended, and an empty file gets no blank lead.
+t = T.set(file, "vm", "domain", "x");
+assert.ok(t.endsWith('\n\n[vm]\ndomain = "x"\n'), JSON.stringify(t));
+assert.strictEqual(T.set("", "vm", "autostart", false), "[vm]\nautostart = false\n");
+assert.strictEqual(T.set("", "", "target", "h"), 'target = "h"\n');
+// Strings are escaped and read back the same.
+t = T.set(file, "", "state_dir", 'a "b" \\ c');
+assert.strictEqual(T.get(t, "", "state_dir"), 'a "b" \\ c');
+// The same key in another section is untouched.
+assert.strictEqual(T.set("[a]\nx = 1\n\n[b]\nx = 2\n", "b", "x", 3), "[a]\nx = 1\n\n[b]\nx = 3\n");
+// A value spanning lines is refused, never duplicated.
+assert.throws(() => T.set("o = [\n \"a\",\n]\n", "", "o", ["b"]), /cannot edit/);
+
+// remove deletes the line outright.
+t = T.remove(file, "manifests", "gtk+3");
+assert.deepStrictEqual(T.entries(t, "manifests").map(e => e.key), ["neovim"]);
+assert.strictEqual(T.remove(file, "manifests", "nope"), file);
+
+console.log("test_toml: ok");