mirror of
https://github.com/danbulant/oxc
synced 2026-05-20 12:48:38 +00:00
159 lines
4.4 KiB
JavaScript
159 lines
4.4 KiB
JavaScript
// https://github.com/evanw/esbuild/blob/main/scripts/test262.js
|
|
//
|
|
import fs from 'node:fs';
|
|
import { createServer } from 'node:http';
|
|
import path from 'node:path';
|
|
import process from 'node:process';
|
|
import vm from 'node:vm';
|
|
|
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
const harnessDir = path.join(__dirname, '../..', 'test262', 'harness');
|
|
|
|
const { Script, createContext, SourceTextModule, runInContext, SyntheticModule } = vm;
|
|
|
|
async function runCodeInHarness(options = {}) {
|
|
const { code = '', includes = [], importDir = '', isAsync = false, isModule = true, isRaw = false } = options;
|
|
const context = {};
|
|
|
|
if (process.env.DEBUG) {
|
|
const { code: c, ...o } = options;
|
|
console.log(c);
|
|
console.log(o);
|
|
}
|
|
|
|
const runCode = async () => {
|
|
const moduleCache = new Map();
|
|
const dynamicImportCache = new Map();
|
|
|
|
const findModule = (modulePath) => {
|
|
let module = moduleCache.get(modulePath);
|
|
if (!module) {
|
|
const code = fs.readFileSync(modulePath, 'utf8');
|
|
if (modulePath.endsWith('json')) {
|
|
const evaluate = function() {
|
|
this.setExport('default', runInContext('JSON.parse', context)(code));
|
|
};
|
|
module = new SyntheticModule(['default'], evaluate, { context });
|
|
} else {
|
|
module = new SourceTextModule(code, { context, importModuleDynamically });
|
|
}
|
|
moduleCache.set(modulePath, module);
|
|
}
|
|
return module;
|
|
};
|
|
|
|
const linker = (specifier) => {
|
|
return findModule(path.join(importDir, specifier));
|
|
};
|
|
|
|
const importModuleDynamically = (specifier) => {
|
|
const where = path.join(importDir, specifier);
|
|
let promise = dynamicImportCache.get(where);
|
|
if (!promise) {
|
|
const module = findModule(where);
|
|
if (module.status === 'unlinked') {
|
|
promise = module.link(linker)
|
|
.then(() => module.evaluate())
|
|
.then(() => module);
|
|
} else {
|
|
promise = Promise.resolve(module);
|
|
}
|
|
dynamicImportCache.set(where, promise);
|
|
}
|
|
return promise;
|
|
};
|
|
|
|
createContext(context);
|
|
if (!isRaw) runInContext(createHarnessForTest(includes), context);
|
|
|
|
if (isModule) {
|
|
const module = new SourceTextModule(code, { context, importModuleDynamically });
|
|
await module.link(linker);
|
|
await module.evaluate();
|
|
} else {
|
|
const script = new Script(code, { importModuleDynamically });
|
|
script.runInContext(context);
|
|
}
|
|
};
|
|
|
|
if (isAsync) {
|
|
await new Promise((resolve, reject) => {
|
|
context.$DONE = err => err ? reject(err) : resolve();
|
|
runCode().catch(reject);
|
|
});
|
|
} else {
|
|
await runCode();
|
|
}
|
|
}
|
|
|
|
const harnessFiles = new Map();
|
|
let defaultHarness = '';
|
|
|
|
for (const entry of fs.readdirSync(harnessDir)) {
|
|
if (entry.startsWith('.') || !entry.endsWith('.js')) {
|
|
continue;
|
|
}
|
|
const file = path.join(harnessDir, entry);
|
|
const content = fs.readFileSync(file, 'utf8');
|
|
if (entry === 'assert.js' || entry === 'sta.js') {
|
|
defaultHarness += content;
|
|
continue;
|
|
}
|
|
harnessFiles.set(entry, content);
|
|
}
|
|
|
|
const babelHelpers = fs.readFileSync(path.join(__dirname, './babelHelpers.js'), 'utf8');
|
|
|
|
function createHarnessForTest(includes) {
|
|
let harness = defaultHarness;
|
|
|
|
if (includes) {
|
|
for (const include of includes) {
|
|
const content = harnessFiles.get(include);
|
|
if (!content) throw new Error(`Included file is missing: ${include}`);
|
|
harness += content;
|
|
}
|
|
}
|
|
|
|
harness += babelHelpers;
|
|
|
|
return harness;
|
|
}
|
|
|
|
const server = createServer((req, res) => {
|
|
if (req.method == 'DELETE') {
|
|
server.closeAllConnections();
|
|
server.close();
|
|
}
|
|
if (req.method === 'POST') {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString(); // convert Buffer to string
|
|
});
|
|
req.on('end', async () => {
|
|
const options = JSON.parse(body);
|
|
try {
|
|
await runCodeInHarness(options);
|
|
} catch (err) {
|
|
if (parseInt(process.version.split('.')[0].replace('v', '')) < 22) {
|
|
return res.end('Please upgrade the Node.js version to 22 or later.');
|
|
}
|
|
return res.end(err.toString());
|
|
}
|
|
|
|
// res.setHeader('Content-Type', 'application/json');
|
|
res.end();
|
|
});
|
|
} else {
|
|
res.statusCode = 404;
|
|
res.end('Not Found');
|
|
}
|
|
});
|
|
|
|
process.on('unhandledRejection', () => {
|
|
// Don't exit when a test does this
|
|
});
|
|
|
|
server.timeout = 3000;
|
|
|
|
server.listen(32055, () => {});
|