| // Copyright (c) 2022, 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:expect/expect.dart'; |
| |
| const String scriptName = 'zone_callback_stack_traces_test.dart'; |
| |
| Future<void> foo() async {} |
| |
| Future<void> bar() async { |
| await foo(); |
| } |
| |
| Future<void> runTest() { |
| final Zone testZone = Zone.current.fork( |
| specification: ZoneSpecification( |
| registerUnaryCallback: _registerUnaryCallback, |
| registerBinaryCallback: _registerBinaryCallback)); |
| return testZone.run(bar); |
| } |
| |
| StackTrace? registerUnaryCallbackStackTrace; |
| StackTrace? registerBinaryCallbackStackTrace; |
| |
| ZoneUnaryCallback<R, T> _registerUnaryCallback<R, T>( |
| Zone self, ZoneDelegate parent, Zone zone, R Function(T) f) { |
| final stackTrace = StackTrace.current; |
| print('registerUnaryCallback got stack trace:'); |
| print(stackTrace); |
| if (stackTrace.toString().contains('bar')) { |
| Expect.isNull(registerUnaryCallbackStackTrace); |
| registerUnaryCallbackStackTrace = stackTrace; |
| } |
| return parent.registerUnaryCallback(zone, f); |
| } |
| |
| ZoneBinaryCallback<R, T1, T2> _registerBinaryCallback<R, T1, T2>( |
| Zone self, ZoneDelegate parent, Zone zone, R Function(T1, T2) f) { |
| final stackTrace = StackTrace.current; |
| print('registerBinaryCallback got stack trace:'); |
| print(stackTrace); |
| if (stackTrace.toString().contains('bar')) { |
| Expect.isNull(registerBinaryCallbackStackTrace); |
| registerBinaryCallbackStackTrace = stackTrace; |
| } |
| return parent.registerBinaryCallback(zone, f); |
| } |
| |
| void verifyStackTrace(List<String> expected, StackTrace stackTrace) { |
| final List<String> actual = stackTrace |
| .toString() |
| .split('\n') |
| .where((entry) => entry.contains(scriptName)) |
| .toList(); |
| print('Expected:\n${expected.join('\n')}'); |
| print('Actual:\n${actual.join('\n')}'); |
| Expect.equals(expected.length, actual.length); |
| for (int i = 0; i < expected.length; ++i) { |
| if (!RegExp(expected[i]).hasMatch(actual[i])) { |
| Expect.fail("Stack trace entry $i doesn't match:\n" |
| " expected: ${expected[i]}\n actual: ${actual[i]}"); |
| } |
| } |
| } |
| |
| main() async { |
| await runTest(); |
| verifyStackTrace([ |
| r'^#\d+ _registerUnaryCallback \(.*zone_callback_stack_traces_test.dart:30(:33)?\)$', |
| r'^#\d+ bar \(.*zone_callback_stack_traces_test.dart:14(:3)?\)$', |
| r'^#\d+ runTest \(.*zone_callback_stack_traces_test.dart:22(:19)?\)$', |
| r'^#\d+ main \(.*zone_callback_stack_traces_test.dart:70(:9)?\)$', |
| ], registerUnaryCallbackStackTrace!); |
| |
| verifyStackTrace([ |
| r'^#\d+ _registerBinaryCallback \(.*zone_callback_stack_traces_test.dart:42(:33)?\)$', |
| r'^#\d+ bar \(.*zone_callback_stack_traces_test.dart:14(:3)?\)$', |
| r'^#\d+ runTest \(.*zone_callback_stack_traces_test.dart:22(:19)?\)$', |
| r'^#\d+ main \(.*zone_callback_stack_traces_test.dart:70(:9)?\)$', |
| ], registerBinaryCallbackStackTrace!); |
| } |