banner_theme_test.dart 7.27 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('MaterialBannerThemeData copyWith, ==, hashCode basics', () {
    expect(const MaterialBannerThemeData(), const MaterialBannerThemeData().copyWith());
    expect(const MaterialBannerThemeData().hashCode, const MaterialBannerThemeData().copyWith().hashCode);
  });

  test('MaterialBannerThemeData null fields by default', () {
    const MaterialBannerThemeData bannerTheme = MaterialBannerThemeData();
    expect(bannerTheme.backgroundColor, null);
    expect(bannerTheme.contentTextStyle, null);
  });

  testWidgets('Default MaterialBannerThemeData debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const MaterialBannerThemeData().debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

    expect(description, <String>[]);
  });

  testWidgets('MaterialBannerThemeData implements debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const MaterialBannerThemeData(
      backgroundColor: Color(0xFFFFFFFF),
      contentTextStyle: TextStyle(color: Color(0xFFFFFFFF)),
    ).debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

    expect(description, <String>[
      'backgroundColor: Color(0xffffffff)',
      'contentTextStyle: TextStyle(inherit: true, color: Color(0xffffffff))',
    ]);
  });

  testWidgets('Passing no MaterialBannerThemeData returns defaults', (WidgetTester tester) async {
    const String contentText = 'Content';
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: MaterialBanner(
          content: const Text(contentText),
          actions: <Widget>[
58
            TextButton(
59 60 61 62 63 64 65 66 67 68
              child: const Text('Action'),
              onPressed: () { },
            ),
          ],
        ),
      ),
    ));

    final Container container = _getContainerFromBanner(tester);
    final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
69
    expect(container.color, const Color(0xffffffff));
70
    // Default value for ThemeData.typography is Typography.material2014()
71
    expect(content.text.style, Typography.material2014().englishLike.bodyText2!.merge(Typography.material2014().black.bodyText2));
72 73 74 75 76 77 78 79 80 81 82 83
  });

  testWidgets('MaterialBanner uses values from MaterialBannerThemeData', (WidgetTester tester) async {
    final MaterialBannerThemeData bannerTheme = _bannerTheme();
    const String contentText = 'Content';
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(bannerTheme: bannerTheme),
      home: Scaffold(
        body: MaterialBanner(
          leading: const Icon(Icons.ac_unit),
          content: const Text(contentText),
          actions: <Widget>[
84
            TextButton(
85 86 87 88 89 90 91 92 93 94
              child: const Text('Action'),
              onPressed: () { },
            ),
          ],
        ),
      ),
    ));

    final Container container = _getContainerFromBanner(tester);
    final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
95
    expect(container.color, bannerTheme.backgroundColor);
96 97 98 99 100 101
    expect(content.text.style, bannerTheme.contentTextStyle);

    final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
    final Offset containerTopLeft = tester.getTopLeft(_containerFinder());
    final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
    expect(contentTopLeft.dy - containerTopLeft.dy, 24);
102
    expect(contentTopLeft.dx - containerTopLeft.dx, 41);
103
    expect(leadingTopLeft.dy - containerTopLeft.dy, 19);
104
    expect(leadingTopLeft.dx - containerTopLeft.dx, 11);
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  });

  testWidgets('MaterialBanner widget properties take priority over theme', (WidgetTester tester) async {
    const Color backgroundColor = Colors.purple;
    const TextStyle textStyle = TextStyle(color: Colors.green);
    final MaterialBannerThemeData bannerTheme = _bannerTheme();
    const String contentText = 'Content';
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(bannerTheme: bannerTheme),
      home: Scaffold(
        body: MaterialBanner(
          backgroundColor: backgroundColor,
          leading: const Icon(Icons.ac_unit),
          contentTextStyle: textStyle,
          content: const Text(contentText),
          padding: const EdgeInsets.all(10),
121
          leadingPadding: const EdgeInsets.all(12),
122
          actions: <Widget>[
123
            TextButton(
124 125 126 127 128 129 130 131 132 133
              child: const Text('Action'),
              onPressed: () { },
            ),
          ],
        ),
      ),
    ));

    final Container container = _getContainerFromBanner(tester);
    final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
134
    expect(container.color, backgroundColor);
135 136 137 138 139 140
    expect(content.text.style, textStyle);

    final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
    final Offset containerTopLeft = tester.getTopLeft(_containerFinder());
    final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
    expect(contentTopLeft.dy - containerTopLeft.dy, 29);
141
    expect(contentTopLeft.dx - containerTopLeft.dx, 58);
142
    expect(leadingTopLeft.dy - containerTopLeft.dy, 24);
143
    expect(leadingTopLeft.dx - containerTopLeft.dx, 22);
144 145 146 147 148 149 150 151 152 153
  });

  testWidgets('MaterialBanner uses color scheme when necessary', (WidgetTester tester) async {
    final ColorScheme colorScheme = const ColorScheme.light().copyWith(surface: Colors.purple);
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(colorScheme: colorScheme),
      home: Scaffold(
        body: MaterialBanner(
          content: const Text('Content'),
          actions: <Widget>[
154
            TextButton(
155 156 157 158 159 160 161 162 163
              child: const Text('Action'),
              onPressed: () { },
            ),
          ],
        ),
      ),
    ));

    final Container container = _getContainerFromBanner(tester);
164
    expect(container.color, colorScheme.surface);
165 166 167 168 169 170 171 172
  });
}

MaterialBannerThemeData _bannerTheme() {
  return const MaterialBannerThemeData(
    backgroundColor: Colors.orange,
    contentTextStyle: TextStyle(color: Colors.pink),
    padding: EdgeInsets.all(5),
173
    leadingPadding: EdgeInsets.all(6),
174 175 176 177 178 179 180 181 182 183 184 185
  );
}

Container _getContainerFromBanner(WidgetTester tester) {
  return tester.widget<Container>(_containerFinder());
}

Finder _containerFinder() {
  return find.descendant(of: find.byType(MaterialBanner), matching: find.byType(Container)).first;
}

RenderParagraph _getTextRenderObjectFromDialog(WidgetTester tester, String text) {
186
  return tester.element<StatelessElement>(_textFinder(text)).renderObject! as RenderParagraph;
187 188 189 190
}

Finder _textFinder(String text) {
  return find.descendant(of: find.byType(MaterialBanner), matching: find.text(text));
191
}