module: correctly detect top-level await in ambiguous contexts · nodejs/node@7880978

1+

import { spawnPromisified } from '../common/index.mjs';

2+

import { describe, it } from 'node:test';

3+

import { strictEqual, match } from 'node:assert';

4+5+

describe('unusual top-level await syntax errors', () => {

6+

const expressions = [

7+

// string

8+

{ expression: '""' },

9+

// number

10+

{ expression: '0' },

11+

// boolean

12+

{ expression: 'true' },

13+

// null

14+

{ expression: 'null' },

15+

// undefined

16+

{ expression: 'undefined' },

17+

// object

18+

{ expression: '{}' },

19+

// array

20+

{ expression: '[]' },

21+

// new

22+

{ expression: 'new Date()' },

23+

// identifier

24+

{ initialize: 'const a = 2;', expression: 'a' },

25+

];

26+

it('should not crash the process', async () => {

27+

for (const { expression, initialize } of expressions) {

28+

const wrapperExpressions = [

29+

`function callAwait() {}; callAwait(await ${expression});`,

30+

`if (await ${expression}) {}`,

31+

`{ key: await ${expression} }`,

32+

`[await ${expression}]`,

33+

`(await ${expression})`,

34+

];

35+

for (const wrapperExpression of wrapperExpressions) {

36+

const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [

37+

'--eval',

38+

`

39+

${initialize || ''}

40+

${wrapperExpression}

41+

`,

42+

]);

43+44+

strictEqual(stderr, '');

45+

strictEqual(stdout, '');

46+

strictEqual(code, 0);

47+

strictEqual(signal, null);

48+

}

49+

}

50+

});

51+52+

it('should throw the error for unrelated syntax errors', async () => {

53+

const expression = 'foo bar';

54+

const wrapperExpressions = [

55+

[`function callSyntaxError() {}; callSyntaxError(${expression});`, /missing \) after argument list/],

56+

[`if (${expression}) {}`, /Unexpected identifier/],

57+

[`{ key: ${expression} }`, /Unexpected identifier/],

58+

[`[${expression}]`, /Unexpected identifier/],

59+

[`(${expression})`, /Unexpected identifier/],

60+

[`const ${expression} = 1;`, /Missing initializer in const declaration/],

61+

[`console.log('PI: ' Math.PI);`, /missing \) after argument list/],

62+

[`callAwait(await "" "");`, /missing \) after argument list/],

63+

];

64+65+

for (const [wrapperExpression, error] of wrapperExpressions) {

66+

const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [

67+

'--eval',

68+

`

69+

${wrapperExpression}

70+

`,

71+

]);

72+

match(stderr, error);

73+

strictEqual(stdout, '');

74+

strictEqual(code, 1);

75+

strictEqual(signal, null);

76+

}

77+

});

78+

});