// Copyright (C) 2026 Danilo M. // // 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/); // A value followed by junk is refused too: a multi-line string opens with // an empty one, and trailing text is no comment. assert.throws(() => T.set('x = """\nabc\n"""\n', "", "x", "n"), /cannot edit/); assert.throws(() => T.set('x = "a" junk\n', "", "x", "n"), /cannot edit/); assert.strictEqual(T.get('x = "a" junk\n', "", "x"), undefined); // 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");