const { installForTests, removeRecursiveSync } = require('./esbuild')
const child_process = require('child_process')
const path = require('path')
const fs = require('fs')
const assert = require('assert')
const esbuild = installForTests()
const rootTestDir = path.join(__dirname, '.register-test')
removeRecursiveSync(rootTestDir)
fs.mkdirSync(rootTestDir)
const entry = path.join(rootTestDir, 'entry.ts')
fs.writeFileSync(entry, `
console.log('in entry.ts' as string)
require('./other.ts')
`)
const other = path.join(rootTestDir, 'other.ts')
fs.writeFileSync(other, `
console.log('in other.ts' as string)
`)
const register = path.join(rootTestDir, 'register.js')
fs.writeFileSync(register, `
const esbuild = require(${JSON.stringify(esbuild.ESBUILD_PACKAGE_PATH)});
const fs = require('fs');
require.extensions['.ts'] = (mod, filename) => {
const ts = fs.readFileSync(filename, 'utf8');
const { code } = esbuild.transformSync(ts, { loader: 'ts' });
mod._compile(code, filename);
};
`)
let tests = {
async fromMainThread() {
let result = await new Promise((resolve, reject) => child_process.execFile('node', ['-r', register, entry], (err, stdout) => {
if (err) reject(err)
else resolve(stdout)
}))
assert.strictEqual(result, `in entry.ts\nin other.ts\n`)
},
async fromChildThread({ testDir }) {
const startThread = path.join(testDir, 'startThread.js')
fs.writeFileSync(startThread, `
const worker_threads = require('worker_threads')
if (worker_threads.isMainThread) {
console.log('in startThread.js')
const worker = new worker_threads.Worker(__filename)
worker.postMessage(null)
worker.on('message', logs => {
for (const log of logs) console.log(log)
worker.terminate()
})
} else {
worker_threads.parentPort.on('message', () => {
console.log('in worker')
let logs = []
console.log = x => logs.push(x)
require('../entry.ts')
worker_threads.parentPort.postMessage(logs)
})
}
`)
let result = await new Promise((resolve, reject) => child_process.execFile('node', ['-r', register, startThread], (err, stdout) => {
if (err) reject(err)
else resolve(stdout)
}))
assert.strictEqual(result, `in startThread.js\nin worker\nin entry.ts\nin other.ts\n`)
},
}
async function main() {
let minutes = 5
let timeout = setTimeout(() => {
console.error(`❌ register tests timed out after ${minutes} minutes, exiting...`)
process.exit(1)
}, minutes * 60 * 1000)
const runTest = async ([name, fn]) => {
let testDir = path.join(rootTestDir, name)
try {
fs.mkdirSync(testDir)
await fn({ esbuild, testDir })
removeRecursiveSync(testDir)
return true
} catch (e) {
console.error(`❌ ${name}: ${e && e.message || e}`)
return false
}
}
let allTestsPassed = true
for (let test of Object.entries(tests)) {
if (!await runTest(test)) {
allTestsPassed = false
}
}
if (!allTestsPassed) {
console.error(`❌ register tests failed`)
process.exit(1)
} else {
console.log(`✅ register tests passed`)
removeRecursiveSync(rootTestDir)
}
clearTimeout(timeout);
}
main().catch(e => setTimeout(() => { throw e }))