-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexport-tests.mjs
More file actions
85 lines (79 loc) · 3.47 KB
/
Copy pathexport-tests.mjs
File metadata and controls
85 lines (79 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env node
// export-tests.mjs — generate a human-readable tests/ tree from the Postman collection.
//
// Each request becomes tests/<folder...>/<request>.js containing its method/URL (+ body),
// its pre-request script, and its test (assertion) script. This is a READ-ONLY VIEW for
// browsing on GitHub — the collection (postman/dms.postman_collection.json) is the single
// source of truth and the only thing that actually runs (run-tests.mjs / CI).
//
// RUN: node export-tests.mjs (or: npm run export:tests)
import { readFileSync, writeFileSync, mkdirSync, rmSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const HERE = dirname(fileURLToPath(import.meta.url));
const COL = join(HERE, "postman", "dms.postman_collection.json");
const OUT = join(HERE, "tests");
const RESERVED = new Set(["con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"]);
function sanitize(name) {
let s = String(name).replace(/[<>:"/\\|?*\x00-\x1f]/g, "-").replace(/[. ]+$/g, "").trim();
if (!s) s = "_";
if (RESERVED.has(s.toLowerCase())) s = "_" + s;
return s;
}
function scriptOf(item, listen) {
const ev = (item.event || []).find((e) => e.listen === listen);
if (!ev || !ev.script) return "";
const ex = ev.script.exec;
return Array.isArray(ex) ? ex.join("\n") : (ex || "");
}
function urlOf(item) {
const u = item.request && item.request.url;
if (!u) return "";
return typeof u === "string" ? u : (u.raw || "");
}
function bodyOf(item) {
const b = item.request && item.request.body;
return b && b.mode === "raw" && b.raw ? b.raw : "";
}
let count = 0;
const used = new Set(); // collision guard per directory
function uniqueFile(dir, base) {
let name = base, i = 2;
while (used.has(join(dir, name + ".js").toLowerCase())) name = base + " (" + i++ + ")";
used.add(join(dir, name + ".js").toLowerCase());
return name + ".js";
}
function walk(items, segs) {
for (const it of items || []) {
if (it.item) {
walk(it.item, segs.concat(sanitize(it.name)));
} else {
const method = it.request ? (typeof it.request === "string" ? "GET" : it.request.method || "") : "";
const url = urlOf(it);
const body = bodyOf(it);
const pre = scriptOf(it, "prerequest");
const test = scriptOf(it, "test");
const L = [];
L.push("// " + "=".repeat(78));
L.push("// " + segs.concat(it.name).join(" / "));
L.push("// " + (method + " " + url).trim());
if (body) L.push("// Body: " + body.replace(/\s+/g, " ").slice(0, 240));
L.push("// Generated from postman/dms.postman_collection.json — READ-ONLY view; tests run via the collection.");
L.push("// " + "=".repeat(78));
L.push("");
if (pre.trim()) { L.push("// ---------- Pre-request script ----------"); L.push(pre); L.push(""); }
L.push("// ---------- Tests ----------");
L.push(test.trim() ? test : "// (no test script)");
L.push("");
const dir = join(OUT, ...segs);
mkdirSync(dir, { recursive: true });
writeFileSync(join(dir, uniqueFile(dir, sanitize(it.name))), L.join("\n"), "utf-8");
count++;
}
}
}
const col = JSON.parse(readFileSync(COL, "utf-8"));
try { rmSync(OUT, { recursive: true, force: true }); } catch { /* first run */ }
mkdirSync(OUT, { recursive: true });
walk(col.item, []);
console.log(`generated ${count} readable test files under tests/`);