Update test framework: fix run_tests.py to support all test files, add auto-import-check for test files

This commit is contained in:
qiaoxinjiu
2026-05-09 15:11:30 +08:00
parent eb053a347f
commit eaba8328da
21739 changed files with 2236758 additions and 719 deletions

17
node_modules/import-in-the-middle/test/README.md generated vendored Normal file
View File

@@ -0,0 +1,17 @@
These tests are organized as follows:
* Located in the `hook` directory if they use the `Hook` class.
* Located in the `low-level` directory if they use the "low-level" API,
`addHook` and `removeHook`.
* Other tests are in other adjacent directories.
The tests can be run individually as Node.js programs with non-zero exit codes
upon failures. They should be run with the following Node.js command-line
options (assuming they're run from the project root):
```
--require ./test/version-check.js
--experimental-loader ./test/generic-loader.mjs
```
The entire test suite can be run with `npm test`.

View File

@@ -0,0 +1,317 @@
import { spawnSync } from 'child_process'
import { deepStrictEqual } from 'assert'
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
const cwd = dirname(fileURLToPath(import.meta.url))
const hook = resolve(cwd, '..', '..', 'hook.mjs')
const mostPopular240NpmModules = [
'ansi-styles',
'semver',
'supports-color',
'chalk', 'has-flag',
'debug',
'tslib',
'color-convert',
'ms',
'color-name',
'lru-cache',
'minimatch',
'strip-ansi',
'source-map',
'ansi-regex',
'glob',
'readable-stream',
'commander',
'yallist',
'string-width',
'escape-string-regexp',
'brace-expansion',
'find-up',
'p-locate',
'locate-path',
'wrap-ansi',
'p-limit',
'safe-buffer',
'kind-of',
'minipass',
'uuid',
'string_decoder',
'ajv',
'emoji-regex',
'isarray',
'react-is',
'fs-extra',
'is-fullwidth-code-point',
'get-stream',
'json-schema-traverse',
'yargs-parser',
'glob-parent',
'yargs',
'rimraf',
'acorn',
'which',
'estraverse',
'js-yaml',
'path-exists',
'argparse',
'pretty-format',
'resolve-from',
'cliui',
'schema-utils',
'globals',
'camelcase',
'execa',
'punycode',
'path-key',
'signal-exit',
'inherits',
'resolve',
'mkdirp',
'is-stream',
'ws',
'universalify',
'qs',
'slash',
'json5',
'iconv-lite',
'form-data',
'is-number',
'eslint-visitor-keys',
'@jest/types',
'postcss',
'make-dir',
'pify',
'cross-spawn',
'braces',
'whatwg-url',
'fill-range',
'eslint-scope',
'tr46',
'micromatch',
'convert-source-map',
'define-property',
'agent-base',
'shebang-regex',
'shebang-command',
'mimic-fn',
'globby',
'npm-run-path',
'mime',
'@babel/code-frame',
'extend-shallow',
'to-regex-range',
'onetime',
'https-proxy-agent',
'y18n',
'buffer',
'strip-bom',
'is-glob',
'doctrine',
'picocolors',
'pkg-dir',
'@babel/types',
'regenerator-runtime',
'human-signals',
'@jridgewell/trace-mapping',
'ignore',
'jsesc',
'parse-json',
'jest-worker',
'graceful-fs',
'jest-util',
'jsonfile',
'normalize-path',
'strip-json-comments',
'cosmiconfig',
'minimist',
'path-type',
'@babel/parser',
'balanced-match',
'picomatch',
'typescript',
'isexe',
'statuses',
'entities',
'bytes',
'node-fetch',
'http-errors',
'@babel/highlight',
'@babel/helper-validator-identifier',
'function-bind',
'async',
'sprintf-js',
'@babel/generator',
'is-extendable',
'get-intrinsic',
'lodash',
'mime-db',
'source-map-support',
'mime-types',
'is-arrayish',
'@babel/core',
'once',
'anymatch',
'depd',
'hosted-git-info',
'path-to-regexp',
'axios',
'is-core-module',
'@babel/template',
'cookie',
'write-file-atomic',
'js-tokens',
'@typescript-eslint/typescript-estree',
'@typescript-eslint/types',
'object-inspect',
'wrappy',
'is-extglob',
'chokidar',
'@typescript-eslint/visitor-keys',
'call-bind',
'loader-utils',
'browserslist',
'http-proxy-agent',
'fast-glob',
'concat-map',
'inflight',
'ajv-keywords',
'ansi-escapes',
'ci-info',
'fast-deep-equal',
'caniuse-lite',
'fs.realpath',
'@jridgewell/gen-mapping',
'setprototypeof',
'strip-final-newline',
'optionator',
'path-is-absolute',
'@babel/traverse',
'core-util-is',
'has-symbols',
'yocto-queue',
'p-try',
'electron-to-chromium',
'@smithy/smithy-client',
'yaml',
'ini',
'@babel/helper-plugin-utils',
'jest-get-type',
'type-check',
'levn',
'is-descriptor',
'prelude-ls',
'slice-ansi',
'@typescript-eslint/scope-manager',
'isobject',
'esprima',
'@babel/helper-split-export-declaration',
'callsites',
'readdirp',
'escalade',
'import-fresh',
'get-caller-file',
'@jridgewell/sourcemap-codec',
'acorn-walk',
'rxjs',
'ieee754',
'is-plain-obj',
'istanbul-lib-instrument',
'@babel/helper-module-imports',
'side-channel',
'normalize-package-data',
'is-plain-object',
'@jridgewell/resolve-uri',
'follow-redirects',
'array-union',
'json-parse-even-better-errors',
'path-parse',
'has-property-descriptors',
'uri-js',
'safer-buffer',
'@babel/helpers',
'on-finished',
'@babel/helper-function-name',
'p-map',
'postcss-value-parser',
'indent-string',
'@babel/helper-module-transforms',
'object-assign',
'delayed-stream',
'@nodelib/fs.stat',
'require-directory',
'diff',
'parse5',
'asynckit',
'tmp',
'combined-stream'
]
const otherCommonModulesUsedWithInstrumentation = [
'express',
'fastify',
'@hapi/hapi',
'connect',
'svelte',
'@sveltejs/kit',
'next',
'gatsby',
'@remix-run/node',
'@remix-run/react'
]
const modules = [...mostPopular240NpmModules, ...otherCommonModulesUsedWithInstrumentation]
function installLibs (names) {
spawnSync('npm', ['init', '-y'], { cwd })
spawnSync('npm', ['install', ...names], { cwd })
}
function getExports (name, loader) {
const args = ['--input-type=module', '--no-warnings', '-e', `import * as lib from '${name}'; console.log(JSON.stringify(Object.keys(lib)))`]
if (loader) args.push(loader)
const out = spawnSync(process.execPath, args, { cwd })
if (out.status !== 0) {
console.error(out.stderr.toString())
throw new Error(`Getting exports returned non-zero exit code '${name}'`)
}
const stdout = out.stdout.toString()
return JSON.parse(stdout).sort()
}
const NPM_LIST_SEMVER_PARSE = /└──.*@((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)/
function getVersion (name) {
const result = spawnSync('npm', ['list', name, '--depth', '0'], { cwd })
const stdout = result.output.toString()
const [, version] = stdout.match(NPM_LIST_SEMVER_PARSE)
return version
}
function testLib (name) {
const version = getVersion(name)
try {
const expected = getExports(name)
const actual = getExports(name, `--experimental-loader=${hook}`)
deepStrictEqual(actual, expected, `Exports for ${name} are different`)
console.log(`✅ Exports for ${name}@${version} match`)
return false
} catch (err) {
console.error(`❌ Error getting exports for ${name}@${version}:`, err)
return true
}
}
console.log(`📦 Installing ${modules.length} libraries...`)
installLibs(modules)
let errored = false
for (const mod of modules) {
errored += testLib(mod)
}
if (errored) {
console.error('❌ Some tests failed')
process.exit(1)
}

View File

@@ -0,0 +1,7 @@
export const a = 'a'
export function aFunc () {
return a
}
export * from './foo.mjs'

View File

@@ -0,0 +1,5 @@
export const b = 'b'
export function bFunc () {
return b
}

View File

@@ -0,0 +1,4 @@
import bar from './something.mjs'
export default bar
export * from './a.mjs'
export * from './b.mjs'

View File

@@ -0,0 +1,18 @@
// The following is generated by tslib. __exportStar is a format which cjs-module-lexer exposes as a reexport
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./circular-b"), exports);
exports.foo = 42;

View File

@@ -0,0 +1,5 @@
import { bar } from './circular-b.mjs'
export const foo = 1
export { bar }

View File

@@ -0,0 +1,15 @@
// The following is generated by tslib. __exportStar is a format which cjs-module-lexer exposes as a reexport
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./circular-a"), exports);

View File

@@ -0,0 +1,3 @@
import { foo } from './circular-a.mjs'
export const bar = foo + 1

View File

@@ -0,0 +1,7 @@
import { testB } from './cyclical-b.mjs'
export function testA () {
console.log('testA')
}
testB()

View File

@@ -0,0 +1,6 @@
import { testA } from './cyclical-a.mjs'
export function testB () {
console.log('testB')
testA()
}

View File

@@ -0,0 +1,8 @@
// File generated from our OpenAPI spec by Stainless.
import * as BatchesAPI from './cyclical-self.mjs'
export class Batches {}
export class BatchesPage {}
(function (Batches) {
Batches.BatchesPage = BatchesAPI.BatchesPage
// eslint-disable-next-line no-class-assign
})(Batches || (Batches = {}))

View File

@@ -0,0 +1,4 @@
export const foo = 'a'
export default function () {
return 'c'
}

View File

@@ -0,0 +1 @@
export const foo = 'b'

View File

@@ -0,0 +1 @@
export const foo = 'c'

View File

@@ -0,0 +1,5 @@
export * from './duplicate-a.mjs'
export * from './duplicate-b.mjs'
export { foo } from './duplicate-c.mjs'
export * from './duplicate-a.mjs'
export * from './duplicate-b.mjs'

View File

@@ -0,0 +1,5 @@
export * from './duplicate-a.mjs'
export * from './duplicate-b.mjs'
const foo = 'foo'
export default foo

View File

@@ -0,0 +1,8 @@
let env = { FOO: 'baz' }
function setEnv (newEnv) {
console.log('setting env, env.FOO is', newEnv.FOO)
env = newEnv
}
export { setEnv, env }

View File

@@ -0,0 +1,32 @@
// Exporting declarations
export let name1, name2/*, … */; // also var //| name1,name2
export const name1 = 1, name2 = 2/*, … */; // also var, let //| name1,name2
export function functionName() { /* … */ } //| functionName
export class ClassName { /* … */ } //| ClassName
export function* generatorFunctionName() { /* … */ } //| generatorFunctionName
export const { name1, name2: bar } = o; //| name1,bar
export const [ name1, name2 ] = array; //| name1,name2
// Export list
let name1, nameN; export { name1, /* …, */ nameN }; //| name1,nameN
let variable1, variable2, nameN; export { variable1 as name1, variable2 as name2, /* …, */ nameN }; //| name1,name2,nameN
let variable1; export { variable1 as "string name" }; //| string name
let name1; export { name1 as default /*, … */ }; //| default
// Default exports
export default expression; //| default
export default function functionName() { /* … */ } //| default
export default class ClassName { /* … */ } //| default
export default function* generatorFunctionName() { /* … */ } //| default
export default function () { /* … */ } //| default
export default class { /* … */ } //| default
export default function* () { /* … */ } //| default
// Aggregating modules
export * from "module-name"; //| * from module-name
export * as name1 from "module-name"; //| name1
export { name1, /* …, */ nameN } from "module-name"; //| name1,nameN
export { import1 as name1, import2 as name2, /* …, */ nameN } from "module-name"; //| name1,name2,nameN
export { default, /* …, */ } from "module-name"; //| default
export { default as name1 } from "module-name"; //| name1

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env node
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
// This script doesn't actually have to do anything.

View File

@@ -0,0 +1,19 @@
const o = { name5: 1, name6: 1 }
const array = [1, 1]
// Exporting declarations
export const name1 = 1; export const name2 = 1/*, … */ // also var
export const name3 = 1; export const name4 = 1/*, … */ // also var, let
export function functionName () { return 1 }
export class ClassName { getFoo () { return 1 } }
export function * generatorFunctionName () { return 1 }
export const { name5, name6: bar } = o
export const [name7, name8] = array
export async function asyncFunctionName () { return 1 }
export async function * asyncGeneratorFunctionName () { yield 1 }
export const arrowFunction = () => {
return 1
}
export const asyncArrowFunction = async () => {
return 1
}

View File

@@ -0,0 +1,2 @@
export * from './default-call-expression.mjs'
export { default as somethingElse } from './default-call-expression.mjs'

View File

@@ -0,0 +1 @@
export default parseInt('1')

View File

@@ -0,0 +1 @@
export default class { getFoo () { return 1 } }

View File

@@ -0,0 +1 @@
export default class ClassName { getFoo () { return 1 } }

View File

@@ -0,0 +1 @@
export default [1]

View File

@@ -0,0 +1 @@
export default 1

View File

@@ -0,0 +1 @@
export default 'dog'

View File

@@ -0,0 +1 @@
export default function () { return 1 }

View File

@@ -0,0 +1 @@
export default function functionName () { return 1 }

View File

@@ -0,0 +1 @@
export default function * () { return 1 }

View File

@@ -0,0 +1 @@
export default function * generatorFunctionName () { return 1 }

View File

@@ -0,0 +1,3 @@
export default function () {
return 1
}

View File

@@ -0,0 +1,2 @@
import fnDefaultExport from './fn-default-export.mjs'
export default fnDefaultExport

View File

@@ -0,0 +1,12 @@
// Export list
const name1 = 1
const name2 = 1
const name5 = 1
const variable1 = 1
const variable2 = 1
const variable3 = 1
const name6 = 1
export { name1, name2 }
export { variable1 as name3, variable2 as name4, /* …, */ name5 }
export { variable3 as 'name' }
export { name6 as default /*, … */ }

View File

@@ -0,0 +1,5 @@
const temp = function () {
return 1
}
export default temp

View File

@@ -0,0 +1,5 @@
export function foo () {
return 'foo'
}
export * from './lib/baz.mjs'

View File

@@ -0,0 +1,11 @@
// This replicates the way the in-the-wild `got` module does things:
// https://github.com/sindresorhus/got/blob/3822412/source/index.ts
class got {
foo = 'foo'
}
export default got
export { got }
export * from './something.mjs'
export { default as renamedDefaultExport } from './lib/baz.mjs'

View File

@@ -0,0 +1,10 @@
import { strictEqual } from 'assert'
import * as foo from './foo.mjs'
import { dirname, join } from 'path'
import { fileURLToPath } from 'url'
const fooPath = join(dirname(fileURLToPath(import.meta.url)), 'foo.mjs')
strictEqual(typeof foo.foo, 'function')
strictEqual(global.hooked.length, 1)
strictEqual(global.hooked[0], fooPath)

View File

@@ -0,0 +1,18 @@
import { register } from 'module'
import { Hook, createAddHookMessageChannel } from '../../index.js'
import { dirname, join } from 'path'
import { fileURLToPath } from 'url'
const fooPath = join(dirname(fileURLToPath(import.meta.url)), 'foo.mjs')
const { registerOptions, waitForAllMessagesAcknowledged } = createAddHookMessageChannel()
register('../../hook.mjs', import.meta.url, registerOptions)
global.hooked = []
Hook([fooPath], (_, name) => {
global.hooked.push(name)
})
await waitForAllMessagesAcknowledged()

View File

@@ -0,0 +1,16 @@
import { strictEqual } from 'assert'
import { sep } from 'path'
import * as os from 'node:os'
import { Hook } from '../../index.js'
const hooked = []
Hook((_, name) => {
hooked.push(name)
})
strictEqual(hooked.length, 2)
strictEqual(hooked[0], 'path')
strictEqual(hooked[1], 'os')
strictEqual(sep, '@')
strictEqual(os.arch(), 'new_crazy_arch')

View File

@@ -0,0 +1,23 @@
import { register } from 'module'
import { Hook, createAddHookMessageChannel } from '../../index.js'
// We've imported path here to ensure that the hook is still applied later even
// if the library is used here.
import * as path from 'path'
const { registerOptions, waitForAllMessagesAcknowledged } = createAddHookMessageChannel()
register('../../hook.mjs', import.meta.url, registerOptions)
Hook(['path'], (exports) => {
exports.sep = '@'
})
Hook(['os'], (exports) => {
exports.arch = function () {
return 'new_crazy_arch'
}
})
console.assert(path.sep !== '@')
await waitForAllMessagesAcknowledged()

View File

@@ -0,0 +1 @@
module.exports.foo = 'something'

View File

@@ -0,0 +1,8 @@
// These export identifiers are only supported in Node 16+
exports['one.two'] = () => console.log('b')
// See: https://github.com/nodejs/import-in-the-middle/issues/94
exports['unsigned short'] = 'something'
exports._ = 'foo'
exports.$ = 'bar'

View File

@@ -0,0 +1,5 @@
import coolFile from './something.json' with { type: 'json' }
export default {
data: coolFile.data
}

View File

@@ -0,0 +1,9 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import coolFile from './something.json' assert { type: 'json' }
export default {
data: coolFile.data
}

View File

@@ -0,0 +1,4 @@
export function baz () {
return 'baz'
}
export default baz

View File

@@ -0,0 +1,7 @@
// Regression test for https://github.com/nodejs/import-in-the-middle/issues/196
export default function foo () {
// do nothing
}
export { foo as 'module.exports' }

View File

@@ -0,0 +1,2 @@
console.log(`skipping ${process.env.IITM_TEST_FILE} as no native module is available for ${process.platform}-${process.arch}`)
process.exit(0)

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-darwin-arm64')

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-darwin-x64')

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-linux-arm64-gnu')

View File

@@ -0,0 +1,2 @@
console.log(`skipping ${process.env.IITM_TEST_FILE} as no native module is available for ${process.platform}-${process.arch}`)
process.exit(0)

View File

@@ -0,0 +1,2 @@
console.log(`skipping ${process.env.IITM_TEST_FILE} as no native module is available for ${process.platform}-${process.arch}`)
process.exit(0)

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-linux-x64-gnu')

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-win32-arm64-msvc')

View File

@@ -0,0 +1 @@
module.exports = require('@node-rs/crc32-win32-x64-msvc')

View File

@@ -0,0 +1 @@
module.exports = { ...require('#main-entry-point') }

View File

@@ -0,0 +1,17 @@
{
"name": "test-fixtures",
"imports": {
"#main-entry-point": {
"require": {
"node": "./something.js",
"default": "./something.js"
},
"import": {
"node":"./something.mjs",
"default": "./something.mjs"
}
},
"#main-entry-point-string" : "./something.js",
"#main-entry-point-external" : "some-external-cjs-module"
}
}

View File

@@ -0,0 +1 @@
module.exports = require('util').deprecate

View File

@@ -0,0 +1 @@
module.exports = require('./something.json')

View File

@@ -0,0 +1 @@
module.exports = require('some-external-cjs-module').foo

View File

@@ -0,0 +1 @@
export * from 'some-external-module'

View File

@@ -0,0 +1,15 @@
// The following is generated by tslib. __exportStar is a format which cjs-module-lexer exposes as a reexport
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./something"), exports);

View File

@@ -0,0 +1 @@
module.exports = { ...require('.') }

View File

@@ -0,0 +1,3 @@
export const sayHi = (name: string) => {
return `Hi ${name}`
};

View File

@@ -0,0 +1,10 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
'use strict'
module.exports = function bar () {
return 42
}
module.exports.foo = 42

View File

@@ -0,0 +1,3 @@
{
"data": "dog"
}

View File

@@ -0,0 +1,9 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
export const foo = 42
export default function bar () {
return foo
}

View File

@@ -0,0 +1,7 @@
export type { Debugger } from 'node:inspector'
export const foo: number = 42
export function bar(): number {
return foo
}

View File

@@ -0,0 +1 @@
module.exports = { ...require('#main-entry-point-external') }

View File

@@ -0,0 +1 @@
module.exports = { ...require('#main-entry-point-string') }

View File

@@ -0,0 +1 @@
export * from '#main-entry-point'

View File

@@ -0,0 +1 @@
export * from 'some-external-module/sub'

View File

@@ -0,0 +1,14 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2024 Datadog, Inc.
import * as tsLoader from './typescript/iitm-ts-node-loader.mjs'
import * as regularLoader from '../hook.mjs'
import path from 'path'
const filename = process.env.IITM_TEST_FILE
export const { initialize, load, resolve, getFormat, getSource } =
filename.includes('disabled') || filename.includes('register')
? {}
: (path.extname(filename).slice(-2) === 'ts' ? tsLoader : regularLoader)

View File

@@ -0,0 +1,3 @@
// v18.19.0 backported ESM hook execution to a separate thread,
// thus being equivalent to >=v20.
require('./v20-get-esm-exports')

View File

@@ -0,0 +1,31 @@
'use strict'
const getEsmExports = require('../../lib/get-esm-exports.js')
const fs = require('fs')
const assert = require('assert')
const path = require('path')
const fixturePath = path.join(__dirname, '../fixtures/esm-exports.txt')
const fixture = fs.readFileSync(fixturePath, 'utf8')
fixture.split('\n').forEach(line => {
if (!line.includes(' //| ')) return
const [mod, testStr] = line.split(' //| ')
const expectedNames = testStr.split(',').map(x => x.trim())
if (expectedNames[0] === '') {
expectedNames.length = 0
}
const names = Array.from(getEsmExports(mod))
assert.deepEqual(expectedNames, names)
console.log(`${mod}\n ✅ contains exports: ${testStr}`)
})
// // Generate fixture data
// fixture.split('\n').forEach(line => {
// if (!line.includes('export ')) {
// console.log(line)
// return
// }
// const names = getEsmExports(line)
// console.log(line, '//|', names.join(','))
// })

View File

@@ -0,0 +1,11 @@
import { foo } from '../fixtures/circular-b.js'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/circular-[ab].js/)) {
exports.foo += 15
}
})
strictEqual(foo, 57)

View File

@@ -0,0 +1,4 @@
import { Batches, BatchesPage } from '../fixtures/cyclical-self.mjs'
import { strictEqual } from 'assert'
strictEqual(Batches.BatchesPage, BatchesPage)

View File

@@ -0,0 +1,86 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import a from '../fixtures/export-types/default-expression-array.mjs'
import n from '../fixtures/export-types/default-expression-num.mjs'
import s from '../fixtures/export-types/default-expression-string.mjs'
import fn from '../fixtures/export-types/default-function.mjs'
import cn from '../fixtures/export-types/default-class.mjs'
import gfn from '../fixtures/export-types/default-generator.mjs'
import afn from '../fixtures/export-types/default-function-anon.mjs'
import acn from '../fixtures/export-types/default-class-anon.mjs'
import agfn from '../fixtures/export-types/default-generator-anon.mjs'
import callEx from '../fixtures/export-types/default-call-expression.mjs'
import { somethingElse } from '../fixtures/export-types/default-call-expression-renamed.mjs'
import defaultImportExport from '../fixtures/export-types/import-default-export.mjs'
import varDefaultExport from '../fixtures/export-types/variable-default-export.mjs'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/default-expression-array\.m?js/)) {
exports.default[0] += 1
} else if (name.match(/default-expression-num\.m?js/)) {
exports.default += 1
} else if (name.match(/default-expression-string\.m?js/)) {
exports.default += 'dawg'
} else if (name.match(/default-function\.m?js/)) {
const orig = exports.default
exports.default = function () {
return orig() + 1
}
} else if (name.match(/default-class\.m?js/)) {
exports.default.prototype.getFoo = function () {
return 2
}
} else if (name.match(/default-generator\.m?js/)) {
const orig2 = exports.default
exports.default = function * () {
return orig2().next().value + 1
}
} else if (name.match(/default-function-anon\.m?js/)) {
const orig = exports.default
exports.default = function () {
return orig() + 1
}
} else if (name.match(/default-class-anon\.m?js/)) {
exports.default.prototype.getFoo = function () {
return 2
}
} else if (name.match(/default-generator-anon\.m?js/)) {
const orig2 = exports.default
exports.default = function * () {
return orig2().next().value + 1
}
} else if (name.match(/import-default-export\.m?js/)) {
const orig3 = exports.default
exports.default = function () {
return orig3() + 1
}
} else if (name.match(/variable-default-export\.m?js/)) {
const orig4 = exports.default
exports.default = function () {
return orig4() + 1
}
} else if (name.match(/default-call-expression\.m?js/)) {
exports.default += 1
} else if (name.match(/default-call-expression-renamed\.m?js/)) {
exports.somethingElse += 1
}
})
/* eslint-disable new-cap */
strictEqual(defaultImportExport(), 2)
strictEqual(varDefaultExport(), 2)
strictEqual(a[0], 2)
strictEqual(fn(), 2)
strictEqual(new cn().getFoo(), 2)
strictEqual(gfn().next().value, 2)
strictEqual(afn(), 2)
strictEqual(new acn().getFoo(), 2)
strictEqual(agfn().next().value, 2)
strictEqual(n, 2)
strictEqual(s, 'dogdawg')
strictEqual(callEx, 2)
strictEqual(somethingElse, 2)

View File

@@ -0,0 +1,20 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
const Hook = require('../../index.js')
const { rejects } = require('assert')
Hook((exports, name) => {
if (name === 'os') {
Object.defineProperty(exports, 'freemem', {
get: () => () => 47
})
}
})
;(async () => {
rejects(async () => {
await import('os')
})
})()

View File

@@ -0,0 +1,13 @@
import * as lib from '../fixtures/duplicate-explicit.mjs'
import { strictEqual } from 'assert'
import Hook from '../../index.js'
Hook((exports, name) => {
if (name.endsWith('duplicate-explicit.mjs')) {
strictEqual(exports.foo, 'c')
exports.foo += '-wrapped'
}
})
// foo should not be exported because there are duplicate exports
strictEqual(lib.foo, 'c-wrapped')

View File

@@ -0,0 +1,19 @@
import * as lib from '../fixtures/duplicate.mjs'
import { notEqual, strictEqual } from 'assert'
import Hook from '../../index.js'
Hook((exports, name) => {
if (name.match(/duplicate\.mjs/)) {
// foo should not be exported because there are duplicate * exports
strictEqual('foo' in exports, false)
// default should be exported
strictEqual(exports.default, 'foo')
}
})
notEqual(lib, undefined)
// foo should not be exported because there are duplicate exports
strictEqual('foo' in lib, false)
// default should be exported
strictEqual(lib.default, 'foo')

View File

@@ -0,0 +1,29 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
const Hook = require('../../index.js')
const { strictEqual } = require('assert')
Hook((exports, name) => {
if (name.match(/something.js/)) {
const orig = exports.default
exports.default = function bar () {
return orig() + 15
}
}
if (name.match(/something.mjs/)) {
const orig = exports.default
return function bar () {
return orig() + 15
}
}
})
;(async () => {
const { default: barMjs } = await import('../fixtures/something.mjs')
const { default: barJs } = await import('../fixtures/something.js')
strictEqual(barMjs(), 57)
strictEqual(barJs(), 57)
})()

View File

@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/something\.m?js/)) {
const orig = exports.default
exports.default = function bar () {
return orig() + 15
}
}
})
;(async () => {
const { default: barMjs } = await import('../fixtures/something.mjs')
const { default: barJs } = await import('../fixtures/something.js')
strictEqual(barMjs(), 57)
strictEqual(barJs(), 57)
})()

View File

@@ -0,0 +1,27 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
const { Hook } = require('../../index.js')
const { strictEqual } = require('assert')
Hook((exports, name) => {
if (name.match(/something\.m?js/)) {
exports.foo += 15
}
if (name === 'os') {
Object.defineProperty(exports, 'freemem', {
value: () => 47
})
}
})
;(async () => {
const { foo: fooMjs } = await import('../fixtures/something.mjs')
const { foo: fooJs } = await import('../fixtures/something.js')
const { freemem } = await import('os')
strictEqual(fooMjs, 57)
strictEqual(fooJs, 57)
strictEqual(freemem(), 47)
})()

View File

@@ -0,0 +1,27 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/something\.m?js/)) {
exports.foo += 15
}
if (name === 'os') {
Object.defineProperty(exports, 'freemem', {
value: () => 47
})
}
})
;(async () => {
const { foo: fooMjs } = await import('../fixtures/something.mjs')
const { foo: fooJs } = await import('../fixtures/something.js')
const { freemem } = await import('os')
strictEqual(fooMjs, 57)
strictEqual(fooJs, 57)
strictEqual(freemem(), 47)
})()

View File

@@ -0,0 +1,11 @@
import { foo } from '../fixtures/reexport.js'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/reexport.js/)) {
exports.foo += 15
}
})
strictEqual(foo, 57)

View File

@@ -0,0 +1,5 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
// Empty file just to validate the loader is not crashing.

View File

@@ -0,0 +1,25 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import { foo as fooMjs } from '../fixtures/something.mjs'
import { foo as fooJs } from '../fixtures/something.js'
import { strictEqual, deepStrictEqual } from 'assert'
let hookedExports
Hook((exports, name) => {
hookedExports = exports
})
strictEqual(fooMjs, 42)
strictEqual(fooJs, 42)
strictEqual(hookedExports[Symbol.toStringTag], 'Module')
deepStrictEqual(Object.getOwnPropertyDescriptor(hookedExports, Symbol.toStringTag), {
value: 'Module',
enumerable: false,
writable: false,
configurable: false
})

View File

@@ -0,0 +1,26 @@
import Hook from '../../index.js'
import foo from '../fixtures/re-export-cjs-built-in.js'
import foo2 from '../fixtures/re-export-cjs.js'
import foo3 from '../fixtures/re-export-cjs-json.js'
import { deepStrictEqual, strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/re-export-cjs-built-in.js')) {
strictEqual(typeof exports.default, 'function')
exports.default = '1'
}
if (name.endsWith('fixtures/re-export-cjs.js')) {
strictEqual(exports.default, 'bar')
exports.default = '2'
}
if (name.endsWith('fixtures/re-export-cjs-json.js')) {
deepStrictEqual(exports.default, { data: 'dog' })
exports.default = '3'
}
})
strictEqual(foo, '1')
strictEqual(foo2, '2')
strictEqual(foo3, '3')

View File

@@ -0,0 +1,17 @@
import Hook from '../../index.js'
import { foo } from '../fixtures/re-export-star-external.mjs'
import { bar } from '../fixtures/sub-directory/re-export-star-external.mjs'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/re-export-star-external.mjs')) {
exports.foo = '1'
}
if (name.endsWith('fixtures/sub-directory/re-export-star-external.mjs')) {
exports.bar = '2'
}
})
strictEqual(foo, '1')
strictEqual(bar, '2')

23
node_modules/import-in-the-middle/test/hook/remove.mjs generated vendored Normal file
View File

@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import { strictEqual } from 'assert'
const hook = new Hook((exports, name) => {
if (name.match(/something\.m?js/)) {
exports.foo += 15
}
})
;(async () => {
const { foo: fooMjs } = await import('../fixtures/something.mjs')
hook.unhook()
const { foo: fooJs } = await import('../fixtures/something.js')
strictEqual(fooMjs, 57)
strictEqual(fooJs, 42)
})()

View File

@@ -0,0 +1,12 @@
import Hook from '../../index.js'
import { foo } from '../fixtures/require-root.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('require-root.js')) {
strictEqual(exports.foo, 'something')
exports.foo += '-wrap'
}
})
strictEqual(foo, 'something-wrap')

View File

@@ -0,0 +1,11 @@
import { foo } from '../fixtures/specifier-external.js'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/specifier-external.js')) {
exports.foo = 'bar2'
}
})
strictEqual(foo, 'bar2')

View File

@@ -0,0 +1,10 @@
import { foo } from '../fixtures/specifier.mjs'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/specifier.mjs')) {
exports.foo = 1
}
})
strictEqual(foo, 1)

View File

@@ -0,0 +1,11 @@
import { foo } from '../fixtures/nested-folder/specifier.js'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/nested-folder/specifier.js')) {
exports.foo = 1
}
})
strictEqual(foo, 1)

View File

@@ -0,0 +1,11 @@
import { foo } from '../fixtures/specifier-string.js'
import Hook from '../../index.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.endsWith('fixtures/specifier-string.js')) {
exports.foo = 1
}
})
strictEqual(foo, 1)

View File

@@ -0,0 +1,26 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import { Hook } from '../../index.js'
import barMjs from '../fixtures/something.mjs'
import barJs from '../fixtures/something.js'
import { strictEqual } from 'assert'
Hook((exports, name) => {
if (name.match(/something.mjs/)) {
const orig = exports.default
exports.default = function bar () {
return orig() + 15
}
}
if (name.match(/something.js/)) {
const orig = exports.default
return function bar () {
return orig() + 15
}
}
})
strictEqual(barMjs(), 57)
strictEqual(barJs(), 57)

View File

@@ -0,0 +1,15 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
import Hook from '../../index.js'
import { foo as fooMjs } from '../fixtures/something.mjs'
import { foo as fooJs } from '../fixtures/something.js'
import { strictEqual, fail } from 'assert'
Hook(() => {
fail('should not have been called at all')
})
strictEqual(fooMjs, 42)
strictEqual(fooJs, 42)

Some files were not shown because too many files have changed in this diff Show More