OLD | NEW |
| (Empty) |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 // Tests basic functionality of tasks in zones. | |
6 | |
7 import 'package:expect/expect.dart'; | |
8 import 'package:async_helper/async_helper.dart'; | |
9 import 'dart:async'; | |
10 | |
11 List log = []; | |
12 | |
13 class MySpecification extends TaskSpecification { | |
14 final Function callback; | |
15 final bool isOneShot; | |
16 final int value; | |
17 | |
18 MySpecification(void this.callback(), this.isOneShot, this.value); | |
19 | |
20 String get name => "test.specification-name"; | |
21 } | |
22 | |
23 class MyTask { | |
24 final Zone zone; | |
25 final Function callback; | |
26 final int id; | |
27 int invocationCount = 0; | |
28 bool shouldStop = false; | |
29 | |
30 MyTask(this.zone, void this.callback(), this.id); | |
31 } | |
32 | |
33 void runMyTask(MyTask task, int value) { | |
34 log.add("running " | |
35 "zone: ${Zone.current['name']} " | |
36 "task-id: ${task.id} " | |
37 "invocation-count: ${task.invocationCount} " | |
38 "value: $value"); | |
39 task.callback(); | |
40 task.invocationCount++; | |
41 } | |
42 | |
43 MyTask createMyTask(MySpecification spec, Zone zone) { | |
44 var task = new MyTask(zone, spec.callback, spec.value); | |
45 log.add("creating task: ${spec.value} oneshot?: ${spec.isOneShot}"); | |
46 if (spec.isOneShot) { | |
47 Timer.run(() { | |
48 zone.runTask(runMyTask, task, task.id); | |
49 }); | |
50 } else { | |
51 new Timer.periodic(const Duration(milliseconds: 10), (Timer timer) { | |
52 zone.runTask(runMyTask, task, task.id); | |
53 if (task.shouldStop) { | |
54 timer.cancel(); | |
55 } | |
56 }); | |
57 } | |
58 return task; | |
59 } | |
60 | |
61 MyTask startTask(f, bool oneShot, int value) { | |
62 var spec = new MySpecification(f, oneShot, value); | |
63 return Zone.current.createTask(createMyTask, spec); | |
64 } | |
65 | |
66 /// Makes sure things are working in a simple setting. | |
67 /// No interceptions, changes, ... | |
68 Future testCustomTask() { | |
69 var testCompleter = new Completer(); | |
70 asyncStart(); | |
71 | |
72 Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone, | |
73 TaskCreate create, TaskSpecification specification) { | |
74 if (specification is MySpecification) { | |
75 log.add("create enter " | |
76 "zone: ${self['name']} " | |
77 "spec-value: ${specification.value} " | |
78 "spec-oneshot?: ${specification.isOneShot}"); | |
79 MyTask result = parent.createTask(zone, create, specification); | |
80 log.add("create leave"); | |
81 return result; | |
82 } | |
83 return parent.createTask(zone, create, specification); | |
84 } | |
85 | |
86 void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run, | |
87 Object task, Object arg) { | |
88 if (task is MyTask) { | |
89 log.add("run enter " | |
90 "zone: ${self['name']} " | |
91 "task-id: ${task.id} " | |
92 "invocation-count: ${task.invocationCount} " | |
93 "arg: $arg"); | |
94 parent.runTask(zone, run, task, arg); | |
95 log.add("run leave invocation-count: ${task.invocationCount}"); | |
96 return; | |
97 } | |
98 parent.runTask(zone, run, task, arg); | |
99 } | |
100 | |
101 runZoned(() async { | |
102 var completer0 = new Completer(); | |
103 startTask(() { | |
104 completer0.complete("done"); | |
105 }, true, 0); | |
106 await completer0.future; | |
107 | |
108 Expect.listEquals([ | |
109 'create enter zone: custom zone spec-value: 0 spec-oneshot?: true', | |
110 'creating task: 0 oneshot?: true', | |
111 'create leave', | |
112 'run enter zone: custom zone task-id: 0 invocation-count: 0 arg: 0', | |
113 'running zone: custom zone task-id: 0 invocation-count: 0 value: 0', | |
114 'run leave invocation-count: 1' | |
115 ], log); | |
116 log.clear(); | |
117 | |
118 var completer1 = new Completer(); | |
119 MyTask task1; | |
120 task1 = startTask(() { | |
121 if (task1.invocationCount == 1) { | |
122 task1.shouldStop = true; | |
123 completer1.complete("done"); | |
124 } | |
125 }, false, 1); | |
126 await completer1.future; | |
127 | |
128 Expect.listEquals([ | |
129 'create enter zone: custom zone spec-value: 1 spec-oneshot?: false', | |
130 'creating task: 1 oneshot?: false', | |
131 'create leave', | |
132 'run enter zone: custom zone task-id: 1 invocation-count: 0 arg: 1', | |
133 'running zone: custom zone task-id: 1 invocation-count: 0 value: 1', | |
134 'run leave invocation-count: 1', | |
135 'run enter zone: custom zone task-id: 1 invocation-count: 1 arg: 1', | |
136 'running zone: custom zone task-id: 1 invocation-count: 1 value: 1', | |
137 'run leave invocation-count: 2', | |
138 ], log); | |
139 log.clear(); | |
140 | |
141 testCompleter.complete("done"); | |
142 asyncEnd(); | |
143 }, | |
144 zoneValues: {'name': 'custom zone'}, | |
145 zoneSpecification: new ZoneSpecification( | |
146 createTask: createTaskHandler, | |
147 runTask: runTaskHandler)); | |
148 | |
149 return testCompleter.future; | |
150 } | |
151 | |
152 /// More complicated zone, that intercepts... | |
153 Future testCustomTask2() { | |
154 var testCompleter = new Completer(); | |
155 asyncStart(); | |
156 | |
157 Object createTaskHandler(Zone self, ZoneDelegate parent, Zone zone, | |
158 TaskCreate create, TaskSpecification specification) { | |
159 if (specification is MySpecification) { | |
160 log.add("create enter " | |
161 "zone: ${self['name']} " | |
162 "spec-value: ${specification.value} " | |
163 "spec-oneshot?: ${specification.isOneShot}"); | |
164 var replacement = new MySpecification(specification.callback, | |
165 specification.isOneShot, specification.value + 1); | |
166 MyTask result = parent.createTask(zone, create, replacement); | |
167 log.add("create leave"); | |
168 return result; | |
169 } | |
170 return parent.createTask(zone, create, specification); | |
171 } | |
172 | |
173 void runTaskHandler(Zone self, ZoneDelegate parent, Zone zone, TaskRun run, | |
174 Object task, Object arg) { | |
175 if (task is MyTask) { | |
176 log.add("run enter " | |
177 "zone: ${self['name']} " | |
178 "task-id: ${task.id} " | |
179 "invocation-count: ${task.invocationCount} " | |
180 "arg: $arg"); | |
181 int value = arg; | |
182 parent.runTask(zone, run, task, value + 101); | |
183 log.add("run leave invocation-count: ${task.invocationCount}"); | |
184 return; | |
185 } | |
186 parent.runTask(zone, run, task, arg); | |
187 } | |
188 | |
189 runZoned(() async { | |
190 var completer0 = new Completer(); | |
191 startTask(() { | |
192 completer0.complete("done"); | |
193 }, true, 0); | |
194 await completer0.future; | |
195 | |
196 Expect.listEquals([ | |
197 'create enter zone: outer-zone spec-value: 0 spec-oneshot?: true', | |
198 'creating task: 1 oneshot?: true', | |
199 'create leave', | |
200 'run enter zone: outer-zone task-id: 1 invocation-count: 0 arg: 1', | |
201 'running zone: outer-zone task-id: 1 invocation-count: 0 value: 102', | |
202 'run leave invocation-count: 1' | |
203 ], log); | |
204 log.clear(); | |
205 | |
206 var completer1 = new Completer(); | |
207 MyTask task1; | |
208 task1 = startTask(() { | |
209 if (task1.invocationCount == 1) { | |
210 task1.shouldStop = true; | |
211 completer1.complete("done"); | |
212 } | |
213 }, false, 1); | |
214 await completer1.future; | |
215 | |
216 Expect.listEquals([ | |
217 'create enter zone: outer-zone spec-value: 1 spec-oneshot?: false', | |
218 'creating task: 2 oneshot?: false', | |
219 'create leave', | |
220 'run enter zone: outer-zone task-id: 2 invocation-count: 0 arg: 2', | |
221 'running zone: outer-zone task-id: 2 invocation-count: 0 value: 103', | |
222 'run leave invocation-count: 1', | |
223 'run enter zone: outer-zone task-id: 2 invocation-count: 1 arg: 2', | |
224 'running zone: outer-zone task-id: 2 invocation-count: 1 value: 103', | |
225 'run leave invocation-count: 2', | |
226 ], log); | |
227 log.clear(); | |
228 | |
229 var nestedCompleter = new Completer(); | |
230 | |
231 runZoned(() async { | |
232 var completer0 = new Completer(); | |
233 startTask(() { | |
234 completer0.complete("done"); | |
235 }, true, 0); | |
236 await completer0.future; | |
237 | |
238 Expect.listEquals([ | |
239 'create enter zone: inner-zone spec-value: 0 spec-oneshot?: true', | |
240 'create enter zone: outer-zone spec-value: 1 spec-oneshot?: true', | |
241 'creating task: 2 oneshot?: true', | |
242 'create leave', | |
243 'create leave', | |
244 'run enter zone: inner-zone task-id: 2 invocation-count: 0 arg: 2', | |
245 'run enter zone: outer-zone task-id: 2 invocation-count: 0 arg: 103', | |
246 'running zone: inner-zone task-id: 2 invocation-count: 0 value: 204', | |
247 'run leave invocation-count: 1', | |
248 'run leave invocation-count: 1' | |
249 ], log); | |
250 log.clear(); | |
251 | |
252 var completer1 = new Completer(); | |
253 MyTask task1; | |
254 task1 = startTask(() { | |
255 if (task1.invocationCount == 1) { | |
256 task1.shouldStop = true; | |
257 completer1.complete("done"); | |
258 } | |
259 }, false, 1); | |
260 await completer1.future; | |
261 | |
262 Expect.listEquals([ | |
263 'create enter zone: inner-zone spec-value: 1 spec-oneshot?: false', | |
264 'create enter zone: outer-zone spec-value: 2 spec-oneshot?: false', | |
265 'creating task: 3 oneshot?: false', | |
266 'create leave', | |
267 'create leave', | |
268 'run enter zone: inner-zone task-id: 3 invocation-count: 0 arg: 3', | |
269 'run enter zone: outer-zone task-id: 3 invocation-count: 0 arg: 104', | |
270 'running zone: inner-zone task-id: 3 invocation-count: 0 value: 205', | |
271 'run leave invocation-count: 1', | |
272 'run leave invocation-count: 1', | |
273 'run enter zone: inner-zone task-id: 3 invocation-count: 1 arg: 3', | |
274 'run enter zone: outer-zone task-id: 3 invocation-count: 1 arg: 104', | |
275 'running zone: inner-zone task-id: 3 invocation-count: 1 value: 205', | |
276 'run leave invocation-count: 2', | |
277 'run leave invocation-count: 2', | |
278 ], log); | |
279 log.clear(); | |
280 | |
281 nestedCompleter.complete("done"); | |
282 }, | |
283 zoneValues: {'name': 'inner-zone'}, | |
284 zoneSpecification: new ZoneSpecification( | |
285 createTask: createTaskHandler, | |
286 runTask: runTaskHandler)); | |
287 | |
288 await nestedCompleter.future; | |
289 testCompleter.complete("done"); | |
290 asyncEnd(); | |
291 }, | |
292 zoneValues: {'name': 'outer-zone'}, | |
293 zoneSpecification: new ZoneSpecification( | |
294 createTask: createTaskHandler, | |
295 runTask: runTaskHandler)); | |
296 | |
297 return testCompleter.future; | |
298 } | |
299 | |
300 runTests() async { | |
301 await testCustomTask(); | |
302 await testCustomTask2(); | |
303 } | |
304 | |
305 main() { | |
306 asyncStart(); | |
307 runTests().then((_) { | |
308 asyncEnd(); | |
309 }); | |
310 } | |
OLD | NEW |