-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ac3cd09
commit 50eec00
Showing
1 changed file
with
340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,340 @@ | ||
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/;", | ||
"/(?<!a)b/;", | ||
"/\\k<name>/;", | ||
"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/", | ||
"/(?<!(?!a)b)c/", | ||
"/\\k<name>\\k<other>/", | ||
"/\\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); | ||
}); | ||
} | ||
}); |