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