| // Copyright 2017 The Chromium 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 'package:flutter/foundation.dart'; |
| import '../flutter_test_alternative.dart'; |
| |
| import 'capture_output.dart'; |
| |
| void main() { |
| test('debugPrintStack', () { |
| final List<String> log = captureOutput(() { |
| debugPrintStack(label: 'Example label', maxFrames: 7); |
| }); |
| expect(log[0], contains('Example label')); |
| expect(log[1], contains('debugPrintStack')); |
| }); |
| |
| test('debugPrintStack', () { |
| final List<String> log = captureOutput(() { |
| final FlutterErrorDetails details = FlutterErrorDetails( |
| exception: 'Example exception', |
| stack: StackTrace.current, |
| library: 'Example library', |
| context: ErrorDescription('Example context'), |
| informationCollector: () sync* { |
| yield ErrorDescription('Example information'); |
| }, |
| ); |
| |
| FlutterError.dumpErrorToConsole(details); |
| }); |
| |
| expect(log[0], contains('EXAMPLE LIBRARY')); |
| expect(log[1], contains('Example context')); |
| expect(log[2], contains('Example exception')); |
| |
| final String joined = log.join('\n'); |
| |
| expect(joined, contains('captureOutput')); |
| expect(joined, contains('\nExample information\n')); |
| }); |
| |
| test('FlutterErrorDetails.toString', () { |
| expect( |
| FlutterErrorDetails( |
| exception: 'MESSAGE', |
| library: 'LIBRARY', |
| context: ErrorDescription('CONTEXTING'), |
| informationCollector: () sync* { |
| yield ErrorDescription('INFO'); |
| }, |
| ).toString(), |
| '══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n' |
| 'The following message was thrown CONTEXTING:\n' |
| 'MESSAGE\n' |
| '\n' |
| 'INFO\n' |
| '═════════════════════════════════════════════════════════════════\n' |
| |
| ); |
| expect( |
| FlutterErrorDetails( |
| library: 'LIBRARY', |
| context: ErrorDescription('CONTEXTING'), |
| informationCollector: () sync* { |
| yield ErrorDescription('INFO'); |
| }, |
| ).toString(), |
| '══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n' |
| 'The following Null object was thrown CONTEXTING:\n' |
| ' null\n' |
| '\n' |
| 'INFO\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| expect( |
| FlutterErrorDetails( |
| exception: 'MESSAGE', |
| context: ErrorDescription('CONTEXTING'), |
| informationCollector: () sync* { |
| yield ErrorDescription('INFO'); |
| }, |
| ).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following message was thrown CONTEXTING:\n' |
| 'MESSAGE\n' |
| '\n' |
| 'INFO\n' |
| '═════════════════════════════════════════════════════════════════\n' |
| ); |
| expect( |
| FlutterErrorDetails( |
| exception: 'MESSAGE', |
| context: ErrorDescription('CONTEXTING ${'SomeContext(BlaBla)'}'), |
| informationCollector: () sync* { |
| yield ErrorDescription('INFO'); |
| }, |
| ).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following message was thrown CONTEXTING SomeContext(BlaBla):\n' |
| 'MESSAGE\n' |
| '\n' |
| 'INFO\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| expect( |
| const FlutterErrorDetails( |
| exception: 'MESSAGE', |
| ).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following message was thrown:\n' |
| 'MESSAGE\n' |
| '═════════════════════════════════════════════════════════════════\n' |
| ); |
| expect( |
| const FlutterErrorDetails().toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following Null object was thrown:\n' |
| ' null\n' |
| '═════════════════════════════════════════════════════════════════\n' |
| ); |
| }); |
| |
| test('FlutterErrorDetails.toStringShort', () { |
| expect( |
| FlutterErrorDetails( |
| exception: 'MESSAGE', |
| library: 'library', |
| context: ErrorDescription('CONTEXTING'), |
| informationCollector: () sync* { |
| yield ErrorDescription('INFO'); |
| }, |
| ).toStringShort(), |
| 'Exception caught by library', |
| ); |
| }); |
| |
| test('FlutterError default constructor', () { |
| FlutterError error = FlutterError( |
| 'My Error Summary.\n' |
| 'My first description.\n' |
| 'My second description.' |
| ); |
| expect(error.diagnostics.length, equals(3)); |
| expect(error.diagnostics[0].level, DiagnosticLevel.summary); |
| expect(error.diagnostics[1].level, DiagnosticLevel.info); |
| expect(error.diagnostics[2].level, DiagnosticLevel.info); |
| expect(error.diagnostics[0].toString(), 'My Error Summary.'); |
| expect(error.diagnostics[1].toString(), 'My first description.'); |
| expect(error.diagnostics[2].toString(), 'My second description.'); |
| expect( |
| error.toStringDeep(), |
| 'FlutterError\n' |
| ' My Error Summary.\n' |
| ' My first description.\n' |
| ' My second description.\n' |
| ); |
| |
| error = FlutterError( |
| 'My Error Summary.\n' |
| 'My first description.\n' |
| 'My second description.\n' |
| '\n' |
| ); |
| |
| expect(error.diagnostics.length, equals(5)); |
| expect(error.diagnostics[0].level, DiagnosticLevel.summary); |
| expect(error.diagnostics[1].level, DiagnosticLevel.info); |
| expect(error.diagnostics[2].level, DiagnosticLevel.info); |
| expect(error.diagnostics[0].toString(), 'My Error Summary.'); |
| expect(error.diagnostics[1].toString(), 'My first description.'); |
| expect(error.diagnostics[2].toString(), 'My second description.'); |
| expect(error.diagnostics[3].toString(), ''); |
| expect(error.diagnostics[4].toString(), ''); |
| expect( |
| error.toStringDeep(), |
| 'FlutterError\n' |
| ' My Error Summary.\n' |
| ' My first description.\n' |
| ' My second description.\n' |
| '\n' |
| '\n' |
| ); |
| |
| error = FlutterError( |
| 'My Error Summary.\n' |
| 'My first description.\n' |
| '\n' |
| 'My second description.' |
| ); |
| expect(error.diagnostics.length, equals(4)); |
| expect(error.diagnostics[0].level, DiagnosticLevel.summary); |
| expect(error.diagnostics[1].level, DiagnosticLevel.info); |
| expect(error.diagnostics[2].level, DiagnosticLevel.info); |
| expect(error.diagnostics[3].level, DiagnosticLevel.info); |
| expect(error.diagnostics[0].toString(), 'My Error Summary.'); |
| expect(error.diagnostics[1].toString(), 'My first description.'); |
| expect(error.diagnostics[2].toString(), ''); |
| expect(error.diagnostics[3].toString(), 'My second description.'); |
| |
| expect( |
| error.toStringDeep(), |
| 'FlutterError\n' |
| ' My Error Summary.\n' |
| ' My first description.\n' |
| '\n' |
| ' My second description.\n' |
| ); |
| error = FlutterError('My Error Summary.'); |
| expect(error.diagnostics.length, 1); |
| expect(error.diagnostics.first.level, DiagnosticLevel.summary); |
| expect(error.diagnostics.first.toString(), 'My Error Summary.'); |
| |
| expect( |
| error.toStringDeep(), |
| 'FlutterError\n' |
| ' My Error Summary.\n' |
| ); |
| }); |
| |
| test('Malformed FlutterError objects', () { |
| { |
| AssertionError error; |
| try { |
| throw FlutterError.fromParts(<DiagnosticsNode>[]); |
| } on AssertionError catch (e) { |
| error = e; |
| } |
| expect( |
| FlutterErrorDetails(exception: error).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following assertion was thrown:\n' |
| 'Empty FlutterError\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| } |
| |
| { |
| AssertionError error; |
| try { |
| throw FlutterError.fromParts(<DiagnosticsNode>[ |
| (ErrorDescription('Error description without a summary'))]); |
| } on AssertionError catch (e) { |
| error = e; |
| } |
| expect( |
| FlutterErrorDetails(exception: error).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following assertion was thrown:\n' |
| 'FlutterError is missing a summary.\n' |
| 'All FlutterError objects should start with a short (one line)\n' |
| 'summary description of the problem that was detected.\n' |
| 'Malformed FlutterError:\n' |
| ' Error description without a summary\n' |
| '\n' |
| 'This error should still help you solve your problem, however\n' |
| 'please also report this malformed error in the framework by\n' |
| 'filing a bug on GitHub:\n' |
| ' https://github.com/flutter/flutter/issues/new?template=BUG.md\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| } |
| |
| { |
| AssertionError error; |
| try { |
| throw FlutterError.fromParts(<DiagnosticsNode>[ |
| ErrorSummary('Error Summary A'), |
| ErrorDescription('Some descriptionA'), |
| ErrorSummary('Error Summary B'), |
| ErrorDescription('Some descriptionB'), |
| ]); |
| } on AssertionError catch (e) { |
| error = e; |
| } |
| expect( |
| FlutterErrorDetails(exception: error).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following assertion was thrown:\n' |
| 'FlutterError contained multiple error summaries.\n' |
| 'All FlutterError objects should have only a single short (one\n' |
| 'line) summary description of the problem that was detected.\n' |
| 'Malformed FlutterError:\n' |
| ' Error Summary A\n' |
| ' Some descriptionA\n' |
| ' Error Summary B\n' |
| ' Some descriptionB\n' |
| '\n' |
| 'The malformed error has 2 summaries.\n' |
| 'Summary 1: Error Summary A\n' |
| 'Summary 2: Error Summary B\n' |
| '\n' |
| 'This error should still help you solve your problem, however\n' |
| 'please also report this malformed error in the framework by\n' |
| 'filing a bug on GitHub:\n' |
| ' https://github.com/flutter/flutter/issues/new?template=BUG.md\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| } |
| |
| { |
| AssertionError error; |
| try { |
| throw FlutterError.fromParts(<DiagnosticsNode>[ |
| ErrorDescription('Some description'), |
| ErrorSummary('Error summary'), |
| ]); |
| } on AssertionError catch (e) { |
| error = e; |
| } |
| expect( |
| FlutterErrorDetails(exception: error).toString(), |
| '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' |
| 'The following assertion was thrown:\n' |
| 'FlutterError is missing a summary.\n' |
| 'All FlutterError objects should start with a short (one line)\n' |
| 'summary description of the problem that was detected.\n' |
| 'Malformed FlutterError:\n' |
| ' Some description\n' |
| ' Error summary\n' |
| '\n' |
| 'This error should still help you solve your problem, however\n' |
| 'please also report this malformed error in the framework by\n' |
| 'filing a bug on GitHub:\n' |
| ' https://github.com/flutter/flutter/issues/new?template=BUG.md\n' |
| '═════════════════════════════════════════════════════════════════\n', |
| ); |
| } |
| }); |
| |
| test('User-thrown exceptions have ErrorSummary properties', () { |
| { |
| DiagnosticsNode node; |
| try { |
| throw 'User thrown string'; |
| } catch (e) { |
| node = FlutterErrorDetails(exception: e).toDiagnosticsNode(); |
| } |
| final ErrorSummary summary = node.getProperties().whereType<ErrorSummary>().single; |
| expect(summary.value, equals(<String>['User thrown string'])); |
| } |
| |
| { |
| DiagnosticsNode node; |
| try { |
| throw ArgumentError.notNull('myArgument'); |
| } catch (e) { |
| node = FlutterErrorDetails(exception: e).toDiagnosticsNode(); |
| } |
| final ErrorSummary summary = node.getProperties().whereType<ErrorSummary>().single; |
| expect(summary.value, equals(<String>['Invalid argument(s) (myArgument): Must not be null'])); |
| } |
| }); |
| } |