• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/foundation.dart';
6import '../flutter_test_alternative.dart';
7
8import 'capture_output.dart';
9
10void main() {
11  test('debugPrintStack', () {
12    final List<String> log = captureOutput(() {
13      debugPrintStack(label: 'Example label', maxFrames: 7);
14    });
15    expect(log[0], contains('Example label'));
16    expect(log[1], contains('debugPrintStack'));
17  });
18
19  test('debugPrintStack', () {
20    final List<String> log = captureOutput(() {
21      final FlutterErrorDetails details = FlutterErrorDetails(
22        exception: 'Example exception',
23        stack: StackTrace.current,
24        library: 'Example library',
25        context: ErrorDescription('Example context'),
26        informationCollector: () sync* {
27          yield ErrorDescription('Example information');
28        },
29      );
30
31      FlutterError.dumpErrorToConsole(details);
32    });
33
34    expect(log[0], contains('EXAMPLE LIBRARY'));
35    expect(log[1], contains('Example context'));
36    expect(log[2], contains('Example exception'));
37
38    final String joined = log.join('\n');
39
40    expect(joined, contains('captureOutput'));
41    expect(joined, contains('\nExample information\n'));
42  });
43
44  test('FlutterErrorDetails.toString', () {
45    expect(
46      FlutterErrorDetails(
47        exception: 'MESSAGE',
48        library: 'LIBRARY',
49        context: ErrorDescription('CONTEXTING'),
50        informationCollector: () sync* {
51          yield ErrorDescription('INFO');
52        },
53      ).toString(),
54        '══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n'
55        'The following message was thrown CONTEXTING:\n'
56        'MESSAGE\n'
57        '\n'
58        'INFO\n'
59        '═════════════════════════════════════════════════════════════════\n'
60
61    );
62    expect(
63      FlutterErrorDetails(
64        library: 'LIBRARY',
65        context: ErrorDescription('CONTEXTING'),
66        informationCollector: () sync* {
67          yield ErrorDescription('INFO');
68        },
69      ).toString(),
70      '══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n'
71      'The following Null object was thrown CONTEXTING:\n'
72      '  null\n'
73      '\n'
74      'INFO\n'
75      '═════════════════════════════════════════════════════════════════\n',
76    );
77    expect(
78      FlutterErrorDetails(
79        exception: 'MESSAGE',
80        context: ErrorDescription('CONTEXTING'),
81        informationCollector: () sync* {
82          yield ErrorDescription('INFO');
83        },
84      ).toString(),
85        '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
86        'The following message was thrown CONTEXTING:\n'
87        'MESSAGE\n'
88        '\n'
89        'INFO\n'
90        '═════════════════════════════════════════════════════════════════\n'
91    );
92    expect(
93      FlutterErrorDetails(
94        exception: 'MESSAGE',
95        context: ErrorDescription('CONTEXTING ${'SomeContext(BlaBla)'}'),
96        informationCollector: () sync* {
97          yield ErrorDescription('INFO');
98        },
99      ).toString(),
100      '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
101      'The following message was thrown CONTEXTING SomeContext(BlaBla):\n'
102      'MESSAGE\n'
103      '\n'
104      'INFO\n'
105      '═════════════════════════════════════════════════════════════════\n',
106    );
107    expect(
108      const FlutterErrorDetails(
109        exception: 'MESSAGE',
110      ).toString(),
111      '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
112      'The following message was thrown:\n'
113      'MESSAGE\n'
114      '═════════════════════════════════════════════════════════════════\n'
115    );
116    expect(
117      const FlutterErrorDetails().toString(),
118      '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
119      'The following Null object was thrown:\n'
120      '  null\n'
121      '═════════════════════════════════════════════════════════════════\n'
122    );
123  });
124
125  test('FlutterErrorDetails.toStringShort', () {
126    expect(
127        FlutterErrorDetails(
128          exception: 'MESSAGE',
129          library: 'library',
130          context: ErrorDescription('CONTEXTING'),
131          informationCollector: () sync* {
132            yield ErrorDescription('INFO');
133          },
134        ).toStringShort(),
135        'Exception caught by library',
136    );
137  });
138
139  test('FlutterError default constructor', () {
140    FlutterError error = FlutterError(
141      'My Error Summary.\n'
142      'My first description.\n'
143      'My second description.'
144    );
145    expect(error.diagnostics.length, equals(3));
146    expect(error.diagnostics[0].level, DiagnosticLevel.summary);
147    expect(error.diagnostics[1].level, DiagnosticLevel.info);
148    expect(error.diagnostics[2].level, DiagnosticLevel.info);
149    expect(error.diagnostics[0].toString(), 'My Error Summary.');
150    expect(error.diagnostics[1].toString(), 'My first description.');
151    expect(error.diagnostics[2].toString(), 'My second description.');
152    expect(
153      error.toStringDeep(),
154      'FlutterError\n'
155      '   My Error Summary.\n'
156      '   My first description.\n'
157      '   My second description.\n'
158    );
159
160    error = FlutterError(
161      'My Error Summary.\n'
162      'My first description.\n'
163      'My second description.\n'
164      '\n'
165    );
166
167    expect(error.diagnostics.length, equals(5));
168    expect(error.diagnostics[0].level, DiagnosticLevel.summary);
169    expect(error.diagnostics[1].level, DiagnosticLevel.info);
170    expect(error.diagnostics[2].level, DiagnosticLevel.info);
171    expect(error.diagnostics[0].toString(), 'My Error Summary.');
172    expect(error.diagnostics[1].toString(), 'My first description.');
173    expect(error.diagnostics[2].toString(), 'My second description.');
174    expect(error.diagnostics[3].toString(), '');
175    expect(error.diagnostics[4].toString(), '');
176    expect(
177      error.toStringDeep(),
178      'FlutterError\n'
179      '   My Error Summary.\n'
180      '   My first description.\n'
181      '   My second description.\n'
182      '\n'
183      '\n'
184    );
185
186    error = FlutterError(
187      'My Error Summary.\n'
188      'My first description.\n'
189      '\n'
190      'My second description.'
191    );
192    expect(error.diagnostics.length, equals(4));
193    expect(error.diagnostics[0].level, DiagnosticLevel.summary);
194    expect(error.diagnostics[1].level, DiagnosticLevel.info);
195    expect(error.diagnostics[2].level, DiagnosticLevel.info);
196    expect(error.diagnostics[3].level, DiagnosticLevel.info);
197    expect(error.diagnostics[0].toString(), 'My Error Summary.');
198    expect(error.diagnostics[1].toString(), 'My first description.');
199    expect(error.diagnostics[2].toString(), '');
200    expect(error.diagnostics[3].toString(), 'My second description.');
201
202    expect(
203      error.toStringDeep(),
204      'FlutterError\n'
205      '   My Error Summary.\n'
206      '   My first description.\n'
207      '\n'
208      '   My second description.\n'
209    );
210    error = FlutterError('My Error Summary.');
211    expect(error.diagnostics.length, 1);
212    expect(error.diagnostics.first.level, DiagnosticLevel.summary);
213    expect(error.diagnostics.first.toString(), 'My Error Summary.');
214
215    expect(
216      error.toStringDeep(),
217      'FlutterError\n'
218      '   My Error Summary.\n'
219    );
220  });
221
222  test('Malformed FlutterError objects', () {
223    {
224      AssertionError error;
225      try {
226        throw FlutterError.fromParts(<DiagnosticsNode>[]);
227      } on AssertionError catch (e) {
228        error = e;
229      }
230      expect(
231        FlutterErrorDetails(exception: error).toString(),
232        '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
233        'The following assertion was thrown:\n'
234        'Empty FlutterError\n'
235        '═════════════════════════════════════════════════════════════════\n',
236      );
237    }
238
239    {
240      AssertionError error;
241      try {
242        throw FlutterError.fromParts(<DiagnosticsNode>[
243          (ErrorDescription('Error description without a summary'))]);
244      } on AssertionError catch (e) {
245        error = e;
246      }
247      expect(
248        FlutterErrorDetails(exception: error).toString(),
249        '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
250        'The following assertion was thrown:\n'
251        'FlutterError is missing a summary.\n'
252        'All FlutterError objects should start with a short (one line)\n'
253        'summary description of the problem that was detected.\n'
254        'Malformed FlutterError:\n'
255        '  Error description without a summary\n'
256        '\n'
257        'This error should still help you solve your problem, however\n'
258        'please also report this malformed error in the framework by\n'
259        'filing a bug on GitHub:\n'
260        '  https://github.com/flutter/flutter/issues/new?template=BUG.md\n'
261        '═════════════════════════════════════════════════════════════════\n',
262      );
263    }
264
265    {
266      AssertionError error;
267      try {
268        throw FlutterError.fromParts(<DiagnosticsNode>[
269          ErrorSummary('Error Summary A'),
270          ErrorDescription('Some descriptionA'),
271          ErrorSummary('Error Summary B'),
272          ErrorDescription('Some descriptionB'),
273        ]);
274      } on AssertionError catch (e) {
275        error = e;
276      }
277      expect(
278        FlutterErrorDetails(exception: error).toString(),
279        '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
280        'The following assertion was thrown:\n'
281        'FlutterError contained multiple error summaries.\n'
282        'All FlutterError objects should have only a single short (one\n'
283        'line) summary description of the problem that was detected.\n'
284        'Malformed FlutterError:\n'
285        '  Error Summary A\n'
286        '  Some descriptionA\n'
287        '  Error Summary B\n'
288        '  Some descriptionB\n'
289        '\n'
290        'The malformed error has 2 summaries.\n'
291        'Summary 1: Error Summary A\n'
292        'Summary 2: Error Summary B\n'
293        '\n'
294        'This error should still help you solve your problem, however\n'
295        'please also report this malformed error in the framework by\n'
296        'filing a bug on GitHub:\n'
297        '  https://github.com/flutter/flutter/issues/new?template=BUG.md\n'
298        '═════════════════════════════════════════════════════════════════\n',
299      );
300    }
301
302    {
303      AssertionError error;
304      try {
305        throw FlutterError.fromParts(<DiagnosticsNode>[
306          ErrorDescription('Some description'),
307          ErrorSummary('Error summary'),
308        ]);
309      } on AssertionError catch (e) {
310        error = e;
311      }
312      expect(
313        FlutterErrorDetails(exception: error).toString(),
314        '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
315        'The following assertion was thrown:\n'
316        'FlutterError is missing a summary.\n'
317        'All FlutterError objects should start with a short (one line)\n'
318        'summary description of the problem that was detected.\n'
319        'Malformed FlutterError:\n'
320        '  Some description\n'
321        '  Error summary\n'
322        '\n'
323        'This error should still help you solve your problem, however\n'
324        'please also report this malformed error in the framework by\n'
325        'filing a bug on GitHub:\n'
326        '  https://github.com/flutter/flutter/issues/new?template=BUG.md\n'
327        '═════════════════════════════════════════════════════════════════\n',
328      );
329    }
330  });
331
332  test('User-thrown exceptions have ErrorSummary properties', () {
333    {
334      DiagnosticsNode node;
335      try {
336        throw 'User thrown string';
337      } catch (e) {
338        node = FlutterErrorDetails(exception: e).toDiagnosticsNode();
339      }
340      final ErrorSummary summary = node.getProperties().whereType<ErrorSummary>().single;
341      expect(summary.value, equals(<String>['User thrown string']));
342    }
343
344    {
345      DiagnosticsNode node;
346      try {
347        throw ArgumentError.notNull('myArgument');
348      } catch (e) {
349        node = FlutterErrorDetails(exception: e).toDiagnosticsNode();
350      }
351      final ErrorSummary summary = node.getProperties().whereType<ErrorSummary>().single;
352      expect(summary.value, equals(<String>['Invalid argument(s) (myArgument): Must not be null']));
353    }
354  });
355}
356