From b8239c7667f9e3691cb025ff8c08baf4df547017 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 16 Nov 2022 06:56:55 -0800 Subject: [PATCH] add tests --- .gitignore | 1 + test/unit.test.js | 55 +++++++++++++++---- test/unit/cjs-querystring/input.js | 7 +++ .../noPunctuation/whowhatidk.js | 12 ++++ test/unit/cjs-querystring/output.js | 5 ++ .../animalFacts/aardvark.mjs | 4 ++ .../esm-querystring-mjs/animalFacts/bear.mjs | 4 ++ .../animalFacts/cheetah.mjs | 1 + test/unit/esm-querystring-mjs/input.js | 6 ++ test/unit/esm-querystring-mjs/output.js | 7 +++ test/unit/esm-querystring-mjs/package.json | 4 ++ .../esm-querystring/animalFacts/aardvark.js | 4 ++ test/unit/esm-querystring/animalFacts/bear.js | 4 ++ .../esm-querystring/animalFacts/cheetah.js | 1 + test/unit/esm-querystring/input.js | 5 ++ test/unit/esm-querystring/output.js | 7 +++ test/unit/esm-querystring/package.json | 4 ++ test/unit/querystring-self-import/base.js | 5 ++ test/unit/querystring-self-import/dep.js | 1 + test/unit/querystring-self-import/input.js | 10 ++++ test/unit/querystring-self-import/output.js | 6 ++ 21 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 test/unit/cjs-querystring/input.js create mode 100644 test/unit/cjs-querystring/noPunctuation/whowhatidk.js create mode 100644 test/unit/cjs-querystring/output.js create mode 100644 test/unit/esm-querystring-mjs/animalFacts/aardvark.mjs create mode 100644 test/unit/esm-querystring-mjs/animalFacts/bear.mjs create mode 100644 test/unit/esm-querystring-mjs/animalFacts/cheetah.mjs create mode 100644 test/unit/esm-querystring-mjs/input.js create mode 100644 test/unit/esm-querystring-mjs/output.js create mode 100644 test/unit/esm-querystring-mjs/package.json create mode 100644 test/unit/esm-querystring/animalFacts/aardvark.js create mode 100644 test/unit/esm-querystring/animalFacts/bear.js create mode 100644 test/unit/esm-querystring/animalFacts/cheetah.js create mode 100644 test/unit/esm-querystring/input.js create mode 100644 test/unit/esm-querystring/output.js create mode 100644 test/unit/esm-querystring/package.json create mode 100644 test/unit/querystring-self-import/base.js create mode 100644 test/unit/querystring-self-import/dep.js create mode 100644 test/unit/querystring-self-import/input.js create mode 100644 test/unit/querystring-self-import/output.js diff --git a/.gitignore b/.gitignore index ea00b8f0..657bcd13 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ out coverage test/**/dist test/**/actual.js +test/unit/cjs-querystring/who?what?idk!.js diff --git a/test/unit.test.js b/test/unit.test.js index ce269b38..e774439c 100644 --- a/test/unit.test.js +++ b/test/unit.test.js @@ -1,23 +1,39 @@ const fs = require('fs'); -const { join, relative } = require('path'); +const { join, relative, sep } = require('path'); const { nodeFileTrace } = require('../out/node-file-trace'); global._unit = true; -const skipOnWindows = ['yarn-workspaces', 'yarn-workspaces-base-root', 'yarn-workspace-esm', 'asset-symlink', 'require-symlink']; +const skipOnWindows = ['yarn-workspaces', 'yarn-workspaces-base-root', 'yarn-workspace-esm', 'asset-symlink', 'require-symlink', 'cjs-querystring']; const unitTestDirs = fs.readdirSync(join(__dirname, 'unit')); const unitTests = [ - ...unitTestDirs.map(testName => ({testName, isRoot: false})), ...unitTestDirs.map(testName => ({testName, isRoot: true})), + ...unitTestDirs.map(testName => ({testName, isRoot: false})), ]; for (const { testName, isRoot } of unitTests) { const testSuffix = `${testName} from ${isRoot ? 'root' : 'cwd'}`; - if (process.platform === 'win32' && (isRoot || skipOnWindows.includes(testName))) { - console.log(`Skipping unit test on Windows: ${testSuffix}`); - continue; - }; const unitPath = join(__dirname, 'unit', testName); + + if (process.platform === 'win32') { + if (isRoot || skipOnWindows.includes(testName)) { + console.log(`Skipping unit test on Windows: ${testSuffix}`); + continue; + } + } else { + if (testName === 'cjs-querystring') { + // Create (a git-ignored copy of) the file we need, since committing it + // breaks CI on Windows. See https://github.com/vercel/nft/pull/322. + const currentFilepath = join(unitPath, 'noPunctuation', 'whowhatidk.js'); + const newFilepath = currentFilepath.replace( + 'noPunctuation' + sep + 'whowhatidk.js', + 'who?what?idk!.js' + ); + if (!fs.existsSync(newFilepath)) { + fs.copyFileSync(currentFilepath, newFilepath); + } + } + } it(`should correctly trace ${testSuffix}`, async () => { @@ -41,6 +57,25 @@ for (const { testName, isRoot } of unitTests) { return null } } + + // mock an in-memory module store (such as webpack's) where the same filename with + // two different querystrings can correspond to two different modules, one importing + // the other + if (testName === 'querystring-self-import') { + if (id.endsWith('input.js') || id.endsWith('base.js') || id.endsWith('dep.js')) { + return fs.readFileSync(id).toString() + } + + if (id.endsWith('base.js?__withQuery')) { + return ` + import * as origBase from './base'; + export const dogs = origBase.dogs.concat('Cory', 'Bodhi'); + export const cats = origBase.cats.concat('Teaberry', 'Sassafras', 'Persephone'); + export const rats = origBase.rats; + `; + } + } + return this.constructor.prototype.readFile.apply(this, arguments); }); @@ -67,8 +102,8 @@ for (const { testName, isRoot } of unitTests) { if (testName === 'multi-input') { inputFileNames.push('input-2.js', 'input-3.js', 'input-4.js'); } - - const { fileList, reasons } = await nodeFileTrace( + + const { fileList, reasons, warnings } = await nodeFileTrace( inputFileNames.map(file => join(unitPath, file)), { base: isRoot ? '/' : `${__dirname}/../`, @@ -193,7 +228,7 @@ for (const { testName, isRoot } of unitTests) { expect(sortedFileList).toEqual(expected); } catch (e) { - console.warn(reasons); + console.warn({reasons, warnings}); fs.writeFileSync(join(unitPath, 'actual.js'), JSON.stringify(sortedFileList, null, 2)); throw e; } diff --git a/test/unit/cjs-querystring/input.js b/test/unit/cjs-querystring/input.js new file mode 100644 index 00000000..5a1baf7e --- /dev/null +++ b/test/unit/cjs-querystring/input.js @@ -0,0 +1,7 @@ +// Test that CJS files treat question marks in filenames as any other character, +// matching Node behavior + +// https://www.youtube.com/watch?v=2ve20PVNZ18 + +const baseball = require('./who?what?idk!'); +console.log(baseball.players); diff --git a/test/unit/cjs-querystring/noPunctuation/whowhatidk.js b/test/unit/cjs-querystring/noPunctuation/whowhatidk.js new file mode 100644 index 00000000..4c4c4b72 --- /dev/null +++ b/test/unit/cjs-querystring/noPunctuation/whowhatidk.js @@ -0,0 +1,12 @@ +module.exports = { + players: { + first: 'Who', + second: 'What', + third: "I Don't Know", + left: 'Why', + center: 'Because', + pitcher: 'Tomorrow', + catcher: 'Today', + shortstop: "I Don't Give a Damn!", + }, +}; diff --git a/test/unit/cjs-querystring/output.js b/test/unit/cjs-querystring/output.js new file mode 100644 index 00000000..296a204b --- /dev/null +++ b/test/unit/cjs-querystring/output.js @@ -0,0 +1,5 @@ +[ + "package.json", + "test/unit/cjs-querystring/input.js", + "test/unit/cjs-querystring/who?what?idk!.js" +] diff --git a/test/unit/esm-querystring-mjs/animalFacts/aardvark.mjs b/test/unit/esm-querystring-mjs/animalFacts/aardvark.mjs new file mode 100644 index 00000000..a2efff8a --- /dev/null +++ b/test/unit/esm-querystring-mjs/animalFacts/aardvark.mjs @@ -0,0 +1,4 @@ +import { numSpecies } from "./bear.mjs?beaver?bison"; +console.log(`There are ${numSpecies} species of bears.`); + +export const food = "termites"; diff --git a/test/unit/esm-querystring-mjs/animalFacts/bear.mjs b/test/unit/esm-querystring-mjs/animalFacts/bear.mjs new file mode 100644 index 00000000..a8ee2dd0 --- /dev/null +++ b/test/unit/esm-querystring-mjs/animalFacts/bear.mjs @@ -0,0 +1,4 @@ +import * as cheetah from "./cheetah.mjs?cow=chipmunk"; +console.log(`Cheetahs can run ${cheetah.topSpeed} mph.`); + +export const numSpecies = 8; diff --git a/test/unit/esm-querystring-mjs/animalFacts/cheetah.mjs b/test/unit/esm-querystring-mjs/animalFacts/cheetah.mjs new file mode 100644 index 00000000..836b4ddf --- /dev/null +++ b/test/unit/esm-querystring-mjs/animalFacts/cheetah.mjs @@ -0,0 +1 @@ +export const topSpeed = 65; diff --git a/test/unit/esm-querystring-mjs/input.js b/test/unit/esm-querystring-mjs/input.js new file mode 100644 index 00000000..a07ace77 --- /dev/null +++ b/test/unit/esm-querystring-mjs/input.js @@ -0,0 +1,6 @@ +// Test that querystrings of various forms get stripped from esm imports when those +// imports contain the `.mjs` file extension + +import * as aardvark from "./animalFacts/aardvark.mjs?anteater"; + +console.log(`Aardvarks eat ${aardvark.food}.`); diff --git a/test/unit/esm-querystring-mjs/output.js b/test/unit/esm-querystring-mjs/output.js new file mode 100644 index 00000000..95137ed7 --- /dev/null +++ b/test/unit/esm-querystring-mjs/output.js @@ -0,0 +1,7 @@ +[ + "test/unit/esm-querystring-mjs/animalFacts/aardvark.mjs", + "test/unit/esm-querystring-mjs/animalFacts/bear.mjs", + "test/unit/esm-querystring-mjs/animalFacts/cheetah.mjs", + "test/unit/esm-querystring-mjs/input.js", + "test/unit/esm-querystring-mjs/package.json" +] \ No newline at end of file diff --git a/test/unit/esm-querystring-mjs/package.json b/test/unit/esm-querystring-mjs/package.json new file mode 100644 index 00000000..e986b24b --- /dev/null +++ b/test/unit/esm-querystring-mjs/package.json @@ -0,0 +1,4 @@ +{ + "private": true, + "type": "module" +} diff --git a/test/unit/esm-querystring/animalFacts/aardvark.js b/test/unit/esm-querystring/animalFacts/aardvark.js new file mode 100644 index 00000000..4c497265 --- /dev/null +++ b/test/unit/esm-querystring/animalFacts/aardvark.js @@ -0,0 +1,4 @@ +import { numSpecies } from './bear?beaver?bison'; +console.log(`There are ${numSpecies} species of bears.`); + +export const food = 'termites'; diff --git a/test/unit/esm-querystring/animalFacts/bear.js b/test/unit/esm-querystring/animalFacts/bear.js new file mode 100644 index 00000000..4578358b --- /dev/null +++ b/test/unit/esm-querystring/animalFacts/bear.js @@ -0,0 +1,4 @@ +import * as cheetah from './cheetah?cow=chipmunk'; +console.log(`Cheetahs can run ${cheetah.topSpeed} mph.`); + +export const numSpecies = 8; diff --git a/test/unit/esm-querystring/animalFacts/cheetah.js b/test/unit/esm-querystring/animalFacts/cheetah.js new file mode 100644 index 00000000..836b4ddf --- /dev/null +++ b/test/unit/esm-querystring/animalFacts/cheetah.js @@ -0,0 +1 @@ +export const topSpeed = 65; diff --git a/test/unit/esm-querystring/input.js b/test/unit/esm-querystring/input.js new file mode 100644 index 00000000..b0d51697 --- /dev/null +++ b/test/unit/esm-querystring/input.js @@ -0,0 +1,5 @@ +// Test that querystrings of various forms get stripped from esm imports + +import * as aardvark from './animalFacts/aardvark?anteater'; + +console.log(`Aardvarks eat ${aardvark.food}.`); diff --git a/test/unit/esm-querystring/output.js b/test/unit/esm-querystring/output.js new file mode 100644 index 00000000..d03f7cb8 --- /dev/null +++ b/test/unit/esm-querystring/output.js @@ -0,0 +1,7 @@ +[ + "test/unit/esm-querystring/animalFacts/aardvark.js", + "test/unit/esm-querystring/animalFacts/bear.js", + "test/unit/esm-querystring/animalFacts/cheetah.js", + "test/unit/esm-querystring/input.js", + "test/unit/esm-querystring/package.json" +] \ No newline at end of file diff --git a/test/unit/esm-querystring/package.json b/test/unit/esm-querystring/package.json new file mode 100644 index 00000000..e986b24b --- /dev/null +++ b/test/unit/esm-querystring/package.json @@ -0,0 +1,4 @@ +{ + "private": true, + "type": "module" +} diff --git a/test/unit/querystring-self-import/base.js b/test/unit/querystring-self-import/base.js new file mode 100644 index 00000000..8f48a38a --- /dev/null +++ b/test/unit/querystring-self-import/base.js @@ -0,0 +1,5 @@ +import * as dep from './dep'; + +export const dogs = ['Charlie', 'Maisey']; +export const cats = ['Piper']; +export const rats = dep.rats; diff --git a/test/unit/querystring-self-import/dep.js b/test/unit/querystring-self-import/dep.js new file mode 100644 index 00000000..aaff193a --- /dev/null +++ b/test/unit/querystring-self-import/dep.js @@ -0,0 +1 @@ +export const rats = ['Debra']; diff --git a/test/unit/querystring-self-import/input.js b/test/unit/querystring-self-import/input.js new file mode 100644 index 00000000..25f53ce9 --- /dev/null +++ b/test/unit/querystring-self-import/input.js @@ -0,0 +1,10 @@ +// Test that if a file and the same file with a querystring correspond to different +// modules in memory, one can successfully import the other. The import chain +// goes `input` (this file) -> `base?__withQuery` -> `base` -> `dep`, which means +// that if `dep` shows up in `output`, we know that both `base?__withQuery` and +// `base` have been loaded successfully. + +import * as baseWithQuery from './base?__withQuery'; +console.log('Dogs:', baseWithQuery.dogs); +console.log('Cats:', baseWithQuery.cats); +console.log('Rats:', baseWithQuery.rats); diff --git a/test/unit/querystring-self-import/output.js b/test/unit/querystring-self-import/output.js new file mode 100644 index 00000000..d6dc6b2c --- /dev/null +++ b/test/unit/querystring-self-import/output.js @@ -0,0 +1,6 @@ +[ + "package.json", + "test/unit/querystring-self-import/base.js", + "test/unit/querystring-self-import/dep.js", + "test/unit/querystring-self-import/input.js" +]