// Copyright (c) 2011, 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.

// Test the basic StreamController and StreamController.singleSubscription.
library stream_controller_test;

import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
import 'dart:async';
import 'event_helper.dart';

const MS = const Duration(milliseconds: 1);

fail(e) { Expect.fail("Unexepected error: $e"); }

void testMultiController() {
  // Test normal flow.
  {
    var c = new StreamController(sync: true);
    Events expectedEvents = new Events()
        ..add(42)
        ..add("dibs")
        ..error("error!")
        ..error("error too!")
        ..close();
    CaptureEvents actualEvents =
      new Events.capture(c.stream.asBroadcastStream());
    expectedEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test automatic unsubscription on error.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add(42)..error("error");
    var actualEvents = new Events.capture(c.stream.asBroadcastStream(),
                                      cancelOnError: true);
    Events sentEvents =
        new Events()..add(42)..error("error")..add("Are you there?");
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test manual unsubscription.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add(42)..error("error")..add(37);
    var actualEvents = new Events.capture(c.stream.asBroadcastStream(),
                                      cancelOnError: false);
    expectedEvents.replay(c);
    actualEvents.subscription.cancel();
    c.add("Are you there");  // Not sent to actualEvents.
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test filter.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()
      ..add("a string")..add("another string")..close();
    var sentEvents = new Events()
      ..add("a string")..add(42)..add("another string")..close();
    var actualEvents = new Events.capture(c.stream
      .asBroadcastStream()
      .where((v) => v is String));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test map.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add("abab")..error("error")..close();
    var sentEvents = new Events()..add("ab")..error("error")..close();
    var actualEvents = new Events.capture(c.stream
      .asBroadcastStream()
      .map((v) => "$v$v"));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test handleError.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add("ab")..error("[foo]");
    var sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
    var actualEvents = new Events.capture(c.stream
      .asBroadcastStream()
      .handleError((error) {
          if (error is String) {
            // TODO(floitsch): this test originally changed the stacktrace.
            throw "[${error}]";
          }
        }), cancelOnError: true);
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // reduce is tested asynchronously and therefore not in this file.

  // Test expand
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add(3)..add(2)..add(4)..close();
    var expectedEvents = new Events()..add(1)..add(2)..add(3)
                                ..add(1)..add(2)
                                ..add(1)..add(2)..add(3)..add(4)
                                ..close();
    var actualEvents =
        new Events.capture(c.stream.asBroadcastStream().expand((v) {
      var l = [];
      for (int i = 0; i < v; i++) l.add(i + 1);
      return l;
    }));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test transform.
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add("a")..error(42)..add("b")..close();
    var expectedEvents =
        new Events()..error("a")..add(42)..error("b")..add("foo")..close();
    var actualEvents =
        new Events.capture(c.stream.asBroadcastStream().transform(
        new StreamTransformer.fromHandlers(
            handleData: (v, s) { s.addError(v); },
            handleError: (e, st, s) { s.add(e); },
            handleDone: (s) {
              s.add("foo");
              s.close();
            })));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test multiple filters.
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add(42)
                            ..add("snugglefluffy")
                            ..add(7)
                            ..add("42")
                            ..error("not FormatException")  // Unsubscribes.
                            ..close();
    var expectedEvents = new Events()..add(42)..error("not FormatException");
    var actualEvents = new Events.capture(
        c.stream.asBroadcastStream().where((v) => v is String)
        .map((v) => int.parse(v))
        .handleError((error) {
            if (error is! FormatException) throw error;
          })
        .where((v) => v > 10),
        cancelOnError: true);
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test subscription changes while firing.
  {
    var c = new StreamController(sync: true);
    var sink = c.sink;
    var stream = c.stream.asBroadcastStream();
    var counter = 0;
    var subscription = stream.listen(null);
    subscription.onData((data) {
      counter += data;
      subscription.cancel();
      stream.listen((data) {
        counter += 10 * data;
      });
      var subscription2 = stream.listen(null);
      subscription2.onData((data) {
        counter += 100 * data;
        if (data == 4) subscription2.cancel();
      });
    });
    sink.add(1); // seen by stream 1
    sink.add(2); // seen by stream 10 and 100
    sink.add(3); // -"-
    sink.add(4); // -"-
    sink.add(5); // seen by stream 10
    Expect.equals(1 + 20 + 200 + 30 + 300 + 40 + 400 + 50, counter);
  }
}

testSingleController() {
  // Test normal flow.
  {
    var c = new StreamController(sync: true);
    Events expectedEvents = new Events()
        ..add(42)
        ..add("dibs")
        ..error("error!")
        ..error("error too!")
        ..close();
    CaptureEvents actualEvents = new Events.capture(c.stream);
    expectedEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test automatic unsubscription on error.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add(42)..error("error");
    var actualEvents = new Events.capture(c.stream, cancelOnError: true);
    Events sentEvents =
        new Events()..add(42)..error("error")..add("Are you there?");
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test manual unsubscription.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add(42)..error("error")..add(37);
    var actualEvents = new Events.capture(c.stream, cancelOnError: false);
    expectedEvents.replay(c);
    actualEvents.subscription.cancel();
    c.add("Are you there");  // Not sent to actualEvents.
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test filter.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()
      ..add("a string")..add("another string")..close();
    var sentEvents = new Events()
      ..add("a string")..add(42)..add("another string")..close();
    var actualEvents = new Events.capture(c.stream.where((v) => v is String));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test map.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add("abab")..error("error")..close();
    var sentEvents = new Events()..add("ab")..error("error")..close();
    var actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test handleError.
  {
    var c = new StreamController(sync: true);
    var expectedEvents = new Events()..add("ab")..error("[foo]");
    var sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
    var actualEvents = new Events.capture(c.stream.handleError((error) {
          if (error is String) {
            // TODO(floitsch): this error originally changed the stack trace.
            throw "[${error}]";
          }
        }), cancelOnError: true);
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // reduce is tested asynchronously and therefore not in this file.

  // Test expand
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add(3)..add(2)..add(4)..close();
    var expectedEvents = new Events()..add(1)..add(2)..add(3)
                                ..add(1)..add(2)
                                ..add(1)..add(2)..add(3)..add(4)
                                ..close();
    var actualEvents = new Events.capture(c.stream.expand((v) {
      var l = [];
      for (int i = 0; i < v; i++) l.add(i + 1);
      return l;
    }));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // test contains.
  {
    var c = new StreamController(sync: true);
    // Error after match is not important.
    var sentEvents = new Events()..add("a")..add("x")..error("FAIL")..close();
    Future<bool> contains = c.stream.contains("x");
    contains.then((var c) {
      Expect.isTrue(c);
    });
    sentEvents.replay(c);
  }

  {
    var c = new StreamController(sync: true);
    // Not matching is ok.
    var sentEvents = new Events()..add("a")..add("x")..add("b")..close();
    Future<bool> contains = c.stream.contains("y");
    contains.then((var c) {
      Expect.isFalse(c);
    });
    sentEvents.replay(c);
  }

  {
    var c = new StreamController(sync: true);
    // Error before match makes future err.
    var sentEvents = new Events()..add("a")..error("FAIL")..add("b")..close();
    Future<bool> contains = c.stream.contains("b");
    contains.then((var c) {
      Expect.fail("no value expected");
    }).catchError((error) {
      Expect.equals("FAIL", error);
    });
    sentEvents.replay(c);
  }

  // Test transform.
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add("a")..error(42)..add("b")..close();
    var expectedEvents =
        new Events()..error("a")..add(42)..error("b")..add("foo")..close();
    var actualEvents = new Events.capture(c.stream.transform(
        new StreamTransformer.fromHandlers(
            handleData: (v, s) { s.addError(v); },
            handleError: (e, st, s) { s.add(e); },
            handleDone: (s) {
              s.add("foo");
              s.close();
            })));
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test multiple filters.
  {
    var c = new StreamController(sync: true);
    var sentEvents = new Events()..add(42)
                            ..add("snugglefluffy")
                            ..add(7)
                            ..add("42")
                            ..error("not FormatException")  // Unsubscribes.
                            ..close();
    var expectedEvents = new Events()..add(42)..error("not FormatException");
    var actualEvents = new Events.capture(
        c.stream.where((v) => v is String)
        .map((v) => int.parse(v))
        .handleError((error) {
            if (error is! FormatException) throw error;
          })
        .where((v) => v > 10),
        cancelOnError: true);
    sentEvents.replay(c);
    Expect.listEquals(expectedEvents.events, actualEvents.events);
  }

  // Test that only one subscription is allowed.
  {
    var c = new StreamController(sync: true);
    var sink = c.sink;
    var stream = c.stream;
    var counter = 0;
    var subscription = stream.listen((data) { counter += data; });
    Expect.throws(() => stream.listen(null), (e) => e is StateError);
    sink.add(1);
    Expect.equals(1, counter);
    c.close();
  }
}

testExtraMethods() {
  Events sentEvents = new Events()..add(1)..add(2)..add(3)..close();

  var c = new StreamController(sync: true);
  Events expectedEvents = new Events()..add(3)..close();
  Events actualEvents = new Events.capture(c.stream.skip(2));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);

  c = new StreamController(sync: true);
  expectedEvents = new Events()..close();
  actualEvents = new Events.capture(c.stream.skip(3));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);

  c = new StreamController(sync: true);
  expectedEvents = new Events()..close();
  actualEvents = new Events.capture(c.stream.skip(7));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);

  c = new StreamController(sync: true);
  expectedEvents = sentEvents;
  actualEvents = new Events.capture(c.stream.skip(0));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  expectedEvents = new Events()..add(3)..close();
  actualEvents = new Events.capture(c.stream.skipWhile((x) => x <= 2));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  expectedEvents = new Events()..add(2)..add(3)..close();
  actualEvents = new Events.capture(c.stream.skipWhile((x) => x <= 1));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  expectedEvents = new Events()..add(1)..add(2)..add(3)..close();
  actualEvents = new Events.capture(c.stream.skipWhile((x) => false));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  expectedEvents = new Events()..add(1)..add(2)..close();
  actualEvents = new Events.capture(c.stream.take(2));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  expectedEvents = new Events()..add(1)..add(2)..close();
  actualEvents = new Events.capture(c.stream.takeWhile((x) => x <= 2));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  sentEvents = new Events()
      ..add(1)..add(1)..add(2)..add(1)..add(2)..add(2)..add(2)..close();
  expectedEvents = new Events()
      ..add(1)..add(2)..add(1)..add(2)..close();
  actualEvents = new Events.capture(c.stream.distinct());
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);


  c = new StreamController(sync: true);
  sentEvents = new Events()
      ..add(5)..add(6)..add(4)..add(6)..add(8)..add(3)..add(4)..add(1)..close();
  expectedEvents = new Events()
      ..add(5)..add(4)..add(3)..add(1)..close();
  // Use 'distinct' as a filter with access to the previously emitted event.
  actualEvents = new Events.capture(c.stream.distinct((a, b) => a < b));
  sentEvents.replay(c);
  Expect.listEquals(expectedEvents.events, actualEvents.events);
}

void testClosed() {
  StreamController c = new StreamController(sync: true);
  Expect.isFalse(c.isClosed);
  c.add(42);
  Expect.isFalse(c.isClosed);
  c.addError("bad");
  Expect.isFalse(c.isClosed);
  c.close();
  Expect.isTrue(c.isClosed);
}

void testCloseFuture() {
  asyncStart();
  asyncStart();
  var c = new StreamController();
  var f = c.close();
  Expect.isTrue(c.isClosed);
  bool doneSeen = false;
  f.then((_) {
    Expect.isTrue(doneSeen);
    asyncEnd();
  });
  // Only listen after a while.
  new Timer(MS * 250, () {
    c.stream.listen(null, onDone: () {
      asyncEnd();
      doneSeen = true;
    });
  });
}

void testCloseFuture2() {
  asyncStart();
  asyncStart();
  var c = new StreamController.broadcast();
  var f = c.close();
  Expect.isTrue(c.isClosed);
  bool doneSeen = false;
  f.then((_) {
    // Done future on broadcast stream can happen
    // before a listener is added.
    Expect.isFalse(doneSeen);
    asyncEnd();
  });
  // Only listen after a while.
  new Timer(MS * 250, () {
    c.stream.listen(null, onDone: () {
      doneSeen = true;
      asyncEnd();
    });
  });
}

void testCloseFuture3() {
  asyncStart();
  var c = new StreamController.broadcast();
  c..add(1)..add(2)..add(3)..add(4);
  c.stream.listen(null).cancel();
  var f = c.close();
  Expect.isTrue(c.isClosed);
  f.then((_) {
    asyncEnd();
  });
}

void testStreamEquals() {
  StreamController c;
  c = new StreamController(sync: false);
  Expect.equals(c.stream, c.stream);
  c = new StreamController(sync: true);
  Expect.equals(c.stream, c.stream);
  c = new StreamController(sync: false, onListen: () {});
  Expect.equals(c.stream, c.stream);
  c = new StreamController(sync: true, onListen: () {});
  Expect.equals(c.stream, c.stream);
  c = new StreamController.broadcast(sync: false);
  Expect.equals(c.stream, c.stream);
  c = new StreamController.broadcast(sync: true);
  Expect.equals(c.stream, c.stream);
  c = new StreamController.broadcast(sync: false, onListen: () {});
  Expect.equals(c.stream, c.stream);
  c = new StreamController.broadcast(sync: true, onListen: () {});
  Expect.equals(c.stream, c.stream);
}

void testCancelThrow() {
  asyncStart();
  asyncStart();
  asyncStart();
  StreamController c = new StreamController(onCancel: () {
    asyncEnd();
    throw "ERROR";
  });
  c.add(1);
  c.add(2);
  c.add(3);
  Future done = c.close();
  StreamSubscription sub;
  sub = c.stream.listen((v) {
    Expect.equals(1, v);
    Future f = sub.cancel();
    f.catchError((e) {
      // Must complete with error from onCancel.
      Expect.equals("ERROR", e);
      asyncEnd();
    });
  });
  done.catchError(fail).whenComplete(asyncEnd);  // Must complete without error.
}

void testCancelThrow2() {
  asyncStart();
  asyncStart();
  asyncStart();
  asyncStart();
  asyncStart();
  StreamController c2 = new StreamController(onCancel: () {
    asyncEnd();
    throw "ERROR";
  });
  c2.add(1);
  c2.add(2);
  Future done2 = c2.close();
  done2.catchError(fail).whenComplete(asyncEnd);  // Should not get error;

  StreamController c = new StreamController();
  var sub;
  sub = c.stream.listen((v) {
    Expect.equals(1, v);
    Future f = sub.cancel();
    f.catchError((e) {
      // Error from addStream stream's cancel must go only here.
      asyncEnd();
      Expect.equals("ERROR", e);
    });
  });
  var addDone = c.addStream(c2.stream);
  addDone.catchError(fail).whenComplete(asyncEnd);  // Should not get error.
  var done = c.done;
  done.catchError(fail).whenComplete(asyncEnd);  // Should not get error.
}

void testCancelThrow3() {
  asyncStart();
  asyncStart();
  asyncStart();
  asyncStart();
  asyncStart();
  asyncStart();
  StreamController c2 = new StreamController(onCancel: () {
    asyncEnd();
    throw "ERROR2";
  });
  c2.add(1);
  c2.add(2);
  var done2 = c2.close();
  done2.catchError(fail).whenComplete(asyncEnd);  // Should not get error;

  StreamController c = new StreamController(onCancel: () {
    asyncEnd();
    throw "ERROR1";
  });
  var sub;
  sub = c.stream.listen((v) {
    Expect.equals(1, v);
    Future f = sub.cancel();
    f.catchError((e) {
      // Only the last error ends up here.
      Expect.equals("ERROR1", e);
      asyncEnd();
    });
  });
  var addDone = c.addStream(c2.stream);
  addDone.catchError(fail).whenComplete(asyncEnd);  // Error must not go here.
  c.done.catchError(fail).whenComplete(asyncEnd); // Error must not go here.
}

void testBroadcastListenAfterClose() {
  asyncStart();
  StreamController c = new StreamController.broadcast();
  var f = c.close();
  f.then((_) {
    // Listening after close is allowed. The listener gets a done event.
    c.stream.listen(null, onDone: asyncEnd);
  });
}

void testBroadcastListenAfterClosePaused() {
  asyncStart();
  StreamController c = new StreamController.broadcast();
  var f = c.close();
  f.then((_) {
    // Listening after close is allowed. The listener gets a done event.
    var sub = c.stream.listen(null, onDone: () {
      Expect.fail("wrong done");
    });
    sub.pause();
    sub.pause();
    new Timer(MS * 100, () {
      sub.asFuture().whenComplete(() { Expect.fail("Bad complete"); });
      sub.resume();
      new Timer(MS * 100, () {
        sub.onDone(asyncEnd);
        sub.resume();
      });
    });
  });
}

void testAsBroadcastListenAfterClose() {
  asyncStart();
  asyncStart();
  StreamController c = new StreamController();
  Stream s = c.stream.asBroadcastStream();
  s.listen(null, onDone: asyncEnd);
  var f = c.close();
  f.then((_) {
    // Listening after close is allowed. The listener gets a done event.
    s.listen(null, onDone: asyncEnd);
  });
}

void testAsBroadcastListenAfterClosePaused() {
  asyncStart();
  asyncStart();
  StreamController c = new StreamController();
  Stream s = c.stream.asBroadcastStream();
  s.listen(null, onDone: asyncEnd);
  var f = c.close();
  f.then((_) {
    // Listening after close is allowed. The listener gets a done event.
    var sub = s.listen(null, onDone: () {
      Expect.fail("wrong done");
    });
    sub.pause();
    sub.pause();
    new Timer(MS * 100, () {
      sub.asFuture().whenComplete(() { Expect.fail("Bad complete"); });
      sub.resume();
      new Timer(MS * 100, () {
        sub.onDone(asyncEnd);
        sub.resume();
      });
    });
  });
}

void testEventInListen() {
  asyncStart();
  // Regression test for http://dartbug.com/19722
  var c;
  void send() {
    c.add(1);
  }
  int i = 1;
  c = new StreamController.broadcast(onListen: send, sync: true);
  c.stream.listen((v) {
    Expect.equals(i++, v);
  }, onDone: asyncEnd);
  c.add(2);
  c.close();
}

void testSyncControllerNotReentrant() {
  Stream emptyStream = (new StreamController.broadcast()..close()).stream;
  asyncStart();
  for (int listenerCount = 1; listenerCount <= 2; listenerCount++) {
    StreamController c = new StreamController.broadcast(sync: true);
    for (int i = 0; i < listenerCount; i++) {
      asyncStart();
      asyncStart();
      c.stream.listen((v) {
        Expect.equals(42, v);
        Expect.throws(() {
          c.add(37);
        });
        Expect.throws(() {
          c.addError(37);
        });
        Expect.throws(() {
          c.addStream(emptyStream);
        });
        Expect.throws(() {
          c.close();
        });
        asyncEnd();
      }, onError: (e, s) {
        Expect.equals(87, e);
        Expect.throws(() {
          c.add(37);
        });
        Expect.throws(() {
          c.addError(37);
        });
        Expect.throws(() {
          c.addStream(emptyStream);
        });
        Expect.throws(() {
          c.close();
        });
        asyncEnd();
      });
    }
    c.add(42);
    c.addError(87);
  }
  asyncEnd();
}

void testSettingCallbacks() {
  const int initial = 0;
  const int running = 1;
  const int paused  = 2;
  const int canceled = 3;

  var controller = new StreamController();
  var stream = controller.stream;
  var state = initial;

  var onListen = () { state = running; };
  var onPause  = () { state = paused; };
  var onResume = () { state = running; };
  var onCancel = () { state = canceled; };

  Expect.isNull(controller.onListen);
  Expect.isNull(controller.onPause);
  Expect.isNull(controller.onResume);
  Expect.isNull(controller.onCancel);

  controller..onListen = onListen
            ..onPause  = onPause
            ..onResume = onResume
            ..onCancel = onCancel;

  Expect.equals(onListen, controller.onListen);
  Expect.equals(onPause,  controller.onPause);
  Expect.equals(onResume, controller.onResume);
  Expect.equals(onCancel, controller.onCancel);

  Expect.equals(initial, state);
  var sub = stream.listen(null);
  Expect.equals(running, state);
  sub.pause();
  Expect.equals(paused, state);
  Expect.isTrue(controller.isPaused);
  sub.resume();
  Expect.equals(running, state);
  Expect.isFalse(controller.isPaused);

  var onListen2 = () { state = -running; };
  var onPause2  = () { state = -paused; };
  var onResume2 = () { state = -running; };
  var onCancel2 = () { state = -canceled; };
  // Changing them later does make a difference.
  controller..onListen = onListen2
            ..onPause  = onPause2
            ..onResume = onResume2
            ..onCancel = onCancel2;

  Expect.equals(onListen2, controller.onListen);
  Expect.equals(onPause2,  controller.onPause);
  Expect.equals(onResume2, controller.onResume);
  Expect.equals(onCancel2, controller.onCancel);

  Expect.equals(running, state);
  sub.pause();
  Expect.equals(-paused, state);
  Expect.isTrue(controller.isPaused);
  sub.resume();
  Expect.equals(-running, state);
  Expect.isFalse(controller.isPaused);
  sub.cancel();
  Expect.equals(-canceled, state);
}

void testSettingNullCallbacks() {
  failCallback() => fail("Callback should not be called");
  var controller = new StreamController(onListen: failCallback,
                                        onPause : failCallback,
                                        onResume: failCallback,
                                        onCancel: failCallback);

  var stream = controller.stream;

  Expect.isFalse(controller.hasListener);
  Expect.isTrue(controller.isPaused);

  Expect.isNotNull(controller.onListen);
  controller.onListen = null;
  Expect.isNull(controller.onListen);

  var sub = stream.listen(null);

  Expect.isTrue(controller.hasListener);
  Expect.isFalse(controller.isPaused);

  Expect.isNotNull(controller.onPause);
  controller.onPause = null;
  Expect.isNull(controller.onPause);

  sub.pause();

  Expect.isTrue(controller.hasListener);
  Expect.isTrue(controller.isPaused);

  Expect.isNotNull(controller.onResume);
  controller.onResume = null;
  Expect.isNull(controller.onResume);

  sub.resume();

  Expect.isTrue(controller.hasListener);
  Expect.isFalse(controller.isPaused);

  Expect.isNotNull(controller.onCancel);
  controller.onCancel = null;
  Expect.isNull(controller.onCancel);

  sub.cancel();

  Expect.isFalse(controller.hasListener);
  Expect.isFalse(controller.isPaused);
}

void testBroadcastSettingCallbacks() {
  const int initial = 0;
  const int running = 1;
  const int canceled = 2;

  var controller = new StreamController.broadcast();
  var stream = controller.stream;
  var state = initial;

  Expect.throws(() { controller.onPause = () {}; },
                (e) => e is UnsupportedError);
  Expect.throws(() { controller.onResume = () {}; },
                (e) => e is UnsupportedError);

  controller..onListen = () { state = running; }
            ..onCancel = () { state = canceled; };

  Expect.equals(initial, state);
  var sub = stream.listen(null);
  Expect.equals(running, state);
  sub.cancel();
  Expect.equals(canceled, state);

  // Changing them later does make a difference.
  controller..onListen = () { state = -running; }
            ..onCancel = () { state = -canceled; };

  var sub2 = stream.listen(null);
  Expect.equals(-running, state);
  sub2.cancel();
  Expect.equals(-canceled, state);
}

void testBroadcastSettingNullCallbacks() {
  failCallback() => fail("Callback should not be called");
  var controller = new StreamController.broadcast(onListen: failCallback,
                                                  onCancel: failCallback);

  var stream = controller.stream;

  Expect.isFalse(controller.hasListener);

  controller.onListen = null;

  var sub = stream.listen(null);

  Expect.isTrue(controller.hasListener);

  controller.onCancel = null;

  sub.cancel();

  Expect.isFalse(controller.hasListener);
}

main() {
  asyncStart();
  testMultiController();
  testSingleController();
  testExtraMethods();
  testClosed();
  testCloseFuture();
  testCloseFuture2();
  testCloseFuture3();
  testStreamEquals();
  testCancelThrow();
  testCancelThrow2();
  testCancelThrow3();
  testBroadcastListenAfterClose();
  testBroadcastListenAfterClosePaused();
  testAsBroadcastListenAfterClose();
  testAsBroadcastListenAfterClosePaused();
  testEventInListen();
  testSyncControllerNotReentrant();
  testSettingCallbacks();
  testSettingNullCallbacks();
  testBroadcastSettingCallbacks();
  testBroadcastSettingNullCallbacks();
  asyncEnd();
}
