Index: pkg/pool/test/pool_test.dart |
diff --git a/pkg/pool/test/pool_test.dart b/pkg/pool/test/pool_test.dart |
index 40bcf8a74d5c3fe57fbda269f4c640adf6483123..bb9e607681fd40bdd29e802df9ff190bdc6562a3 100644 |
--- a/pkg/pool/test/pool_test.dart |
+++ b/pkg/pool/test/pool_test.dart |
@@ -4,6 +4,7 @@ |
import 'dart:async'; |
+import 'package:fake_async/fake_async.dart'; |
import 'package:pool/pool.dart'; |
import 'package:stack_trace/stack_trace.dart'; |
import 'package:unittest/unittest.dart'; |
@@ -19,30 +20,36 @@ void main() { |
}); |
test("resources block past the limit", () { |
- var pool = new Pool(50); |
- var requests = []; |
- for (var i = 0; i < 50; i++) { |
- expect(pool.request(), completes); |
- } |
- expect(pool.request(), doesNotComplete); |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50); |
+ var requests = []; |
+ for (var i = 0; i < 50; i++) { |
+ expect(pool.request(), completes); |
+ } |
+ expect(pool.request(), doesNotComplete); |
+ |
+ async.elapse(new Duration(seconds: 1)); |
+ }); |
}); |
test("a blocked resource is allocated when another is released", () { |
- var pool = new Pool(50); |
- var requests = []; |
- for (var i = 0; i < 49; i++) { |
- expect(pool.request(), completes); |
- } |
- |
- return pool.request().then((lastAllocatedResource) { |
- var blockedResource = pool.request(); |
- |
- return pumpEventQueue().then((_) { |
- lastAllocatedResource.release(); |
- return pumpEventQueue(); |
- }).then((_) { |
- expect(blockedResource, completes); |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50); |
+ var requests = []; |
+ for (var i = 0; i < 49; i++) { |
+ expect(pool.request(), completes); |
+ } |
+ |
+ pool.request().then((lastAllocatedResource) { |
+ // This will only complete once [lastAllocatedResource] is released. |
+ expect(pool.request(), completes); |
+ |
+ new Future.delayed(new Duration(microseconds: 1)).then((_) { |
+ lastAllocatedResource.release(); |
+ }); |
}); |
+ |
+ async.elapse(new Duration(seconds: 1)); |
}); |
}); |
}); |
@@ -57,62 +64,113 @@ void main() { |
}); |
test("blocks the callback past the limit", () { |
- var pool = new Pool(50); |
- var requests = []; |
- for (var i = 0; i < 50; i++) { |
- pool.withResource(expectAsync(() => new Completer().future)); |
- } |
- pool.withResource(expectNoAsync()); |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50); |
+ var requests = []; |
+ for (var i = 0; i < 50; i++) { |
+ pool.withResource(expectAsync(() => new Completer().future)); |
+ } |
+ pool.withResource(expectNoAsync()); |
+ |
+ async.elapse(new Duration(seconds: 1)); |
+ }); |
}); |
test("a blocked resource is allocated when another is released", () { |
- var pool = new Pool(50); |
- var requests = []; |
- for (var i = 0; i < 49; i++) { |
- pool.withResource(expectAsync(() => new Completer().future)); |
- } |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50); |
+ var requests = []; |
+ for (var i = 0; i < 49; i++) { |
+ pool.withResource(expectAsync(() => new Completer().future)); |
+ } |
+ |
+ var completer = new Completer(); |
+ var lastAllocatedResource = pool.withResource(() => completer.future); |
+ var blockedResourceAllocated = false; |
+ var blockedResource = pool.withResource(() { |
+ blockedResourceAllocated = true; |
+ }); |
- var completer = new Completer(); |
- var lastAllocatedResource = pool.withResource(() => completer.future); |
- var blockedResourceAllocated = false; |
- var blockedResource = pool.withResource(() { |
- blockedResourceAllocated = true; |
- }); |
+ new Future.delayed(new Duration(microseconds: 1)).then((_) { |
+ expect(blockedResourceAllocated, isFalse); |
+ completer.complete(); |
+ return new Future.delayed(new Duration(microseconds: 1)); |
+ }).then((_) { |
+ expect(blockedResourceAllocated, isTrue); |
+ }); |
- return pumpEventQueue().then((_) { |
- expect(blockedResourceAllocated, isFalse); |
- completer.complete(); |
- return pumpEventQueue(); |
- }).then((_) { |
- expect(blockedResourceAllocated, isTrue); |
+ async.elapse(new Duration(seconds: 1)); |
}); |
}); |
}); |
- // TODO(nweiz): test timeouts when seaneagan's fake_async package lands. |
-} |
+ group("with a timeout", () { |
+ test("doesn't time out if there are no pending requests", () { |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50, timeout: new Duration(seconds: 5)); |
+ for (var i = 0; i < 50; i++) { |
+ expect(pool.request(), completes); |
+ } |
-/// Returns a [Future] that completes after pumping the event queue [times] |
-/// times. By default, this should pump the event queue enough times to allow |
-/// any code to run, as long as it's not waiting on some external event. |
-Future pumpEventQueue([int times = 20]) { |
- if (times == 0) return new Future.value(); |
- // We use a delayed future to allow microtask events to finish. The |
- // Future.value or Future() constructors use scheduleMicrotask themselves and |
- // would therefore not wait for microtask callbacks that are scheduled after |
- // invoking this method. |
- return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); |
+ async.elapse(new Duration(seconds: 6)); |
+ }); |
+ }); |
+ |
+ test("resets the timer if a resource is returned", () { |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50, timeout: new Duration(seconds: 5)); |
+ for (var i = 0; i < 49; i++) { |
+ expect(pool.request(), completes); |
+ } |
+ |
+ pool.request().then((lastAllocatedResource) { |
+ // This will only complete once [lastAllocatedResource] is released. |
+ expect(pool.request(), completes); |
+ |
+ new Future.delayed(new Duration(seconds: 3)).then((_) { |
+ lastAllocatedResource.release(); |
+ expect(pool.request(), doesNotComplete); |
+ }); |
+ }); |
+ |
+ async.elapse(new Duration(seconds: 6)); |
+ }); |
+ }); |
+ |
+ test("resets the timer if a resource is requested", () { |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50, timeout: new Duration(seconds: 5)); |
+ for (var i = 0; i < 50; i++) { |
+ expect(pool.request(), completes); |
+ } |
+ expect(pool.request(), doesNotComplete); |
+ |
+ new Future.delayed(new Duration(seconds: 3)).then((_) { |
+ expect(pool.request(), doesNotComplete); |
+ }); |
+ |
+ async.elapse(new Duration(seconds: 6)); |
+ }); |
+ }); |
+ |
+ test("times out if nothing happens", () { |
+ new FakeAsync().run((async) { |
+ var pool = new Pool(50, timeout: new Duration(seconds: 5)); |
+ for (var i = 0; i < 50; i++) { |
+ expect(pool.request(), completes); |
+ } |
+ expect(pool.request(), throwsA(new isInstanceOf<TimeoutException>())); |
+ |
+ async.elapse(new Duration(seconds: 6)); |
+ }); |
+ }); |
+ }); |
} |
/// Returns a function that will cause the test to fail if it's called. |
/// |
-/// This won't let the test complete until it's confident that the function |
-/// won't be called. |
+/// This should only be called within a [FakeAsync.run] zone. |
Function expectNoAsync() { |
- // Make sure the test lasts long enough for the function to get called if it's |
- // going to get called. |
- expect(pumpEventQueue(), completes); |
- |
var stack = new Trace.current(1); |
return () => handleExternalError( |
new TestFailure("Expected function not to be called."), "", |
@@ -121,13 +179,9 @@ Function expectNoAsync() { |
/// A matcher for Futures that asserts that they don't complete. |
/// |
-/// This won't let the test complete until it's confident that the function |
-/// won't be called. |
+/// This should only be called within a [FakeAsync.run] zone. |
Matcher get doesNotComplete => predicate((future) { |
expect(future, new isInstanceOf<Future>('Future')); |
- // Make sure the test lasts long enough for the function to get called if it's |
- // going to get called. |
- expect(pumpEventQueue(), completes); |
var stack = new Trace.current(1); |
future.then((_) => handleExternalError( |