Skip to content

Commit

Permalink
add parser tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkot committed Mar 25, 2016
1 parent 887b379 commit 16ce1ce
Show file tree
Hide file tree
Showing 5,562 changed files with 14,521 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
127 changes: 127 additions & 0 deletions parser-test/README.md
@@ -0,0 +1,127 @@
# 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; } }

0 comments on commit 16ce1ce

Please sign in to comment.