Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Unified Diff: tests/lib_strong/async/stream_state_helper.dart

Issue 2802973005: Migrate async tests to strong (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/lib_strong/async/stream_state_helper.dart
diff --git a/tests/lib_strong/async/stream_state_helper.dart b/tests/lib_strong/async/stream_state_helper.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0ba61fc9e69aa060601c1c86c7ab0531cb773ad1
--- /dev/null
+++ b/tests/lib_strong/async/stream_state_helper.dart
@@ -0,0 +1,589 @@
+// 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_state_helper;
+
+import "package:unittest/unittest.dart";
+import "dart:async";
+import "dart:collection";
+
+class SubscriptionProtocolTest {
+ final StreamProtocolTest _streamTest;
+ final int id;
+ StreamSubscription _subscription;
+
+ SubscriptionProtocolTest(this.id, this._subscription, this._streamTest);
+
+ void pause([Future resumeSignal]) {
+ if (_subscription == null) throw new StateError("Not subscribed");
+ _subscription.pause(resumeSignal);
+ }
+
+ void resume() {
+ if (_subscription == null) throw new StateError("Not subscribed");
+ _subscription.resume();
+ }
+
+ void cancel() {
+ if (_subscription == null) throw new StateError("Not subscribed");
+ _subscription.cancel();
+ _subscription = null;
+ }
+
+ void expectData(var data, [void action()]) {
+ _streamTest._expectData(this, data, action);
+ }
+
+ void expectError(var error, [void action()]) {
+ _streamTest._expectError(this, error, action);
+ }
+
+ void expectDone([void action()]) {
+ _streamTest._expectDone(this, action);
+ }
+}
+
+class StreamProtocolTest {
+ bool trace = false;
+ final bool isBroadcast;
+ final bool isAsBroadcast;
+ StreamController _controller;
+ Stream _controllerStream;
+ // Most recent subscription created. Used as default for pause/resume.
+ SubscriptionProtocolTest _latestSubscription;
+ List<Event> _expectations = new List<Event>();
+ int _nextExpectationIndex = 0;
+ int _subscriptionIdCounter = 0;
+ Function _onComplete;
+
+ StreamProtocolTest.broadcast({ bool sync: false })
+ : isBroadcast = true, isAsBroadcast = false {
+ _controller = new StreamController.broadcast(
+ sync: sync,
+ onListen: _onListen,
+ onCancel: _onCancel);
+ _controllerStream = _controller.stream;
+ _onComplete = expectAsync((){
+ _onComplete = null; // Being null marks the test as being complete.
+ });
+ }
+
+ StreamProtocolTest({ bool sync: false })
+ : isBroadcast = false, isAsBroadcast = false {
+ _controller = new StreamController(
+ sync: sync,
+ onListen: _onListen,
+ onPause: _onPause,
+ onResume: _onResume,
+ onCancel: _onCancel);
+ _controllerStream = _controller.stream;
+ _onComplete = expectAsync((){
+ _onComplete = null; // Being null marks the test as being complete.
+ });
+ }
+
+ StreamProtocolTest.asBroadcast({ bool sync: false })
+ : isBroadcast = false, isAsBroadcast = true {
+ _controller = new StreamController(
+ sync: sync,
+ onListen: _onListen,
+ onPause: _onPause,
+ onResume: _onResume,
+ onCancel: _onCancel);
+ _controllerStream = _controller.stream.asBroadcastStream(
+ onListen: _onBroadcastListen,
+ onCancel: _onBroadcastCancel);
+ _onComplete = expectAsync((){
+ _onComplete = null; // Being null marks the test as being complete.
+ });
+ }
+
+ // Actions on the stream and controller.
+ void add(var data) { _controller.add(data); }
+ void error(var error) { _controller.addError(error); }
+ void close() { _controller.close(); }
+
+ SubscriptionProtocolTest listen({bool cancelOnError : false}) {
+ int subscriptionId = _subscriptionIdCounter++;
+
+ StreamSubscription subscription = _controllerStream.listen(
+ (var data) { _onData(subscriptionId, data); },
+ onError: (Object error) { _onError(subscriptionId, error); },
+ onDone: () { _onDone(subscriptionId); },
+ cancelOnError: cancelOnError);
+ _latestSubscription =
+ new SubscriptionProtocolTest(subscriptionId, subscription, this);
+ if (trace) {
+ print("[Listen #$subscriptionId(#${_latestSubscription.hashCode})]");
+ }
+ return _latestSubscription;
+ }
+
+ // Actions on the most recently created subscription.
+ void pause([Future resumeSignal]) {
+ _latestSubscription.pause(resumeSignal);
+ }
+
+ void resume() {
+ _latestSubscription.resume();
+ }
+
+ void cancel() {
+ _latestSubscription.cancel();
+ _latestSubscription = null;
+ }
+
+ // End the test now. There must be no open expectations, and no furter
+ // expectations will be allowed.
+ // Called automatically by an onCancel event on a non-broadcast stream.
+ void terminate() {
+ if (_nextExpectationIndex != _expectations.length) {
+ _withNextExpectation((Event expect) {
+ _fail("Expected: $expect\n"
+ "Found : Early termination.\n${expect._stackTrace}");
+ });
+ }
+ _onComplete();
+ }
+
+ // Handling of stream events.
+ void _onData(int id, var data) {
+ if (trace) print("[Data#$id : $data]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchData(id, data)) {
+ _fail("Expected: $expect\n"
+ "Found : [Data#$id: $data]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onError(int id, Object error) {
+ if (trace) print("[Error#$id : $error]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchError(id, error)) {
+ _fail("Expected: $expect\n"
+ "Found : [Error#$id: ${error}]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onDone(int id) {
+ if (trace) print("[Done#$id]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchDone(id)) {
+ _fail("Expected: $expect\n"
+ "Found : [Done#$id]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onPause() {
+ if (trace) print("[Pause]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchPause()) {
+ _fail("Expected: $expect\n"
+ "Found : [Paused]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onResume() {
+ if (trace) print("[Resumed]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchResume()) {
+ _fail("Expected: $expect\n"
+ "Found : [Resumed]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onListen() {
+ if (trace) print("[Subscribed]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchSubscribe()) {
+ _fail("Expected: $expect\n"
+ "Found: [Subscribed]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onCancel() {
+ if (trace) print("[Cancelled]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchCancel()) {
+ _fail("Expected: $expect\n"
+ "Found: [Cancelled]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onBroadcastListen(StreamSubscription sub) {
+ if (trace) print("[BroadcastListen]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchBroadcastListen(sub)) {
+ _fail("Expected: $expect\n"
+ "Found: [BroadcastListen]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _onBroadcastCancel(StreamSubscription sub) {
+ if (trace) print("[BroadcastCancel]");
+ _withNextExpectation((Event expect) {
+ if (!expect.matchBroadcastCancel(sub)) {
+ _fail("Expected: $expect\n"
+ "Found: [BroadcastCancel]\n${expect._stackTrace}");
+ }
+ });
+ }
+
+ void _withNextExpectation(void action(Event expect)) {
+ if (_nextExpectationIndex == _expectations.length) {
+ _nextExpectationIndex++;
+ action(new MismatchEvent());
+ } else {
+ Event next = _expectations[_nextExpectationIndex++];
+ action(next);
+ }
+ }
+
+ // Adds _expectations.
+ void expectAny([void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new LogAnyEvent(action));
+ }
+
+ void expectData(var data, [void action()]) {
+ _expectData(null, data, action);
+ }
+
+ void _expectData(SubscriptionProtocolTest sub, var data, void action()) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new DataEvent(sub, data, action));
+ }
+
+ void expectError(var error, [void action()]) {
+ _expectError(null, error, action);
+ }
+
+ void _expectError(SubscriptionProtocolTest sub, var error, void action()) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new ErrorEvent(sub, error, action));
+ }
+
+ void expectDone([void action()]) {
+ _expectDone(null, action);
+ }
+
+ void _expectDone(SubscriptionProtocolTest sub, [void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new DoneEvent(sub, action));
+ }
+
+ void expectPause([void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new PauseCallbackEvent(action));
+ }
+
+ void expectResume([void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(new ResumeCallbackEvent(action));
+ }
+
+ void expectListen([void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(
+ new SubscriptionCallbackEvent(action));
+ }
+
+ void expectCancel([void action()]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ _expectations.add(
+ new CancelCallbackEvent(action));
+ }
+
+ void expectBroadcastListen([void action(StreamSubscription sub)]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ if (!isAsBroadcast) throw new StateError("Not an asBroadcast stream");
+ _expectations.add(new BroadcastListenCallbackEvent(action));
+ }
+
+ void expectBroadcastCancel([void action(StreamSubscription sub)]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ if (!isAsBroadcast) throw new StateError("Not an asBroadcast stream");
+ _expectations.add(new BroadcastCancelCallbackEvent(action));
+ }
+
+ void expectBroadcastListenOpt([void action(StreamSubscription sub)]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ if (!isAsBroadcast) return;
+ _expectations.add(new BroadcastListenCallbackEvent(action));
+ }
+
+ void expectBroadcastCancelOpt([void action(StreamSubscription sub)]) {
+ if (_onComplete == null) {
+ _fail("Adding expectation after completing");
+ }
+ if (!isAsBroadcast) return;
+ _expectations.add(new BroadcastCancelCallbackEvent(action));
+ }
+
+ void _fail(String message) {
+ if (_nextExpectationIndex == 0) {
+ throw "Unexpected event:\n$message\nNo earlier events matched.";
+ }
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < _expectations.length; i++) {
+ if (i == _nextExpectationIndex - 1) {
+ buf.write("->");
+ } else {
+ buf.write(" ");
+ }
+ buf.write(_expectations[i]);
+ buf.write("\n");
+ }
+ throw "Unexpected event:\n$message\nAll expectations:\n$buf";
+ }
+}
+
+class Event {
+ Function _action;
+ StackTrace _stackTrace;
+ Event(void action())
+ : _action = (action == null) ? null : expectAsync(action) {
+ try { throw 0; } catch (_, s) { _stackTrace = s; }
+ }
+ Event.broadcast(void action(StreamSubscription sub))
+ : _action = (action == null) ? null : expectAsync(action) {
+ try { throw 0; } catch (_, s) { _stackTrace = s; }
+ }
+
+ bool matchData(int id, var data) {
+ return false;
+ }
+
+ bool matchError(int id, e) {
+ return false;
+ }
+
+ bool matchDone(int id) {
+ return false;
+ }
+
+ bool matchPause() {
+ if (!_testPause()) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchResume() {
+ if (!_testResume()) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchSubscribe() {
+ if (!_testSubscribe()) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchCancel() {
+ if (!_testCancel()) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchBroadcastListen(StreamSubscription sub) {
+ if (!_testBroadcastListen()) return false;
+ if (_action != null) _action(sub);
+ return true;
+ }
+
+ bool matchBroadcastCancel(StreamSubscription sub) {
+ if (!_testBroadcastCancel()) return false;
+ if (_action != null) _action(sub);
+ return true;
+ }
+
+ bool _testData(_) => false;
+ bool _testError(_) => false;
+ bool _testDone() => false;
+ bool _testPause() => false;
+ bool _testResume() => false;
+ bool _testSubscribe() => false;
+ bool _testCancel() => false;
+ bool _testBroadcastListen() => false;
+ bool _testBroadcastCancel() => false;
+}
+
+class SubscriptionEvent extends Event {
+ SubscriptionProtocolTest subscription;
+ SubscriptionEvent(this.subscription, void action()) : super(action);
+
+ bool matchData(int id, var data) {
+ if (subscription != null && subscription.id != id) return false;
+ if (!_testData(data)) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchError(int id, e) {
+ if (subscription != null && subscription.id != id) return false;
+ if (!_testError(e)) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ bool matchDone(int id) {
+ if (subscription != null && subscription.id != id) return false;
+ if (!_testDone()) return false;
+ if (_action != null) _action();
+ return true;
+ }
+
+ String get _id => (subscription == null) ? "" : "#${subscription.id}";
+}
+
+class MismatchEvent extends Event {
+ MismatchEvent() : super(null);
+ toString() => "[No event expected]";
+}
+
+class DataEvent extends SubscriptionEvent {
+ final data;
+ DataEvent(SubscriptionProtocolTest sub, this.data, void action())
+ : super(sub, action);
+ bool _testData(var data) => this.data == data;
+ String toString() => "[Data$_id: $data]";
+}
+
+class ErrorEvent extends SubscriptionEvent {
+ final error;
+ ErrorEvent(SubscriptionProtocolTest sub, this.error, void action())
+ : super(sub, action);
+ bool _testError(error) => this.error == error;
+ String toString() => "[Error$_id: $error]";
+}
+
+class DoneEvent extends SubscriptionEvent {
+ DoneEvent(SubscriptionProtocolTest sub, void action()) : super(sub, action);
+ bool _testDone() => true;
+ String toString() => "[Done$_id]";
+}
+
+class PauseCallbackEvent extends Event {
+ PauseCallbackEvent(void action()) : super(action);
+ bool _testPause() => true;
+ String toString() => "[Paused]";
+}
+
+class ResumeCallbackEvent extends Event {
+ ResumeCallbackEvent(void action()) : super(action);
+ bool _testResume() => true;
+ String toString() => "[Resumed]";
+}
+
+class SubscriptionCallbackEvent extends Event {
+ SubscriptionCallbackEvent(void action()) : super(action);
+ bool _testSubscribe() => true;
+ String toString() => "[Subscribed]";
+}
+
+class CancelCallbackEvent extends Event {
+ CancelCallbackEvent(void action()) : super(action);
+ bool _testCancel() => true;
+ String toString() => "[Cancelled]";
+}
+
+class BroadcastCancelCallbackEvent extends Event {
+ BroadcastCancelCallbackEvent(void action(StreamSubscription sub))
+ : super.broadcast(action);
+ bool _testBroadcastCancel() => true;
+ String toString() => "[BroadcastCancel]";
+}
+
+class BroadcastListenCallbackEvent extends Event {
+ BroadcastListenCallbackEvent(void action(StreamSubscription sub))
+ : super.broadcast(action);
+ bool _testBroadcastListen() => true;
+ String toString() => "[BroadcastListen]";
+}
+
+/** Event matcher that matches any other event. */
+class LogAnyEvent extends Event {
+ String _actual = "*Not matched yet*";
+
+ LogAnyEvent(void action()) : super(action);
+
+ bool _testData(var data) {
+ _actual = "*[Data $data]";
+ return true;
+ }
+
+ bool _testError(error) {
+ _actual = "*[Error ${error}]";
+ return true;
+ }
+
+ bool _testDone() {
+ _actual = "*[Done]";
+ return true;
+ }
+
+ bool _testPause() {
+ _actual = "*[Paused]";
+ return true;
+ }
+
+ bool _testResume() {
+ _actual = "*[Resumed]";
+ return true;
+ }
+
+ bool _testSubcribe() {
+ _actual = "*[Subscribed]";
+ return true;
+ }
+
+ bool _testCancel() {
+ _actual = "*[Cancelled]";
+ return true;
+ }
+
+ bool _testBroadcastListen() {
+ _actual = "*[BroadcastListen]";
+ return true;
+ }
+
+ bool _testBroadcastCancel() {
+ _actual = "*[BroadcastCancel]";
+ return true;
+ }
+
+ /** Returns a representation of the event it was tested against. */
+ String toString() => _actual;
+}

Powered by Google App Engine
This is Rietveld 408576698