// 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.

// @dart = 2.9

// 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);
    dynamic 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);
    dynamic 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.throwsStateError(() => stream.listen(null));
    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.throwsUnsupportedError(() => controller.onPause = () {});
  Expect.throwsUnsupportedError(() => controller.onResume = () {});

  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();
}
