// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --harmony-async-iteration --allow-natives-syntax

// .return() from state suspendedStart with undefined
testAsync(test => {
  test.plan(3);

  async function* gen() {
    test.unreachable();
  }

  let didResolvePromise = false;
  let g = gen();
  g.return(undefined).then(
      (iterResult) => {
        test.equals(true, didResolvePromise);
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());

  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());

  // Race: generator request's promise should resolve after this Promise.
  Promise.resolve("already-resolved").then(
      _ => { didResolvePromise = true },
      test.unexpectedRejection());

}, "AsyncGenerator.return(undefined) / suspendStart");

// .return() from state suspendedStart with thenable
testAsync(test => {
  test.plan(3);

  async function* gen() {
    test.unreachable();
  }

  let didResolvePromise = false;
  let g = gen();

  let resolve;
  let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };

  g.return(awaitedThenable).then(
      (iterResult) => {
        test.equals(true, didResolvePromise);
        test.equals({ value: "resolvedPromise", done: true }, iterResult);
      },
      test.unexpectedRejection());

  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());

  test.drainMicrotasks();
  resolve("resolvedPromise");

  // Race: generator request's promise should resolve after this Promise.
  Promise.resolve("already-resolved").then(
      _ => { didResolvePromise = true },
      test.unexpectedRejection());

}, "AsyncGenerator.return(thenable) / suspendStart");

// .return() from state suspendedYield with undefined
testAsync(test => {
  test.plan(4);

  async function* gen() {
    yield;
    test.unreachable();
  }

  let didResolvePromise = false;
  let g = gen();
  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: false }, iterResult);
      },
      test.unexpectedRejection());
  g.return(undefined).then(
      (iterResult) => {
        test.equals(true, didResolvePromise);
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());
  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());

  // Race: generator request's promise should resolve after this Promise.
  Promise.resolve("already-resolved").then(
      _ => { didResolvePromise = true },
      test.unexpectedRejection());

}, "AsyncGenerator.return(undefined) / suspendedYield");

// .return() from state suspendedYield with thenable
testAsync(test => {
  test.plan(4);

  async function* gen() {
    yield;
    test.unreachable();
  }

  let didResolvePromise = false;
  let g = gen();

  let resolve;
  let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };

  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: false }, iterResult);
      },
      test.unexpectedRejection());
  g.return(awaitedThenable).then(
      (iterResult) => {
        test.equals(true, didResolvePromise);
        test.equals({ value: "resolvedPromise", done: true }, iterResult);
      },
      test.unexpectedRejection());

  g.next().then(
      (iterResult) => {
        test.equals({ value: undefined, done: true }, iterResult);
      },
      test.unexpectedRejection());

  test.drainMicrotasks();
  resolve("resolvedPromise");

  // Race: generator request's promise should resolve after this Promise.
  Promise.resolve("already-resolved").then(
      _ => { didResolvePromise = true },
      test.unexpectedRejection());

}, "AsyncGenerator.return(thenable) / suspendYield");
