Index: tests/lib_strong/async/zone_debug_test.dart |
diff --git a/tests/lib_strong/async/zone_debug_test.dart b/tests/lib_strong/async/zone_debug_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6b6e490ea00d253ceb2af7ae6339c67488b9de0b |
--- /dev/null |
+++ b/tests/lib_strong/async/zone_debug_test.dart |
@@ -0,0 +1,134 @@ |
+// Copyright (c) 2013, 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 'package:expect/expect.dart'; |
+import 'package:async_helper/async_helper.dart'; |
+import 'dart:async'; |
+ |
+import 'dart:collection'; |
+ |
+/** |
+ * We represent the current stack trace by an integer. From time to time we |
+ * increment the variable. This corresponds to a new stack trace. |
+ */ |
+int stackTrace = 0; |
+List restoredStackTrace = []; |
+ |
+List events = []; |
+ |
+debugZoneRegisterCallback(Zone self, ZoneDelegate parent, Zone origin, f()) { |
+ List savedTrace = [stackTrace]..addAll(restoredStackTrace); |
+ return parent.registerCallback(origin, () { |
+ restoredStackTrace = savedTrace; |
+ return f(); |
+ }); |
+} |
+ |
+debugZoneRegisterUnaryCallback(Zone self, ZoneDelegate parent, Zone origin, |
+ f(arg)) { |
+ List savedTrace = [stackTrace]..addAll(restoredStackTrace); |
+ return parent.registerUnaryCallback(origin, (arg) { |
+ restoredStackTrace = savedTrace; |
+ return f(arg); |
+ }); |
+} |
+ |
+debugZoneRun(Zone self, ZoneDelegate parent, Zone origin, f()) { |
+ stackTrace++; |
+ restoredStackTrace = []; |
+ return parent.run(origin, f); |
+} |
+ |
+debugZoneRunUnary(Zone self, ZoneDelegate parent, Zone origin, f(arg), arg) { |
+ stackTrace++; |
+ restoredStackTrace = []; |
+ return parent.runUnary(origin, f, arg); |
+} |
+ |
+List expectedDebugTrace; |
+ |
+debugUncaughtHandler( |
+ Zone self, ZoneDelegate parent, Zone origin, error, StackTrace stackTrace) { |
+ events.add("handling uncaught error $error"); |
+ Expect.listEquals(expectedDebugTrace, restoredStackTrace); |
+ // Suppress the error and don't propagate to parent. |
+} |
+ |
+const DEBUG_SPECIFICATION = const ZoneSpecification( |
+ registerCallback: debugZoneRegisterCallback, |
+ registerUnaryCallback: debugZoneRegisterUnaryCallback, |
+ run: debugZoneRun, |
+ runUnary: debugZoneRunUnary, |
+ handleUncaughtError: debugUncaughtHandler); |
+ |
+main() { |
+ Completer done = new Completer(); |
+ |
+ // runGuarded calls run, captures the synchronous error (if any) and |
+ // gives that one to handleUncaughtError. |
+ |
+ Expect.identical(Zone.ROOT, Zone.current); |
+ Zone forked; |
+ forked = Zone.current.fork(specification: DEBUG_SPECIFICATION); |
+ |
+ asyncStart(); |
+ |
+ int openTests = 0; |
+ |
+ openTests++; |
+ forked.run(() { |
+ int forkTrace = stackTrace; |
+ scheduleMicrotask(() { |
+ int scheduleMicrotaskTrace = stackTrace; |
+ scheduleMicrotask(() { |
+ expectedDebugTrace = [scheduleMicrotaskTrace, forkTrace]; |
+ openTests--; |
+ if (openTests == 0) { |
+ done.complete(); |
+ } |
+ throw "foo"; |
+ }); |
+ expectedDebugTrace = [forkTrace]; |
+ throw "bar"; |
+ }); |
+ }); |
+ |
+ Expect.listEquals([], restoredStackTrace); |
+ Zone forked2 = forked.fork(); |
+ Zone forked3 = forked2.fork(); |
+ int fork2Trace; |
+ int fork3Trace; |
+ var f2; |
+ var globalTrace = stackTrace; |
+ var f = forked3.bindCallback(() { |
+ Expect.identical(forked3, Zone.current); |
+ fork2Trace = stackTrace; |
+ f2 = forked2.bindCallback(() { |
+ Expect.identical(forked2, Zone.current); |
+ Expect.listEquals([fork2Trace, globalTrace], restoredStackTrace); |
+ fork3Trace = stackTrace; |
+ openTests--; |
+ if (openTests == 0) { |
+ done.complete(); |
+ } |
+ scheduleMicrotask(() { |
+ expectedDebugTrace = [fork3Trace, fork2Trace, globalTrace]; |
+ throw "gee"; |
+ }); |
+ }, runGuarded: false); |
+ }, runGuarded: false); |
+ openTests++; |
+ f(); |
+ f2(); |
+ |
+ done.future.whenComplete(() { |
+ // We don't really care for the order. |
+ events.sort(); |
+ Expect.listEquals([ "handling uncaught error bar", |
+ "handling uncaught error foo", |
+ "handling uncaught error gee"], |
+ events); |
+ asyncEnd(); |
+ }); |
+} |