blob: 2f76f436699933c10f03fa8745ec91ab30b00085 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. 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:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:stack_trace/stack_trace.dart' as stack_trace;
Future<void> main() async {
// We use AutomatedTestWidgetsFlutterBinding to allow the test binding to set
// FlutterError.demangleStackTrace and FlutterError.onError without testWidgets.
final AutomatedTestWidgetsFlutterBinding binding = AutomatedTestWidgetsFlutterBinding();
test('FlutterErrorDetails demangles', () async {
await binding.runTest(() async {
// When we call toString on a FlutterErrorDetails, it attempts to parse and
// filter the stack trace, which fails if demangleStackTrace returns a
// mangled stack trace.
FlutterErrorDetails(
exception: const CustomException(),
stack: await getMangledStack(),
).toString();
// Additional logic is used to parse assertion stack traces.
FlutterErrorDetails(
exception: AssertionError('Some assertion'),
stack: await getMangledStack(),
).toString();
}, () {});
binding.postTest();
});
test('debugPrintStack demangles', () async {
await binding.runTest(() async {
final DebugPrintCallback oldDebugPrint = debugPrint;
try {
debugPrint = (String? message, {int? wrapWidth}) {};
debugPrintStack(
stackTrace: await getMangledStack(),
);
} finally {
debugPrint = oldDebugPrint;
}
}, () {});
binding.postTest();
});
}
Future<StackTrace> getMangledStack() {
// package:test uses package:stack_trace to wrap tests in a Zone that overrides
// errorCallback, the error callback transforms any StackTrace propagated
// to futures into a Chain, which has a format different from the vm.
final Completer<StackTrace> stackCompleter = Completer<StackTrace>();
final Completer<void> completer = Completer<void>();
completer.future.then(
(void value) {
assert(false);
},
onError: (Object error, StackTrace stack) {
expect(error, isA<CustomException>());
expect(stack, isA<stack_trace.Chain>());
stackCompleter.complete(stack);
},
);
completer.completeError(const CustomException());
return stackCompleter.future;
}
class CustomException implements Exception {
const CustomException();
}