// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS
// file for details. All rights reserved. Use of this source code is governed
// by a BSD-style license that can be found in the LICENSE file.

/// @assertion If the errorAreFatal, onExit and/or onError parameters are
/// provided, the isolate will act as if, respectively, setErrorsFatal,
/// addOnExitListener and addErrorListener were called with the corresponding
/// parameter and was processed before the isolate starts running.
///
/// @description Check that if onError parameter is supplied, the isolate
/// captures and send only first error on given send port, errorAreFatal is true.
/// The isolate is active.
/// @author a.semenov@unipro.ru

import "dart:isolate";
import "dart:async";
import "../../../Utils/expect.dart";
import "IsolateUtil.dart";

void entryPoint(message) {
  dynamic i1 = 1, i2 = 2, i3 = 3, i4 = 4;
  // second error
  new Future.delayed(ONE_SECOND, () => "b" + i2);
  // third error
  new Future.delayed(TWO_SECONDS, () => "c" + i3);
  // fourth error
  new Future.delayed(THREE_SECONDS, () => "d" + i4);
  // first error
  var x = "a" + i1;
}

test() async {
  ReceivePort errorPort = new ReceivePort();
  Isolate.spawn(entryPoint, "hello",
      errorsAreFatal: true, onError: errorPort.sendPort);

  int count = 0;
  await for (var error in errorPort) {
    Expect.equals(0, count, "received unexpected data $error");
    Expect.isTrue(error is List);
    Expect.equals(2, error.length);
    Expect.isTrue(error[0] is String);
    Expect.isTrue(error[1] is String);
    count++;
    new Future.delayed(THREE_SECONDS, () => errorPort.close());
  }
  asyncEnd();
}

main() {
  asyncStart();
  test();
}
