Skip to content

Commit

Permalink
Add regression test for #15902
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner committed Dec 21, 2024
1 parent ac3cd09 commit 50eec00
Showing 1 changed file with 340 additions and 0 deletions.
340 changes: 340 additions & 0 deletions test/cli/run/syntax.test.ts
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);
});
}
});

0 comments on commit 50eec00

Please sign in to comment.