Skip to content

Commit d9b194c

Browse files
committed
Add no-deprecations build test
Fails if the site build logs any Hugo deprecation notices; includes a seeded-deprecation sanity case. Builds to tmp/ to avoid racing with tests that read public/.
1 parent e1d9216 commit d9b194c

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/public
2+
/tmp
23
resources/
34
node_modules/
45
package-lock.json

tests/no-deprecations.test.mjs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert/strict';
3+
import { spawnSync } from 'node:child_process';
4+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
5+
import { dirname, join } from 'node:path';
6+
import { fileURLToPath } from 'node:url';
7+
8+
const siteDir = fileURLToPath(new URL('../', import.meta.url));
9+
10+
// Build to a scratch dir so this test never races with tests that read
11+
// public/ (node --test runs test files concurrently). Kept after the run
12+
// for inspection; cleared at start.
13+
const outDir = join(siteDir, 'tmp', 'test-no-deprecations');
14+
15+
function buildSite() {
16+
const res = spawnSync(`npm run build -- -d ${outDir}`, {
17+
cwd: siteDir,
18+
shell: true,
19+
encoding: 'utf8',
20+
});
21+
const output = `${res.stdout ?? ''}${res.stderr ?? ''}`;
22+
const deprecations = output
23+
.split('\n')
24+
.filter((line) => /deprecated/i.test(line));
25+
return { res, output, deprecations };
26+
}
27+
28+
test('site build logs no Hugo deprecation notices', (t) => {
29+
// The `_hugo-dev` script builds with `--logLevel info`, the level at which
30+
// Hugo first reports deprecated API usage.
31+
rmSync(outDir, { recursive: true, force: true });
32+
const { res, output, deprecations } = buildSite();
33+
assert.equal(res.status, 0, `Build failed:\n${output}`);
34+
assert.deepEqual(deprecations, [], 'Hugo build logged deprecation notice(s)');
35+
t.diagnostic(`Scanned ${output.split('\n').length} build-log lines`);
36+
});
37+
38+
// Sanity check that the test above can actually detect deprecation notices:
39+
// seed a deprecated API call via the theme's head-end hook and ensure that
40+
// Hugo reports it. Guards against, e.g., Hugo demoting deprecation notices
41+
// below the info log level.
42+
test('build with seeded deprecated API call logs a deprecation notice', (t) => {
43+
const hookPath = join(
44+
siteDir,
45+
'layouts',
46+
'_partials',
47+
'hooks',
48+
'head-end.html',
49+
);
50+
assert.ok(
51+
!existsSync(hookPath),
52+
`${hookPath} already exists; this test needs to create it`,
53+
);
54+
mkdirSync(dirname(hookPath), { recursive: true });
55+
writeFileSync(
56+
hookPath,
57+
'{{/* Temporary file seeded by no-deprecations.test.mjs. */}}\n' +
58+
'{{ .Language.LanguageName }}\n',
59+
);
60+
try {
61+
const { res, output, deprecations } = buildSite();
62+
assert.equal(res.status, 0, `Seeded build failed:\n${output}`);
63+
assert.ok(
64+
deprecations.length > 0,
65+
'Seeded deprecated API call was not reported by the Hugo build',
66+
);
67+
t.diagnostic(`Seeded deprecation reported as: ${deprecations[0].trim()}`);
68+
} finally {
69+
rmSync(hookPath);
70+
rmSync(dirname(hookPath), { recursive: true, force: true });
71+
}
72+
});

0 commit comments

Comments
 (0)