| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 library substitute_future; | 5 library substitute_future; | 
| 6 | 6 | 
| 7 import 'dart:async'; | 7 import 'dart:async'; | 
| 8 | 8 | 
| 9 /// A wrapper for [Future] that allows other [Future]s to be substituted in as | 9 /// A wrapper for [Future] that allows other [Future]s to be substituted in as | 
| 10 /// the wrapped [Future]. This is used for injecting timeout errors into | 10 /// the wrapped [Future]. This is used for injecting timeout errors into | 
| 11 /// long-running [Future]s. | 11 /// long-running [Future]s. | 
| 12 class SubstituteFuture<T> implements Future<T> { | 12 class SubstituteFuture<T> implements Future<T> { | 
| 13   /// The wrapped [Future]. | 13   /// The wrapped [Future]. | 
| 14   Future<T> _inner; | 14   Future<T> _inner; | 
| 15 | 15 | 
| 16   /// The completer that corresponds to [this]'s result. | 16   /// The completer that corresponds to [this]'s result. | 
| 17   final Completer<T> _completer = new Completer<T>(); | 17   final Completer<T> _completer = new Completer<T>(); | 
| 18 | 18 | 
| 19   /// Whether or not [this] has been completed yet. | 19   /// Whether or not [this] has been completed yet. | 
| 20   bool _complete = false; | 20   bool _complete = false; | 
| 21 | 21 | 
| 22   SubstituteFuture(Future wrapped) { | 22   SubstituteFuture(Future wrapped) { | 
| 23     substitute(wrapped); | 23     substitute(wrapped); | 
| 24   } | 24   } | 
| 25 | 25 | 
| 26   Stream<T> asStream() => _completer.future.asStream(); | 26   Stream<T> asStream() => _completer.future.asStream(); | 
| 27   Future catchError(onError(AsyncError asyncError), {bool test(error)}) => | 27   Future catchError(onError(asyncError), {bool test(error)}) => | 
| 28     _completer.future.catchError(onError, test: test); | 28     _completer.future.catchError(onError, test: test); | 
| 29   Future then(onValue(T value), {onError(AsyncError asyncError)}) => | 29   Future then(onValue(T value), {onError(error)}) => | 
| 30     _completer.future.then(onValue, onError: onError); | 30     _completer.future.then(onValue, onError: onError); | 
| 31   Future<T> whenComplete(action()) => _completer.future.whenComplete(action); | 31   Future<T> whenComplete(action()) => _completer.future.whenComplete(action); | 
| 32 | 32 | 
| 33   /// Substitutes [newFuture] for the currently wrapped [Future], which is | 33   /// Substitutes [newFuture] for the currently wrapped [Future], which is | 
| 34   /// returned. | 34   /// returned. | 
| 35   Future<T> substitute(Future<T> newFuture) { | 35   Future<T> substitute(Future<T> newFuture) { | 
| 36     if (_complete) { | 36     if (_complete) { | 
| 37       throw new StateError("You may not call substitute on a SubstituteFuture " | 37       throw new StateError("You may not call substitute on a SubstituteFuture " | 
| 38           "that's already complete."); | 38           "that's already complete."); | 
| 39     } | 39     } | 
| 40 | 40 | 
| 41     var oldFuture = _inner; | 41     var oldFuture = _inner; | 
| 42     _inner = newFuture; | 42     _inner = newFuture; | 
| 43     _inner.then((value) { | 43     _inner.then((value) { | 
| 44       if (_inner != newFuture) return; | 44       if (_inner != newFuture) return; | 
| 45       _completer.complete(value); | 45       _completer.complete(value); | 
| 46       _complete = true; | 46       _complete = true; | 
| 47     }).catchError((error) { | 47     }).catchError((error) { | 
| 48       if (_inner != newFuture) return; | 48       if (_inner != newFuture) return; | 
| 49       _completer.completeError(error); | 49       _completer.completeError(error); | 
| 50       _complete = true; | 50       _complete = true; | 
| 51     }); | 51     }); | 
| 52     return oldFuture; | 52     return oldFuture; | 
| 53   } | 53   } | 
| 54 } | 54 } | 
| OLD | NEW | 
|---|