| 1 | // Run with: node --test "extension/lib/*.test.js" |
| 2 | // |
| 3 | // The whole value of this module is agreeing with the devport shell script, so |
| 4 | // most of what is checked here are ports taken from running it. If cksum is |
| 5 | // ever "optimised" into an ordinary zlib CRC-32 these are the tests that fail. |
| 6 | |
| 7 | const test = require("node:test"); |
| 8 | const assert = require("node:assert"); |
| 9 | |
| 10 | const Devport = require("./devport.js"); |
| 11 | |
| 12 | // `devport -n <name>`, run for real. |
| 13 | const KNOWN = { |
| 14 | "browser-terminal-extension": 26210, |
| 15 | myapp: 26270, |
| 16 | dotfiles: 26140, |
| 17 | termbridge: 12820, |
| 18 | Code: 25000, |
| 19 | a: 30900, |
| 20 | }; |
| 21 | |
| 22 | test("agrees with the devport script", () => { |
| 23 | for (const [name, port] of Object.entries(KNOWN)) { |
| 24 | assert.equal(Devport.portOf(name), port, name); |
| 25 | } |
| 26 | }); |
| 27 | |
| 28 | test("cksum matches the POSIX checksum", () => { |
| 29 | // `printf '%s' "" | cksum` and `printf '%s' abc | cksum`. |
| 30 | assert.equal(Devport.cksum(""), 4294967295); |
| 31 | assert.equal(Devport.cksum("abc"), 1219131554); |
| 32 | }); |
| 33 | |
| 34 | test("every port lands in the assignable range, on a block boundary", () => { |
| 35 | const top = Devport.BASE + Devport.BLOCKS * Devport.SLOT; |
| 36 | for (let i = 0; i < 500; i++) { |
| 37 | const port = Devport.portOf(`project-${i}`); |
| 38 | assert.ok(port >= Devport.BASE && port < top, `${port} out of range`); |
| 39 | assert.equal((port - Devport.BASE) % Devport.SLOT, 0); |
| 40 | } |
| 41 | }); |
| 42 | |
| 43 | test("a block covers the ten ports that follow its base", () => { |
| 44 | const base = Devport.portOf("myapp"); |
| 45 | for (let i = 0; i < Devport.SLOT; i++) { |
| 46 | assert.equal(Devport.blockOf(base + i), base, `offset ${i}`); |
| 47 | assert.ok(Devport.owns(base + i, "myapp")); |
| 48 | } |
| 49 | // One past the end belongs to the next block, not this one. |
| 50 | assert.notEqual(Devport.blockOf(base + Devport.SLOT), base); |
| 51 | }); |
| 52 | |
| 53 | test("ports outside the range belong to nobody", () => { |
| 54 | for (const port of [80, 3000, 5173, 8080, 10239, 31240, 65535, -1, 1.5, NaN]) { |
| 55 | assert.equal(Devport.blockOf(port), null, String(port)); |
| 56 | assert.equal(Devport.owns(port, "myapp"), false, String(port)); |
| 57 | } |
| 58 | }); |
| 59 | |
| 60 | test("an empty name owns nothing", () => { |
| 61 | // Not because it hashes badly — it hashes fine — but because a session with |
| 62 | // no working directory would otherwise match one arbitrary block. |
| 63 | assert.equal(Devport.owns(Devport.portOf(""), ""), false); |
| 64 | }); |
| 65 | |
| 66 | test("unicode names hash by their bytes", () => { |
| 67 | // The shell pipes bytes into cksum, so the name has to be UTF-8 encoded here |
| 68 | // rather than iterated as UTF-16 code units. |
| 69 | assert.equal(Devport.portOf("café"), Devport.portOf("café")); |
| 70 | assert.notEqual(Devport.portOf("café"), Devport.portOf("cafe")); |
| 71 | }); |