blob: b9cf2e2cd042b49fc550330ba20518e86e30c35a [file] [log] [blame]
// Copyright (c) 2013, 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.
library stream_listen_zeno_test;
import "dart:async";
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
main() {
asyncStart();
var controller;
for (bool overrideDone in [false, true]) {
for (bool sync in [false, true]) {
var mode = "${sync ? "-sync" : ""}${overrideDone ? "-od": ""}";
controller = new StreamController(sync: sync);
testStream("SC$mode", controller, controller.stream, overrideDone);
controller = new StreamController.broadcast(sync: sync);
testStream("BSC$mode", controller, controller.stream, overrideDone);
controller = new StreamController(sync: sync);
testStream("SCAB$mode", controller, controller.stream.asBroadcastStream(),
overrideDone, 3);
controller = new StreamController(sync: sync);
testStream("SCMap$mode", controller, controller.stream.map((x) => x),
overrideDone, 3);
}
}
asyncEnd();
}
void testStream(
String name, StreamController controller, Stream stream, bool overrideDone,
[int registerExpect = 0]) {
asyncStart();
late StreamSubscription sub;
late Zone zone;
int registerCount = 0;
int callbackBits = 0;
int stepCount = 0;
late void Function() step;
void nextStep() {
Zone.root.scheduleMicrotask(step);
}
runZoned(() {
zone = Zone.current;
sub = stream.listen((v) {
Expect.identical(zone, Zone.current, name);
Expect.equals(42, v, name);
callbackBits |= 1;
nextStep();
}, onError: (e, s) {
Expect.identical(zone, Zone.current, name);
Expect.equals("ERROR", e, name);
callbackBits |= 2;
nextStep();
}, onDone: () {
Expect.identical(zone, Zone.current, name);
if (overrideDone) throw "RUNNING WRONG ONDONE";
callbackBits |= 4;
nextStep();
});
registerExpect += 3;
Expect.equals(registerExpect, registerCount, name);
},
zoneSpecification: new ZoneSpecification(
registerCallback: <R>(self, p, z, R callback()) {
Expect.identical(zone, self, name);
registerCount++;
return () {
Expect.identical(zone, Zone.current, name);
return callback();
};
}, registerUnaryCallback: <R, T>(self, p, z, R callback(T a)) {
Expect.identical(zone, self, name);
registerCount++;
return (a) {
Expect.identical(zone, Zone.current, name);
return callback(a);
};
}, registerBinaryCallback:
<R, T1, T2>(self, package, z, R callback(T1 a, T2 b)) {
Expect.identical(zone, self, name);
registerCount++;
return (a, b) {
Expect.identical(zone, Zone.current, name);
return callback(a, b);
};
}));
int expectedBits = 0;
step = () {
var stepName = "$name-$stepCount";
Expect.identical(Zone.root, Zone.current, stepName);
Expect.equals(expectedBits, callbackBits, stepName);
switch (stepCount++) {
case 0:
expectedBits |= 1;
controller.add(42);
break;
case 1:
expectedBits |= 2;
controller.addError("ERROR", null);
break;
case 2:
Expect.equals(registerExpect, registerCount, stepName);
sub.onData((v) {
Expect.identical(zone, Zone.current, stepName);
Expect.equals(37, v);
callbackBits |= 8;
nextStep();
});
Expect.equals(++registerExpect, registerCount, stepName);
expectedBits |= 8;
controller.add(37);
break;
case 3:
Expect.equals(registerExpect, registerCount, stepName);
sub.onError((e, s) {
Expect.identical(zone, Zone.current);
Expect.equals("BAD", e);
callbackBits |= 16;
nextStep();
});
Expect.equals(++registerExpect, registerCount, stepName);
expectedBits |= 16;
controller.addError("BAD", null);
break;
case 4:
Expect.equals(registerExpect, registerCount, stepName);
if (overrideDone) {
sub.onDone(() {
Expect.identical(zone, Zone.current);
callbackBits |= 32;
nextStep();
});
registerExpect++;
expectedBits |= 32;
} else {
expectedBits |= 4;
}
Expect.equals(registerExpect, registerCount, stepName);
controller.close();
break;
case 5:
asyncEnd();
}
};
step();
}