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

Side by Side Diff: third_party/pkg/angular/lib/mock/zone.dart

Issue 124053002: Adding Angular and dependent packages for testing (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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
OLDNEW
(Empty)
1 library angular.mock_zone;
2
3 import 'dart:async' as dart_async;
4
5 List<Function> _asyncQueue = [];
6 List<_TimerSpec> _timerQueue = [];
7 List _asyncErrors = [];
8 bool _noMoreAsync = false;
9
10 /**
11 * Runs any queued up async calls and any async calls queued with
12 * running microLeap. Example:
13 *
14 * it('should run async code', async(() {
15 * var thenRan = false;
16 * new Future.value('s').then((_) { thenRan = true; });
17 * expect(thenRan).toBe(false);
18 * microLeap();
19 * expect(thenRan).toBe(true);
20 * }));
21 *
22 * it('should run chained thens', async(() {
23 * var log = [];
24 * new Future.value('s')
25 * .then((_) { log.add('firstThen'); })
26 * .then((_) { log.add('2ndThen'); });
27 * expect(log.join(' ')).toEqual('');
28 * microLeap();
29 * expect(log.join(' ')).toEqual('firstThen 2ndThen');
30 * }));
31 *
32 */
33 microLeap() {
34 while (!_asyncQueue.isEmpty) {
35 // copy the queue as it may change.
36 var toRun = new List.from(_asyncQueue);
37 _asyncQueue = [];
38 // TODO: Support the case where multiple exceptions are thrown.
39 // e.g. with a throwNextException() method.
40 assert(_asyncErrors.isEmpty);
41 toRun.forEach((fn) => fn());
42 if (!_asyncErrors.isEmpty) {
43 var e = _asyncErrors.removeAt(0);
44 throw ['Async error', e[0], e[1]];
45 }
46 }
47 }
48
49 /**
50 * Simulates a clock tick by running any scheduled timers. Can only be used
51 * in [async] tests.Clock tick will call [microLeap] to process the microtask
52 * queue before each timer callback.
53 *
54 * Note: microtasks scheduled form the last timer are not going to be processed.
55 *
56 * Example:
57 *
58 * it('should run queued timer after sufficient clock ticks', async(() {
59 * bool timerRan = false;
60 * new Timer(new Duration(milliseconds: 10), () => timerRan = true);
61 *
62 * clockTick(milliseconds: 9);
63 * expect(timerRan).toBeFalsy();
64 * clockTick(milliseconds: 1);
65 * expect(timerRan).toBeTruthy();
66 * }));
67 *
68 * it('should run periodic timer', async(() {
69 * int timerRan = 0;
70 * new Timer.periodic(new Duration(milliseconds: 10), (_) => timerRan++);
71 *
72 * clockTick(milliseconds: 9);
73 * expect(timerRan).toBe(0);
74 * clockTick(milliseconds: 1);
75 * expect(timerRan).toBe(1);
76 * clockTick(milliseconds: 30);
77 * expect(timerRan).toBe(4);
78 * }));
79 */
80 clockTick({int days: 0,
81 int hours: 0,
82 int minutes: 0,
83 int seconds: 0,
84 int milliseconds: 0,
85 int microseconds: 0}) {
86 var tickDuration = new Duration(days: days, hours: hours, minutes: minutes,
87 seconds: seconds, milliseconds: milliseconds, microseconds: microseconds);
88
89 var queue = _timerQueue;
90 var remainingTimers = [];
91 _timerQueue = [];
92 queue.forEach((_TimerSpec spec) {
93 if (!spec.isActive) return; // Skip over inactive timers.
94 if (spec.periodic) {
95 // We always add back the periodic timer unless it's cancelled.
96 remainingTimers.add(spec);
97
98 // Ignore ZERO duration ticks for periodic timers.
99 if (tickDuration == Duration.ZERO) return;
100
101 spec.elapsed += tickDuration;
102 // Run the timer as many times as the timer priod fits into the tick.
103 while (spec.elapsed >= spec.duration) {
104 spec.elapsed -= spec.duration;
105 microLeap();
106 spec.fn(spec);
107 }
108 } else {
109 spec.duration -= tickDuration;
110 if (spec.duration <= Duration.ZERO) {
111 microLeap();
112 spec.fn();
113 } else {
114 remainingTimers.add(spec);
115 }
116 }
117 });
118 // Remaining timers should come before anything else scheduled after them.
119 _timerQueue.insertAll(0, remainingTimers);
120 }
121
122 /**
123 * Causes scheduleMicrotask calls to throw exceptions.
124 *
125 * This function is useful while debugging async tests: the exception
126 * is thrown from the scheduleMicrotask call-site instead later in the test.
127 */
128 noMoreAsync() {
129 _noMoreAsync = true;
130 }
131
132 /**
133 * Captures all scheduleMicrotask calls inside of a function.
134 *
135 * Typically used within a test:
136 *
137 * it('should be async', async(() {
138 * ...
139 * }));
140 */
141 async(Function fn) =>
142 () {
143 _noMoreAsync = false;
144 _asyncErrors = [];
145 _timerQueue = [];
146 var zoneSpec = new dart_async.ZoneSpecification(
147 scheduleMicrotask: (_, __, ___, asyncFn) {
148 if (_noMoreAsync) {
149 throw ['scheduleMicrotask called after noMoreAsync()'];
150 } else {
151 _asyncQueue.add(asyncFn);
152 }
153 },
154 createTimer: (_, __, ____, Duration duration, void f()) =>
155 _createTimer(f, duration, false),
156 createPeriodicTimer:
157 (_, __, ___, Duration period, void f(dart_async.Timer timer)) =>
158 _createTimer(f, period, true),
159 handleUncaughtError: (_, __, ___, e, s) => _asyncErrors.add([e, s])
160 );
161 dart_async.runZoned(() {
162 fn();
163 microLeap();
164 }, zoneSpecification: zoneSpec);
165
166 _asyncErrors.forEach((e) {
167 throw "During runZoned: ${e[0]}. Stack:\n${e[1]}";
168 });
169
170 if (!_timerQueue.isEmpty && _timerQueue.any((_TimerSpec spec) => spec.isActive )) {
171 throw ["${_timerQueue.where((_TimerSpec spec) => spec.isActive).length} "
172 "active timer(s) are still in the queue."];
173 }
174 };
175
176 _createTimer(Function fn, Duration duration, bool periodic) {
177 var timer = new _TimerSpec(fn, duration, periodic);
178 _timerQueue.add(timer);
179 return timer;
180 }
181
182 /**
183 * Enforces synchronous code. Any calls to scheduleMicrotask inside of 'sync'
184 * will throw an exception.
185 */
186 sync(Function fn) => () {
187 dart_async.runZoned(fn, zoneSpecification: new dart_async.ZoneSpecification(
188 scheduleMicrotask: (_, __, ___, asyncFn) {
189 throw ['scheduleMicrotask called from sync function.'];
190 },
191 createTimer: (_, __, ____, Duration duration, void f()) {
192 throw ['Timer created from sync function.'];
193 },
194 createPeriodicTimer:
195 (_, __, ___, Duration period, void f(dart_async.Timer timer)) {
196 throw ['periodic Timer created from sync function.'];
197 }
198 ));
199 };
200
201 class _TimerSpec implements dart_async.Timer {
202 Function fn;
203 Duration duration;
204 Duration elapsed = Duration.ZERO;
205 bool periodic;
206 bool isActive = true;
207
208 _TimerSpec(this.fn, this.duration, this.periodic);
209
210 void cancel() {
211 isActive = false;
212 }
213 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698