import { describe, expect, test } from "bun:test"; import { bunEnv, bunExe, tempDirWithFiles } from "harness"; import { join } from "path"; const exitCode0 = [ " ", "\n", "\t", "\r\n", " ", "\n\n\n", "export default '\\u{000C}'", "export default '\\u{200B}'", "export default '\\u{200C}'", "export default '\\u{200D}'", "export default '\\u{FEFF}'", '"use strict";', '"use strict";\n', "'use strict';", '"use strict";\n\n', '"use asm";', '"use asm";\n', "'use strict'; 'use asm';", '"use strict"; "use strict";', "// empty comment", "/* empty block comment */", "/** JSDoc comment */", "//\n//\n//", "/* \n Multi\n line\n comment\n */", "-->", "// TODO: ", "/** @type {number} */", "const a = 123;", "let a;", "var a = undefined;", "const a = null;", "const [a] = [];", "const {a} = {};", "const [...a] = [];", "const {...a} = {};", "let [a = 1] = [];", "let {a: b = 1} = {};", "``", "`template`", "`template${123}`", "`${null}`", "`${'`'}`", "`\n`", "`\n`", "({});", "({ a: 1 });", "({ ['computed']: 1 });", "({ get x() { return 1; } });", "({ __proto__: null });", "({ get [1+2](){}, set [1+2](x){} });", "({ a: 1, ...{b: 2} });", "[];", "[,];", "[,,];", "[1,];", "[,...[1]];", "[,,...[1]];", "[[[[[]]]]]", "[...[...[...[]]]]", "[1,,2,,3];", "Array(1_000_000).fill(1);", "()=>{};", "async()=>{};", "(function(){}).bind(null);", "()=>()=>()=>1;", "function f(a=1,{b}={},...c){};", "async function* f(){await 1; yield 2;};", "(async()=>await 1)();", "class A{}", "class A extends null{}", "class A{#private=1}", "class A{static{}}", "class A{get #a(){} set #a(x){}}", "class A{*#gen(){yield this.#p}#p=1}", "class A extends class B{}{};", "export {};", "export default 1;", "export default function(){};", "import.meta.url;", "const pi = Math.PI;", "const hello = 'world';", "const star = '⭐';", "'\\u0000\\uFFFF';", "'\\x00\\xFF';", "const \\u{61} = 1;", "'\\0';", "'\\v\\f\\b';", "'\\\r\n';", "/./;", "/[]/;", "/[^]/;", "/\\u{0}/u;", "/[\\u0000-\\u{10FFFF}]/u;", "/./gimsuyd;", "/\\p{Script=Latin}/u;", "/(?<=a)b/;", "/(?/;", "1n;", "0n;", "9007199254740991n;", "0b1n;", "0o7n;", "0xFn;", "1_2_3n;", "BigInt(1);", "-0n;", "~0n;", "0b1_0_1;", "0o7_7_7;", "0xF_F_F;", "1_2_3_4;", "try{}catch{}", "try{}catch(e){}", "try{}catch{}finally{}", "try{}finally{}", "try{throw 1}catch(e){}", "try{throw new Error}catch{}", "try{throw{}}catch({message}){}", "try{throw null}catch(e){}", "try{throw undefined}catch(e){}", "try{throw function(){}}catch(e){}", "function*g(){yield;}", "function*g(){yield*g();}", "async function*g(){yield;}", "async function*g(){await 1;}", "(async function*(){for await(x of y){}});", "function*g(){try{yield}finally{}}", "[...new Set];", "for(x of[]){}", "for await(x of[]){}", "async function f(){for await(x of y){}}", "void 0;", "new (class{})();", "(class extends null{});", "(class{[Symbol.hasInstance](){}});", "function*g(){yield yield yield;}", "1..toString();", "`${`${`${1}`}`}`", "String.raw`\n`", "String.raw`\\n`", "`${`${function*(){yield 1}}`}`", "`${class{}}${()=>{}}${/./}`", "`${`${async()=>await 1}`}`", "`${`${class{static{``}}}`}`", "await import('bun');", "await import('bun:ffi');", "await import(import.meta.path);", "/(?:)/", "/\\b\\B\\d\\D\\w\\W\\s\\S/", "/\\cA\\cZ\\ca\\cz/", "/\\p{General_Category=Letter}/u", "/\\p{Script_Extensions=Latin}/u", "/(?<=(?=a)b)c/", "/(?\\k/", "/\\u{10FFFF}\\u{0000}/u", "/[\\p{ASCII}--\\p{Decimal_Number}]/v", "const [{a: [b = 1] = []} = [{a: [2]}]] = [];", "let {a: {b: {c = 1} = {}} = {}} = {};", "const [a, , ...{0: b, length}] = [];", "const {[class{}.prop]: x} = {};", "const {[()=>{}]: x} = {};", "let {[/./]: x} = {};", "const {[class extends null{}]: x} = {};", "const {[function*(){}]: x} = {};", "function f([a] = [1], {b} = {b: 2}, ...c){}", "(function({[key]: value} = {}){})", "(({[this?.prop]: x} = {})=>{})", "function f(a = () => b, b = 1){}", "(a = class{}, b = new a)=>{}", "function f(a = new.target){}", "for await(const x of async function*(){yield 1}()){}", "for(const x of function*(){yield 1}()){}", "for(const {[key]: x} of []){}", "for(let [{a = 1} = {}] of []){}", "do{continue}while(false);", "label:do{break label}while(false);", "outer:for(;;)inner:break outer;", "block:{break block;}", "while(false)with(null);", "switch(0){case 1:default:case 2:}", "try{throw async()=>{}}catch(e){await e}", "try{throw class{}}catch(e){new e}", "try{throw{[Symbol.iterator]:()=>{}}}catch(e){}", "try{throw Object.create(null)}catch(e){}", "try{throw new Proxy({},{})}catch(e){}", "try{throw new WeakMap}catch(e){}", "try{throw new Int32Array}catch(e){}", "try{throw new SharedArrayBuffer(0)}catch(e){}", "try{throw new WebAssembly.Module(new Uint8Array)}catch(e){}", "void void void 0;", "typeof typeof typeof 0;", "delete (delete (delete 0));", "await (await (await 1));", "--{a:1}.a;", "(class{}).prototype.constructor;", "(()=>{}).prototype?.call;", "(async()=>{}).prototype?.call;", "(function*(){}).prototype.next;", "(async function*(){}).prototype.next;", "this?.prop?.[key]?.();", "0b0_1_0_1;", "0B0_1_0_1;", "0o0_1_2_3;", "0O0_1_2_3;", "0x0_1_2_3;", "0X0_1_2_3;", "1_2_3.4_5_6;", "1_2_3e1_2_3;", "1_2_3E1_2_3;", ".0_1_2_3;", "0b1_0_1n;", "0B1_0_1n;", "0o1_2_3n;", "0O1_2_3n;", "0x1_2_3n;", "0X1_2_3n;", "1_2_3_4_5n;", "BigInt(0b101);", "BigInt(0o777);", "BigInt(0xff);", "for(const [,,...a] of [[]]){}", "for(let {a: [b]} of []){}", "for await(const [a = await 1] of []){}", "for(const {[await 1]: x} of []){}", "for(var {[class{}]: x} of []){}", "for(let {[/./]: x} of []){}", "for(const {[`${a}`]: x} of []){}", "for await(const x of async function*(){yield*[1,2,3]}()){}", "new class extends (await Promise.resolve(class{})){}", "function*g(){yield yield*function*(){yield yield yield;}();}", "async function*f(){yield await Promise.all([1,2,3])}", "async function*f(){yield*[await 1,await 2]}", "(async function(){await (async()=>1)()})();", "async function*f(){for await(const x of async function*(){yield 1}())yield x}", "async function f(){return await new Promise(r=>r(1))}", "async function*f(){try{yield await 1}finally{await 2}}", "(async()=>{for await(const x of[])for await(const y of[]){}})();", "async function*f(){yield await(yield await(yield await 1))}", "async function*f(){yield*async function*(){yield await 1}()}", "export default await(async()=>1)();", "function*g(){yield*{[Symbol.iterator]:function*(){yield 1}}}", "function*g(){yield*{async*[Symbol.asyncIterator](){yield 1}}}", "function*g(){yield*function*(){yield function*(){yield 1}}()}", "function*g(){yield*{get[Symbol.iterator](){return function*(){yield 1}}}}", "function*g(){yield*(class{static*[Symbol.iterator](){yield 1}});}", "function*g(){yield*class{static*[Symbol.iterator](){yield 1}}}", "function*g(){yield*{*[Symbol.iterator](){yield class{}}}}", "function*g(){yield*{*[Symbol.iterator](){yield function(){}}}}", "function*g(){yield*{*[Symbol.iterator](){yield async()=>{}}}}", "function*g(){yield*{*[Symbol.iterator](){yield function*(){}}}}", "({[function*(){yield 1}]:1});", "({[async function*(){yield 1}]:1});", "({[(()=>class{})()]:1});", "({[new class{valueOf(){return 1}}]:2});", "({[new class{[Symbol.toPrimitive](){return 1}}]:2});", "({[new class{toString(){return '1'}}]:2});", "({[new class{get [Symbol.toPrimitive](){return()=>1}}]:2});", "({[new class{static{this.prototype.valueOf=()=>1}}]:2});", "label:while(1)try{continue label}finally{break label}", "new Proxy(class{},{construct(){return{}}});", "new Proxy(function(){},{apply(){return{}}});", "new Proxy({},{get(){return new Proxy({},{})}})", "new Proxy([],{get(){return new Proxy({},{})}});", "new Proxy(function(){},{construct(){return new Proxy({},{})}})", "new Proxy(class{},{construct(){return new Proxy({},{})}})", "new Proxy({},{get(){return function(){return new Proxy({},{})}}})", "new Proxy(function(){},{apply(){return new Proxy(class{},{})}})", "new Proxy(class{},{construct(){return new Proxy(function(){},{})}})", "Reflect.get(new Proxy({},{}),'')", "Reflect.set(new Proxy({},{}),'')", "Reflect.has(new Proxy({},{}),'')", "Reflect.deleteProperty(new Proxy({},{}),'')", "Reflect.getOwnPropertyDescriptor(new Proxy({},{}),'')", "Reflect.getPrototypeOf(new Proxy({},{}))", "Reflect.setPrototypeOf(new Proxy({},{}),{})", "Reflect.isExtensible(new Proxy({},{}))", "Reflect.preventExtensions(new Proxy({},{}))", "Promise.all([Promise.race([]),Promise.allSettled([])])", "Promise.race([Promise.all([]),Promise.any([])])", "Promise.allSettled([Promise.race([]),Promise.all([])])", "Promise.any([Promise.allSettled([]),Promise.race([])])", "Promise.resolve(Promise.reject().catch(()=>Promise.all([])))", "new Function(`return function*(){${`yield${`yield${`yield`}`}`}}`)();", "new Function(`return async()=>${`await${`await${`1`}`}`}`)();", "new Function(`return class{${`*[Symbol.iterator](){${`yield 1`}}`}}`)();", "new Function(`return class{${`async*[Symbol.asyncIterator](){${`yield 1`}}`}}`)();", "new Function(`return class{${`get #a(){${`return 1`}}`}}`)();", "new Function(`return class{${`set #a(v){${`this.#b=v`}}#b`}}`)();", "new Function(`return class{${`#a;${`#b;${`#c`}`}`}}`)();", "for await(let {...x} of async function*(){yield*[]}()){}", "for await(const x of (async function*(){yield await 1})()){}", "function f(){let a=b,b=1}", "(function(){const[a=b,b=1]=[]})", "(()=>{let{a=b,b=1}={}})", ]; describe("exit code 0", () => { const fixturePath = tempDirWithFiles("fixture", { [`package.json`]: `{ "name": "test", }`, "fixture.js": "export default 1", }); for (let i = 0; i < exitCode0.length; i++) { const source = exitCode0[i]; test(`file #${i}: ${JSON.stringify(source)}`, async () => { await Bun.write(join(fixturePath, "fixture.js"), source); await using proc = Bun.spawn([bunExe(), "./fixture.js"], { stdout: "inherit", env: bunEnv, cwd: fixturePath, stderr: "inherit", stdin: "inherit", }); const exitCode = await proc.exited; expect(exitCode).toBe(0); }); test(`eval #${i}: ${JSON.stringify(source)}`, async () => { await using proc = Bun.spawn([bunExe(), "--eval", source], { stdout: "inherit", env: bunEnv, stderr: "inherit", stdin: "inherit", }); const exitCode = await proc.exited; expect(exitCode).toBe(0); }); } });