Add testing

- This brings in the flow test suite that contains a ton of JavaScript parsing edge cases
- This creates snapshot tests using the pretty printer for all of them
- If uncomment `RUN_AST_TESTS` line in `tests/run_specs.js`, it checks ast(pretty_print(x)) == ast(x). Right now, "178 failed, 197 passed, 375 of 377 total". So half of the tests are not passing, most of them are crashes and many of the rest are subtle issues.
This commit is contained in:
Christopher Chedeau committed 2016-12-23 19:51:53 +00:00
1 parent d5b07f5c3d
commit cf45afba61
1873 files changed
+93549 -1

No files matched your search

+14 -1
View File
@@ -11,6 +11,19 @@
"recast": "^0.11.18" "recast": "^0.11.18"
}, },
"devDependencies": { "devDependencies": {
"glob": "^7.1.1" "glob": "^7.1.1",
"jest": "^18.0.0",
"flow-parser": "^0.37.0"
},
"scripts": {
"test": "jest"
},
"jest": {
"setupFiles": [
"<rootDir>/tests_config/run_spec.js"
],
"testRegex": [
"jsfmt\\.spec\\.js$"
]
} }
} }
@@ -0,0 +1,127 @@
exports[`test break-continue.js 1`] = `
"function foo() {
while(true) { break; }
}
function bar() {
L: do { continue L; } while(false)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:925
if (endsWithBrace(doBody))
^
ReferenceError: endsWithBrace is not defined
at genericPrintNoParens (/src/printer.js:925:11)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:963:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test return.js 1`] = `
"function bar(x:number) { }
function foo() {
var x = null;
if (x == null) return;
bar(x);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bar(x: number) {
}
function foo() {
var x = null;
if (x == null)
return;
bar(x);
}
"
`;
exports[`test toplevel_break.js 1`] = `
"// @flow
break; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unsyntactic break (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseBreakContinueStatement (/node_modules/babylon/lib/index.js:1843:44)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1703:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_continue.js 1`] = `
"// @flow
continue; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unsyntactic continue (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseBreakContinueStatement (/node_modules/babylon/lib/index.js:1843:44)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1703:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_return.js 1`] = `
"// @flow
return; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: \'return\' outside of function (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseReturnStatement (/node_modules/babylon/lib/index.js:1939:10)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1722:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_throw.js 1`] = `
"// @flow
throw new Error(\'foo\'); // no error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
throw new Error(\"foo\");// no error
"
`;
+7
View File
@@ -0,0 +1,7 @@
function foo() {
while(true) { break; }
}
function bar() {
L: do { continue L; } while(false)
}
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+6
View File
@@ -0,0 +1,6 @@
function bar(x:number) { }
function foo() {
var x = null;
if (x == null) return;
bar(x);
}
+3
View File
@@ -0,0 +1,3 @@
// @flow
break; // error, illegal
+3
View File
@@ -0,0 +1,3 @@
// @flow
continue; // error, illegal
+3
View File
@@ -0,0 +1,3 @@
// @flow
return; // error, illegal
+3
View File
@@ -0,0 +1,3 @@
// @flow
throw new Error('foo'); // no error
@@ -0,0 +1,234 @@
exports[`test annot.js 1`] = `
"function foo(str:string, i:number):string {
return str;
}
var bar: (str:number, i:number)=> string = foo;
var qux = function(str:string, i:number):number { return foo(str,i); }
var obj: {str:string; i:number; j:boolean} = {str: \"...\", i: \"...\", k: false};
var arr: Array<number> = [1,2,\"...\"];
// array sugar
var array: number[] = [1,2,\"...\"];
var matrix: number[][] = [[1,2],[3,4]];
var matrix_parens: (number[])[] = matrix;
var nullable_array: ?number[] = null;
var nullable_array_parens: ?(number[]) = nullable_array;
var array_of_nullable: (?number)[] = [null, 3];
var array_of_tuple: [number, string][] = [[0, \"foo\"], [1, \"bar\"]];
var array_of_tuple_parens: ([number, string])[] = array_of_tuple;
type ObjType = { \'bar-foo\': string; \'foo-bar\': number; };
var test_obj: ObjType = { \'bar-foo\': \'23\' };
// param type annos are strict UBs like var type annos
function param_anno(n:number):void {
n = \"hey\"; // error
}
// another error on param UB, more typical of www (mis)use-cases
// this one cribbed from API.atlas.js
function param_anno2(
batchRequests: Array<{method: string; path: string; params: ?Object}>,
): void {
// error below, since we\'re assigning elements to batchRequests
// which lack a path property.
// just assign result to new var instead of reassigning to param.
// Transform the requests to the format the Graph API expects.
batchRequests = batchRequests.map((request) => {
return {
method: request.method,
params: request.params,
relative_url: request.path,
};
});
// ...
}
var toz : null = 3;
var zer : null = null;
function foobar(n : ?number) : number | null | void { return n; }
function barfoo(n : number | null | void) : ?number { return n; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test forward_ref.js 1`] = `
"let myClassInstance: MyClass = null; // forward ref ok, null ~> class error
function bar(): MyClass {
return null; // forward ref ok, null ~> class error
}
class MyClass { } // looked up above
function foo() {
let myClassInstance: MyClass = mk(); // ok (no confusion across scopes)
function mk() { return new MyClass(); }
class MyClass { } // looked up above
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let myClassInstance: MyClass = null;// forward ref ok, null ~> class error
function bar(): MyClass {
return null;// forward ref ok, null ~> class error
}
class MyClass {}// looked up above
function foo() {
let myClassInstance: MyClass = mk();// ok (no confusion across scopes)
function mk() {
return new MyClass();
}
class MyClass {}// looked up above
}
"
`;
exports[`test issue-530.js 1`] = `
"function foo(...args: any) { }
module.exports = foo;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo(...args) {
}
module.exports = foo;
"
`;
exports[`test leak.js 1`] = `
"/** @flow */
/* This test documents an example we ran into of a type annotation leaking.
*
* When foo() calls bar(), we should make sure the type of x matches the type
* annotation for y and stop. We should type the body of bar() with the type
* annotation of y.
*
* However, the leaky type annotation meant that we were flowing x\'s type to y
* and type checking the body of bar() using the stricter dictionary type,
* leading to an error.
*/
type MyObj = Object;
function foo(x: {[key: string]: mixed}) {
bar(x);
}
function bar(y: MyObj): string {
return y.foo;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** @flow */
/* This test documents an example we ran into of a type annotation leaking.
*
* When foo() calls bar(), we should make sure the type of x matches the type
* annotation for y and stop. We should type the body of bar() with the type
* annotation of y.
*
* However, the leaky type annotation meant that we were flowing x\'s type to y
* and type checking the body of bar() using the stricter dictionary type,
* leading to an error.
*/
type MyObj = Object;
function foo(x: { [key: string]: mixed }) {
bar(x);
}
function bar(y: MyObj): string {
return y.foo;
}
"
`;
exports[`test other.js 1`] = `
"class C { }
module.exports = (C: any);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {}
module.exports = (C: any);
"
`;
exports[`test scope.js 1`] = `
"type Merge<T> = (a: T, b: T) => T;
// hypothetical immutable map
declare class Map<K,V> {
(): Map<K,V>;
insertWith(fn: Merge<V>, k: K, v: V): Map<K,V>;
}
declare function foldr<A,B>(fn: (a: A, b: B) => B, b: B, as: A[]): B;
function insertMany<K,V>(merge: Merge<V>, vs: [K,V][], m: Map<K,V>): Map<K,V> {
function f([k,v]: [K,V], m: Map<K,V>): Map<K,V> {
return m.insertWith(merge, k, v)
}
return foldr(f, m, vs)
}
class Foo<A> {
bar<B>() {
return function<C>(a: A, b: B, c: C): void {
([a,b,c] : [A,B,C]);
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1479:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test test.js 1`] = `
"var C = require(\'./other\');
((0: C): string);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var C = require(\"./other\");
((0: C): string);
"
`;
+60
View File
@@ -0,0 +1,60 @@
function foo(str:string, i:number):string {
return str;
}
var bar: (str:number, i:number)=> string = foo;
var qux = function(str:string, i:number):number { return foo(str,i); }
var obj: {str:string; i:number; j:boolean} = {str: "...", i: "...", k: false};
var arr: Array<number> = [1,2,"..."];
// array sugar
var array: number[] = [1,2,"..."];
var matrix: number[][] = [[1,2],[3,4]];
var matrix_parens: (number[])[] = matrix;
var nullable_array: ?number[] = null;
var nullable_array_parens: ?(number[]) = nullable_array;
var array_of_nullable: (?number)[] = [null, 3];
var array_of_tuple: [number, string][] = [[0, "foo"], [1, "bar"]];
var array_of_tuple_parens: ([number, string])[] = array_of_tuple;
type ObjType = { 'bar-foo': string; 'foo-bar': number; };
var test_obj: ObjType = { 'bar-foo': '23' };
// param type annos are strict UBs like var type annos
function param_anno(n:number):void {
n = "hey"; // error
}
// another error on param UB, more typical of www (mis)use-cases
// this one cribbed from API.atlas.js
function param_anno2(
batchRequests: Array<{method: string; path: string; params: ?Object}>,
): void {
// error below, since we're assigning elements to batchRequests
// which lack a path property.
// just assign result to new var instead of reassigning to param.
// Transform the requests to the format the Graph API expects.
batchRequests = batchRequests.map((request) => {
return {
method: request.method,
params: request.params,
relative_url: request.path,
};
});
// ...
}
var toz : null = 3;
var zer : null = null;
function foobar(n : ?number) : number | null | void { return n; }
function barfoo(n : number | null | void) : ?number { return n; }
+9
View File
@@ -0,0 +1,9 @@
type T = any;
export default class {
p: T;
constructor() {
this.p = 0;
}
}
+5
View File
@@ -0,0 +1,5 @@
import A from "./A"
class B extends A {
p: string; // OK, string ~> any
}
@@ -0,0 +1,36 @@
exports[`test A.js 1`] = `
"type T = any;
export default class {
p: T;
constructor() {
this.p = 0;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
type T = any;
export default class {
p: T;
constructor() {
this.p = 0;
}
}
"
`;
exports[`test B.js 1`] = `
"import A from "./A"
class B extends A {
p: string; // OK, string ~> any
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import A from "./A";
class B extends A {
p: string;// OK, string ~> any
}
"
`;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+14
View File
@@ -0,0 +1,14 @@
let myClassInstance: MyClass = null; // forward ref ok, null ~> class error
function bar(): MyClass {
return null; // forward ref ok, null ~> class error
}
class MyClass { } // looked up above
function foo() {
let myClassInstance: MyClass = mk(); // ok (no confusion across scopes)
function mk() { return new MyClass(); }
class MyClass { } // looked up above
}
+3
View File
@@ -0,0 +1,3 @@
function foo(...args: any) { }
module.exports = foo;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+22
View File
@@ -0,0 +1,22 @@
/** @flow */
/* This test documents an example we ran into of a type annotation leaking.
*
* When foo() calls bar(), we should make sure the type of x matches the type
* annotation for y and stop. We should type the body of bar() with the type
* annotation of y.
*
* However, the leaky type annotation meant that we were flowing x's type to y
* and type checking the body of bar() using the stricter dictionary type,
* leading to an error.
*/
type MyObj = Object;
function foo(x: {[key: string]: mixed}) {
bar(x);
}
function bar(y: MyObj): string {
return y.foo;
}
+2
View File
@@ -0,0 +1,2 @@
class C { }
module.exports = (C: any);
+24
View File
@@ -0,0 +1,24 @@
type Merge<T> = (a: T, b: T) => T;
// hypothetical immutable map
declare class Map<K,V> {
(): Map<K,V>;
insertWith(fn: Merge<V>, k: K, v: V): Map<K,V>;
}
declare function foldr<A,B>(fn: (a: A, b: B) => B, b: B, as: A[]): B;
function insertMany<K,V>(merge: Merge<V>, vs: [K,V][], m: Map<K,V>): Map<K,V> {
function f([k,v]: [K,V], m: Map<K,V>): Map<K,V> {
return m.insertWith(merge, k, v)
}
return foldr(f, m, vs)
}
class Foo<A> {
bar<B>() {
return function<C>(a: A, b: B, c: C): void {
([a,b,c] : [A,B,C]);
}
}
}
+2
View File
@@ -0,0 +1,2 @@
var C = require('./other');
((0: C): string);
+14
View File
@@ -0,0 +1,14 @@
/**
* @providesModule A
* @flow
*/
import type T from "T";
export default class {
p: T;
constructor() {
this.p = 0;
}
}
+9
View File
@@ -0,0 +1,9 @@
/**
* @flow
*/
import A from "A"
class B extends A {
p: string; // OK, string ~> any
}
+3
View File
@@ -0,0 +1,3 @@
/**
* @providesModule T
*/
@@ -0,0 +1,62 @@
exports[`test A.js 1`] = `
"/**
* @providesModule A
* @flow
*/
import type T from "T";
export default class {
p: T;
constructor() {
this.p = 0;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @providesModule A
* @flow
*/
import type T from "T";
export default class {
p: T;
constructor() {
this.p = 0;
}
}
"
`;
exports[`test B.js 1`] = `
"/**
* @flow
*/
import A from "A"
class B extends A {
p: string; // OK, string ~> any
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @flow
*/
import A from "A";
class B extends A {
p: string;// OK, string ~> any
}
"
`;
exports[`test T.js 1`] = `
"/**
* @providesModule T
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"
`;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+202
View File
@@ -0,0 +1,202 @@
exports[`test any.js 1`] = `
"// @flow
function foo(x:any):any { return x; }
function bar(x:any):mixed { return x; }
function qux(x:mixed):any { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
function foo(x: any): any {
return x;
}
function bar(x: any): mixed {
return x;
}
function qux(x: mixed): any {
return x;
}
var x: string = foo(0);
var y: string = bar(0);
var z: string = qux(0);
"
`;
exports[`test anyexportflowfile.js 1`] = `
"// @flow
module.exports = ((x: any) => x: any);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
module.exports = ((x: any) => x: any);
"
`;
exports[`test flowfixme.js 1`] = `
"/*
FlowFixMe is a synonym for any, used by the Flow team to
signal a needed mod to JS devs.
@flow
*/
// no param
function foo(x:$FlowFixMe):$FlowFixMe { return x; }
function bar(x:$FlowFixMe):mixed { return x; }
// param (info only)
function qux(x:$FlowFixMe<number>):$FlowFixMe<number> { return x; }
// ...params are still checked. unknown type
function baz(x:$FlowFixMe<nnumber>): $FlowFixMe<number> { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test flowissue.js 1`] = `
"/*
$FlowIssue is a synonym for any, used by JS devs to signal
a potential typechecker bug to the Flow team.
@flow
*/
// no param
function foo(x:$FlowIssue):$FlowIssue { return x; }
function bar(x:$FlowIssue):mixed { return x; }
// param (info only)
function qux(x:$FlowIssue<number>):$FlowIssue<number> { return x; }
// ...params are still checked. unknown type
function baz(x:$FlowIssue<nnumber>): $FlowIssue<number> { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test nonflowfile.js 1`] = `
"// @noflow
module.exports = (x) => x;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
module.exports = x => x;
"
`;
exports[`test propagate.js 1`] = `
"// @flow
declare class C {
bar(n1: number, n2: number): number;
bar(s1: string, s2: string): string;
}
function foo(c: C, x: any): string {
let y = x.y;
return c.bar(0, y); // should be able to select first case and error
}
var any_fun1 = require(\'./nonflowfile\');
function bar1(x: mixed) {
if (any_fun1(x)) {
(x: boolean);
}
}
var any_fun2 = require(\'./anyexportflowfile\');
function bar2(x: mixed) {
if (any_fun2(x)) {
(x: boolean);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test reach.js 1`] = `
"/**
* like class and function values, any-typed values may be used in
* type annotations. Here we test propagation of any through the
* annotation - without it, the body of the if will be unreachable
*/
type AsyncRequest = any;
function foo(o: ?AsyncRequest) {
if (o) {
var n: number = o;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* like class and function values, any-typed values may be used in
* type annotations. Here we test propagation of any through the
* annotation - without it, the body of the if will be unreachable
*/
type AsyncRequest = any;
function foo(o: ?AsyncRequest) {
if (o) {
var n: number = o;
}
}
"
`;
+9
View File
@@ -0,0 +1,9 @@
// @flow
function foo(x:any):any { return x; }
function bar(x:any):mixed { return x; }
function qux(x:mixed):any { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
+3
View File
@@ -0,0 +1,3 @@
// @flow
module.exports = ((x: any) => x: any);
+19
View File
@@ -0,0 +1,19 @@
/*
FlowFixMe is a synonym for any, used by the Flow team to
signal a needed mod to JS devs.
@flow
*/
// no param
function foo(x:$FlowFixMe):$FlowFixMe { return x; }
function bar(x:$FlowFixMe):mixed { return x; }
// param (info only)
function qux(x:$FlowFixMe<number>):$FlowFixMe<number> { return x; }
// ...params are still checked. unknown type
function baz(x:$FlowFixMe<nnumber>): $FlowFixMe<number> { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
+19
View File
@@ -0,0 +1,19 @@
/*
$FlowIssue is a synonym for any, used by JS devs to signal
a potential typechecker bug to the Flow team.
@flow
*/
// no param
function foo(x:$FlowIssue):$FlowIssue { return x; }
function bar(x:$FlowIssue):mixed { return x; }
// param (info only)
function qux(x:$FlowIssue<number>):$FlowIssue<number> { return x; }
// ...params are still checked. unknown type
function baz(x:$FlowIssue<nnumber>): $FlowIssue<number> { return x; }
var x:string = foo(0);
var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+3
View File
@@ -0,0 +1,3 @@
// @noflow
module.exports = (x) => x;
+25
View File
@@ -0,0 +1,25 @@
// @flow
declare class C {
bar(n1: number, n2: number): number;
bar(s1: string, s2: string): string;
}
function foo(c: C, x: any): string {
let y = x.y;
return c.bar(0, y); // should be able to select first case and error
}
var any_fun1 = require('./nonflowfile');
function bar1(x: mixed) {
if (any_fun1(x)) {
(x: boolean);
}
}
var any_fun2 = require('./anyexportflowfile');
function bar2(x: mixed) {
if (any_fun2(x)) {
(x: boolean);
}
}
+13
View File
@@ -0,0 +1,13 @@
/**
* like class and function values, any-typed values may be used in
* type annotations. Here we test propagation of any through the
* annotation - without it, the body of the if will be unreachable
*/
type AsyncRequest = any;
function foo(o: ?AsyncRequest) {
if (o) {
var n: number = o;
}
}
+91
View File
@@ -0,0 +1,91 @@
/* @providesModule Arith */
function num(x:number) { }
function str(x:string) { }
function foo() {
var x = 0;
var y = "...";
var z = {};
num(x+x);
num(x+y); // error
str(x+y);
str(x+x); // error
str(z+y); // error
}
// test MaybeT(NumT)
function bar0(x: ?number, y: number) {
num(x + y);
}
function bar1(x: number, y: ?number) {
num(x + y);
}
// test OptionalT(NumT)
function bar2(x?: number, y: number) {
num(x + y);
}
function bar3(x: number, y?: number) {
num(x + y);
}
// test OptionalT(MaybeT(NumT))
function bar4(x?: ?number, y: number) {
num(x + y);
}
function bar5(x: number, y?: ?number) {
num(x + y);
}
num(null + null); // === 0
num(undefined + undefined); // === NaN
num(null + 1); // === 1
num(1 + null); // === 1
num(undefined + 1); // === NaN
num(1 + undefined); // === NaN
num(null + true); // === 1
num(true + null); // === 1
num(undefined + true); // === NaN
num(true + undefined); // === NaN
str("foo" + true); // error
str(true + "foo"); // error
str("foo" + null); // error
str(null + "foo"); // error
str("foo" + undefined); // error
str(undefined + "foo"); // error
let tests = [
function(x: mixed, y: mixed) {
(x + y); // error
(x + 0); // error
(0 + x); // error
(x + ""); // error
("" + x); // error
(x + {}); // error
({} + x); // error
},
// when one side is a string or number and the other is invalid, we
// assume you are expecting a string or number (respectively), rather than
// erroring twice saying number !~> string and obj !~> string.
function() {
((1 + {}): number); // error: object !~> number
(({} + 1): number); // error: object !~> number
(("1" + {}): string); // error: object !~> string
(({} + "1"): string); // error: object !~> string
},
function(x: any, y: number, z: string) {
(x + y: string); // ok
(y + x: string); // ok
(x + z: empty); // error, string ~> empty
(z + x: empty); // error, string ~> empty
},
];
@@ -0,0 +1,318 @@
exports[`test Arith.js 1`] = `
"
/* @providesModule Arith */
function num(x:number) { }
function str(x:string) { }
function foo() {
var x = 0;
var y = \"...\";
var z = {};
num(x+x);
num(x+y); // error
str(x+y);
str(x+x); // error
str(z+y); // error
}
// test MaybeT(NumT)
function bar0(x: ?number, y: number) {
num(x + y);
}
function bar1(x: number, y: ?number) {
num(x + y);
}
// test OptionalT(NumT)
function bar2(x?: number, y: number) {
num(x + y);
}
function bar3(x: number, y?: number) {
num(x + y);
}
// test OptionalT(MaybeT(NumT))
function bar4(x?: ?number, y: number) {
num(x + y);
}
function bar5(x: number, y?: ?number) {
num(x + y);
}
num(null + null); // === 0
num(undefined + undefined); // === NaN
num(null + 1); // === 1
num(1 + null); // === 1
num(undefined + 1); // === NaN
num(1 + undefined); // === NaN
num(null + true); // === 1
num(true + null); // === 1
num(undefined + true); // === NaN
num(true + undefined); // === NaN
str(\"foo\" + true); // error
str(true + \"foo\"); // error
str(\"foo\" + null); // error
str(null + \"foo\"); // error
str(\"foo\" + undefined); // error
str(undefined + \"foo\"); // error
let tests = [
function(x: mixed, y: mixed) {
(x + y); // error
(x + 0); // error
(0 + x); // error
(x + \"\"); // error
(\"\" + x); // error
(x + {}); // error
({} + x); // error
},
// when one side is a string or number and the other is invalid, we
// assume you are expecting a string or number (respectively), rather than
// erroring twice saying number !~> string and obj !~> string.
function() {
((1 + {}): number); // error: object !~> number
(({} + 1): number); // error: object !~> number
((\"1\" + {}): string); // error: object !~> string
(({} + \"1\"): string); // error: object !~> string
},
function(x: any, y: number, z: string) {
(x + y: string); // ok
(y + x: string); // ok
(x + z: empty); // error, string ~> empty
(z + x: empty); // error, string ~> empty
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Arith */
function num(x: number) {
}
function str(x: string) {
}
function foo() {
var x = 0;
var y = \"...\";
var z = {};
num(x + x);
num(x + y);// error
str(x + y);
str(x + x);// error
str(z + y);// error
}
// test MaybeT(NumT)
function bar0(x: ?number, y: number) {
num(x + y);
}
function bar1(x: number, y: ?number) {
num(x + y);
}
// test OptionalT(NumT)
function bar2(x: number, y: number) {
num(x + y);
}
function bar3(x: number, y: number) {
num(x + y);
}
// test OptionalT(MaybeT(NumT))
function bar4(x: ?number, y: number) {
num(x + y);
}
function bar5(x: number, y: ?number) {
num(x + y);
}
num(null + null);// === 0
num(undefined + undefined);// === NaN
num(null + 1);// === 1
num(1 + null);// === 1
num(undefined + 1);// === NaN
num(1 + undefined);// === NaN
num(null + true);// === 1
num(true + null);// === 1
num(undefined + true);// === NaN
num(true + undefined);// === NaN
str(\"foo\" + true);// error
str(true + \"foo\");// error
str(\"foo\" + null);// error
str(null + \"foo\");// error
str(\"foo\" + undefined);// error
str(undefined + \"foo\");// error
let tests = [
function(x: mixed, y: mixed) {
x + y;// error
x + 0;// error
0 + x;// error
x + \"\";// error
\"\" + x;// error
x + {};// error
({}) + x;// error
},
// when one side is a string or number and the other is invalid, we
// assume you are expecting a string or number (respectively), rather than
// erroring twice saying number !~> string and obj !~> string.
function() {
(1 + {}: number);// error: object !~> number
({} + 1: number);// error: object !~> number
(\"1\" + {}: string);// error: object !~> string
({} + \"1\": string);// error: object !~> string
},
function(x: any, y: number, z: string) {
(x + y: string);// ok
(y + x: string);// ok
(x + z: empty);// error, string ~> empty
(z + x: empty);// error, string ~> empty
}
];
"
`;
exports[`test exponent.js 1`] = `
"/* @flow */
let x: number = 2 ** 3;
x **= 4;
let y: string = \"123\";
y **= 2; // error
1 + 2 ** 3 + 4;
2 ** 2;
(-2) ** 2;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
let x: number = 2 ** 3;
x **= 4;
let y: string = \"123\";
y **= 2;// error
1 + 2 ** 3 + 4;
2 ** 2;
-2 ** 2;
"
`;
exports[`test generic.js 1`] = `
"/* @flow */
function f<A>(a: A): A { return a + a; } // error
function f<A,B>(a: A, b: B): A {return a + b; } // error
function f<A,B>(a: A, b: B): A {return b + a; } // error
function f<A,B>(a: A, b: B): B {return a + b; } // error
function f<A,B>(a: A, b: B): B {return b + a; } // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test mult.js 1`] = `
"/* @flow */
function num(x:number) { }
num(null * 1);
num(1 * null);
let x: number = 2 * 3;
x *= 4;
let y: string = \"123\";
y *= 2; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
function num(x: number) {
}
num(null * 1);
num(1 * null);
let x: number = 2 * 3;
x *= 4;
let y: string = \"123\";
y *= 2;// error
"
`;
exports[`test relational.js 1`] = `
"/* @flow */
(1 < 2);
(1 < \"foo\"); // error
(\"foo\" < 1); // error
(\"foo\" < \"bar\");
(1 < {foo: 1}); // error
({foo: 1} < 1); // error
({foo: 1} < {foo: 1}); // error
(\"foo\" < {foo: 1}); // error
({foo: 1} < \"foo\"); // error
var x = (null : ?number);
(1 < x); // 2 errors: null !~> number; undefined !~> number
(x < 1); // 2 errors: null !~> number; undefined !~> number
(null < null); // error
(undefined < null); // error
(null < undefined); // error
(undefined < undefined); // error
(NaN < 1);
(1 < NaN);
(NaN < NaN);
let tests = [
function(x: any, y: number, z: string) {
(x > y);
(x > z);
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
1 < 2;
1 < \"foo\";// error
\"foo\" < 1;// error
\"foo\" < \"bar\";
1 < { foo: 1 };// error
({ foo: 1 }) < 1;// error
({ foo: 1 }) < { foo: 1 };// error
\"foo\" < { foo: 1 };// error
({ foo: 1 }) < \"foo\";// error
var x = (null: ?number);
1 < x;// 2 errors: null !~> number; undefined !~> number
x < 1;// 2 errors: null !~> number; undefined !~> number
null < null;// error
undefined < null;// error
null < undefined;// error
undefined < undefined;// error
NaN < 1;
1 < NaN;
NaN < NaN;
let tests = [
function(x: any, y: number, z: string) {
x > y;
x > z;
}
];
"
`;
+11
View File
@@ -0,0 +1,11 @@
/* @flow */
let x: number = 2 ** 3;
x **= 4;
let y: string = "123";
y **= 2; // error
1 + 2 ** 3 + 4;
2 ** 2;
(-2) ** 2;
+7
View File
@@ -0,0 +1,7 @@
/* @flow */
function f<A>(a: A): A { return a + a; } // error
function f<A,B>(a: A, b: B): A {return a + b; } // error
function f<A,B>(a: A, b: B): A {return b + a; } // error
function f<A,B>(a: A, b: B): B {return a + b; } // error
function f<A,B>(a: A, b: B): B {return b + a; } // error
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+12
View File
@@ -0,0 +1,12 @@
/* @flow */
function num(x:number) { }
num(null * 1);
num(1 * null);
let x: number = 2 * 3;
x *= 4;
let y: string = "123";
y *= 2; // error
+30
View File
@@ -0,0 +1,30 @@
/* @flow */
(1 < 2);
(1 < "foo"); // error
("foo" < 1); // error
("foo" < "bar");
(1 < {foo: 1}); // error
({foo: 1} < 1); // error
({foo: 1} < {foo: 1}); // error
("foo" < {foo: 1}); // error
({foo: 1} < "foo"); // error
var x = (null : ?number);
(1 < x); // 2 errors: null !~> number; undefined !~> number
(x < 1); // 2 errors: null !~> number; undefined !~> number
(null < null); // error
(undefined < null); // error
(null < undefined); // error
(undefined < undefined); // error
(NaN < 1);
(1 < NaN);
(NaN < NaN);
let tests = [
function(x: any, y: number, z: string) {
(x > y);
(x > z);
},
];
@@ -0,0 +1,63 @@
exports[`test test.js 1`] = `
"/* @flow */
function filterOutVoids<T> (arr: Array<?T>): Array<T> {
return arr.filter(Boolean)
}
function filterOutSmall (arr: Array<?number>): Array<?number> {
return arr.filter(num => num && num > 10)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test test2.js 1`] = `
"/* @flow */
function filterItems(items: Array<string|number>): Array<string|number> {
return items.map(item => {
if (typeof item === \'string\') {
return item.length > 2 ? item : null;
} else {
return item*10;
}
}).filter(Boolean);
}
const filteredItems = filterItems([\'foo\', \'b\', 1, 2]);
console.log(filteredItems);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1530
return fromString(\" | \").join(path.map(print, \"types\"));
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1530:32)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.map (/src/fast-path.js:167:19)
at genericPrintNoParens (/src/printer.js:1497:36)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+9
View File
@@ -0,0 +1,9 @@
/* @flow */
function filterOutVoids<T> (arr: Array<?T>): Array<T> {
return arr.filter(Boolean)
}
function filterOutSmall (arr: Array<?number>): Array<?number> {
return arr.filter(num => num && num > 10)
}
+15
View File
@@ -0,0 +1,15 @@
/* @flow */
function filterItems(items: Array<string|number>): Array<string|number> {
return items.map(item => {
if (typeof item === 'string') {
return item.length > 2 ? item : null;
} else {
return item*10;
}
}).filter(Boolean);
}
const filteredItems = filterItems(['foo', 'b', 1, 2]);
console.log(filteredItems);
@@ -0,0 +1,27 @@
exports[`test test.js 1`] = `
"var A = [1,2,3];
var B = [...A];
var C = [1,2,3];
B.sort((a, b) => a - b);
C.sort((a, b) => a - b);
var x: Array<string> = [\'1\', \'2\'];
var y: Array<string> = [\'3\', ...x];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+8
View File
@@ -0,0 +1,8 @@
var A = [1,2,3];
var B = [...A];
var C = [1,2,3];
B.sort((a, b) => a - b);
C.sort((a, b) => a - b);
var x: Array<string> = ['1', '2'];
var y: Array<string> = ['3', ...x];
@@ -0,0 +1,76 @@
exports[`test array_lib.js 1`] = `
"/* @flow */
function foo(x:string) { }
var a = [0];
var b = a.map(function (x) { foo(x); return \"\" + x; });
var c: number = a[0];
var d: number = b[0];
var e:Array<string> = a.reverse();
var f = [\"\"];
var g:number = f.map(function () { return 0; })[0];
var h: Array<number> = [1,2,3];
var i: Array<string> = [\'a\', \'b\', \'c\'];
var j: Array<number | string> = h.concat(i);
var k: Array<number> = h.concat(h);
var l: Array<number> = h.concat(1,2,3);
var m: Array<number | string> = h.concat(\'a\', \'b\', \'c\');
var n: Array<number> = h.concat(\'a\', \'b\', \'c\'); // Error
function reduce_test() {
/* Adapted from the following source:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
*/
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
});
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
}, 10);
var total = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
});
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
/* Added later, because the above is insufficient */
// acc is element type of array when no init is provided
[\"\"].reduce((acc, str) => acc * str.length); // error, string ~> number
[\"\"].reduceRight((acc, str) => acc * str.length); // error, string ~> number
}
function from_test() {
var a: Array<string> = Array.from([1, 2, 3], function(val, index) {
return index % 2 ? \"foo\" : String(val);
});
var b: Array<string> = Array.from([1, 2, 3], function(val) {
return String(val);
});
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
+57
View File
@@ -0,0 +1,57 @@
/* @flow */
function foo(x:string) { }
var a = [0];
var b = a.map(function (x) { foo(x); return "" + x; });
var c: number = a[0];
var d: number = b[0];
var e:Array<string> = a.reverse();
var f = [""];
var g:number = f.map(function () { return 0; })[0];
var h: Array<number> = [1,2,3];
var i: Array<string> = ['a', 'b', 'c'];
var j: Array<number | string> = h.concat(i);
var k: Array<number> = h.concat(h);
var l: Array<number> = h.concat(1,2,3);
var m: Array<number | string> = h.concat('a', 'b', 'c');
var n: Array<number> = h.concat('a', 'b', 'c'); // Error
function reduce_test() {
/* Adapted from the following source:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
*/
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
});
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
}, 10);
var total = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
});
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
/* Added later, because the above is insufficient */
// acc is element type of array when no init is provided
[""].reduce((acc, str) => acc * str.length); // error, string ~> number
[""].reduceRight((acc, str) => acc * str.length); // error, string ~> number
}
function from_test() {
var a: Array<string> = Array.from([1, 2, 3], function(val, index) {
return index % 2 ? "foo" : String(val);
});
var b: Array<string> = Array.from([1, 2, 3], function(val) {
return String(val);
});
}
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+39
View File
@@ -0,0 +1,39 @@
/* @providesModule Arrays */
function foo(x:string) { }
var a = [];
a[0] = 1;
a[1] = "...";
foo(a[1]);
var y;
a.forEach(x => y=x);
// for literals, composite element type is union of individuals
// note: test both tuple and non-tuple inferred literals
var alittle: Array<?number> = [0, 1, 2, 3, null];
var abig: Array<?number> = [0, 1, 2, 3, 4, 5, 6, 8, null];
var abig2: Array<{x:number; y:number}> = [
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0, a:true},
{x:0, y:0, b:"hey"},
{x:0, y:0, c:1},
{x:0, y:0, c:"hey"}
];
module.exports = "arrays";
@@ -0,0 +1,77 @@
exports[`test Arrays.js 1`] = `
"
/* @providesModule Arrays */
function foo(x:string) { }
var a = [];
a[0] = 1;
a[1] = \"...\";
foo(a[1]);
var y;
a.forEach(x => y=x);
// for literals, composite element type is union of individuals
// note: test both tuple and non-tuple inferred literals
var alittle: Array<?number> = [0, 1, 2, 3, null];
var abig: Array<?number> = [0, 1, 2, 3, 4, 5, 6, 8, null];
var abig2: Array<{x:number; y:number}> = [
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0, a:true},
{x:0, y:0, b:\"hey\"},
{x:0, y:0, c:1},
{x:0, y:0, c:\"hey\"}
];
module.exports = \"arrays\";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test numeric_elem.js 1`] = `
"var arr = [];
var day = new Date;
// Date instances are numeric (see Flow_js.numeric) and thus can index into
// arrays.
arr[day] = 0;
(arr[day]: string); // error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var arr = [ ];
var day = new Date();
// Date instances are numeric (see Flow_js.numeric) and thus can index into
// arrays.
arr[day] = 0;
(arr[day]: string);// error: number ~> string
"
`;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+7
View File
@@ -0,0 +1,7 @@
var arr = [];
var day = new Date;
// Date instances are numeric (see Flow_js.numeric) and thus can index into
// arrays.
arr[day] = 0;
(arr[day]: string); // error: number ~> string
@@ -0,0 +1,60 @@
exports[`test advanced_arrows.js 1`] = `
"/**
* @flow
*/
var add = (x: number, y: number): number => x + y;
var bad = (x: number): string => x; // Error!
var ident = <T>(x: T): T => x;
(ident(1): number);
(ident(\"hi\"): number); // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:367:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test arrows.js 1`] = `
"function selectBestEffortImageForWidth(
maxWidth: number,
images: Array<Image>
): Image {
var maxPixelWidth = maxWidth;
//images = images.sort(function (a, b) { return a.width - b.width });
images = images.sort((a, b) => (a.width - b.width) + \"\");
return images.find(image => image.width >= maxPixelWidth) ||
images[images.length - 1];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
+11
View File
@@ -0,0 +1,11 @@
/**
* @flow
*/
var add = (x: number, y: number): number => x + y;
var bad = (x: number): string => x; // Error!
var ident = <T>(x: T): T => x;
(ident(1): number);
(ident("hi"): number); // Error
+10
View File
@@ -0,0 +1,10 @@
function selectBestEffortImageForWidth(
maxWidth: number,
images: Array<Image>
): Image {
var maxPixelWidth = maxWidth;
//images = images.sort(function (a, b) { return a.width - b.width });
images = images.sort((a, b) => (a.width - b.width) + "");
return images.find(image => image.width >= maxPixelWidth) ||
images[images.length - 1];
}
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
@@ -0,0 +1,34 @@
exports[`test foo.js 1`] = `
"// Regex literals require a lexer mode change
/asdf/g;
// JSX also requires a lexer mode change
<div attr1=\'42\' attr2={\'asdf\'} >asdf</div>;
// Async arrow functions require backtracking
var a = async () => 42;
// Type annotations have a special lex mode
var a: number = 42;
// Token stream should continue even with parse errors
var var
a;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (14:4)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$2.parseBindingAtom (/node_modules/babylon/lib/index.js:2929:12)
at Parser.pp$1.parseVarHead (/node_modules/babylon/lib/index.js:2226:18)
at Parser.parseVarHead (/node_modules/babylon/lib/index.js:5611:13)
at Parser.pp$1.parseVar (/node_modules/babylon/lib/index.js:2209:10)
at Parser.pp$1.parseVarStatement (/node_modules/babylon/lib/index.js:2042:8)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1735:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
"
`;
+15
View File
@@ -0,0 +1,15 @@
// Regex literals require a lexer mode change
/asdf/g;
// JSX also requires a lexer mode change
<div attr1='42' attr2={'asdf'} >asdf</div>;
// Async arrow functions require backtracking
var a = async () => 42;
// Type annotations have a special lex mode
var a: number = 42;
// Token stream should continue even with parse errors
var var
a;
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
@@ -0,0 +1,471 @@
exports[`test async.js 1`] = `
"// @flow
// \"For async functions, a Promise<T> is returned,
// and the type of return expressions must be T.\"
//
async function f0(): Promise<number> {
return 1;
}
async function f1(): Promise<bool> {
return 1; // error, number != bool
}
// await: (p: Promise<T> | T) => T
//
async function f2(p: Promise<number>): Promise<number> {
var x: number = await p;
var y: number = await 1;
return x + y;
}
async function f3(p: Promise<number>): Promise<number> {
return await p;
}
// TODO: this is one of those bad generic errors, currently:
// \"inconsistent use of library definitions\" with two core.js locs
async function f4(p: Promise<number>): Promise<bool> {
return await p; // error, number != bool
}
// async arrow functions
//
var f5: () => Promise<number> = async () => await 1;
// async methods
//
class C {
async m() { return 1; }
async mt<T>(a: T): Promise<T> { return a; }
static async m(a): void { await a; } // error, void != Promise<void>
static async mt<T>(a: T): Promise<T> { return a; }
}
// async function props
var obj = { f: async () => await 1 };
var objf : () => Promise<number> = obj.f;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async_base_class.js 1`] = `
"// This is kind of weird, but it should parse. This works in babel without the
// parens around (await promise). From the es6 and async/await specs I (nmote)
// am not clear on whether it should. In any case it\'s a strange corner case
// that is probably not important to support.
class C {};
var P: Promise<Class<C>> = new Promise(function (resolve, reject) {
resolve(C);
});
async function foo() {
class Bar extends (await P) { }
return Bar;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async_parse.js 1`] = `
"async function f() {}
async function ft<T>(a: T) {}
class C {
async m() {}
async mt<T>(a: T) {}
static async m(a) {}
static async mt<T>(a: T) {}
}
var e = async function () {};
var et = async function<T> (a: T) {};
var n = new async function() {};
var o = { async m() {} };
var ot = { async m<T>(a: T) {} };
var oz = { async async() {} };
var x = { async : 5 };
console.log(x.async);
var async = 3;
var y = { async };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async_promise.js 1`] = `
"async function f(): Promise<number> {
return Promise.resolve(1);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async_return_void.js 1`] = `
"// @flow
async function foo1(): Promise<string> {
return;
}
async function foo2(): Promise<string> {
return undefined;
}
async function foo3(): Promise<string> {
function bar() { }
return bar();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async2.js 1`] = `
"// @flow
// misc basic
function test1() {
async function foo() {
return 42;
}
async function bar() {
var a = await foo();
var b: number = a; // valid
var c: string = a; // Error: number ~> string
}
}
//
// void returns:
//
// inference should produce return type Promise<void>
// in the absence of an explicit return
//
function test2() {
async function voidoid1() {
console.log(\"HEY\");
}
var voidoid2: () => Promise<void> = voidoid1; // ok
var voidoid3: () => void = voidoid1; // error, void != Promise<void>
}
// annotated return type of Promise<void> should work
//
function test3() {
async function voidoid4(): Promise<void> { // ok
console.log(\"HEY\");
}
}
// other annotated return types should fail
// (note: misannotated return types with explicit
// return statements are covered in async.js)
//
function test4() {
async function voidoid5(): void { // error, void != Promise<void>
console.log(\"HEY\");
}
}
function test5() {
async function voidoid6()
: Promise<number> { // error, number != void
console.log(\"HEY\");
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test async3.js 1`] = `
"// @flow
/**
* test nested-promise unwrapping.
* Note: currently we don\'t do this properly in the underlying
* type of the Promise class, which causes spurious errors to
* be raised here. Once that\'s fixed, the errors here will go
* away.
*/
async function foo() {
return 42;
}
async function bar() {
return foo();
}
async function baz() {
// a should now be typed as number, but is in fact
// Promise<number> until nested-promise unwrap is fixed
var a = await bar();
// TODO this is valid code, but currently gives Promise ~> number error
// due to lack of transitive Promise unwrap.
var b: number = a;
// should be number ~> string error, but currently gives
// Promise ~> string error for the same reason
var c: string = a;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
/**
* test nested-promise unwrapping.
* Note: currently we don\'t do this properly in the underlying
* type of the Promise class, which causes spurious errors to
* be raised here. Once that\'s fixed, the errors here will go
* away.
*/
async function foo() {
return 42;
}
async function bar() {
return foo();
}
async function baz() {
// a should now be typed as number, but is in fact
// Promise<number> until nested-promise unwrap is fixed
var a = await bar();
// TODO this is valid code, but currently gives Promise ~> number error
// due to lack of transitive Promise unwrap.
var b: number = a;
// should be number ~> string error, but currently gives
// Promise ~> string error for the same reason
var c: string = a;
}
"
`;
exports[`test await_not_in_async.js 1`] = `
"// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f() {
await 1;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (5:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
"
`;
exports[`test await_not_in_async2.js 1`] = `
"// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f(x) { return x; }
f(await 1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (6:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
"
`;
exports[`test await_not_in_async3.js 1`] = `
"// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
async function f(x) { return x; }
f(await 1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (6:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
"
`;
exports[`test await_parse.js 1`] = `
"async function f() { await 1; }
async function ft<T>(a: T) { await 1; }
class C {
async m() { await 1; }
async mt<T>(a: T) { await 1; }
static async m(a) { await 1; }
static async mt<T>(a: T) { await 1; }
}
var e = async function () { await 1; };
var et = async function<T> (a: T) { await 1; };
var n = new async function() { await 1; };
var o = { async m() { await 1; } };
var ot = { async m<T>(a: T) { await 1; } };
var oz = { async async(async) { await async; } };
var x = { await : 5 };
console.log(x.await);
var await = 3;
var y = { await };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (23:4)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$2.checkLVal (/node_modules/babylon/lib/index.js:2990:12)
at Parser.checkLVal (/node_modules/babylon/lib/index.js:5446:22)
at Parser.pp$1.parseVarHead (/node_modules/babylon/lib/index.js:2227:8)
at Parser.parseVarHead (/node_modules/babylon/lib/index.js:5611:13)
at Parser.pp$1.parseVar (/node_modules/babylon/lib/index.js:2209:10)
at Parser.pp$1.parseVarStatement (/node_modules/babylon/lib/index.js:2042:8)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1735:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
"
`;
+52
View File
@@ -0,0 +1,52 @@
// @flow
// "For async functions, a Promise<T> is returned,
// and the type of return expressions must be T."
//
async function f0(): Promise<number> {
return 1;
}
async function f1(): Promise<bool> {
return 1; // error, number != bool
}
// await: (p: Promise<T> | T) => T
//
async function f2(p: Promise<number>): Promise<number> {
var x: number = await p;
var y: number = await 1;
return x + y;
}
async function f3(p: Promise<number>): Promise<number> {
return await p;
}
// TODO: this is one of those bad generic errors, currently:
// "inconsistent use of library definitions" with two core.js locs
async function f4(p: Promise<number>): Promise<bool> {
return await p; // error, number != bool
}
// async arrow functions
//
var f5: () => Promise<number> = async () => await 1;
// async methods
//
class C {
async m() { return 1; }
async mt<T>(a: T): Promise<T> { return a; }
static async m(a): void { await a; } // error, void != Promise<void>
static async mt<T>(a: T): Promise<T> { return a; }
}
// async function props
var obj = { f: async () => await 1 };
var objf : () => Promise<number> = obj.f;
+60
View File
@@ -0,0 +1,60 @@
// @flow
// misc basic
function test1() {
async function foo() {
return 42;
}
async function bar() {
var a = await foo();
var b: number = a; // valid
var c: string = a; // Error: number ~> string
}
}
//
// void returns:
//
// inference should produce return type Promise<void>
// in the absence of an explicit return
//
function test2() {
async function voidoid1() {
console.log("HEY");
}
var voidoid2: () => Promise<void> = voidoid1; // ok
var voidoid3: () => void = voidoid1; // error, void != Promise<void>
}
// annotated return type of Promise<void> should work
//
function test3() {
async function voidoid4(): Promise<void> { // ok
console.log("HEY");
}
}
// other annotated return types should fail
// (note: misannotated return types with explicit
// return statements are covered in async.js)
//
function test4() {
async function voidoid5(): void { // error, void != Promise<void>
console.log("HEY");
}
}
function test5() {
async function voidoid6()
: Promise<number> { // error, number != void
console.log("HEY");
}
}
+32
View File
@@ -0,0 +1,32 @@
// @flow
/**
* test nested-promise unwrapping.
* Note: currently we don't do this properly in the underlying
* type of the Promise class, which causes spurious errors to
* be raised here. Once that's fixed, the errors here will go
* away.
*/
async function foo() {
return 42;
}
async function bar() {
return foo();
}
async function baz() {
// a should now be typed as number, but is in fact
// Promise<number> until nested-promise unwrap is fixed
var a = await bar();
// TODO this is valid code, but currently gives Promise ~> number error
// due to lack of transitive Promise unwrap.
var b: number = a;
// should be number ~> string error, but currently gives
// Promise ~> string error for the same reason
var c: string = a;
}
+14
View File
@@ -0,0 +1,14 @@
// This is kind of weird, but it should parse. This works in babel without the
// parens around (await promise). From the es6 and async/await specs I (nmote)
// am not clear on whether it should. In any case it's a strange corner case
// that is probably not important to support.
class C {};
var P: Promise<Class<C>> = new Promise(function (resolve, reject) {
resolve(C);
});
async function foo() {
class Bar extends (await P) { }
return Bar;
}
+24
View File
@@ -0,0 +1,24 @@
async function f() {}
async function ft<T>(a: T) {}
class C {
async m() {}
async mt<T>(a: T) {}
static async m(a) {}
static async mt<T>(a: T) {}
}
var e = async function () {};
var et = async function<T> (a: T) {};
var n = new async function() {};
var o = { async m() {} };
var ot = { async m<T>(a: T) {} };
var oz = { async async() {} };
var x = { async : 5 };
console.log(x.async);
var async = 3;
var y = { async };
+3
View File
@@ -0,0 +1,3 @@
async function f(): Promise<number> {
return Promise.resolve(1);
}
+14
View File
@@ -0,0 +1,14 @@
// @flow
async function foo1(): Promise<string> {
return;
}
async function foo2(): Promise<string> {
return undefined;
}
async function foo3(): Promise<string> {
function bar() { }
return bar();
}
+6
View File
@@ -0,0 +1,6 @@
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f() {
await 1;
}
+6
View File
@@ -0,0 +1,6 @@
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f(x) { return x; }
f(await 1);
+6
View File
@@ -0,0 +1,6 @@
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
async function f(x) { return x; }
f(await 1);
+24
View File
@@ -0,0 +1,24 @@
async function f() { await 1; }
async function ft<T>(a: T) { await 1; }
class C {
async m() { await 1; }
async mt<T>(a: T) { await 1; }
static async m(a) { await 1; }
static async mt<T>(a: T) { await 1; }
}
var e = async function () { await 1; };
var et = async function<T> (a: T) { await 1; };
var n = new async function() { await 1; };
var o = { async m() { await 1; } };
var ot = { async m<T>(a: T) { await 1; } };
var oz = { async async(async) { await async; } };
var x = { await : 5 };
console.log(x.await);
var await = 3;
var y = { await };
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
@@ -0,0 +1,213 @@
exports[`test delegate_yield.js 1`] = `
"async function *delegate_next() {
async function *inner() {
var x: void = yield; // error: number ~> void
}
yield *inner();
}
delegate_next().next(0);
async function *delegate_yield() {
async function *inner() {
yield 0;
}
yield *inner();
}
(async () => {
for await (const x of delegate_yield()) {
(x: void); // error: number ~> void
}
});
async function *delegate_return() {
async function *inner() {
return 0;
}
var x: void = yield *inner(); // error: number ~> void
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
async function* delegate_next() {
async function* inner() {
var x: void = yield;// error: number ~> void
}
yield* inner();
}
delegate_next().next(0);
async function* delegate_yield() {
async function* inner() {
yield 0;
}
yield* inner();
}
async () => {
for await (const x of delegate_yield()) {
(x: void);// error: number ~> void
}
};
async function* delegate_return() {
async function* inner() {
return 0;
}
var x: void = yield* inner();// error: number ~> void
}
"
`;
exports[`test generator.js 1`] = `
"declare interface File {
readLine(): Promise<string>;
close(): void;
EOF: boolean;
}
declare function fileOpen(path: string): Promise<File>;
async function* readLines(path) {
let file: File = await fileOpen(path);
try {
while (!file.EOF) {
yield await file.readLine();
}
} finally {
file.close();
}
}
async function f() {
for await (const line of readLines(\"/path/to/file\")) {
(line: void); // error: string ~> void
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1391
fromString(\", \").join(path.map(print, \"extends\"))
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1391:28)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at /src/printer.js:1601:18
at FastPath.map (/src/fast-path.js:167:19)
at printStatementSequence (/src/printer.js:1586:8)
at /src/printer.js:238:16
at FastPath.call (/src/fast-path.js:113:16)
"
`;
exports[`test return.js 1`] = `
"declare var gen: AsyncGenerator<void,string,void>;
// You can pass whatever you like to return, it doesn\'t need to be related to
// the AsyncGenerator\'s return type
gen.return(0).then(result => {
(result.value: void); // error: string | number ~> void
});
// However, a generator can \"refuse\" the return by catching an exception and
// yielding or returning internally.
async function *refuse_return() {
try {
yield 1;
} finally {
return 0;
}
}
refuse_return().return(\"string\").then(result => {
if (result.done) {
(result.value: string); // error: number | void ~> string
}
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
"
`;
exports[`test throw.js 1`] = `
"async function *catch_return() {
try {
yield 0;
} catch (e) {
return e;
}
}
(async () => {
catch_return().throw(\"\").then(({value}) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
});
async function *yield_return() {
try {
yield 0;
return;
} catch (e) {
yield e;
}
}
(async () => {
yield_return().throw(\"\").then(({value}) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
async function* catch_return() {
try {
yield 0;
} catch (e) {
return e;
}
}
async () => {
catch_return().throw(\"\").then(
({ value }) => {
if (value !== undefined) {
(value: void);// error: number ~> void
}
}
);
};
async function* yield_return() {
try {
yield 0;
return;
} catch (e) {
yield e;
}
}
async () => {
yield_return().throw(\"\").then(
({ value }) => {
if (value !== undefined) {
(value: void);// error: number ~> void
}
}
);
};
"
`;
+26
View File
@@ -0,0 +1,26 @@
async function *delegate_next() {
async function *inner() {
var x: void = yield; // error: number ~> void
}
yield *inner();
}
delegate_next().next(0);
async function *delegate_yield() {
async function *inner() {
yield 0;
}
yield *inner();
}
(async () => {
for await (const x of delegate_yield()) {
(x: void); // error: number ~> void
}
});
async function *delegate_return() {
async function *inner() {
return 0;
}
var x: void = yield *inner(); // error: number ~> void
}
+25
View File
@@ -0,0 +1,25 @@
declare interface File {
readLine(): Promise<string>;
close(): void;
EOF: boolean;
}
declare function fileOpen(path: string): Promise<File>;
async function* readLines(path) {
let file: File = await fileOpen(path);
try {
while (!file.EOF) {
yield await file.readLine();
}
} finally {
file.close();
}
}
async function f() {
for await (const line of readLines("/path/to/file")) {
(line: void); // error: string ~> void
}
}
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+22
View File
@@ -0,0 +1,22 @@
declare var gen: AsyncGenerator<void,string,void>;
// You can pass whatever you like to return, it doesn't need to be related to
// the AsyncGenerator's return type
gen.return(0).then(result => {
(result.value: void); // error: string | number ~> void
});
// However, a generator can "refuse" the return by catching an exception and
// yielding or returning internally.
async function *refuse_return() {
try {
yield 1;
} finally {
return 0;
}
}
refuse_return().return("string").then(result => {
if (result.done) {
(result.value: string); // error: number | void ~> string
}
});
+32
View File
@@ -0,0 +1,32 @@
async function *catch_return() {
try {
yield 0;
} catch (e) {
return e;
}
}
(async () => {
catch_return().throw("").then(({value}) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
});
async function *yield_return() {
try {
yield 0;
return;
} catch (e) {
yield e;
}
}
(async () => {
yield_return().throw("").then(({value}) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
});
@@ -0,0 +1,582 @@
exports[`test bar.js 1`] = `
"// @flow
var o = require(\'./unknown\');
o.x.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test bool.js 1`] = `
"// @flow
true.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (4:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test customfun.js 1`] = `
"// @flow
declare var idx: $Facebookism$Idx;
declare var merge: $Facebookism$Merge;
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
declare var mergeInto: $Facebookism$MergeInto;
declare var mixin: $Facebookism$Mixin;
declare var objectGetPrototypeOf: Object$GetPrototypeOf
declare var objectAssign: Object$Assign
m
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
declare var idx: $Facebookism$Idx;
declare var merge: $Facebookism$Merge;
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
declare var mergeInto: $Facebookism$MergeInto;
declare var mixin: $Facebookism$Mixin;
declare var objectGetPrototypeOf: Object$GetPrototypeOf;
declare var objectAssign: Object$Assign;
m;
"
`;
exports[`test foo.js 1`] = `
"/**
* @flow
*/
var obj = {
num: 123,
str: \'hello\',
};
obj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test foo_parse_fail.js 1`] = `
"/**
* @flow
*/
var obj = {
num: 123,
str: \'hello\',
};
console.log(obj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test fun.js 1`] = `
"/* @flow */
function foo(f: () => number) {
f.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test function_builtins.js 1`] = `
"/* @flow */
function foo(f: Function) {
f.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test generics.js 1`] = `
"// @flow
class C<X> { }
function foo(o: { cn: C<number> }) {
o.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test if.js 1`] = `
"// @flow
const x = \'\';
if (x.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (3:6)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test issue-1368.js 1`] = `
"/* @flow */
class Test {
prop: number;
constructor(prop: number) {
this.prop = prop;
}
}
class ExtendTest extends Test {
extended: string;
constructor(extended: string) {
super(10);
this.extended = extended;
}
method() {
this.prop = 12;
this./* here */
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (21:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test jsx1.js 1`] = `
"// @flow
var React = require(\'react\');
class C extends React.Component {
props: { x: number };
}
<C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:5687
throw jsxError || err;
^
SyntaxError: Unexpected token (9:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$8.jsxParseIdentifier (/node_modules/babylon/lib/index.js:6199:10)
at Parser.pp$8.jsxParseNamespacedName (/node_modules/babylon/lib/index.js:6210:19)
at Parser.pp$8.jsxParseAttribute (/node_modules/babylon/lib/index.js:6305:20)
at Parser.pp$8.jsxParseOpeningElementAt (/node_modules/babylon/lib/index.js:6317:31)
at Parser.pp$8.jsxParseElementAt (/node_modules/babylon/lib/index.js:6339:29)
at Parser.pp$8.jsxParseElement (/node_modules/babylon/lib/index.js:6394:15)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6406:21)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
"
`;
exports[`test jsx2.js 1`] = `
"// @flow
var React = require(\'react\');
class C extends React.Component {
props: { x: number, y: string };
}
<C x = 0,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:5687
throw jsxError || err;
^
SyntaxError: JSX value should be either an expression or a quoted JSX text (8:7)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$8.jsxParseAttributeValue (/node_modules/babylon/lib/index.js:6255:12)
at Parser.pp$8.jsxParseAttribute (/node_modules/babylon/lib/index.js:6306:42)
at Parser.pp$8.jsxParseOpeningElementAt (/node_modules/babylon/lib/index.js:6317:31)
at Parser.pp$8.jsxParseElementAt (/node_modules/babylon/lib/index.js:6339:29)
at Parser.pp$8.jsxParseElement (/node_modules/babylon/lib/index.js:6394:15)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6406:21)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
"
`;
exports[`test num.js 1`] = `
"// @flow
var num = 123;
num.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test object_builtins.js 1`] = `
"/* @flow */
function foo(o: Object) {
o.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test optional.js 1`] = `
"// @flow
function foo(obj: { x?: string, f: (x?: string) => void, o: { x?: string } }) {
return obj.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test override.js 1`] = `
"// @flow
class C {
override(): number | string { return 0; }
}
class D extends C {
foo() { return this.override() }
override(): string { return \"\"; }
bar() { this.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test qux.js 1`] = `
"// @flow
class C { x: number; }
var c: C = new C;
c.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test str.js 1`] = `
"// @flow
\"hello\".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (4:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test this.js 1`] = `
"/* @flow */
// issue #1197
class Foo {
baz: string;
bar() {}
hello() {
this.
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (9:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test typeparams.js 1`] = `
"// @flow
class Bounds<N: number, F: () => N> {
foo: F;
bar() {
this.foo().
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test union.js 1`] = `
"/* @flow */
function foo(a: boolean, x: { bar: string }, y: Object) {
var z;
if (a) {
z = x;
} else {
z = y;
}
z.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test unknown.js 1`] = `
"// @noflow
module.exports = { x: { y: \"\" } };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
module.exports = { x: { y: \"\" } };
"
`;
+4
View File
@@ -0,0 +1,4 @@
// @flow
var o = require('./unknown');
o.x.
+3
View File
@@ -0,0 +1,3 @@
// @flow
true.
+11
View File
@@ -0,0 +1,11 @@
// @flow
declare var idx: $Facebookism$Idx;
declare var merge: $Facebookism$Merge;
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
declare var mergeInto: $Facebookism$MergeInto;
declare var mixin: $Facebookism$Mixin;
declare var objectGetPrototypeOf: Object$GetPrototypeOf
declare var objectAssign: Object$Assign
m
+10
View File
@@ -0,0 +1,10 @@
/**
* @flow
*/
var obj = {
num: 123,
str: 'hello',
};
obj.
+10
View File
@@ -0,0 +1,10 @@
/**
* @flow
*/
var obj = {
num: 123,
str: 'hello',
};
console.log(obj.
+5
View File
@@ -0,0 +1,5 @@
/* @flow */
function foo(f: () => number) {
f.
}
+5
View File
@@ -0,0 +1,5 @@
/* @flow */
function foo(f: Function) {
f.
}
+7
View File
@@ -0,0 +1,7 @@
// @flow
class C<X> { }
function foo(o: { cn: C<number> }) {
o.
}
+3
View File
@@ -0,0 +1,3 @@
// @flow
const x = '';
if (x.)
+22
View File
@@ -0,0 +1,22 @@
/* @flow */
class Test {
prop: number;
constructor(prop: number) {
this.prop = prop;
}
}
class ExtendTest extends Test {
extended: string;
constructor(extended: string) {
super(10);
this.extended = extended;
}
method() {
this.prop = 12;
this./* here */
}
}
+1
View File
@@ -0,0 +1 @@
run_spec(__dirname);
+8
View File
@@ -0,0 +1,8 @@
// @flow
var React = require('react');
class C extends React.Component {
props: { x: number };
}
<C
+8
View File
@@ -0,0 +1,8 @@
// @flow
var React = require('react');
class C extends React.Component {
props: { x: number, y: string };
}
<C x = 0,
+4
View File
@@ -0,0 +1,4 @@
// @flow
var num = 123;
num.
+5
View File
@@ -0,0 +1,5 @@
/* @flow */
function foo(o: Object) {
o.
}
+5
View File
@@ -0,0 +1,5 @@
// @flow
function foo(obj: { x?: string, f: (x?: string) => void, o: { x?: string } }) {
return obj.
}
Loaded 100 of 1873 files, more files were not shown because too many files have changed in this diff. Show more