Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
coverage
.snapshots
8 changes: 8 additions & 0 deletions test/example-deps/lib/node_modules/pkg-3/lib/foo.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions test/example-deps/lib/node_modules/pkg-3/lib/foo.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions test/example-deps/lib/node_modules/pkg-3/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

139 changes: 111 additions & 28 deletions test/hook.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@ import test from 'node:test'
import assert from 'node:assert'
import path from 'node:path'
import { readFileSync } from 'node:fs'
import { createRequire } from 'node:module'
import Snap from '@matteo.collina/snap'

test.beforeEach(async (t) => {
const esmLoaderRewriter = await import('../hook.mjs')
esmLoaderRewriter.initialize({
instrumentations: [
{
channelName: 'unitTestEsm',
module: { name: 'esm-pkg', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'doStuff',
kind: 'Async'
}
},
{
channelName: 'unitTestCjs',
module: { name: 'pkg-1', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'doStuff',
kind: 'Async'
}
{
channelName: 'unitTestEsm',
module: { name: 'esm-pkg', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'doStuff',
kind: 'Async'
}
]
},
{
channelName: 'unitTestCjs',
module: { name: 'pkg-1', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'doStuff',
kind: 'Async'
}
}
]
})

const snap = Snap(`${import.meta.url}/${t.name}`)
Expand Down Expand Up @@ -61,7 +62,7 @@ test('should rewrite code if it matches a subscriber and esm module', async (t)
})

test('should not rewrite code if it does not match a subscriber and a esm module', async (t) => {
const { esmLoaderRewriter, snap } = t.ctx
const { esmLoaderRewriter, snap } = t.ctx
const esmPath = path.join(import.meta.dirname, './example-deps/lib/node_modules/esm-pkg-2/index.js')
async function resolveFn() {
return { url: `file://${esmPath}` }
Expand Down Expand Up @@ -152,16 +153,16 @@ test('should not rewrite code if a function query does not exist in file', async
const { esmLoaderRewriter, snap } = t.ctx
esmLoaderRewriter.initialize({
instrumentations: [
{
channelName: 'unitTestEsm',
module: { name: 'esm-pkg', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'nonExistentMethod',
kind: 'Async'
}
{
channelName: 'unitTestEsm',
module: { name: 'esm-pkg', versionRange: '>=1', filePath: 'foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'nonExistentMethod',
kind: 'Async'
}
]
}
]
})
const esmPath = path.join(import.meta.dirname, './example-deps/lib/node_modules/esm-pkg/foo.js')
async function resolveFn() {
Expand Down Expand Up @@ -203,3 +204,85 @@ test('should default initialization to not crash if not defined', async (t) => {
const snapshot = await snap(result.source)
assert.deepEqual(result.source, snapshot)
})

test('should rewrite code with conditional exports, cjs', async (t) => {
const { esmLoaderRewriter, snap } = t.ctx

esmLoaderRewriter.initialize({
instrumentations: [
{
channelName: 'unitTestConditional',
module: { name: 'pkg-3', versionRange: '>=1', filePath: 'lib/foo.cjs' },
functionQuery: {
className: 'Foo',
methodName: 'bar',
kind: 'Sync'
}
}
]
})

const pkgDir = path.join(import.meta.dirname, './example-deps/lib/node_modules')
const require = createRequire(path.join(pkgDir, 'pkg-3', 'package.json'))

async function resolveFn(specifier, context) {
try {
const resolved = require.resolve(specifier)
return { url: `file://${resolved}` }
} catch (err) {
throw new Error(`Cannot resolve ${specifier}: ${err.message}`)
}
}
async function nextLoad(url, context) {
const filePath = url.startsWith('file://') ? fileURLToPath(url) : url
const data = readFileSync(filePath, 'utf8')
return {
format: 'commonjs',
source: data
}
}

const url = await esmLoaderRewriter.resolve('pkg-3/foo', {}, resolveFn)
const result = await esmLoaderRewriter.load(url.url, {}, nextLoad)
assert.equal(result.format, 'commonjs')
assert.equal(result.shortCircuit, true)
const snapshot = await snap(result.source)
assert.deepEqual(result.source, snapshot)
})

test('should rewrite code with conditional exports, esm', async (t) => {
const { esmLoaderRewriter, snap } = t.ctx

esmLoaderRewriter.initialize({
instrumentations: [
{
channelName: 'unitTestConditional',
module: { name: 'pkg-3', versionRange: '>=1', filePath: 'lib/foo.js' },
functionQuery: {
className: 'Foo',
methodName: 'bar',
kind: 'Sync'
}
}
]
})

const esmPath = path.join(import.meta.dirname, './example-deps/lib/node_modules/pkg-3/lib/foo.js')
async function resolveFn() {
return { url: `file://${esmPath}` }
}
async function nextLoad(url, context) {
const data = readFileSync(esmPath, 'utf8')
return {
format: 'module',
source: data
}
}

const url = await esmLoaderRewriter.resolve('pkg-3/foo', {}, resolveFn)
const result = await esmLoaderRewriter.load(url.url, {}, nextLoad)
assert.equal(result.format, 'module')
assert.equal(result.shortCircuit, true)
const snapshot = await snap(result.source)
assert.deepEqual(result.source, snapshot)
})