Skip to content

Commit 152fd4e

Browse files
authored
normalize _observablehq hashes during testing (#1565)
* normalize _observablehq hashes during testing * more tests fixes
1 parent 15497ff commit 152fd4e

File tree

139 files changed

+340
-329
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+340
-329
lines changed

test/build-test.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import assert from "node:assert";
22
import {existsSync, readdirSync, statSync} from "node:fs";
3-
import {mkdir, mkdtemp, readFile, rm, writeFile} from "node:fs/promises";
3+
import {mkdir, mkdtemp, open, readFile, rename, rm, unlink, writeFile} from "node:fs/promises";
44
import os from "node:os";
55
import {join, normalize, relative} from "node:path/posix";
66
import {PassThrough} from "node:stream";
@@ -15,6 +15,16 @@ const silentEffects = {
1515
output: {write() {}}
1616
};
1717

18+
function getHashNormalizer() {
19+
const hashes = new Map<string, string>();
20+
let nextHashId = 0;
21+
return (key: string) => {
22+
let hash = hashes.get(key);
23+
if (!hash) hashes.set(key, (hash = String(++nextHashId).padStart(8, "0")));
24+
return hash;
25+
};
26+
}
27+
1828
describe("build", () => {
1929
before(() => setCurrentDate(new Date("2024-01-10T16:00:00")));
2030
mockJsDelivr();
@@ -40,15 +50,37 @@ describe("build", () => {
4050
const expectedDir = join(outputRoot, outname);
4151
const generate = !existsSync(expectedDir) && process.env.CI !== "true";
4252
const outputDir = generate ? expectedDir : actualDir;
53+
const normalizeHash = getHashNormalizer();
4354

4455
await rm(actualDir, {recursive: true, force: true});
4556
if (generate) console.warn(`! generating ${expectedDir}`);
4657
const config = {...(await readConfig(undefined, path)), output: outputDir};
4758
await build({config}, new TestEffects(outputDir, join(config.root, ".observablehq", "cache")));
4859

49-
// For non-public tests (most of them), we don’t want to test the contents
50-
// of the _observablehq files because they change often.
51-
if (!name.endsWith("-public")) await rm(join(outputDir, "_observablehq"), {recursive: true, force: true});
60+
// Replace any hashed files in _observablehq with empty files, and
61+
// renumber the hashes so they are sequential. This way we don’t have to
62+
// update the test snapshots whenever Framework’s client code changes. We
63+
// make an exception for minisearch.json because to test the content.
64+
for (const path of findFiles(join(actualDir, "_observablehq"))) {
65+
const match = /^((.+)\.[0-9a-f]{8})\.(\w+)$/.exec(path);
66+
if (!match) throw new Error(`no hash found: ${path}`);
67+
const [, key, name, ext] = match;
68+
const oldPath = join(actualDir, "_observablehq", path);
69+
const newPath = join(actualDir, "_observablehq", `${name}.${normalizeHash(key)}.${ext}`);
70+
if (/^minisearch\.[0-9a-f]{8}\.json$/.test(path)) {
71+
await rename(oldPath, newPath);
72+
} else {
73+
await unlink(oldPath);
74+
await (await open(newPath, "w")).close();
75+
}
76+
}
77+
78+
// Replace any reference to re-numbered files in _observablehq.
79+
for (const path of findFiles(actualDir)) {
80+
const actual = await readFile(join(actualDir, path), "utf8");
81+
const normalized = actual.replace(/\/_observablehq\/((.+)\.[0-9a-f]{8})\.(\w+)\b/g, (match, key, name, ext) => `/_observablehq/${name}.${normalizeHash(key)}.${ext}`); // prettier-ignore
82+
if (normalized !== actual) await writeFile(join(actualDir, path), normalized);
83+
}
5284

5385
if (generate) return;
5486

test/deploy-test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,10 +1006,10 @@ describe("deploy", () => {
10061006
.handleGetProject(DEPLOY_CONFIG)
10071007
.handlePostDeploy({projectId: DEPLOY_CONFIG.projectId, deployId})
10081008
.expectFileUpload({deployId, path: "index.html", action: "upload"})
1009-
.expectFileUpload({deployId, path: "_observablehq/theme-air,near-midnight.e68849dc.css", action: "skip"})
1010-
.expectFileUpload({deployId, path: "_observablehq/client.e153837f.js", action: "skip"})
1011-
.expectFileUpload({deployId, path: "_observablehq/runtime.4d065c03.js", action: "skip"})
1012-
.expectFileUpload({deployId, path: "_observablehq/stdlib.11a0ff13.js", action: "skip"})
1009+
.expectFileUpload({deployId, path: "_observablehq/client.00000001.js", action: "skip"})
1010+
.expectFileUpload({deployId, path: "_observablehq/runtime.00000002.js", action: "skip"})
1011+
.expectFileUpload({deployId, path: "_observablehq/stdlib.00000003.js", action: "skip"})
1012+
.expectFileUpload({deployId, path: "_observablehq/theme-air,near-midnight.00000004.css", action: "skip"})
10131013
.handlePostDeployUploaded({deployId})
10141014
.handleGetDeploy({deployId, deployStatus: "uploaded"})
10151015
.start();

test/mocks/observableApi.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,10 @@ class ObservableApiMock {
284284

285285
expectStandardFiles(options: Omit<ExpectedFileSpec, "path">) {
286286
return this.expectFileUpload({...options, path: "index.html"})
287-
.expectFileUpload({...options, path: "_observablehq/theme-air,near-midnight.e68849dc.css"})
288-
.expectFileUpload({...options, path: "_observablehq/client.e153837f.js"})
289-
.expectFileUpload({...options, path: "_observablehq/runtime.4d065c03.js"})
290-
.expectFileUpload({...options, path: "_observablehq/stdlib.11a0ff13.js"});
287+
.expectFileUpload({...options, path: "_observablehq/client.00000001.js"})
288+
.expectFileUpload({...options, path: "_observablehq/runtime.00000002.js"})
289+
.expectFileUpload({...options, path: "_observablehq/stdlib.00000003.js"})
290+
.expectFileUpload({...options, path: "_observablehq/theme-air,near-midnight.00000004.css"});
291291
}
292292

293293
/** Register a file that is expected to be uploaded. Also includes that file in

test/output/build/404/404.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
<title>Page not found</title>
66
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
77
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&amp;display=swap" crossorigin>
8-
<link rel="preload" as="style" href="./_observablehq/theme-air,near-midnight.e68849dc.css">
8+
<link rel="preload" as="style" href="./_observablehq/theme-air,near-midnight.00000004.css">
99
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&amp;display=swap" crossorigin>
10-
<link rel="stylesheet" type="text/css" href="./_observablehq/theme-air,near-midnight.e68849dc.css">
11-
<link rel="modulepreload" href="./_observablehq/client.e153837f.js">
12-
<link rel="modulepreload" href="./_observablehq/runtime.4d065c03.js">
13-
<link rel="modulepreload" href="./_observablehq/stdlib.11a0ff13.js">
10+
<link rel="stylesheet" type="text/css" href="./_observablehq/theme-air,near-midnight.00000004.css">
11+
<link rel="modulepreload" href="./_observablehq/client.00000001.js">
12+
<link rel="modulepreload" href="./_observablehq/runtime.00000002.js">
13+
<link rel="modulepreload" href="./_observablehq/stdlib.00000003.js">
1414
<script type="module">
1515

1616
if (location.pathname.endsWith("/")) {
@@ -21,7 +21,7 @@
2121
</script>
2222
<script type="module">
2323

24-
import "./_observablehq/client.e153837f.js";
24+
import "./_observablehq/client.00000001.js";
2525

2626
</script>
2727
<aside id="observablehq-toc" data-selector="h1:not(:first-of-type)[id], h2:first-child[id], :not(h1) + h2[id]">

test/output/build/404/_observablehq/client.00000001.js

Whitespace-only changes.

test/output/build/404/_observablehq/runtime.00000002.js

Whitespace-only changes.

test/output/build/404/_observablehq/stdlib.00000003.js

Whitespace-only changes.

test/output/build/404/_observablehq/theme-air,near-midnight.00000004.css

Whitespace-only changes.

test/output/build/archives.posix/_observablehq/client.00000001.js

Whitespace-only changes.

test/output/build/archives.posix/_observablehq/runtime.00000002.js

Whitespace-only changes.

0 commit comments

Comments
 (0)