github.com/evanw/esbuild@v0.21.4/scripts/deno-tests.js (about) 1 // To run this, you must first build the Deno package with "make platform-deno" 2 import * as esbuildNative from '../deno/mod.js' 3 import * as esbuildWASM from '../deno/wasm.js' 4 import * as path from 'https://deno.land/std@0.95.0/path/mod.ts' 5 import * as asserts from 'https://deno.land/std@0.95.0/testing/asserts.ts' 6 7 const __dirname = path.dirname(path.fromFileUrl(import.meta.url)) 8 const rootTestDir = path.join(__dirname, '.deno-tests') 9 const wasmModule = await WebAssembly.compile(await Deno.readFile(path.join(__dirname, '..', 'deno', 'esbuild.wasm'))) 10 11 try { 12 Deno.removeSync(rootTestDir, { recursive: true }) 13 } catch { 14 } 15 Deno.mkdirSync(rootTestDir, { recursive: true }) 16 17 function test(name, backends, fn) { 18 // Note: Do not try to add a timeout for the tests below. It turns out that 19 // calling "setTimeout" from within "Deno.test" changes how Deno waits for 20 // promises in a way that masks problems that would otherwise occur. We want 21 // test coverage for the way that people will likely be using these API calls. 22 // 23 // Specifically tests that Deno would otherwise have failed with "error: 24 // Promise resolution is still pending but the event loop has already 25 // resolved" were being allowed to pass instead. See this issue for more 26 // information: https://github.com/evanw/esbuild/issues/3682 27 28 for (const backend of backends) { 29 switch (backend) { 30 case 'native': 31 Deno.test(name + '-native', async () => { 32 let testDir = path.join(rootTestDir, name + '-native') 33 await Deno.mkdir(testDir, { recursive: true }) 34 try { 35 await fn({ esbuild: esbuildNative, testDir }) 36 await Deno.remove(testDir, { recursive: true }).catch(() => null) 37 } finally { 38 await esbuildNative.stop() 39 } 40 }) 41 break 42 43 case 'wasm-main': 44 Deno.test(name + '-wasm-main', async () => { 45 let testDir = path.join(rootTestDir, name + '-wasm-main') 46 await esbuildWASM.initialize({ wasmModule, worker: false }) 47 await Deno.mkdir(testDir, { recursive: true }) 48 try { 49 await fn({ esbuild: esbuildWASM, testDir }) 50 await Deno.remove(testDir, { recursive: true }).catch(() => null) 51 } finally { 52 await esbuildWASM.stop() 53 } 54 }) 55 break 56 57 case 'wasm-worker': 58 Deno.test(name + '-wasm-worker', async () => { 59 let testDir = path.join(rootTestDir, name + '-wasm-worker') 60 await esbuildWASM.initialize({ wasmModule, worker: true }) 61 await Deno.mkdir(testDir, { recursive: true }) 62 try { 63 await fn({ esbuild: esbuildWASM, testDir }) 64 await Deno.remove(testDir, { recursive: true }).catch(() => null) 65 } finally { 66 await esbuildWASM.stop() 67 } 68 }) 69 break 70 } 71 } 72 } 73 74 window.addEventListener("unload", (e) => { 75 try { 76 Deno.removeSync(rootTestDir, { recursive: true }) 77 } catch { 78 // root test dir possibly already removed, so ignore 79 } 80 }) 81 82 // This test doesn't run in WebAssembly because it requires file system access 83 test("basicBuild", ['native'], async ({ esbuild, testDir }) => { 84 const input = path.join(testDir, 'in.ts') 85 const dep = path.join(testDir, 'dep.ts') 86 const output = path.join(testDir, 'out.ts') 87 await Deno.writeTextFile(input, 'import dep from "./dep.ts"; export default dep === 123') 88 await Deno.writeTextFile(dep, 'export default 123') 89 await esbuild.build({ 90 entryPoints: [input], 91 bundle: true, 92 outfile: output, 93 format: 'esm', 94 }) 95 const result = await import(path.toFileUrl(output)) 96 asserts.assertStrictEquals(result.default, true) 97 }) 98 99 test("basicContext", ['native'], async ({ esbuild, testDir }) => { 100 const input = path.join(testDir, 'in.ts') 101 const dep = path.join(testDir, 'dep.ts') 102 const output = path.join(testDir, 'out.ts') 103 await Deno.writeTextFile(input, 'import dep from "./dep.ts"; export default dep === 123') 104 await Deno.writeTextFile(dep, 'export default 123') 105 const ctx = await esbuild.context({ 106 entryPoints: ['in.ts'], 107 bundle: true, 108 outfile: output, 109 format: 'esm', 110 absWorkingDir: testDir, 111 }) 112 const { errors, warnings } = await ctx.rebuild() 113 asserts.assertStrictEquals(errors.length, 0) 114 asserts.assertStrictEquals(warnings.length, 0) 115 await ctx.dispose() 116 const result = await import(path.toFileUrl(output)) 117 asserts.assertStrictEquals(result.default, true) 118 }) 119 120 test("basicPlugin", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => { 121 const build = await esbuild.build({ 122 entryPoints: ['<entry>'], 123 bundle: true, 124 format: 'esm', 125 write: false, 126 plugins: [{ 127 name: 'plug', 128 setup(build) { 129 build.onResolve({ filter: /^<.*>$/ }, args => ({ path: args.path, namespace: '<>' })) 130 build.onLoad({ filter: /^<entry>$/ }, () => ({ contents: `import dep from "<dep>"; export default dep === 123` })) 131 build.onLoad({ filter: /^<dep>$/ }, () => ({ contents: `export default 123` })) 132 }, 133 }], 134 }) 135 const result = await import('data:application/javascript;base64,' + btoa(build.outputFiles[0].text)) 136 asserts.assertStrictEquals(result.default, true) 137 }) 138 139 test("basicTransform", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => { 140 const ts = 'let x: number = 1+2' 141 const result = await esbuild.transform(ts, { loader: 'ts' }) 142 asserts.assertStrictEquals(result.code, 'let x = 1 + 2;\n') 143 }) 144 145 // This test doesn't run in WebAssembly because of a stack overflow 146 test("largeTransform", ['native'], async ({ esbuild }) => { 147 // This should be large enough to be bigger than Deno's write buffer 148 let x = '0' 149 for (let i = 0; i < 1000; i++) x += '+' + i 150 x += ',' 151 let y = 'return[' 152 for (let i = 0; i < 1000; i++) y += x 153 y += ']' 154 const result = await esbuild.build({ 155 stdin: { 156 contents: y, 157 }, 158 write: false, 159 minifyWhitespace: true, 160 }) 161 asserts.assertStrictEquals(result.outputFiles[0].text, y.slice(0, -2) + '];\n') 162 }) 163 164 test("analyzeMetafile", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => { 165 const result = await esbuild.analyzeMetafile({ 166 outputs: { 167 'out.js': { 168 bytes: 4096, 169 inputs: { 170 'in.js': { 171 bytesInOutput: 1024, 172 }, 173 }, 174 }, 175 }, 176 }) 177 asserts.assertStrictEquals(result, ` 178 out.js 4.0kb 100.0% 179 └ in.js 1.0kb 25.0% 180 `) 181 })