mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Add regression test for #15902
This commit is contained in:
340
test/cli/run/syntax.test.ts
Normal file
340
test/cli/run/syntax.test.ts
Normal file
@@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user