Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add parser tests #559

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
84 changes: 84 additions & 0 deletions parser-test/README.md
@@ -0,0 +1,84 @@
# Parser Tests

This directory contains tests designed for parsers. There are three directories of tests:

- `pass/`, which contains syntactically valid ECMAScript programs,
- `early/`, which contains programs which match the grammar of ECMAScript but which trigger early errors, and
- `fail/`, which contains files which do not match the grammar of ECMAScript.

A fourth directory, `pass-explicit/`, contains alternative versions of the programs in `pass/`, for reasons discussed below.

Note that these tests are not intended to be evaluated, only parsed. Most would throw an error if run. Because they are testing syntax without depending on a functioning `eval()`, they include no metadata; each file is a utf8-encoded sequence of bytes which is to be parsed in full. The file `LICENSES.md` gives the origin and license of each file.


## Equivalence tests

Every file in `pass/` has a corresponding file in `pass-explicit/` of the same name. The explicit version (in `pass-explicit/`) is intended to appear as a human might write it, with parentheses included where there could conceivably be unclear precedence.

The two versions of each file should be parsed to structures which are equivalent excepting unnecessary whitespace, comments, grouping parentheses, and semicolons.


## Contributing

New `pass/` and `early/` tests should be normalized using the NPM module [normalize-parser-test](https://www.npmjs.com/package/normalize-parser-test). `pass/` tests should additionally have an explicit version created using the provided `node.js` program `make-explicit.js`, which requires node v5 or later.

Add copyright information for new tests to `licenses.md`.

## Sample consumer

Below is a `node.js` program which checks that a particular choice of parser has the correct behavior for all of the tests in this directory. Note that a parser which does not distinguish between early errors and other invalid syntax should treat the tests in `early/` just as they would the tests in `fail/`.

```js
const fs = require('fs');
const shift = require('shift-parser');
const assert = require('assert');

function parse(src, {isModule, earlyErrors}) {
(isModule ? shift.parseModule : shift.parseScript)(src, {earlyErrors});
}

let passExcludes = [];
let failExcludes = [];
let earlyExcludes = ['557.script.js', '558.script.js', '559.script.js', '560.script.js', '561.script.js', '563.script.js', '564.script.js', '565.script.js', '566.script.js', '567.script.js', '568.script.js', '569.script.js', '570.script.js', '571.script.js', '572.script.js', '574.script.js', '575.script.js', '576.script.js', '577.script.js', '578.script.js', '579.script.js', '580.script.js', '581.script.js', '582.script.js', '583.script.js', '585.script.js', '586.script.js', '587.script.js', '588.script.js', '589.script.js', '590.script.js', '591.script.js', '592.script.js', '593.script.js', '594.script.js', '596.script.js', '597.script.js', '598.script.js', '599.script.js', '600.script.js', '601.script.js', '602.script.js'];

fs.readdirSync('parser-test/pass').filter(f => !passExcludes.includes(f)).forEach(f => {
let firstTree, secondTree;
assert.doesNotThrow(() => {
firstTree = parse(
fs.readFileSync(`parser-test/pass/${f}`, 'utf8'),
{isModule: f.match('.module.js'), earlyErrors: true}
);
});
assert.doesNotThrow(() => {
secondTree = parse(
fs.readFileSync(`parser-test/pass-explicit/${f}`, 'utf8'),
{isModule: f.match('.module.js'), earlyErrors: true}
);
});
assert.deepStrictEqual(firstTree, secondTree);
});

fs.readdirSync('parser-test/fail').filter(f => !failExcludes.includes(f)).forEach(f => {
assert.throws(() => {
parse(
fs.readFileSync(`parser-test/fail/${f}`, 'utf8'),
{isModule: f.match('.module.js'), earlyErrors: false}
);
});
});

fs.readdirSync('parser-test/early').filter(f => !earlyExcludes.includes(f)).forEach(f => {
assert.doesNotThrow(() => {
parse(
fs.readFileSync(`parser-test/early/${f}`, 'utf8'),
{isModule: f.match('.module.js'), earlyErrors: false}
);
});
assert.throws(() => {
parse(
fs.readFileSync(`parser-test/early/${f}`, 'utf8'),
{isModule: f.match('.module.js'), earlyErrors: true}
);
});
});
```
1 change: 1 addition & 0 deletions parser-test/early/0.script.js
@@ -0,0 +1 @@
break
1 change: 1 addition & 0 deletions parser-test/early/1.script.js
@@ -0,0 +1 @@
continue
1 change: 1 addition & 0 deletions parser-test/early/10.script.js
@@ -0,0 +1 @@
(function () { 'use strict'; delete a; }())
1 change: 1 addition & 0 deletions parser-test/early/100.script.js
@@ -0,0 +1 @@
let let;
1 change: 1 addition & 0 deletions parser-test/early/101.script.js
@@ -0,0 +1 @@
"use strict"; const let = 1;
1 change: 1 addition & 0 deletions parser-test/early/102.script.js
@@ -0,0 +1 @@
var a = new.target;
1 change: 1 addition & 0 deletions parser-test/early/103.script.js
@@ -0,0 +1 @@
({ get __proto(){}, "__proto__": null, __proto__: null, })
1 change: 1 addition & 0 deletions parser-test/early/104.script.js
@@ -0,0 +1 @@
({ __proto__: null, "__proto__": null })
1 change: 1 addition & 0 deletions parser-test/early/105.script.js
@@ -0,0 +1 @@
({ __proto__: null, __proto__: null })
1 change: 1 addition & 0 deletions parser-test/early/106.script.js
@@ -0,0 +1 @@
({ "__proto__": null, __proto__: null })
1 change: 1 addition & 0 deletions parser-test/early/107.script.js
@@ -0,0 +1 @@
({ "__proto__": null, '__proto__': null })
1 change: 1 addition & 0 deletions parser-test/early/108.script.js
@@ -0,0 +1 @@
({ set __proto__(a){}, "__proto__": null, __proto__: null, })
1 change: 1 addition & 0 deletions parser-test/early/109.script.js
@@ -0,0 +1 @@
var a = super();
1 change: 1 addition & 0 deletions parser-test/early/11.script.js
@@ -0,0 +1 @@
(function () { 'use strict'; with (a); }())
1 change: 1 addition & 0 deletions parser-test/early/110.script.js
@@ -0,0 +1 @@
function* a() { (b = yield 1) => {} }
1 change: 1 addition & 0 deletions parser-test/early/111.script.js
@@ -0,0 +1 @@
"use strict"; function *a(){ var b = function yield(){}; }
1 change: 1 addition & 0 deletions parser-test/early/112.script.js
@@ -0,0 +1 @@
"use strict"; function *a() { var b = function(yield) {} }
1 change: 1 addition & 0 deletions parser-test/early/113.script.js
@@ -0,0 +1 @@
"use strict"; ([yield] = a)
1 change: 1 addition & 0 deletions parser-test/early/114.script.js
@@ -0,0 +1 @@
"use strict"; (a = yield) => {}
1 change: 1 addition & 0 deletions parser-test/early/115.script.js
@@ -0,0 +1 @@
"use strict"; (yield) => 1
1 change: 1 addition & 0 deletions parser-test/early/116.script.js
@@ -0,0 +1 @@
"use strict"; var { a: yield } = b;
1 change: 1 addition & 0 deletions parser-test/early/117.script.js
@@ -0,0 +1 @@
"use strict"; try {} catch (yield) {}
1 change: 1 addition & 0 deletions parser-test/early/118.script.js
@@ -0,0 +1 @@
"use strict"; function a(yield) {}
1 change: 1 addition & 0 deletions parser-test/early/119.script.js
@@ -0,0 +1 @@
"use strict"; function a() { yield }
1 change: 1 addition & 0 deletions parser-test/early/12.script.js
@@ -0,0 +1 @@
function a() {'use strict'; var eval = 1; }
1 change: 1 addition & 0 deletions parser-test/early/120.script.js
@@ -0,0 +1 @@
"use strict"; let yield = 1;
1 change: 1 addition & 0 deletions parser-test/early/121.script.js
@@ -0,0 +1 @@
"use strict"; function a(...yield) {}
1 change: 1 addition & 0 deletions parser-test/early/122.script.js
@@ -0,0 +1 @@
"use strict"; var yield;
1 change: 1 addition & 0 deletions parser-test/early/123.script.js
@@ -0,0 +1 @@
const a = 1, b;
1 change: 1 addition & 0 deletions parser-test/early/124.script.js
@@ -0,0 +1 @@
const a, b = 1;
1 change: 1 addition & 0 deletions parser-test/early/125.script.js
@@ -0,0 +1 @@
function a() { "use strict"; var yield; }
1 change: 1 addition & 0 deletions parser-test/early/126.script.js
@@ -0,0 +1 @@
function a() { "use strict"; var let; }
1 change: 1 addition & 0 deletions parser-test/early/127.script.js
@@ -0,0 +1 @@
__proto__: __proto__: 1;
1 change: 1 addition & 0 deletions parser-test/early/128.script.js
@@ -0,0 +1 @@
"use strict"; function a(__proto__, __proto__) { }
1 change: 1 addition & 0 deletions parser-test/early/129.script.js
@@ -0,0 +1 @@
a = { __proto__: 1, __proto__: 2 }
1 change: 1 addition & 0 deletions parser-test/early/13.script.js
@@ -0,0 +1 @@
function a() {'use strict'; var arguments = 1; }
1 change: 1 addition & 0 deletions parser-test/early/130.script.js
@@ -0,0 +1 @@
class a {static prototype(){}}
1 change: 1 addition & 0 deletions parser-test/early/131.script.js
@@ -0,0 +1 @@
class a {static "prototype"(){}}
1 change: 1 addition & 0 deletions parser-test/early/132.script.js
@@ -0,0 +1 @@
class a {get constructor(){}}
1 change: 1 addition & 0 deletions parser-test/early/133.script.js
@@ -0,0 +1 @@
class a {set constructor(b){}}
1 change: 1 addition & 0 deletions parser-test/early/134.script.js
@@ -0,0 +1 @@
class a {constructor(){} "constructor"(){}}
1 change: 1 addition & 0 deletions parser-test/early/135.script.js
@@ -0,0 +1 @@
class a {b(enum){}}
1 change: 1 addition & 0 deletions parser-test/early/136.script.js
@@ -0,0 +1 @@
class a {static [static](){};}
1 change: 1 addition & 0 deletions parser-test/early/137.script.js
@@ -0,0 +1 @@
function a() { "use strict"; implements = 1; }
1 change: 1 addition & 0 deletions parser-test/early/138.script.js
@@ -0,0 +1 @@
function a() { "use strict"; interface = 1; }
1 change: 1 addition & 0 deletions parser-test/early/139.script.js
@@ -0,0 +1 @@
function a() { "use strict"; let = 1; }
1 change: 1 addition & 0 deletions parser-test/early/14.script.js
@@ -0,0 +1 @@
function a() {'use strict'; try { } catch (eval) { } }
1 change: 1 addition & 0 deletions parser-test/early/140.script.js
@@ -0,0 +1 @@
function a() { "use strict"; package = 1; }
1 change: 1 addition & 0 deletions parser-test/early/141.script.js
@@ -0,0 +1 @@
function a() { "use strict"; private = 1; }
1 change: 1 addition & 0 deletions parser-test/early/142.script.js
@@ -0,0 +1 @@
function a() { "use strict"; protected = 1; }
1 change: 1 addition & 0 deletions parser-test/early/143.script.js
@@ -0,0 +1 @@
function a() { "use strict"; public = 1; }
1 change: 1 addition & 0 deletions parser-test/early/144.script.js
@@ -0,0 +1 @@
function a() { "use strict"; static = 1; }
1 change: 1 addition & 0 deletions parser-test/early/145.script.js
@@ -0,0 +1 @@
function a() { "use strict"; yield = 1; }
1 change: 1 addition & 0 deletions parser-test/early/146.script.js
@@ -0,0 +1 @@
"use strict"; for (a in let) {}
1 change: 1 addition & 0 deletions parser-test/early/147.module.js
@@ -0,0 +1 @@
export { a }
1 change: 1 addition & 0 deletions parser-test/early/148.module.js
@@ -0,0 +1 @@
export { a, b }
1 change: 1 addition & 0 deletions parser-test/early/149.module.js
@@ -0,0 +1 @@
export { a as default }
1 change: 1 addition & 0 deletions parser-test/early/15.script.js
@@ -0,0 +1 @@
function a() {'use strict'; try { } catch (arguments) { } }
1 change: 1 addition & 0 deletions parser-test/early/150.module.js
@@ -0,0 +1 @@
export { a, b as c }
1 change: 1 addition & 0 deletions parser-test/early/151.script.js
@@ -0,0 +1 @@
"use strict"; (class a {constructor() { super() }})
1 change: 1 addition & 0 deletions parser-test/early/152.script.js
@@ -0,0 +1 @@
"use strict"; (class a { static constructor() { super() }})
1 change: 1 addition & 0 deletions parser-test/early/153.script.js
@@ -0,0 +1 @@
function a(b, { b }){}
11 changes: 11 additions & 0 deletions parser-test/early/154.script.js
@@ -0,0 +1,11 @@
(function () {
{
function a() {
b.c('d');
}
function a() {
b.c('e');
}
a();
}
}());
14 changes: 14 additions & 0 deletions parser-test/early/155.script.js
@@ -0,0 +1,14 @@
function a() {
b.c('d');
}
function a() {
b.c('e');
}
{
function a() {
b.c('d');
}
function a() {
b.c('e');
}
}
20 changes: 20 additions & 0 deletions parser-test/early/156.script.js
@@ -0,0 +1,20 @@
// Do not optimize this pattern
function a() {
b.c('d');
}

{
function a() {
b.c('d');
}
a();
function a() {
b.c('e');
}
}

a();

function a() {
b.c('e');
}
1 change: 1 addition & 0 deletions parser-test/early/157.script.js
@@ -0,0 +1 @@
function a(b, b) {'use strict';}
4 changes: 4 additions & 0 deletions parser-test/early/158.script.js
@@ -0,0 +1,4 @@
"use strict";
function a([a,a]){ }
function a([a,...a]){ }
function a([{a},...a]){ }
1 change: 1 addition & 0 deletions parser-test/early/159.script.js
@@ -0,0 +1 @@
class a {b(eval){}}
1 change: 1 addition & 0 deletions parser-test/early/16.script.js
@@ -0,0 +1 @@
function a() {'use strict'; eval = 1; }
1 change: 1 addition & 0 deletions parser-test/early/160.module.js
@@ -0,0 +1 @@
export {a as default};
1 change: 1 addition & 0 deletions parser-test/early/161.module.js
@@ -0,0 +1 @@
export {a as b};
1 change: 1 addition & 0 deletions parser-test/early/162.module.js
@@ -0,0 +1 @@
export {a as default, b};
1 change: 1 addition & 0 deletions parser-test/early/163.module.js
@@ -0,0 +1 @@
export {a};
1 change: 1 addition & 0 deletions parser-test/early/164.module.js
@@ -0,0 +1 @@
export {a, b,};
1 change: 1 addition & 0 deletions parser-test/early/165.module.js
@@ -0,0 +1 @@
export {a, b};
1 change: 1 addition & 0 deletions parser-test/early/166.script.js
@@ -0,0 +1 @@
function *a() { (b = yield) => {} }
1 change: 1 addition & 0 deletions parser-test/early/167.script.js
@@ -0,0 +1 @@
function *a(b = yield){}
1 change: 1 addition & 0 deletions parser-test/early/168.script.js
@@ -0,0 +1 @@
'use strict'; ({arguments} = 1);
1 change: 1 addition & 0 deletions parser-test/early/169.script.js
@@ -0,0 +1 @@
'use strict'; ({arguments = 1} = 2);
1 change: 1 addition & 0 deletions parser-test/early/17.script.js
@@ -0,0 +1 @@
function a() {'use strict'; arguments = 1; }
1 change: 1 addition & 0 deletions parser-test/early/170.script.js
@@ -0,0 +1 @@
{ let a; let a; }
1 change: 1 addition & 0 deletions parser-test/early/171.script.js
@@ -0,0 +1 @@
{ let a; const a = 1; }
1 change: 1 addition & 0 deletions parser-test/early/172.script.js
@@ -0,0 +1 @@
{ const a = 1; let a; }
1 change: 1 addition & 0 deletions parser-test/early/173.script.js
@@ -0,0 +1 @@
{ const a = 1; const a = 2; }
1 change: 1 addition & 0 deletions parser-test/early/174.script.js
@@ -0,0 +1 @@
{ function a(){} function a(){} }
1 change: 1 addition & 0 deletions parser-test/early/175.script.js
@@ -0,0 +1 @@
{ function a(){} function* a(){} }
1 change: 1 addition & 0 deletions parser-test/early/176.script.js
@@ -0,0 +1 @@
{ let a; function a(){} }
1 change: 1 addition & 0 deletions parser-test/early/177.script.js
@@ -0,0 +1 @@
{ const a = 1; function a(){} }
1 change: 1 addition & 0 deletions parser-test/early/178.script.js
@@ -0,0 +1 @@
{ let a; var a; }
1 change: 1 addition & 0 deletions parser-test/early/179.script.js
@@ -0,0 +1 @@
{ let a; { var a; } }
1 change: 1 addition & 0 deletions parser-test/early/18.script.js
@@ -0,0 +1 @@
function a() {'use strict'; ++eval; }
1 change: 1 addition & 0 deletions parser-test/early/180.script.js
@@ -0,0 +1 @@
{ var a; let a; }
1 change: 1 addition & 0 deletions parser-test/early/181.script.js
@@ -0,0 +1 @@
{ const a = 1; var a; }
1 change: 1 addition & 0 deletions parser-test/early/182.script.js
@@ -0,0 +1 @@
{ var a; const a = 1; }
1 change: 1 addition & 0 deletions parser-test/early/183.script.js
@@ -0,0 +1 @@
let let;
1 change: 1 addition & 0 deletions parser-test/early/184.script.js
@@ -0,0 +1 @@
let a, let;
1 change: 1 addition & 0 deletions parser-test/early/185.script.js
@@ -0,0 +1 @@
let a, let = 1;
1 change: 1 addition & 0 deletions parser-test/early/186.script.js
@@ -0,0 +1 @@
for(let let;;);
1 change: 1 addition & 0 deletions parser-test/early/187.script.js
@@ -0,0 +1 @@
for(let a, let;;);
1 change: 1 addition & 0 deletions parser-test/early/188.script.js
@@ -0,0 +1 @@
for(const let = 1;;);
1 change: 1 addition & 0 deletions parser-test/early/189.script.js
@@ -0,0 +1 @@
for(const a = 1, let = 2;;);
1 change: 1 addition & 0 deletions parser-test/early/19.script.js
@@ -0,0 +1 @@
function a() {'use strict'; --eval; }
1 change: 1 addition & 0 deletions parser-test/early/190.script.js
@@ -0,0 +1 @@
for(let [let];;);
1 change: 1 addition & 0 deletions parser-test/early/191.script.js
@@ -0,0 +1 @@
let a, a;