// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`class.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
class GeneratorExamples {
  *stmt_yield(): Generator<number, void, void> {
    yield 0; // ok
    yield ""; // error: string ~> number
  }

  *stmt_next(): Generator<void, void, number> {
    var a = yield;
    if (a) {
      (a : number); // ok
    }

    var b = yield;
    if (b) {
      (b : string); // error: number ~> string
    }
  }

  *stmt_return_ok(): Generator<void, number, void> {
    return 0; // ok
  }

  *stmt_return_err(): Generator<void, number, void> {
    return ""; // error: string ~> number
  }

  *infer_stmt() {
    var x: boolean = yield 0; // error: number ~> boolean
    return "";
  }

  *widen_next() {
    var x = yield 0;
    if (typeof x === "number") {
    } else if (typeof x === "boolean") {
    } else {
      (x : string) // ok, sherlock
    }
  }

  *widen_yield() {
    yield 0;
    yield "";
    yield true;
  }

  *delegate_next_generator() {
    function *inner() {
      var x: number = yield; // error: string ~> number
    }
    yield *inner();
  }

  *delegate_yield_generator() {
    function *inner() {
      yield "";
    }

    yield *inner();
  }

  *delegate_return_generator() {
    function *inner() {
      return "";
    }

    var x: number = yield *inner(); // error: string ~> number
  }

  // only generators can make use of a value passed to next
  *delegate_next_iterable(xs: Array<number>) {
    yield *xs;
  }

  *delegate_yield_iterable(xs: Array<number>) {
    yield *xs;
  }

  *delegate_return_iterable(xs: Array<number>) {
    var x: void = yield *xs // ok: Iterator has no yield value
  }

  *generic_yield<Y>(y: Y): Generator<Y,void,void> {
    yield y;
  }

  *generic_return<R>(r: R): Generator<void,R,void> {
    return r;
  }

  *generic_next<N>(): Generator<void,N,N> {
    return yield undefined;
  }
}

var examples = new GeneratorExamples();

for (var x of examples.infer_stmt()) { (x : string) } // error: number ~> string

var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean
if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next : boolean) // error: string ~> boolean
}

examples.widen_next().next(0)
examples.widen_next().next("")
examples.widen_next().next(true)

for (var x of examples.widen_yield()) {
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x : string) // ok, sherlock
  }
}

examples.delegate_next_generator().next("");

for (var x of examples.delegate_yield_generator()) {
  (x : number) // error: string ~> number
}

examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value

for (var x of examples.delegate_yield_iterable([])) {
  (x : string) // error: number ~> string
}

=====================================output=====================================
class GeneratorExamples {
  *stmt_yield(): Generator<number, void, void> {
    yield 0; // ok
    yield ""; // error: string ~> number
  }

  *stmt_next(): Generator<void, void, number> {
    var a = yield;
    if (a) {
      (a: number); // ok
    }

    var b = yield;
    if (b) {
      (b: string); // error: number ~> string
    }
  }

  *stmt_return_ok(): Generator<void, number, void> {
    return 0; // ok
  }

  *stmt_return_err(): Generator<void, number, void> {
    return ""; // error: string ~> number
  }

  *infer_stmt() {
    var x: boolean = yield 0; // error: number ~> boolean
    return "";
  }

  *widen_next() {
    var x = yield 0;
    if (typeof x === "number") {
    } else if (typeof x === "boolean") {
    } else {
      (x: string); // ok, sherlock
    }
  }

  *widen_yield() {
    yield 0;
    yield "";
    yield true;
  }

  *delegate_next_generator() {
    function* inner() {
      var x: number = yield; // error: string ~> number
    }
    yield* inner();
  }

  *delegate_yield_generator() {
    function* inner() {
      yield "";
    }

    yield* inner();
  }

  *delegate_return_generator() {
    function* inner() {
      return "";
    }

    var x: number = yield* inner(); // error: string ~> number
  }

  // only generators can make use of a value passed to next
  *delegate_next_iterable(xs: Array<number>) {
    yield* xs;
  }

  *delegate_yield_iterable(xs: Array<number>) {
    yield* xs;
  }

  *delegate_return_iterable(xs: Array<number>) {
    var x: void = yield* xs; // ok: Iterator has no yield value
  }

  *generic_yield<Y>(y: Y): Generator<Y, void, void> {
    yield y;
  }

  *generic_return<R>(r: R): Generator<void, R, void> {
    return r;
  }

  *generic_next<N>(): Generator<void, N, N> {
    return yield undefined;
  }
}

var examples = new GeneratorExamples();

for (var x of examples.infer_stmt()) {
  (x: string);
} // error: number ~> string

var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean
if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next: boolean); // error: string ~> boolean
}

examples.widen_next().next(0);
examples.widen_next().next("");
examples.widen_next().next(true);

for (var x of examples.widen_yield()) {
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x: string); // ok, sherlock
  }
}

examples.delegate_next_generator().next("");

for (var x of examples.delegate_yield_generator()) {
  (x: number); // error: string ~> number
}

examples.delegate_next_iterable([]).next(""); // error: Iterator has no next value

for (var x of examples.delegate_yield_iterable([])) {
  (x: string); // error: number ~> string
}

================================================================================
`;

exports[`class_failure.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
// generalization of failure in class.js

class GeneratorExamples<X> {
  *infer_stmt() {
    var x: boolean = yield 0; // error: number ~> boolean
    return "";
  }
}

var examples = new GeneratorExamples();

for (var x of examples.infer_stmt()) { (x : string) } // error: number ~> string

var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean

if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next : boolean) // error: string ~> boolean
}

=====================================output=====================================
// generalization of failure in class.js

class GeneratorExamples<X> {
  *infer_stmt() {
    var x: boolean = yield 0; // error: number ~> boolean
    return "";
  }
}

var examples = new GeneratorExamples();

for (var x of examples.infer_stmt()) {
  (x: string);
} // error: number ~> string

var infer_stmt_next = examples.infer_stmt().next(0).value; // error: number ~> boolean

if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next: boolean); // error: string ~> boolean
}

================================================================================
`;

exports[`generators.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
function *stmt_yield(): Generator<number, void, void> {
  yield 0; // ok
  yield ""; // error: string ~> number
}

function *stmt_next(): Generator<void, void, number> {
  var a = yield;
  if (a) {
    (a : number); // ok
  }

  var b = yield;
  if (b) {
    (b : string); // error: number ~> string
  }
}

function *stmt_return_ok(): Generator<void, number, void> {
  return 0; // ok
}

function *stmt_return_err(): Generator<void, number, void> {
  return ""; // error: string ~> number
}

function *infer_stmt() {
  var x: boolean = yield 0;
  return "";
}
for (var x of infer_stmt()) { (x : string) } // error: number ~> string
var infer_stmt_next = infer_stmt().next(0).value; // error: number ~> boolean
if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next : boolean) // error: string ~> boolean
}

function *widen_next() {
  var x = yield 0;
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x : string) // ok, sherlock
  }
}
widen_next().next(0)
widen_next().next("")
widen_next().next(true)

function *widen_yield() {
  yield 0;
  yield "";
  yield true;
}
for (var x of widen_yield()) {
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x : string) // ok, sherlock
  }
}

function *delegate_next_generator() {
  function *inner() {
    var x: number = yield; // error: string ~> number
  }
  yield *inner();
}
delegate_next_generator().next("");

function *delegate_yield_generator() {
  function *inner() {
    yield "";
  }

  yield *inner();
}
for (var x of delegate_yield_generator()) {
  (x : number) // error: string ~> number
}

function *delegate_return_generator() {
  function *inner() {
    return "";
  }

  var x: number = yield *inner(); // error: string ~> number
}

// only generators can make use of a value passed to next
function *delegate_next_iterable(xs: Array<number>) {
  yield *xs;
}
delegate_next_iterable([]).next(""); // error: Iterator has no next value

function *delegate_yield_iterable(xs: Array<number>) {
  yield *xs;
}
for (var x of delegate_yield_iterable([])) {
  (x : string) // error: number ~> string
}

function *delegate_return_iterable(xs: Array<number>) {
  var x: void = yield *xs // ok: Iterator has no yield value
}

function *generic_yield<Y>(y: Y): Generator<Y,void,void> {
  yield y;
}

function *generic_return<R>(r: R): Generator<void,R,void> {
  return r;
}

function *generic_next<N>(): Generator<void,N,N> {
  return yield undefined;
}

function *multiple_return(b) {
  if (b) {
    return 0;
  } else {
    return "foo";
  }
}
let multiple_return_result = multiple_return().next();
if (multiple_return_result.done) {
  (multiple_return_result.value: void); // error: number|string ~> void
}

=====================================output=====================================
function* stmt_yield(): Generator<number, void, void> {
  yield 0; // ok
  yield ""; // error: string ~> number
}

function* stmt_next(): Generator<void, void, number> {
  var a = yield;
  if (a) {
    (a: number); // ok
  }

  var b = yield;
  if (b) {
    (b: string); // error: number ~> string
  }
}

function* stmt_return_ok(): Generator<void, number, void> {
  return 0; // ok
}

function* stmt_return_err(): Generator<void, number, void> {
  return ""; // error: string ~> number
}

function* infer_stmt() {
  var x: boolean = yield 0;
  return "";
}
for (var x of infer_stmt()) {
  (x: string);
} // error: number ~> string
var infer_stmt_next = infer_stmt().next(0).value; // error: number ~> boolean
if (typeof infer_stmt_next === "undefined") {
} else if (typeof infer_stmt_next === "number") {
} else {
  (infer_stmt_next: boolean); // error: string ~> boolean
}

function* widen_next() {
  var x = yield 0;
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x: string); // ok, sherlock
  }
}
widen_next().next(0);
widen_next().next("");
widen_next().next(true);

function* widen_yield() {
  yield 0;
  yield "";
  yield true;
}
for (var x of widen_yield()) {
  if (typeof x === "number") {
  } else if (typeof x === "boolean") {
  } else {
    (x: string); // ok, sherlock
  }
}

function* delegate_next_generator() {
  function* inner() {
    var x: number = yield; // error: string ~> number
  }
  yield* inner();
}
delegate_next_generator().next("");

function* delegate_yield_generator() {
  function* inner() {
    yield "";
  }

  yield* inner();
}
for (var x of delegate_yield_generator()) {
  (x: number); // error: string ~> number
}

function* delegate_return_generator() {
  function* inner() {
    return "";
  }

  var x: number = yield* inner(); // error: string ~> number
}

// only generators can make use of a value passed to next
function* delegate_next_iterable(xs: Array<number>) {
  yield* xs;
}
delegate_next_iterable([]).next(""); // error: Iterator has no next value

function* delegate_yield_iterable(xs: Array<number>) {
  yield* xs;
}
for (var x of delegate_yield_iterable([])) {
  (x: string); // error: number ~> string
}

function* delegate_return_iterable(xs: Array<number>) {
  var x: void = yield* xs; // ok: Iterator has no yield value
}

function* generic_yield<Y>(y: Y): Generator<Y, void, void> {
  yield y;
}

function* generic_return<R>(r: R): Generator<void, R, void> {
  return r;
}

function* generic_next<N>(): Generator<void, N, N> {
  return yield undefined;
}

function* multiple_return(b) {
  if (b) {
    return 0;
  } else {
    return "foo";
  }
}
let multiple_return_result = multiple_return().next();
if (multiple_return_result.done) {
  (multiple_return_result.value: void); // error: number|string ~> void
}

================================================================================
`;

exports[`refi.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
function *a(x: {a: void | string}): Generator<void, void, void> {
  if (!x.a) return;
  (x.a: string); // ok
  yield;
  (x.a: string); // error
}

function *b(x: void | string): Generator<void, void, void> {
  if (!x) return;
  (x: string); // ok
  yield;
  (x: string); // ok
}

declare function fn(): Generator<void, void, void>;

function *c(x: {a: void | string}): Generator<void, void, void> {
  const gen = fn();
  if (!x.a) return;
  (x.a: string); // ok
  yield * gen;
  (x.a: string); // error
}

function *d(x: void | string): Generator<void, void, void> {
  const gen = fn();
  if (!x) return;
  (x: string); // ok
  yield * gen;
  (x: string); // ok
}

=====================================output=====================================
function* a(x: { a: void | string }): Generator<void, void, void> {
  if (!x.a) return;
  (x.a: string); // ok
  yield;
  (x.a: string); // error
}

function* b(x: void | string): Generator<void, void, void> {
  if (!x) return;
  (x: string); // ok
  yield;
  (x: string); // ok
}

declare function fn(): Generator<void, void, void>;

function* c(x: { a: void | string }): Generator<void, void, void> {
  const gen = fn();
  if (!x.a) return;
  (x.a: string); // ok
  yield* gen;
  (x.a: string); // error
}

function* d(x: void | string): Generator<void, void, void> {
  const gen = fn();
  if (!x) return;
  (x: string); // ok
  yield* gen;
  (x: string); // ok
}

================================================================================
`;

exports[`return.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
function test1(gen: Generator<void, string, void>) {
  // You can pass whatever you like to return, it doesn't need to be related to
  // the Generator's return type
  var ret = gen.return(0);
  (ret.value: void); // error: string | number ~> void
}

// However, a generator can "refuse" the return by catching an exception and
// yielding or returning internally.
function *refuse_return() {
  try {
    yield 1;
  } finally {
    return 0;
  }
}
var refuse_return_gen = refuse_return();
var refuse_return_result = refuse_return_gen.return("string");
if (refuse_return_result.done) {
  (refuse_return_result.value: string); // error: number | void ~> string
}

=====================================output=====================================
function test1(gen: Generator<void, string, void>) {
  // You can pass whatever you like to return, it doesn't need to be related to
  // the Generator's return type
  var ret = gen.return(0);
  (ret.value: void); // error: string | number ~> void
}

// However, a generator can "refuse" the return by catching an exception and
// yielding or returning internally.
function* refuse_return() {
  try {
    yield 1;
  } finally {
    return 0;
  }
}
var refuse_return_gen = refuse_return();
var refuse_return_result = refuse_return_gen.return("string");
if (refuse_return_result.done) {
  (refuse_return_result.value: string); // error: number | void ~> string
}

================================================================================
`;

exports[`throw.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
function *catch_return() {
  try {
    yield 0;
  } catch (e) {
    return e;
  }
}

var catch_return_value = catch_return().throw("").value;
if (catch_return_value !== undefined) {
  (catch_return_value : string); // error: number ~> string
}

function *yield_return() {
  try {
    yield 0;
    return;
  } catch (e) {
    yield e;
  }
}
var yield_return_value = yield_return().throw("").value;
if (yield_return_value !== undefined) {
  (yield_return_value: string); // error: number ~> string
}

=====================================output=====================================
function* catch_return() {
  try {
    yield 0;
  } catch (e) {
    return e;
  }
}

var catch_return_value = catch_return().throw("").value;
if (catch_return_value !== undefined) {
  (catch_return_value: string); // error: number ~> string
}

function* yield_return() {
  try {
    yield 0;
    return;
  } catch (e) {
    yield e;
  }
}
var yield_return_value = yield_return().throw("").value;
if (yield_return_value !== undefined) {
  (yield_return_value: string); // error: number ~> string
}

================================================================================
`;

exports[`variance.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
declare var g1: Generator<string, string, ?string>;
var g2: Generator<?string, ?string, string> = g1;

=====================================output=====================================
declare var g1: Generator<string, string, ?string>;
var g2: Generator<?string, ?string, string> = g1;

================================================================================
`;
