Files
test-repo/tests/init/let.js
T
Christopher Chedeau cf45afba61 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.
2016-12-23 19:51:53 +00:00

158 lines
3.1 KiB
JavaScript

/**
* test initialization tracking for lets
* @flow
*/
// deferred init on annotated lets is ok
function linear_deferred_init() {
let x:number;
x = 0;
let y:number = x;
}
// use of let before init gives undefined
function linear_pre_init() {
let x:number;
let y:?number = x; // ok
let z:number = x; // error
x = 0;
let w:number = x; // ok
}
// self-references in let bindings are not ok
function self_init() {
let x = x; // 'x' not initialized!
}
// use of let after partial init (non-exhaustive if) gives undefined
function if_partial_post_init(b) {
let x:number;
if (b) {
x = 0;
}
var y:number = x; // error, possibly uninitialized
}
// use of let after guaranteed init (exhaustive if) is ok
function if_post_init(b) {
let x:number;
if (b) {
x = 0;
} else {
x = 1;
}
var y:number = x;
}
// use of let after partial init (non-exhaustive switch) gives undefined
function switch_partial_post_init(i) {
let x:number;
switch (i) {
case 0:
x = 0;
break;
case 1:
x = 1;
break;
}
var y:number = x; // error, possibly uninitialized
}
// use of let after guaranteed init (exhaustive switch) is ok
function switch_post_init(i) {
let x:number;
switch (i) {
case 0:
x = 0;
break;
case 1:
x = 1;
break;
default:
x = 2;
}
var y:number = x; // no error, all cases covered
}
// use in a switch after a skipped decl is an error
function switch_scoped_init_2(i) {
switch (i) {
case 0:
let x:number;
case 1:
let y:number = x; // error, skipped declaration
}
}
// while leaves it possibly uninitialized
function while_post_init(b) {
let x:number;
while (b) {
x = 0;
}
var y:number = x; // error
}
// do-while is ok, because loop is guaranteed to run at least once
function do_while_post_init(b) {
let x:number;
do {
x = 0;
} while (b);
var y:number = x; // ok
}
// for-in leaves it possibly uninitialized
function for_in_post_init() {
var x:number;
for (var p in {}) {
x = 0;
}
var y:number = x; // error
}
// for-of leaves it possibly uninitialized
function for_of_post_init() {
var x:number;
for (var x of []) {
x = 0;
}
var y:number = x; // error
}
// use of let after guaranteed init (exhaustive switch + throw) is ok
function switch_post_init2(i): number {
let bar;
switch (i) {
case 1:
bar = 3;
break;
default:
throw new Error('Invalid state');
}
return bar; // ok, definitely initialized
}
// use of let after guaranteed init (exhaustive switch + throw) is ok
function switch_post_init2(i): number {
let bar;
switch (i) {
case 1:
bar = 3;
break;
default:
throw new Error('Invalid state');
}
return bar; // ok, definitely initialized
}
// reference of a let-binding is permitted in a sub-closure within the init expr
function sub_closure_init_reference() {
let x = function() { return x; };
const y = function() { return y; };
// var-bindings can reference each other cyclically since they do not incur a
// TDZ (...even though this is weird...)
var z = z;
}