error_reporting_test.dart 10.8 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7 8
@TestOn('!chrome') // web has different stack traces

9 10 11
import 'dart:async';

import 'package:flutter/foundation.dart';
12
import '../flutter_test_alternative.dart';
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

dynamic getAssertionErrorWithMessage() {
  try {
    assert(false, 'Message goes here.');
  } catch (e) {
    return e;
  }
  throw 'assert failed';
}

dynamic getAssertionErrorWithoutMessage() {
  try {
    assert(false);
  } catch (e) {
    return e;
  }
  throw 'assert failed';
}

dynamic getAssertionErrorWithLongMessage() {
  try {
    assert(false, 'word ' * 100);
  } catch (e) {
    return e;
  }
  throw 'assert failed';
}

Future<StackTrace> getSampleStack() async {
42
  return await Future<StackTrace>.sync(() => StackTrace.current);
43 44
}

45
Future<void> main() async {
46 47 48 49
  final List<String> console = <String>[];

  final StackTrace sampleStack = await getSampleStack();

50
  setUp(() async {
51 52 53 54 55 56
    expect(debugPrint, equals(debugPrintThrottled));
    debugPrint = (String message, { int wrapWidth }) {
      console.add(message);
    };
  });

57 58 59 60 61
  tearDown(() async {
    expect(console, isEmpty);
    debugPrint = debugPrintThrottled;
  });

62 63
  test('Error reporting - assert with message', () async {
    expect(console, isEmpty);
64
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
65 66 67
      exception: getAssertionErrorWithMessage(),
      stack: sampleStack,
      library: 'error handling test',
68 69
      context: ErrorDescription('testing the error handling logic'),
      informationCollector: () sync* {
70 71
        yield ErrorDescription('line 1 of extra information');
        yield ErrorHint('line 2 of extra information\n');
72 73
      },
    ));
74
    expect(console.join('\n'), matches(
75 76 77 78 79 80 81 82 83 84 85
      r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n'
      r'The following assertion was thrown testing the error handling logic:\n'
      r'Message goes here\.\n'
      r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n"
      r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n"
      r'\n'
      r'When the exception was thrown, this was the stack:\n'
      r'#0      getSampleStack\.<anonymous closure> \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'#2      getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'#3      main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'(.+\n)+' // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main()
86
    ));
87
    console.clear();
88
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
89 90 91 92 93 94 95 96 97
      exception: getAssertionErrorWithMessage(),
    ));
    expect(console.join('\n'), 'Another exception was thrown: Message goes here.');
    console.clear();
    FlutterError.resetErrorCount();
  });

  test('Error reporting - assert with long message', () async {
    expect(console, isEmpty);
98
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
99 100
      exception: getAssertionErrorWithLongMessage(),
    ));
101
    expect(console.join('\n'), matches(
102 103 104 105 106 107 108 109 110 111
      r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n'
      r'The following assertion was thrown:\n'
      r'word word word word word word word word word word word word word word word word word word word word\n'
      r'word word word word word word word word word word word word word word word word word word word word\n'
      r'word word word word word word word word word word word word word word word word word word word word\n'
      r'word word word word word word word word word word word word word word word word word word word word\n'
      r'word word word word word word word word word word word word word word word word word word word word\n'
      r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n"
      r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n"
      r'════════════════════════════════════════════════════════════════════════════════════════════════════$',
112
    ));
113
    console.clear();
114
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
115 116 117 118 119 120 121 122 123
      exception: getAssertionErrorWithLongMessage(),
    ));
    expect(
      console.join('\n'),
      'Another exception was thrown: '
      'word word word word word word word word word word word word word word word word word word word word '
      'word word word word word word word word word word word word word word word word word word word word '
      'word word word word word word word word word word word word word word word word word word word word '
      'word word word word word word word word word word word word word word word word word word word word '
124
      'word word word word word word word word word word word word word word word word word word word word',
125 126 127 128 129 130 131
    );
    console.clear();
    FlutterError.resetErrorCount();
  });

  test('Error reporting - assert with no message', () async {
    expect(console, isEmpty);
132
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
133 134 135
      exception: getAssertionErrorWithoutMessage(),
      stack: sampleStack,
      library: 'error handling test',
136 137 138 139
      context: ErrorDescription('testing the error handling logic'),
      informationCollector: () sync* {
        yield ErrorDescription('line 1 of extra information');
        yield ErrorDescription('line 2 of extra information\n'); // the trailing newlines here are intentional
140
      },
141
    ));
142
    expect(console.join('\n'), matches(
143 144 145 146 147 148 149 150 151 152
      r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n'
      r'The following assertion was thrown testing the error handling logic:\n'
      r"'[^']+flutter/test/foundation/error_reporting_test\.dart':[\n ]"
      r"Failed[\n ]assertion:[\n ]line[\n ][0-9]+[\n ]pos[\n ][0-9]+:[\n ]'false':[\n ]is[\n ]not[\n ]true\.\n"
      r'\n'
      r'When the exception was thrown, this was the stack:\n'
      r'#0      getSampleStack\.<anonymous closure> \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'#2      getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'#3      main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n'
      r'(.+\n)+' // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main()
153
    ));
154
    console.clear();
155
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
156 157
      exception: getAssertionErrorWithoutMessage(),
    ));
158
    expect(console.join('\n'), matches("Another exception was thrown: '[^']+flutter/test/foundation/error_reporting_test\\.dart': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\\."));
159 160 161 162 163 164
    console.clear();
    FlutterError.resetErrorCount();
  });

  test('Error reporting - NoSuchMethodError', () async {
    expect(console, isEmpty);
165 166 167
    final dynamic exception = NoSuchMethodError.withInvocation(5,
        Invocation.method(#foo, <dynamic>[2, 4]));

168
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
169 170
      exception: exception,
    ));
171
    expect(console.join('\n'), matches(
172 173
      r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n'
      r'The following NoSuchMethodError was thrown:\n'
174
      r'int has no foo method accepting arguments \(_, _\)\n'
175
      r'════════════════════════════════════════════════════════════════════════════════════════════════════$',
176
    ));
177
    console.clear();
178
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
179 180
      exception: exception,
    ));
181 182
    expect(console.join('\n'),
      'Another exception was thrown: NoSuchMethodError: int has no foo method accepting arguments (_, _)');
183 184 185 186 187 188
    console.clear();
    FlutterError.resetErrorCount();
  });

  test('Error reporting - NoSuchMethodError', () async {
    expect(console, isEmpty);
189
    FlutterError.dumpErrorToConsole(const FlutterErrorDetails(
190 191
      exception: 'hello',
    ));
192
    expect(console.join('\n'), matches(
193 194 195 196
      r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n'
      r'The following message was thrown:\n'
      r'hello\n'
      r'════════════════════════════════════════════════════════════════════════════════════════════════════$',
197
    ));
198
    console.clear();
199
    FlutterError.dumpErrorToConsole(const FlutterErrorDetails(
200 201 202 203 204 205
      exception: 'hello again',
    ));
    expect(console.join('\n'), 'Another exception was thrown: hello again');
    console.clear();
    FlutterError.resetErrorCount();
  });
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224

  // Regression test for https://github.com/flutter/flutter/issues/62223
  test('Error reporting - empty stack', () async {
    expect(console, isEmpty);
    FlutterError.dumpErrorToConsole(FlutterErrorDetails(
      exception: 'exception - empty stack',
      stack: StackTrace.fromString(''),
    ));
    expect(console.join('\n'), matches(
      r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n'
      r'The following message was thrown:\n'
      r'exception - empty stack\n'
      r'\n'
      r'When the exception was thrown, this was the stack:\n'
      r'...\n'
      r'════════════════════════════════════════════════════════════════════════════════════════════════════$',
    ));
    console.clear();
  });
225
}