Skip to content

Commit aa4a5f1

Browse files
Move findWranglerConfig tests to workers-utils (#11349)
* Move findWranglerConfig tests to workers-utils What appeared to be a simple move turned into quite a lot of changes. But they are all for the betterment of society and general wellbeing of civilization. * rename `test` entry-point to `test-helpers` * add changeset
1 parent b51377a commit aa4a5f1

35 files changed

+275
-199
lines changed

.changeset/cold-hands-occur.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/workers-utils": patch
3+
---
4+
5+
Adds a new `test-helpers` entry-point to the workers-utils package

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"cfetch",
99
"chatgpt",
1010
"clipboardy",
11+
"cloudchamber",
1112
"cloudflareaccess",
1213
"cloudflared",
1314
"Codespaces",

packages/workers-utils/package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
"license": "MIT OR Apache-2.0",
1515
"author": "[email protected]",
1616
"exports": {
17-
"browser": "./dist/browser.mjs",
18-
"import": "./dist/index.mjs"
17+
".": {
18+
"browser": "./dist/browser.mjs",
19+
"import": "./dist/index.mjs",
20+
"types": "./dist/index.d.mts"
21+
},
22+
"./test-helpers": {
23+
"import": "./dist/test-helpers/index.mjs",
24+
"types": "./dist/test-helpers/index.d.mts"
25+
}
1926
},
20-
"main": "dist/index.mjs",
21-
"types": "dist/index.d.mts",
2227
"files": [
2328
"dist"
2429
],
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export { mockConsoleMethods } from "./mock-console";
2+
export {
3+
normalizeString,
4+
mockCreateDate,
5+
mockEndDate,
6+
mockModifiedDate,
7+
mockQueuedDate,
8+
mockStartDate,
9+
} from "./normalize";
10+
export { runInTempDir } from "./run-in-tmp";
11+
export { seed } from "./seed";
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import * as util from "node:util";
2+
import { afterEach, beforeEach, vi } from "vitest";
3+
import { normalizeString } from "./normalize";
4+
import type { MockInstance } from "vitest";
5+
6+
/**
7+
* We use this module to mock console methods, and optionally
8+
* assert on the values they're called with in our tests.
9+
*/
10+
11+
let debugSpy: MockInstance,
12+
logSpy: MockInstance,
13+
infoSpy: MockInstance,
14+
errorSpy: MockInstance,
15+
warnSpy: MockInstance;
16+
17+
/**
18+
* An object containing the normalized output of each console method.
19+
*
20+
* We use `defineProperties` to add non enumerable methods to the object,
21+
* so they don't show up in test assertions that iterate over the object's keys.
22+
* i.e. `expect(std).toMatchInlineSnapshot('...')`;
23+
*/
24+
const std = Object.defineProperties(
25+
{ debug: "", out: "", info: "", err: "", warn: "", getAndClearOut: () => "" },
26+
{
27+
debug: {
28+
get: () => normalizeOutput(debugSpy),
29+
enumerable: true,
30+
},
31+
out: {
32+
get: () => normalizeOutput(logSpy),
33+
enumerable: true,
34+
},
35+
info: {
36+
get: () => normalizeOutput(infoSpy),
37+
enumerable: true,
38+
},
39+
err: {
40+
get: () => normalizeOutput(errorSpy),
41+
enumerable: true,
42+
},
43+
warn: {
44+
get: () => normalizeOutput(warnSpy),
45+
enumerable: true,
46+
},
47+
/**
48+
* Return the content of the mocked stdout and clear the mock's history.
49+
*
50+
* Helpful for tests that need to assert on multiple sequential console outputs.
51+
*/
52+
getAndClearOut: {
53+
value: () => {
54+
const output = normalizeOutput(logSpy);
55+
logSpy.mockClear();
56+
return output;
57+
},
58+
enumerable: false,
59+
},
60+
}
61+
);
62+
63+
function normalizeOutput(spy: MockInstance, join = "\n"): string {
64+
return normalizeString(captureCalls(spy, join));
65+
}
66+
67+
function captureCalls(spy: MockInstance, join = "\n"): string {
68+
return spy.mock.calls
69+
.map((args: unknown[]) => util.format("%s", ...args))
70+
.join(join);
71+
}
72+
73+
export function mockConsoleMethods() {
74+
beforeEach(() => {
75+
debugSpy = vi.spyOn(console, "debug").mockImplementation(() => {});
76+
logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
77+
infoSpy = vi.spyOn(console, "info").mockImplementation(() => {});
78+
errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
79+
warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
80+
});
81+
afterEach(() => {
82+
debugSpy.mockRestore();
83+
logSpy.mockRestore();
84+
infoSpy.mockRestore();
85+
errorSpy.mockRestore();
86+
warnSpy.mockRestore();
87+
});
88+
return std;
89+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as fs from "node:fs";
2+
import { rm } from "node:fs/promises";
3+
import os from "node:os";
4+
import * as path from "node:path";
5+
import { afterEach, beforeEach, vi } from "vitest";
6+
7+
const originalCwd = process.cwd();
8+
9+
export function runInTempDir({ homedir } = { homedir: "./home" }) {
10+
let tmpDir: string;
11+
12+
beforeEach(() => {
13+
// Use realpath because the temporary path can point to a symlink rather than the actual path.
14+
tmpDir = fs.realpathSync(
15+
fs.mkdtempSync(path.join(os.tmpdir(), "wrangler-tests"))
16+
);
17+
18+
process.chdir(tmpDir);
19+
process.env.PWD = tmpDir;
20+
// The path that is returned from `homedir()` should be absolute.
21+
const absHomedir = path.resolve(tmpDir, homedir);
22+
// Override where the home directory is so that we can write our own user config,
23+
// without destroying the real thing.
24+
fs.mkdirSync(absHomedir, { recursive: true });
25+
// Note it is very important that we use the "default" value from "node:os" (e.g. `import os from "node:os";`)
26+
// rather than an alias to the module (e.g. `import * as os from "node:os";`).
27+
// This is because the module gets transpiled so that the "method" `homedir()` gets converted to a
28+
// getter that is not configurable (and so cannot be spied upon).
29+
vi.spyOn(os, "homedir")?.mockReturnValue(absHomedir);
30+
});
31+
32+
afterEach(() => {
33+
if (fs.existsSync(tmpDir)) {
34+
process.chdir(originalCwd);
35+
process.env.PWD = originalCwd;
36+
// Don't block on deleting the tmp dir
37+
void rm(tmpDir).catch(() => {
38+
// Best effort - try once then just move on - they are only temp files after all.
39+
// It seems that Windows doesn't let us delete this, with errors like:
40+
//
41+
// Error: EBUSY: resource busy or locked, rmdir 'C:\Users\RUNNER~1\AppData\Local\Temp\wrangler-modules-pKJ7OQ'
42+
// ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
43+
// Serialized Error: {
44+
// "code": "EBUSY",
45+
// "errno": -4082,
46+
// "path": "C:\Users\RUNNER~1\AppData\Local\Temp\wrangler-modules-pKJ7OQ",
47+
// "syscall": "rmdir",
48+
});
49+
}
50+
});
51+
}

packages/wrangler/src/__tests__/helpers/seed.ts renamed to packages/workers-utils/src/test-helpers/seed.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Seeds the `root` directory on the file system with some data. Use in
22

3-
import { mkdir, writeFile } from "fs/promises";
4-
import path from "path";
3+
import { mkdir, writeFile } from "node:fs/promises";
4+
import path from "node:path";
55

66
// combination with `dedent` for petty formatting of seeded contents.
77
export async function seed(files: Record<string, string | Uint8Array>) {

packages/wrangler/src/__tests__/config/findWranglerConfig.test.ts renamed to packages/workers-utils/tests/config/findWranglerConfig.test.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import path from "node:path";
2-
import { findWranglerConfig } from "@cloudflare/workers-utils";
3-
import { mockConsoleMethods } from "../helpers/mock-console";
4-
import { normalizeString } from "../helpers/normalize";
5-
import { runInTempDir } from "../helpers/run-in-tmp";
6-
import { seed } from "../helpers/seed";
2+
import { describe, expect, it } from "vitest";
3+
import { findWranglerConfig } from "../../src/config/config-helpers";
4+
import {
5+
mockConsoleMethods,
6+
normalizeString,
7+
runInTempDir,
8+
seed,
9+
} from "../../src/test-helpers";
710

811
describe("config findWranglerConfig()", () => {
912
runInTempDir();

packages/workers-utils/tests/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "@cloudflare/workers-tsconfig/tsconfig.json",
33
"compilerOptions": {
44
"module": "preserve",
5-
"types": ["node", "vitest/globals"],
5+
"types": ["node"],
66
"jsx": "preserve"
77
},
88
"include": ["../*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"]

0 commit comments

Comments
 (0)