Improve async builder docs (#15373)
This commit is contained in:
parent
42e4e16b47
commit
b494e71e36
@ -38,6 +38,7 @@ import 'framework.dart';
|
|||||||
/// on change of stream by overriding [afterDisconnected] and [afterConnected].
|
/// on change of stream by overriding [afterDisconnected] and [afterConnected].
|
||||||
///
|
///
|
||||||
/// [T] is the type of stream events.
|
/// [T] is the type of stream events.
|
||||||
|
///
|
||||||
/// [S] is the type of interaction summary.
|
/// [S] is the type of interaction summary.
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
@ -165,12 +166,17 @@ class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
|
|||||||
/// received from the asynchronous computation.
|
/// received from the asynchronous computation.
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
/// Not currently connected to any asynchronous computation.
|
/// Not currently connected to any asynchronous computation.
|
||||||
|
///
|
||||||
|
/// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
|
||||||
none,
|
none,
|
||||||
|
|
||||||
/// Connected to an asynchronous computation and awaiting interaction.
|
/// Connected to an asynchronous computation and awaiting interaction.
|
||||||
waiting,
|
waiting,
|
||||||
|
|
||||||
/// Connected to an active asynchronous computation.
|
/// Connected to an active asynchronous computation.
|
||||||
|
///
|
||||||
|
/// For example, a [Stream] that has returned at least one value, but is not
|
||||||
|
/// yet done.
|
||||||
active,
|
active,
|
||||||
|
|
||||||
/// Connected to a terminated asynchronous computation.
|
/// Connected to a terminated asynchronous computation.
|
||||||
@ -206,7 +212,15 @@ class AsyncSnapshot<T> {
|
|||||||
/// Current state of connection to the asynchronous computation.
|
/// Current state of connection to the asynchronous computation.
|
||||||
final ConnectionState connectionState;
|
final ConnectionState connectionState;
|
||||||
|
|
||||||
/// Latest data received. Is null, if [error] is not.
|
/// The latest data received by the asynchronous computation.
|
||||||
|
///
|
||||||
|
/// If this is non-null, [hasData] will be true.
|
||||||
|
///
|
||||||
|
/// If [error] is not null, this will be null. See [hasError].
|
||||||
|
///
|
||||||
|
/// If the asynchronous computation has never returned a value, this may be
|
||||||
|
/// set to an initial data value specified by the relevant widget. See
|
||||||
|
/// [FutureBuilder.initialData] and [StreamBuilder.initialData].
|
||||||
final T data;
|
final T data;
|
||||||
|
|
||||||
/// Returns latest data received, failing if there is no data.
|
/// Returns latest data received, failing if there is no data.
|
||||||
@ -221,20 +235,35 @@ class AsyncSnapshot<T> {
|
|||||||
throw new StateError('Snapshot has neither data nor error');
|
throw new StateError('Snapshot has neither data nor error');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Latest error object received. Is null, if [data] is not.
|
/// The latest error object received by the asynchronous computation.
|
||||||
|
///
|
||||||
|
/// If this is non-null, [hasError] will be true.
|
||||||
|
///
|
||||||
|
/// If [data] is not null, this will be null.
|
||||||
final Object error;
|
final Object error;
|
||||||
|
|
||||||
/// Returns a snapshot like this one, but in the specified [state].
|
/// Returns a snapshot like this one, but in the specified [state].
|
||||||
|
///
|
||||||
|
/// The [data] and [error] fields persist unmodified, even if the new state is
|
||||||
|
/// [ConnectionState.none].
|
||||||
AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error);
|
AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error);
|
||||||
|
|
||||||
/// Returns whether this snapshot contains a non-null data value.
|
/// Returns whether this snapshot contains a non-null [data] value.
|
||||||
|
///
|
||||||
|
/// This can be false even when the asynchronous computation has completed
|
||||||
|
/// successfully, if the computation did not return a non-null value. For
|
||||||
|
/// example, a [Future<void>] will complete with the null value even if it
|
||||||
|
/// completes successfully.
|
||||||
bool get hasData => data != null;
|
bool get hasData => data != null;
|
||||||
|
|
||||||
/// Returns whether this snapshot contains a non-null error value.
|
/// Returns whether this snapshot contains a non-null [error] value.
|
||||||
|
///
|
||||||
|
/// This is always true if the asynchronous computation's last result was
|
||||||
|
/// failure.
|
||||||
bool get hasError => error != null;
|
bool get hasError => error != null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AsyncSnapshot($connectionState, $data, $error)';
|
String toString() => '$runtimeType($connectionState, $data, $error)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
@ -289,15 +318,15 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap
|
|||||||
/// pipeline.
|
/// pipeline.
|
||||||
///
|
///
|
||||||
/// Changing the [StreamBuilder] configuration to another stream during event
|
/// Changing the [StreamBuilder] configuration to another stream during event
|
||||||
/// generation introduces snapshot pairs of the form
|
/// generation introduces snapshot pairs of the form:
|
||||||
///
|
///
|
||||||
/// * `new AsyncSnapshot<int>.withData(ConnectionState.none, 5)`
|
/// * `new AsyncSnapshot<int>.withData(ConnectionState.none, 5)`
|
||||||
/// * `new AsyncSnapshot<int>.withData(ConnectionState.waiting, 5)`
|
/// * `new AsyncSnapshot<int>.withData(ConnectionState.waiting, 5)`
|
||||||
///
|
///
|
||||||
/// The latter will be produced only when the new stream is non-null. The former
|
/// The latter will be produced only when the new stream is non-null, and the
|
||||||
/// only when the old stream is non-null.
|
/// former only when the old stream is non-null.
|
||||||
///
|
///
|
||||||
/// The stream may produce errors, resulting in snapshots of the form
|
/// The stream may produce errors, resulting in snapshots of the form:
|
||||||
///
|
///
|
||||||
/// * `new AsyncSnapshot<int>.withError(ConnectionState.active, 'some error')`
|
/// * `new AsyncSnapshot<int>.withError(ConnectionState.active, 'some error')`
|
||||||
///
|
///
|
||||||
@ -331,7 +360,6 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap
|
|||||||
/// case ConnectionState.waiting: return new Text('Awaiting bids...');
|
/// case ConnectionState.waiting: return new Text('Awaiting bids...');
|
||||||
/// case ConnectionState.active: return new Text('\$${snapshot.data}');
|
/// case ConnectionState.active: return new Text('\$${snapshot.data}');
|
||||||
/// case ConnectionState.done: return new Text('\$${snapshot.data} (closed)');
|
/// case ConnectionState.done: return new Text('\$${snapshot.data} (closed)');
|
||||||
/// default: throw "Unknown: ${snapshot.connectionState}";
|
|
||||||
/// }
|
/// }
|
||||||
/// },
|
/// },
|
||||||
/// )
|
/// )
|
||||||
@ -391,14 +419,15 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
|
|||||||
/// will thus receive a timing-dependent sub-sequence of the snapshots that
|
/// will thus receive a timing-dependent sub-sequence of the snapshots that
|
||||||
/// represent the interaction with the future.
|
/// represent the interaction with the future.
|
||||||
///
|
///
|
||||||
/// For a future that completes successfully with data, the [builder] may
|
/// For a future that completes successfully with data, assuming [initialData]
|
||||||
/// be called with either both or only the latter of the following snapshots:
|
/// is null, the [builder] will be called with either both or only the latter of
|
||||||
|
/// the following snapshots:
|
||||||
///
|
///
|
||||||
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
|
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
|
||||||
/// * `new AsyncSnapshot<String>.withData(ConnectionState.done, 'some data')`
|
/// * `new AsyncSnapshot<String>.withData(ConnectionState.done, 'some data')`
|
||||||
///
|
///
|
||||||
/// For a future completing with an error, the [builder] may be called with
|
/// If that same future instead completed with an error, the [builder] would be
|
||||||
/// either both or only the latter of:
|
/// called with either both or only the latter of:
|
||||||
///
|
///
|
||||||
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
|
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
|
||||||
/// * `new AsyncSnapshot<String>.withError(ConnectionState.done, 'some error')`
|
/// * `new AsyncSnapshot<String>.withError(ConnectionState.done, 'some error')`
|
||||||
@ -414,11 +443,11 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
|
|||||||
/// old future has already completed successfully with data as above, changing
|
/// old future has already completed successfully with data as above, changing
|
||||||
/// configuration to a new future results in snapshot pairs of the form:
|
/// configuration to a new future results in snapshot pairs of the form:
|
||||||
///
|
///
|
||||||
/// * `new AsyncSnapshot<String>.withData(ConnectionState.none, 'some data')`
|
/// * `new AsyncSnapshot<String>.withData(ConnectionState.none, 'data of first future')`
|
||||||
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, 'some data')`
|
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, 'data of second future')`
|
||||||
///
|
///
|
||||||
/// In general, the latter will be produced only when the new future is
|
/// In general, the latter will be produced only when the new future is
|
||||||
/// non-null. The former only when the old future is non-null.
|
/// non-null, and the former only when the old future is non-null.
|
||||||
///
|
///
|
||||||
/// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with
|
/// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with
|
||||||
/// `future?.asStream()`, except that snapshots with `ConnectionState.active`
|
/// `future?.asStream()`, except that snapshots with `ConnectionState.active`
|
||||||
@ -461,12 +490,40 @@ class FutureBuilder<T> extends StatefulWidget {
|
|||||||
|
|
||||||
/// The asynchronous computation to which this builder is currently connected,
|
/// The asynchronous computation to which this builder is currently connected,
|
||||||
/// possibly null.
|
/// possibly null.
|
||||||
|
///
|
||||||
|
/// If no future has yet completed, including in the case where [future] is
|
||||||
|
/// null, the data provided to the [builder] will be set to [initialData].
|
||||||
final Future<T> future;
|
final Future<T> future;
|
||||||
|
|
||||||
/// The build strategy currently used by this builder. Cannot be null.
|
/// The build strategy currently used by this builder.
|
||||||
|
///
|
||||||
|
/// The builder is provided with an [AsyncSnapshot] object whose
|
||||||
|
/// [AsyncSnapshot.connectionState] property will be one of the following
|
||||||
|
/// values:
|
||||||
|
///
|
||||||
|
/// * [ConnectionState.none]: [future] is null. The [AsyncSnapshot.data] will
|
||||||
|
/// be set to [initialData], unless a future has previously completed, in
|
||||||
|
/// which case the previous result persists.
|
||||||
|
///
|
||||||
|
/// * [ConnectionState.waiting]: [future] is not null, but has not yet
|
||||||
|
/// completed. The [AsyncSnapshot.data] will be set to [initialData],
|
||||||
|
/// unless a future has previously completed, in which case the previous
|
||||||
|
/// result persists.
|
||||||
|
///
|
||||||
|
/// * [ConnectionState.done]: [future] is not null, and has completed. If the
|
||||||
|
/// future completed successfully, the [AsyncSnapshot.data] will be set to
|
||||||
|
/// the value to which the future completed. If it completed with an error,
|
||||||
|
/// [AsyncSnapshot.hasError] will be true and [AsyncSnapshot.error] will be
|
||||||
|
/// set to the error object.
|
||||||
final AsyncWidgetBuilder<T> builder;
|
final AsyncWidgetBuilder<T> builder;
|
||||||
|
|
||||||
/// The data that will be used to create the initial snapshot. Null by default.
|
/// The data that will be used to create the snapshots provided until a
|
||||||
|
/// non-null [future] has completed.
|
||||||
|
///
|
||||||
|
/// If the future completes with an error, the data in the [AsyncSnapshot]
|
||||||
|
/// provided to the [builder] will become null, regardless of [initialData].
|
||||||
|
/// (The error itself will be available in [AsyncSnapshot.error], and
|
||||||
|
/// [AsyncSnapshot.hasError] will be true.)
|
||||||
final T initialData;
|
final T initialData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -59,12 +59,12 @@ void main() {
|
|||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: null, builder: snapshotText
|
key: key, future: null, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsOneWidget);
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: completer.future, builder: snapshotText
|
key: key, future: completer.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('gracefully handles transition to null future', (WidgetTester tester) async {
|
testWidgets('gracefully handles transition to null future', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -72,14 +72,14 @@ void main() {
|
|||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: completer.future, builder: snapshotText
|
key: key, future: completer.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: null, builder: snapshotText
|
key: key, future: null, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsOneWidget);
|
||||||
completer.complete('hello');
|
completer.complete('hello');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('gracefully handles transition to other future', (WidgetTester tester) async {
|
testWidgets('gracefully handles transition to other future', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -88,35 +88,35 @@ void main() {
|
|||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: completerA.future, builder: snapshotText
|
key: key, future: completerA.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key, future: completerB.future, builder: snapshotText
|
key: key, future: completerB.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
completerB.complete('B');
|
completerB.complete('B');
|
||||||
completerA.complete('A');
|
completerA.complete('A');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, B, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, B, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('tracks life-cycle of Future to success', (WidgetTester tester) async {
|
testWidgets('tracks life-cycle of Future to success', (WidgetTester tester) async {
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
future: completer.future, builder: snapshotText
|
future: completer.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
completer.complete('hello');
|
completer.complete('hello');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, hello, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, hello, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('tracks life-cycle of Future to error', (WidgetTester tester) async {
|
testWidgets('tracks life-cycle of Future to error', (WidgetTester tester) async {
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
future: completer.future, builder: snapshotText
|
future: completer.future, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
completer.completeError('bad');
|
completer.completeError('bad');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, null, bad)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, null, bad)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('runs the builder using given initial data', (WidgetTester tester) async {
|
testWidgets('runs the builder using given initial data', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -126,7 +126,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'I',
|
initialData: 'I',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, I, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('ignores initialData when reconfiguring', (WidgetTester tester) async {
|
testWidgets('ignores initialData when reconfiguring', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -136,7 +136,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'I',
|
initialData: 'I',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, I, null)'), findsOneWidget);
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
await tester.pumpWidget(new FutureBuilder<String>(
|
await tester.pumpWidget(new FutureBuilder<String>(
|
||||||
key: key,
|
key: key,
|
||||||
@ -144,7 +144,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'Ignored',
|
initialData: 'Ignored',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, I, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
group('StreamBuilder', () {
|
group('StreamBuilder', () {
|
||||||
@ -153,12 +153,12 @@ void main() {
|
|||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: null, builder: snapshotText
|
key: key, stream: null, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsOneWidget);
|
||||||
final StreamController<String> controller = new StreamController<String>();
|
final StreamController<String> controller = new StreamController<String>();
|
||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: controller.stream, builder: snapshotText
|
key: key, stream: controller.stream, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('gracefully handles transition to null stream', (WidgetTester tester) async {
|
testWidgets('gracefully handles transition to null stream', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -166,11 +166,11 @@ void main() {
|
|||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: controller.stream, builder: snapshotText
|
key: key, stream: controller.stream, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: null, builder: snapshotText
|
key: key, stream: null, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('gracefully handles transition to other stream', (WidgetTester tester) async {
|
testWidgets('gracefully handles transition to other stream', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -179,14 +179,14 @@ void main() {
|
|||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: controllerA.stream, builder: snapshotText
|
key: key, stream: controllerA.stream, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: controllerB.stream, builder: snapshotText
|
key: key, stream: controllerB.stream, builder: snapshotText
|
||||||
));
|
));
|
||||||
controllerB.add('B');
|
controllerB.add('B');
|
||||||
controllerA.add('A');
|
controllerA.add('A');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.active, B, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.active, B, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('tracks events and errors of stream until completion', (WidgetTester tester) async {
|
testWidgets('tracks events and errors of stream until completion', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -194,19 +194,19 @@ void main() {
|
|||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key, stream: controller.stream, builder: snapshotText
|
key: key, stream: controller.stream, builder: snapshotText
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsOneWidget);
|
||||||
controller.add('1');
|
controller.add('1');
|
||||||
controller.add('2');
|
controller.add('2');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.active, 2, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.active, 2, null)'), findsOneWidget);
|
||||||
controller.add('3');
|
controller.add('3');
|
||||||
controller.addError('bad');
|
controller.addError('bad');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.active, null, bad)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.active, null, bad)'), findsOneWidget);
|
||||||
controller.add('4');
|
controller.add('4');
|
||||||
controller.close();
|
controller.close();
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, 4, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, 4, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('runs the builder using given initial data', (WidgetTester tester) async {
|
testWidgets('runs the builder using given initial data', (WidgetTester tester) async {
|
||||||
final StreamController<String> controller = new StreamController<String>();
|
final StreamController<String> controller = new StreamController<String>();
|
||||||
@ -215,7 +215,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'I',
|
initialData: 'I',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, I, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
testWidgets('ignores initialData when reconfiguring', (WidgetTester tester) async {
|
testWidgets('ignores initialData when reconfiguring', (WidgetTester tester) async {
|
||||||
final GlobalKey key = new GlobalKey();
|
final GlobalKey key = new GlobalKey();
|
||||||
@ -225,7 +225,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'I',
|
initialData: 'I',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, I, null)'), findsOneWidget);
|
||||||
final StreamController<String> controller = new StreamController<String>();
|
final StreamController<String> controller = new StreamController<String>();
|
||||||
await tester.pumpWidget(new StreamBuilder<String>(
|
await tester.pumpWidget(new StreamBuilder<String>(
|
||||||
key: key,
|
key: key,
|
||||||
@ -233,7 +233,7 @@ void main() {
|
|||||||
builder: snapshotText,
|
builder: snapshotText,
|
||||||
initialData: 'Ignored',
|
initialData: 'Ignored',
|
||||||
));
|
));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, I, null)'), findsOneWidget);
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, I, null)'), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
group('FutureBuilder and StreamBuilder behave identically on Stream from Future', () {
|
group('FutureBuilder and StreamBuilder behave identically on Stream from Future', () {
|
||||||
@ -243,10 +243,10 @@ void main() {
|
|||||||
new FutureBuilder<String>(future: completer.future, builder: snapshotText),
|
new FutureBuilder<String>(future: completer.future, builder: snapshotText),
|
||||||
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText),
|
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText),
|
||||||
]));
|
]));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsNWidgets(2));
|
||||||
completer.complete('hello');
|
completer.complete('hello');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, hello, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, hello, null)'), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
testWidgets('when completing with error', (WidgetTester tester) async {
|
testWidgets('when completing with error', (WidgetTester tester) async {
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
@ -254,24 +254,24 @@ void main() {
|
|||||||
new FutureBuilder<String>(future: completer.future, builder: snapshotText),
|
new FutureBuilder<String>(future: completer.future, builder: snapshotText),
|
||||||
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText),
|
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText),
|
||||||
]));
|
]));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, null, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, null, null)'), findsNWidgets(2));
|
||||||
completer.completeError('bad');
|
completer.completeError('bad');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, null, bad)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, null, bad)'), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
testWidgets('when Future is null', (WidgetTester tester) async {
|
testWidgets('when Future is null', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(new Column(children: <Widget>[
|
await tester.pumpWidget(new Column(children: <Widget>[
|
||||||
new FutureBuilder<String>(future: null, builder: snapshotText),
|
new FutureBuilder<String>(future: null, builder: snapshotText),
|
||||||
new StreamBuilder<String>(stream: null, builder: snapshotText),
|
new StreamBuilder<String>(stream: null, builder: snapshotText),
|
||||||
]));
|
]));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, null, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, null, null)'), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
testWidgets('when initialData is used with null Future and Stream', (WidgetTester tester) async {
|
testWidgets('when initialData is used with null Future and Stream', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(new Column(children: <Widget>[
|
await tester.pumpWidget(new Column(children: <Widget>[
|
||||||
new FutureBuilder<String>(future: null, builder: snapshotText, initialData: 'I'),
|
new FutureBuilder<String>(future: null, builder: snapshotText, initialData: 'I'),
|
||||||
new StreamBuilder<String>(stream: null, builder: snapshotText, initialData: 'I'),
|
new StreamBuilder<String>(stream: null, builder: snapshotText, initialData: 'I'),
|
||||||
]));
|
]));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.none, I, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.none, I, null)'), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
testWidgets('when using initialData and completing with data', (WidgetTester tester) async {
|
testWidgets('when using initialData and completing with data', (WidgetTester tester) async {
|
||||||
final Completer<String> completer = new Completer<String>();
|
final Completer<String> completer = new Completer<String>();
|
||||||
@ -279,10 +279,10 @@ void main() {
|
|||||||
new FutureBuilder<String>(future: completer.future, builder: snapshotText, initialData: 'I'),
|
new FutureBuilder<String>(future: completer.future, builder: snapshotText, initialData: 'I'),
|
||||||
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText, initialData: 'I'),
|
new StreamBuilder<String>(stream: completer.future.asStream(), builder: snapshotText, initialData: 'I'),
|
||||||
]));
|
]));
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.waiting, I, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.waiting, I, null)'), findsNWidgets(2));
|
||||||
completer.complete('hello');
|
completer.complete('hello');
|
||||||
await eventFiring(tester);
|
await eventFiring(tester);
|
||||||
expect(find.text('AsyncSnapshot(ConnectionState.done, hello, null)'), findsNWidgets(2));
|
expect(find.text('AsyncSnapshot<String>(ConnectionState.done, hello, null)'), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
group('StreamBuilderBase', () {
|
group('StreamBuilderBase', () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user