import * as esbuildNative from '../deno/mod.js'
import * as esbuildWASM from '../deno/wasm.js'
import * as path from 'https://deno.land/std@0.95.0/path/mod.ts'
import * as asserts from 'https://deno.land/std@0.95.0/testing/asserts.ts'
const __dirname = path.dirname(path.fromFileUrl(import.meta.url))
const rootTestDir = path.join(__dirname, '.deno-tests')
const wasmModule = await WebAssembly.compile(await Deno.readFile(path.join(__dirname, '..', 'deno', 'esbuild.wasm')))
try {
Deno.removeSync(rootTestDir, { recursive: true })
} catch {
}
Deno.mkdirSync(rootTestDir, { recursive: true })
function test(name, backends, fn) {
const singleTest = (name, fn) => Deno.test({
name,
fn: () => new Promise((resolve, reject) => {
const minutes = 5
const timeout = setTimeout(() => reject(new Error(`Timeout for "${name}" after ${minutes} minutes`)), minutes * 60 * 1000)
const cancel = () => clearTimeout(timeout)
const promise = fn()
promise.then(cancel, cancel)
promise.then(resolve, reject)
}),
sanitizeResources: false,
sanitizeOps: false,
})
for (const backend of backends) {
switch (backend) {
case 'native':
singleTest(name + '-native', async () => {
let testDir = path.join(rootTestDir, name + '-native')
await Deno.mkdir(testDir, { recursive: true })
try {
await fn({ esbuild: esbuildNative, testDir })
await Deno.remove(testDir, { recursive: true }).catch(() => null)
} finally {
esbuildNative.stop()
}
})
break
case 'wasm-main':
singleTest(name + '-wasm-main', async () => {
let testDir = path.join(rootTestDir, name + '-wasm-main')
await esbuildWASM.initialize({ wasmModule, worker: false })
await Deno.mkdir(testDir, { recursive: true })
try {
await fn({ esbuild: esbuildWASM, testDir })
await Deno.remove(testDir, { recursive: true }).catch(() => null)
} finally {
esbuildWASM.stop()
}
})
break
case 'wasm-worker':
singleTest(name + '-wasm-worker', async () => {
let testDir = path.join(rootTestDir, name + '-wasm-worker')
await esbuildWASM.initialize({ wasmModule, worker: true })
await Deno.mkdir(testDir, { recursive: true })
try {
await fn({ esbuild: esbuildWASM, testDir })
await Deno.remove(testDir, { recursive: true }).catch(() => null)
} finally {
esbuildWASM.stop()
}
})
break
}
}
}
window.addEventListener("unload", (e) => {
try {
Deno.removeSync(rootTestDir, { recursive: true })
} catch {
}
})
test("basicBuild", ['native'], async ({ esbuild, testDir }) => {
const input = path.join(testDir, 'in.ts')
const dep = path.join(testDir, 'dep.ts')
const output = path.join(testDir, 'out.ts')
await Deno.writeTextFile(input, 'import dep from "./dep.ts"; export default dep === 123')
await Deno.writeTextFile(dep, 'export default 123')
await esbuild.build({
entryPoints: [input],
bundle: true,
outfile: output,
format: 'esm',
})
const result = await import(path.toFileUrl(output))
asserts.assertStrictEquals(result.default, true)
})
test("basicContext", ['native'], async ({ esbuild, testDir }) => {
const input = path.join(testDir, 'in.ts')
const dep = path.join(testDir, 'dep.ts')
const output = path.join(testDir, 'out.ts')
await Deno.writeTextFile(input, 'import dep from "./dep.ts"; export default dep === 123')
await Deno.writeTextFile(dep, 'export default 123')
const ctx = await esbuild.context({
entryPoints: ['in.ts'],
bundle: true,
outfile: output,
format: 'esm',
absWorkingDir: testDir,
})
const { errors, warnings } = await ctx.rebuild()
asserts.assertStrictEquals(errors.length, 0)
asserts.assertStrictEquals(warnings.length, 0)
await ctx.dispose()
const result = await import(path.toFileUrl(output))
asserts.assertStrictEquals(result.default, true)
})
test("basicPlugin", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {
const build = await esbuild.build({
entryPoints: ['<entry>'],
bundle: true,
format: 'esm',
write: false,
plugins: [{
name: 'plug',
setup(build) {
build.onResolve({ filter: /^<.*>$/ }, args => ({ path: args.path, namespace: '<>' }))
build.onLoad({ filter: /^<entry>$/ }, () => ({ contents: `import dep from "<dep>"; export default dep === 123` }))
build.onLoad({ filter: /^<dep>$/ }, () => ({ contents: `export default 123` }))
},
}],
})
const result = await import('data:application/javascript;base64,' + btoa(build.outputFiles[0].text))
asserts.assertStrictEquals(result.default, true)
})
test("basicTransform", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {
const ts = 'let x: number = 1+2'
const result = await esbuild.transform(ts, { loader: 'ts' })
asserts.assertStrictEquals(result.code, 'let x = 1 + 2;\n')
})
test("largeTransform", ['native'], async ({ esbuild }) => {
let x = '0'
for (let i = 0; i < 1000; i++)x += '+' + i
x += ','
let y = 'return['
for (let i = 0; i < 1000; i++)y += x
y += ']'
const result = await esbuild.build({
stdin: {
contents: y,
},
write: false,
minify: true,
})
asserts.assertStrictEquals(result.outputFiles[0].text, y.slice(0, -2) + '];\n')
})
test("analyzeMetafile", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {
const result = await esbuild.analyzeMetafile({
outputs: {
'out.js': {
bytes: 4096,
inputs: {
'in.js': {
bytesInOutput: 1024,
},
},
},
},
})
asserts.assertStrictEquals(result, `
out.js 4.0kb 100.0%
└ in.js 1.0kb 25.0%
`)
})