debug_test.dart 7.61 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
import 'package:flutter/foundation.dart';
8 9 10 11 12
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('debugCheckHasMaterial control test', (WidgetTester tester) async {
13
    await tester.pumpWidget(const ListTile());
14 15
    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
16
    final FlutterError error = exception as FlutterError;
17 18 19 20 21 22 23 24 25 26
    expect(error.diagnostics.length, 5);
    expect(error.diagnostics[2].level, DiagnosticLevel.hint);
    expect(
      error.diagnostics[2].toStringDeep(),
      equalsIgnoringHashCodes(
        'To introduce a Material widget, you can either directly include\n'
        'one, or use a widget that contains Material itself, such as a\n'
        'Card, Dialog, Drawer, or Scaffold.\n',
      ),
    );
Dan Field's avatar
Dan Field committed
27 28
    expect(error.diagnostics[3], isA<DiagnosticsProperty<Element>>());
    expect(error.diagnostics[4], isA<DiagnosticsBlock>());
29 30 31 32 33
    expect(error.toStringDeep(),
      'FlutterError\n'
      '   No Material widget found.\n'
      '   ListTile widgets require a Material widget ancestor.\n'
      '   In material design, most widgets are conceptually "printed" on a\n'
34
      "   sheet of material. In Flutter's material library, that material\n"
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
      '   is represented by the Material widget. It is the Material widget\n'
      '   that renders ink splashes, for instance. Because of this, many\n'
      '   material library widgets require that there be a Material widget\n'
      '   in the tree above them.\n'
      '   To introduce a Material widget, you can either directly include\n'
      '   one, or use a widget that contains Material itself, such as a\n'
      '   Card, Dialog, Drawer, or Scaffold.\n'
      '   The specific widget that could not find a Material ancestor was:\n'
      '     ListTile\n'
      '   The ancestors of this widget were:\n'
      '     [root]\n'
    );
  });

  testWidgets('debugCheckHasMaterialLocalizations control test', (
      WidgetTester tester) async {
    await tester.pumpWidget(const BackButton());
    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
54
    final FlutterError error = exception as FlutterError;
55 56 57 58 59 60 61 62 63 64
    expect(error.diagnostics.length, 6);
    expect(error.diagnostics[3].level, DiagnosticLevel.hint);
    expect(
      error.diagnostics[3].toStringDeep(),
      equalsIgnoringHashCodes(
        'To introduce a MaterialLocalizations, either use a MaterialApp at\n'
        'the root of your application to include them automatically, or\n'
        'add a Localization widget with a MaterialLocalizations delegate.\n',
      ),
    );
Dan Field's avatar
Dan Field committed
65 66
    expect(error.diagnostics[4], isA<DiagnosticsProperty<Element>>());
    expect(error.diagnostics[5], isA<DiagnosticsBlock>());
67 68 69 70 71 72
    expect(error.toStringDeep(),
      'FlutterError\n'
      '   No MaterialLocalizations found.\n'
      '   BackButton widgets require MaterialLocalizations to be provided\n'
      '   by a Localizations widget ancestor.\n'
      '   Localizations are used to generate many different messages,\n'
73
      '   labels, and abbreviations which are used by the material library.\n'
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
      '   To introduce a MaterialLocalizations, either use a MaterialApp at\n'
      '   the root of your application to include them automatically, or\n'
      '   add a Localization widget with a MaterialLocalizations delegate.\n'
      '   The specific widget that could not find a MaterialLocalizations\n'
      '   ancestor was:\n'
      '     BackButton\n'
      '   The ancestors of this widget were:\n'
      '     [root]\n'
    );
  });

  testWidgets(
      'debugCheckHasScaffold control test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
89 90 91 92 93 94 95
        theme: ThemeData(
          pageTransitionsTheme: const PageTransitionsTheme(
            builders: <TargetPlatform, PageTransitionsBuilder>{
              TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
            },
          ),
        ),
96 97 98 99 100 101 102 103 104 105 106
        home: Builder(
          builder: (BuildContext context) {
            showBottomSheet<void>(context: context,
                builder: (BuildContext context) => Container());
            return Container();
          }
        ),
      ),
    );
    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
107
    final FlutterError error = exception as FlutterError;
108
    expect(error.diagnostics.length, 5);
Dan Field's avatar
Dan Field committed
109 110
    expect(error.diagnostics[2], isA<DiagnosticsProperty<Element>>());
    expect(error.diagnostics[3], isA<DiagnosticsBlock>());
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    expect(error.diagnostics[4].level, DiagnosticLevel.hint);
    expect(
      error.diagnostics[4].toStringDeep(),
      equalsIgnoringHashCodes(
        'Typically, the Scaffold widget is introduced by the MaterialApp\n'
        'or WidgetsApp widget at the top of your application widget tree.\n',
      ),
    );
    expect(error.toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   No Scaffold widget found.\n'
      '   Builder widgets require a Scaffold widget ancestor.\n'
      '   The specific widget that could not find a Scaffold ancestor was:\n'
      '     Builder\n'
      '   The ancestors of this widget were:\n'
      '     Semantics\n'
      '     Builder\n'
128
      '     RepaintBoundary-[GlobalKey#00000]\n'
129 130 131 132 133 134 135 136 137 138 139 140 141 142
      '     IgnorePointer\n'
      '     AnimatedBuilder\n'
      '     FadeTransition\n'
      '     FractionalTranslation\n'
      '     SlideTransition\n'
      '     _FadeUpwardsPageTransition\n'
      '     AnimatedBuilder\n'
      '     RepaintBoundary\n'
      '     _FocusMarker\n'
      '     Semantics\n'
      '     FocusScope\n'
      '     PageStorage\n'
      '     Offstage\n'
      '     _ModalScopeStatus\n'
143
      '     _ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#00000]\n'
144
      '     _EffectiveTickerMode\n'
145
      '     TickerMode\n'
146
      '     _OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#00000]\n'
147
      '     _Theatre\n'
148
      '     Overlay-[LabeledGlobalKey<OverlayState>#00000]\n'
149 150 151 152 153 154
      '     _FocusMarker\n'
      '     Semantics\n'
      '     FocusScope\n'
      '     AbsorbPointer\n'
      '     _PointerListener\n'
      '     Listener\n'
155
      '     HeroControllerScope\n'
156
      '     Navigator-[GlobalObjectKey<NavigatorState> _WidgetsAppState#00000]\n'
157 158 159 160 161 162 163 164 165 166 167 168 169 170
      '     IconTheme\n'
      '     IconTheme\n'
      '     _InheritedCupertinoTheme\n'
      '     CupertinoTheme\n'
      '     _InheritedTheme\n'
      '     Theme\n'
      '     AnimatedTheme\n'
      '     Builder\n'
      '     DefaultTextStyle\n'
      '     CustomPaint\n'
      '     Banner\n'
      '     CheckedModeBanner\n'
      '     Title\n'
      '     Directionality\n'
171
      '     _LocalizationsScope-[GlobalKey#00000]\n'
172 173 174 175
      '     Semantics\n'
      '     Localizations\n'
      '     MediaQuery\n'
      '     _MediaQueryFromWindow\n'
176 177 178 179
      '     _FocusMarker\n'
      '     Focus\n'
      '     _FocusTraversalGroupMarker\n'
      '     FocusTraversalGroup\n'
180
      '     _ActionsMarker\n'
181 182 183 184 185 186
      '     Actions\n'
      '     _ShortcutsMarker\n'
      '     Semantics\n'
      '     _FocusMarker\n'
      '     Focus\n'
      '     Shortcuts\n'
187
      '     WidgetsApp-[GlobalObjectKey _MaterialAppState#00000]\n'
188
      '     HeroControllerScope\n'
189 190 191 192 193 194
      '     ScrollConfiguration\n'
      '     MaterialApp\n'
      '     [root]\n'
      '   Typically, the Scaffold widget is introduced by the MaterialApp\n'
      '   or WidgetsApp widget at the top of your application widget tree.\n',
    ));
195 196
  });
}