Files
sdk/tests/lib/async/event_helper.dart
T
Liam Appelbe 428b3c4473 [nnbd] Fix some async tests in strong mode
Fixes:
lib/async/catch_errors6_test
lib/async/catch_errors7_test
lib/async/catch_errors8_test
lib/async/catch_errors_test
lib/async/intercept_print1_test
lib/async/intercept_schedule_microtask1_test
lib/async/intercept_schedule_microtask2_test
lib/async/intercept_schedule_microtask3_test
lib/async/intercept_schedule_microtask4_test
lib/async/intercept_schedule_microtask5_test
lib/async/intercept_schedule_microtask6_test
lib/async/run_zoned7_test
lib/async/run_zoned8_test
lib/async/stream_controller_test
lib/async/stream_event_transformed_test
lib/async/stream_from_iterable_test
lib/async/stream_single_test
lib/async/stream_single_to_multi_subscriber_test
lib/async/stream_state_nonzero_timer_test
lib/async/stream_state_test
lib/async/stream_transform_test
lib/async/stream_transformation_broadcast_test
lib/async/stream_transformer_from_bind_test
lib/async/stream_transformer_from_handlers_test
lib/async/zone_future_schedule_microtask_test
lib/async_star/await_for_test
lib/async_star/await_pauses_test
Change-Id: I9d5d92938c28cc8131c70665ead4d44ffcff6bc5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143001
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2020-04-09 22:01:42 +00:00

185 lines
4.2 KiB
Dart

// Copyright (c) 2012, 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 event_helper;
import 'dart:async';
abstract class Event {
void replay(EventSink sink);
}
class DataEvent implements Event {
final data;
DataEvent(this.data);
void replay(EventSink sink) {
sink.add(data);
}
int get hashCode => data.hashCode;
bool operator ==(Object other) {
if (other is! DataEvent) return false;
DataEvent otherEvent = other;
return data == otherEvent.data;
}
String toString() => "DataEvent: $data";
}
class ErrorEvent implements Event {
final error;
ErrorEvent(this.error);
void replay(EventSink sink) {
sink.addError(error);
}
int get hashCode => error.error.hashCode;
bool operator ==(Object other) {
if (other is! ErrorEvent) return false;
ErrorEvent otherEvent = other;
return error == otherEvent.error;
}
String toString() => "ErrorEvent: ${error}";
}
class DoneEvent implements Event {
const DoneEvent();
void replay(EventSink sink) {
sink.close();
}
int get hashCode => 42;
bool operator ==(Object other) => other is DoneEvent;
String toString() => "DoneEvent";
}
/** Collector of events. */
class Events implements EventSink {
final List<Event> events = [];
bool trace = false;
Completer onDoneSignal = new Completer();
Events();
Events.fromIterable(Iterable iterable) {
for (var value in iterable) add(value);
close();
}
/** Capture events from a stream into a new [Events] object. */
factory Events.capture(Stream stream, {bool cancelOnError}) = CaptureEvents;
// EventSink interface.
void add(var value) {
if (trace) print("Events#$hashCode: add($value)");
events.add(new DataEvent(value));
}
void addError(error, [StackTrace? stackTrace]) {
if (trace) print("Events#$hashCode: addError($error)");
events.add(new ErrorEvent(error));
}
void close() {
if (trace) print("Events#$hashCode: close()");
events.add(const DoneEvent());
onDoneSignal.complete();
}
/**
* Error shorthand, for writing events manually.
*/
void error(var value, [StackTrace? stackTrace]) {
addError(value, stackTrace);
}
/** Replay the captured events on a sink. */
void replay(EventSink sink) {
for (int i = 0; i < events.length; i++) {
events[i].replay(sink);
}
}
/**
* Create a new [Events] with the same captured events.
*
* This does not copy a subscription.
*/
Events copy() {
Events result = new Events();
replay(result);
return result;
}
// Operations that only work when there is a subscription feeding the Events.
/**
* Pauses the subscription that feeds this [Events].
*
* Should only be used when there is a subscription. That is, after a
* call to [subscribeTo].
*/
void pause([Future? resumeSignal]) {
throw new StateError("Not capturing events.");
}
/** Resumes after a call to [pause]. */
void resume() {
throw new StateError("Not capturing events.");
}
/**
* Sets an action to be called when this [Events] receives a 'done' event.
*
* The action will also be called if capturing events from a stream with
* `cancelOnError` set to true and receiving an error.
*/
void onDone(void action()) {
onDoneSignal.future.whenComplete(action);
}
}
class CaptureEvents extends Events {
late StreamSubscription subscription;
bool cancelOnError = false;
CaptureEvents(Stream stream, {bool cancelOnError: false}) {
this.cancelOnError = cancelOnError;
subscription = stream.listen(add,
onError: addError, onDone: close, cancelOnError: cancelOnError);
}
void addError(error, [StackTrace? stackTrace]) {
super.addError(error, stackTrace);
if (cancelOnError) {
onDoneSignal.complete();
}
}
void pause([Future? resumeSignal]) {
if (trace) print("Events#$hashCode: pause");
subscription.pause(resumeSignal);
}
void resume() {
if (trace) print("Events#$hashCode: resume");
subscription.resume();
}
void onDone(void action()) {
if (trace) print("Events#$hashCode: onDone");
super.onDone(action);
}
}