Ensure timers are started before awaits in tests (dart-lang/stream_transform#29) Fixes dart-lang/stream_transform#25 These tests were relying on a 5ms Timer getting started asynchronously and firing before a 10ms delay which is not guaranteed. By waiting an extra cycle through the event loop to ensure that the Timer starts before the delay we can have a better guarantee of ordering. - Add a test util to wait for Timers to start and then elapse. - Replace `await new Future.delayed(arbitraryDelay)` with the new utility. - Add missing copyright notices on touched files.
diff --git a/pkgs/stream_transform/test/audit_test.dart b/pkgs/stream_transform/test/audit_test.dart index a3b2fef..b61a8db 100644 --- a/pkgs/stream_transform/test/audit_test.dart +++ b/pkgs/stream_transform/test/audit_test.dart
@@ -1,7 +1,14 @@ +// Copyright (c) 2017, 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. + import 'dart:async'; + import 'package:test/test.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'utils.dart'; + void main() { var streamTypes = { 'single subscription': () => new StreamController(), @@ -47,15 +54,15 @@ values.add(1); values.add(2); await values.close(); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [2]); }); test('outputs multiple values spaced further than duration', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [1, 2]); }); @@ -63,17 +70,17 @@ values.add(1); await values.close(); expect(isDone, false); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(isDone, true); }); test('closes output if there are no pending values', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); await values.close(); expect(isDone, false); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(isDone, true); }); @@ -84,7 +91,8 @@ values.add(2); await new Future.delayed(const Duration(milliseconds: 3)); values.add(3); - expect(emittedValues, [2]); + await waitForTimer(5); + expect(emittedValues, [2, 3]); }); if (streamType == 'broadcast') { @@ -93,7 +101,7 @@ transformed.listen(otherValues.add); values.add(1); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [2]); expect(otherValues, [2]); });
diff --git a/pkgs/stream_transform/test/debounce_test.dart b/pkgs/stream_transform/test/debounce_test.dart index a28d2ca..59cb809 100644 --- a/pkgs/stream_transform/test/debounce_test.dart +++ b/pkgs/stream_transform/test/debounce_test.dart
@@ -1,7 +1,14 @@ +// Copyright (c) 2017, 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. + import 'dart:async'; + import 'package:test/test.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'utils.dart'; + void main() { var streamTypes = { 'single subscription': () => new StreamController(), @@ -47,21 +54,21 @@ values.add(1); values.add(2); await values.close(); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [2]); }); test('outputs multiple values spaced further than duration', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [1, 2]); }); test('waits for pending value to close', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); await values.close(); await new Future(() {}); expect(isDone, true); @@ -69,12 +76,12 @@ test('closes output if there are no pending values', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); await new Future(() {}); await values.close(); expect(isDone, false); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(isDone, true); }); @@ -84,7 +91,7 @@ transformed.listen(otherValues.add); values.add(1); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [2]); expect(otherValues, [2]); }); @@ -100,7 +107,7 @@ values.add(1); values.add(2); await values.close(); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [ [1, 2] ]); @@ -109,9 +116,9 @@ test('separate lists for multiple values spaced further than duration', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [ [1], [2] @@ -124,7 +131,7 @@ transformed.listen(otherValues.add); values.add(1); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [ [1, 2] ]);
diff --git a/pkgs/stream_transform/test/throttle_test.dart b/pkgs/stream_transform/test/throttle_test.dart index 10a34fd..94e1851 100644 --- a/pkgs/stream_transform/test/throttle_test.dart +++ b/pkgs/stream_transform/test/throttle_test.dart
@@ -1,7 +1,14 @@ +// Copyright (c) 2017, 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. + import 'dart:async'; + import 'package:test/test.dart'; import 'package:stream_transform/stream_transform.dart'; +import 'utils.dart'; + void main() { var streamTypes = { 'single subscription': () => new StreamController(), @@ -47,21 +54,21 @@ values.add(1); values.add(2); await values.close(); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [1]); }); test('outputs multiple values spaced further than duration', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); expect(emittedValues, [1, 2]); }); test('closes output immediately', () async { values.add(1); - await new Future.delayed(const Duration(milliseconds: 10)); + await waitForTimer(5); values.add(2); await values.close(); expect(isDone, true);
diff --git a/pkgs/stream_transform/test/utils.dart b/pkgs/stream_transform/test/utils.dart new file mode 100644 index 0000000..4e38ef7 --- /dev/null +++ b/pkgs/stream_transform/test/utils.dart
@@ -0,0 +1,11 @@ +// Copyright (c) 2017, 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. + +import 'dart:async'; + +/// Cycle the event loop to ensure timers are started, then wait for a delay +/// longer than [milliseconds] to allow for the timer to fire. +Future waitForTimer(int milliseconds) => + new Future(() {/* ensure Timer is started*/}).then((_) => + new Future.delayed(new Duration(milliseconds: milliseconds + 1)));