diff --git a/packages/runtime/src/cli/eval.ts b/packages/runtime/src/cli/eval.ts index 6da89d43b..611863d5a 100644 --- a/packages/runtime/src/cli/eval.ts +++ b/packages/runtime/src/cli/eval.ts @@ -1,14 +1,7 @@ -import { format } from './logger' import { EdgeRuntime } from '../edge-runtime' -export const inlineEval = async (scripts: string[]) => { - const results = [] - - for (const script of scripts) { - const runtime = new EdgeRuntime() - const result = await runtime.evaluate(script) - results.push(format(result)) - } - - return results +export const inlineEval = async (script: string) => { + const runtime = new EdgeRuntime() + const result = await runtime.evaluate(script) + return result } diff --git a/packages/runtime/src/cli/index.ts b/packages/runtime/src/cli/index.ts index e4707f061..f79561ca4 100644 --- a/packages/runtime/src/cli/index.ts +++ b/packages/runtime/src/cli/index.ts @@ -27,8 +27,7 @@ const { _: input, ...flags } = mri(process.argv.slice(2), { async function main() { if (flags.eval) { const { inlineEval } = await import('./eval') - const results = await inlineEval(input) - results.forEach((result) => console.log(result)) + console.log(await inlineEval(input[0])) return } @@ -74,7 +73,7 @@ async function main() { logger(`Waiting incoming requests at ${logger.quotes(server.url)}`) } -main().catch((err: unknown) => { - console.error(err) +main().catch((error: any) => { + if (!(error instanceof Error)) error = new Error(error) process.exit(1) }) diff --git a/packages/runtime/tests/repl.test.ts b/packages/runtime/tests/repl.test.ts index 4fe88cf63..1882fb890 100644 --- a/packages/runtime/tests/repl.test.ts +++ b/packages/runtime/tests/repl.test.ts @@ -7,6 +7,8 @@ type ChildPromise = { code: number } +const scriptPath = path.resolve(__dirname, '../dist/cli/index.js') + const childPromise = (subprocess: ChildProcess): Promise => new Promise((resolve) => { let stdout: any = '' @@ -23,89 +25,129 @@ const childPromise = (subprocess: ChildProcess): Promise => subprocess.on('close', (code) => resolve({ code, stdout, stderr })) }) -test('preload web standard APIs', async () => { - const scriptPath = path.resolve(__dirname, '../dist/cli/index.js') - - const cli = spawn('node', [ - scriptPath, - '--eval', - 'JSON.stringify(Object.getOwnPropertyNames(this))', - ]) +describe('contains all required primitives', () => { + it.each([ + { api: 'AbortController' }, + { api: 'AbortSignal' }, + { api: 'addEventListener' }, + { api: 'Array' }, + { api: 'ArrayBuffer' }, + { api: 'atob' }, + { api: 'Atomics' }, + { api: 'BigInt' }, + { api: 'BigInt64Array' }, + { api: 'BigUint64Array' }, + { api: 'Blob' }, + { api: 'Boolean' }, + { api: 'btoa' }, + { api: 'Cache' }, + { api: 'caches' }, + { api: 'caches' }, + { api: 'CacheStorage' }, + { api: 'clearInterval' }, + { api: 'clearTimeout' }, + { api: 'console' }, + { api: 'console' }, + { api: 'crypto' }, + { api: 'crypto' }, + { api: 'Crypto' }, + { api: 'CryptoKey' }, + { api: 'DataView' }, + { api: 'Date' }, + { api: 'decodeURI' }, + { api: 'decodeURIComponent' }, + { api: 'encodeURI' }, + { api: 'encodeURIComponent' }, + { api: 'Error' }, + { api: 'Error' }, + { api: 'escape' }, + { api: 'eval' }, + { api: 'EvalError' }, + { api: 'EvalError' }, + { api: 'Event' }, + { api: 'Event' }, + { api: 'EventTarget' }, + { api: 'fetch' }, + { api: 'FetchEvent' }, + { api: 'File' }, + { api: 'Float32Array' }, + { api: 'Float64Array' }, + { api: 'FormData' }, + { api: 'Function' }, + { api: 'globalThis' }, + { api: 'Headers' }, + { api: 'Infinity' }, + { api: 'Int8Array' }, + { api: 'Int16Array' }, + { api: 'Int32Array' }, + { api: 'Intl' }, + { api: 'isFinite' }, + { api: 'isNaN' }, + { api: 'JSON' }, + { api: 'Map' }, + { api: 'Math' }, + { api: 'NaN' }, + { api: 'Number' }, + { api: 'Object' }, + { api: 'parseFloat' }, + { api: 'parseInt' }, + { api: 'Promise' }, + { api: 'PromiseRejectionEvent' }, + { api: 'Proxy' }, + { api: 'RangeError' }, + { api: 'ReadableStream' }, + { api: 'ReadableStreamBYOBReader' }, + { api: 'ReadableStreamDefaultReader' }, + { api: 'ReferenceError' }, + { api: 'Reflect' }, + { api: 'RegExp' }, + { api: 'removeEventListener' }, + { api: 'Request' }, + { api: 'Response' }, + { api: 'self' }, + { api: 'Set' }, + { api: 'setInterval' }, + { api: 'setTimeout' }, + { api: 'SharedArrayBuffer' }, + { api: 'String' }, + { api: 'structuredClone' }, + { api: 'SubtleCrypto' }, + { api: 'Symbol' }, + { api: 'SyntaxError' }, + { api: 'TextDecoder' }, + { api: 'TextEncoder' }, + { api: 'TransformStream' }, + { api: 'TypeError' }, + { api: 'Uint8Array' }, + { api: 'Uint8ClampedArray' }, + { api: 'Uint16Array' }, + { api: 'Uint32Array' }, + { api: 'undefined' }, + { api: 'unescape' }, + { api: 'URIError' }, + { api: 'URL' }, + { api: 'URLPattern' }, + { api: 'URLSearchParams' }, + { api: 'WeakMap' }, + { api: 'WeakSet' }, + { api: 'WebAssembly' }, + { api: 'WritableStream' }, + { api: 'WritableStreamDefaultWriter' }, + ])('`$api` is defined in global scope', async ({ api }) => { + const assertion = (() => { + if (api === 'undefined') return `undefined === ${api}` + if (api === 'NaN') return `Number.isNaN(${api})` + return `!!${api}` + })() - const { stdout, code } = await childPromise(cli) - expect(code).toBe(0) + const cli = spawn('node', [ + scriptPath, + '--eval', + `JSON.stringify(${assertion})`, + ]) - const output: string[] = JSON.parse(stdout) - const normalized = output.filter((api) => !api.startsWith('__')).sort() - - expect(normalized).toStrictEqual([ - 'AggregateError', - 'Array', - 'ArrayBuffer', - 'Atomics', - 'BigInt', - 'BigInt64Array', - 'BigUint64Array', - 'Boolean', - 'DataView', - 'Date', - 'Error', - 'EvalError', - 'FinalizationRegistry', - 'Float32Array', - 'Float64Array', - 'Function', - 'Infinity', - 'Int16Array', - 'Int32Array', - 'Int8Array', - 'Intl', - 'JSON', - 'Map', - 'Math', - 'NaN', - 'Number', - 'Object', - 'Promise', - 'Proxy', - 'RangeError', - 'ReferenceError', - 'Reflect', - 'RegExp', - 'Set', - 'SharedArrayBuffer', - 'String', - 'Symbol', - 'SyntaxError', - 'TypeError', - 'URIError', - 'URLPattern', - 'Uint16Array', - 'Uint32Array', - 'Uint8Array', - 'Uint8ClampedArray', - 'WeakMap', - 'WeakRef', - 'WeakSet', - 'WebAssembly', - 'addEventListener', - 'caches', - 'console', - 'crypto', - 'decodeURI', - 'decodeURIComponent', - 'encodeURI', - 'encodeURIComponent', - 'escape', - 'eval', - 'globalThis', - 'isFinite', - 'isNaN', - 'parseFloat', - 'parseInt', - 'removeEventListener', - 'self', - 'undefined', - 'unescape', - ]) + const { stdout, stderr, code } = await childPromise(cli) + expect(code).toBe(0) + expect(JSON.parse(stdout)).toBe(true) + }) }) diff --git a/packages/vm/tests/unit/edge-vm.test.ts b/packages/vm/tests/unit/edge-vm.test.ts index 1cf5b3fe0..1ace0bfac 100644 --- a/packages/vm/tests/unit/edge-vm.test.ts +++ b/packages/vm/tests/unit/edge-vm.test.ts @@ -340,7 +340,7 @@ describe('contains all required primitives', () => { { api: 'WebAssembly' }, { api: 'WritableStream' }, { api: 'WritableStreamDefaultWriter' }, - ])('$api is defined in global scope', ({ api }) => { + ])('`$api` is defined in global scope', ({ api }) => { expect(edgeVM.evaluate(api)).toBeDefined() }) })