Skip to content

Commit 0c9ae17

Browse files
committed
feat(): support setup vscode testing
1 parent 34186b9 commit 0c9ae17

File tree

3 files changed

+136
-1
lines changed

3 files changed

+136
-1
lines changed

packages/yo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"node": ">=16"
2222
},
2323
"dependencies": {
24+
"jsonc-parser": "^3.3.1",
2425
"minimist": "^1.2.8",
2526
"plop": "^4.0.1"
2627
},

packages/yo/src/plopfile.js

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import path from "node:path";
22
import { existsSync } from "node:fs";
3-
import { readFile, readdir, writeFile } from "node:fs/promises";
3+
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
44
import { fileURLToPath } from "node:url";
5+
import { parse } from "jsonc-parser";
56

67
const __dirname = path.dirname(fileURLToPath(import.meta.url));
78

@@ -123,6 +124,10 @@ export default function (
123124
name: "Create a new shared library",
124125
value: "shared",
125126
},
127+
{
128+
name: "Setup VSCode testing settings",
129+
value: "vscode-testing",
130+
},
126131
],
127132
},
128133
{
@@ -387,6 +392,8 @@ export default function (
387392
templateFiles: "templates/shared",
388393
},
389394
];
395+
} else if (data.type === "vscode-testing") {
396+
return [initVscodeTesting];
390397
}
391398
return [];
392399
},
@@ -396,3 +403,125 @@ export default function (
396403
function getObjectPartialInPackageJson(object) {
397404
return JSON.stringify(object, null, 4).replace(/\}\s*$/, " }");
398405
}
406+
407+
async function initVscodeTesting() {
408+
const folders = await getWorkspaceFolders();
409+
if (folders.length === 0) {
410+
return "No workspace folders found, are you sure this is a monorepo?";
411+
}
412+
413+
const vscodeDir = path.join(rootDir, ".vscode");
414+
if (!existsSync(vscodeDir)) {
415+
await mkdir(vscodeDir);
416+
}
417+
418+
const settingsJson = path.join(vscodeDir, "settings.json");
419+
let settings = {};
420+
if (existsSync(settingsJson)) {
421+
// settings = JSON.parse(await readFile(settingsJson, "utf-8"));
422+
const errors = [];
423+
settings = parse(await readFile(settingsJson, "utf-8"), errors, {
424+
allowTrailingComma: true,
425+
});
426+
if (errors.length > 0) {
427+
return `Failed to parse existing .vscode/settings.json: ${errors
428+
.map((e) => `at offset ${e.offset} (${e.error})`)
429+
.join(", ")}`;
430+
}
431+
}
432+
Object.assign(settings, {
433+
"jest.runMode": "on-demand",
434+
"jest.jestCommandLine": "npx test-next",
435+
"jest.useJest30": true,
436+
"jest.nodeEnv": {
437+
NODE_ENV: "test",
438+
},
439+
"jest.virtualFolders": folders.map((folder) => ({
440+
name: folder,
441+
rootPath: folder,
442+
})),
443+
});
444+
await writeFile(settingsJson, JSON.stringify(settings, null, 2) + "\n");
445+
446+
const launchJson = path.join(vscodeDir, "launch.json");
447+
let launchConfig = {};
448+
if (existsSync(launchJson)) {
449+
const errors = [];
450+
launchConfig = parse(await readFile(launchJson, "utf-8"), errors, {
451+
allowTrailingComma: true,
452+
});
453+
if (errors.length > 0) {
454+
return `Failed to parse existing .vscode/launch.json: ${errors
455+
.map((e) => `at offset ${e.offset} (${e.error})`)
456+
.join(", ")}`;
457+
}
458+
}
459+
const configs = folders.map((folder) => ({
460+
type: "node",
461+
name: `vscode-jest-tests.v2.${folder}`,
462+
request: "launch",
463+
args: [
464+
"--runInBand",
465+
"--watchAll=false",
466+
"--testNamePattern",
467+
"${jest.testNamePattern}",
468+
"--runTestsByPath",
469+
"${jest.testFile}",
470+
],
471+
cwd: `${rootDir}/${folder}`,
472+
console: "integratedTerminal",
473+
internalConsoleOptions: "neverOpen",
474+
program: `${rootDir}/node_modules/.bin/test-next`,
475+
env: {
476+
NODE_ENV: "test",
477+
},
478+
}));
479+
launchConfig.configurations = [
480+
...(launchConfig.configurations?.filter(
481+
(config) => !config.name?.startsWith("vscode-jest-tests.")
482+
) ?? []),
483+
...configs,
484+
];
485+
await writeFile(launchJson, JSON.stringify(launchConfig, null, 2) + "\n");
486+
487+
return 'Updated VSCode testing settings in ".vscode/settings.json" and ".vscode/launch.json".';
488+
}
489+
490+
async function getWorkspaceFolders() {
491+
const { workspaces } = packageJson;
492+
/** @type {string[]} */
493+
const folders = (
494+
await Promise.all(
495+
workspaces.map(async (pattern) => {
496+
const result = [];
497+
if (pattern.endsWith("/*")) {
498+
const folder = pattern.slice(0, -2);
499+
const dir = path.join(rootDir, folder);
500+
const dirs = await readdir(dir, {
501+
withFileTypes: true,
502+
});
503+
for (const d of dirs) {
504+
const pkgJsonPath = path.join(dir, d.name, "package.json");
505+
if (d.isDirectory() && existsSync(pkgJsonPath)) {
506+
const pkg = JSON.parse(await readFile(pkgJsonPath, "utf-8"));
507+
if (pkg.scripts?.test) {
508+
result.push(path.join(folder, d.name));
509+
}
510+
}
511+
}
512+
} else {
513+
const dir = path.join(rootDir, pattern);
514+
const pkgJsonPath = path.join(dir, "package.json");
515+
if (existsSync(pkgJsonPath)) {
516+
const pkg = JSON.parse(await readFile(pkgJsonPath, "utf-8"));
517+
if (pkg.scripts?.test) {
518+
result.push(pattern);
519+
}
520+
}
521+
}
522+
return result;
523+
})
524+
)
525+
).flat();
526+
return folders;
527+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9112,6 +9112,11 @@ [email protected]:
91129112
resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz"
91139113
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
91149114

9115+
jsonc-parser@^3.3.1:
9116+
version "3.3.1"
9117+
resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4"
9118+
integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==
9119+
91159120
jsonfile@^6.0.1:
91169121
version "6.0.1"
91179122
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz"

0 commit comments

Comments
 (0)