Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(745)

Side by Side Diff: pkg/scheduled_test/lib/src/mock_clock.dart

Issue 16003002: Add StreamController.multiplex constructor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove unused code Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/mdv_observe/lib/src/observable_list.dart ('k') | sdk/lib/async/stream_controller.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /// A library that wraps [Timer] in a way that can be mocked out in test code. 5 /// A library that wraps [Timer] in a way that can be mocked out in test code.
6 /// Application code only needs to use [newTimer] to get an instance of [Timer]. 6 /// Application code only needs to use [newTimer] to get an instance of [Timer].
7 /// Then test code can call [mock] to mock out all new [Timer] instances so that 7 /// Then test code can call [mock] to mock out all new [Timer] instances so that
8 /// they're controllable by a returned [Clock] object. 8 /// they're controllable by a returned [Clock] object.
9 library mock_clock; 9 library mock_clock;
10 10
(...skipping 26 matching lines...) Expand all
37 _mocked ? new _MockTimer(duration, callback) : new Timer(duration, callback); 37 _mocked ? new _MockTimer(duration, callback) : new Timer(duration, callback);
38 38
39 /// A clock that controls when mocked [Timer]s move forward in time. It starts 39 /// A clock that controls when mocked [Timer]s move forward in time. It starts
40 /// at time 0 and advances forward millisecond-by-millisecond, broadcasting each 40 /// at time 0 and advances forward millisecond-by-millisecond, broadcasting each
41 /// tick on the [onTick] stream. 41 /// tick on the [onTick] stream.
42 class Clock { 42 class Clock {
43 /// The current time of the clock, in milliseconds. Starts at 0. 43 /// The current time of the clock, in milliseconds. Starts at 0.
44 int get time => _time; 44 int get time => _time;
45 int _time = 0; 45 int _time = 0;
46 46
47 /// Collection of controllers of all subscribed listeners. 47 /// Controller providing streams for listening.
48 /// 48 StreamController<int> _multiplexController =
49 /// [StreamController] is not overriding [Object.operator==], so this is 49 new StreamController<int>.multiplex();
50 /// effectively an identity map.
51 Set<StreamController> _subscriptions = new Set<StreamController>();
52 50
53 Clock._(); 51 Clock._();
54 52
55 /// The stream of millisecond ticks of the clock. 53 /// The stream of millisecond ticks of the clock.
56 Stream<int> get onTick { 54 Stream<int> get onTick => _multiplexController.stream;
57 StreamController<int> controller;
58 controller = new StreamController<int>(
59 onListen: () {
60 _subscriptions.add(controller);
61 },
62 onCancel: () {
63 _subscriptions.remove(controller);
64 });
65 return controller.stream;
66 }
67
68 55
69 /// Advances the clock forward by [milliseconds]. This works like synchronous 56 /// Advances the clock forward by [milliseconds]. This works like synchronous
70 /// code that takes [milliseconds] to execute; any [Timer]s that are scheduled 57 /// code that takes [milliseconds] to execute; any [Timer]s that are scheduled
71 /// to fire during the interval will do so asynchronously once control returns 58 /// to fire during the interval will do so asynchronously once control returns
72 /// to the event loop. 59 /// to the event loop.
73 void tick([int milliseconds = 1]) { 60 void tick([int milliseconds = 1]) {
74 for (var i = 0; i < milliseconds; i++) { 61 for (var i = 0; i < milliseconds; i++) {
75 var tickTime = ++_time; 62 var tickTime = ++_time;
76 runAsync(() { 63 runAsync(() {
77 List<StreamController> controllers = _subscriptions.toList(); 64 _multiplexController.add(tickTime);
78 for (StreamController controller in controllers) {
79 if (_subscriptions.contains(controller)) {
80 controller.add(tickTime);
81 }
82 }
83 }); 65 });
84 } 66 }
85 } 67 }
86 68
87 /// Automatically progresses forward in time as long as there are still 69 /// Automatically progresses forward in time as long as there are still
88 /// subscribers to [onTick] (that is, [Timer]s waiting to fire). After each 70 /// subscribers to [onTick] (that is, [Timer]s waiting to fire). After each
89 /// tick, this pumps the event loop repeatedly so that all non-clock-dependent 71 /// tick, this pumps the event loop repeatedly so that all non-clock-dependent
90 /// code runs before the next tick. 72 /// code runs before the next tick.
91 void run() { 73 void run() {
92 pumpEventQueue().then((_) { 74 pumpEventQueue().then((_) {
93 if (_subscriptions.isEmpty) return; 75 if (!_multiplexController.hasListener) return;
94 tick(); 76 tick();
95 return run(); 77 return run();
96 }); 78 });
97 } 79 }
98 } 80 }
99 81
100 /// A mock implementation of [Timer] that uses [Clock] to keep time, rather than 82 /// A mock implementation of [Timer] that uses [Clock] to keep time, rather than
101 /// the system clock. 83 /// the system clock.
102 class _MockTimer implements Timer { 84 class _MockTimer implements Timer {
103 /// The time at which the timer should fire. 85 /// The time at which the timer should fire.
104 final int _time; 86 final int _time;
105 87
106 /// The callback to run when the timer fires. 88 /// The callback to run when the timer fires.
107 final TimerCallback _callback; 89 final TimerCallback _callback;
108 90
109 /// The subscription to the [Clock.onTick] stream. 91 /// The subscription to the [Clock.onTick] stream.
110 StreamSubscription _subscription; 92 StreamSubscription _subscription;
111 93
112 _MockTimer(Duration duration, this._callback) 94 _MockTimer(Duration duration, this._callback)
113 : _time = _clock.time + duration.inMilliseconds { 95 : _time = _clock.time + duration.inMilliseconds {
114 _subscription = _clock.onTick.listen((time) { 96 _subscription = _clock.onTick.listen((time) {
115 if (time < _time) return; 97 if (time < _time) return;
116 _subscription.cancel(); 98 _subscription.cancel();
117 _callback(); 99 _callback();
118 }); 100 });
119 } 101 }
120 102
121 void cancel() => _subscription.cancel(); 103 void cancel() => _subscription.cancel();
122 } 104 }
OLDNEW
« no previous file with comments | « pkg/mdv_observe/lib/src/observable_list.dart ('k') | sdk/lib/async/stream_controller.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698