blob: 92f84ccab77369e71e99fd18fc01e64a3cb614b5 [file] [log] [blame]
// Copyright 2014 The Flutter 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/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart' show Vector3;
void main() {
test('BottomNavigationBarThemeData copyWith, ==, hashCode basics', () {
expect(const BottomNavigationBarThemeData(), const BottomNavigationBarThemeData().copyWith());
expect(const BottomNavigationBarThemeData().hashCode, const BottomNavigationBarThemeData().copyWith().hashCode);
});
test('BottomNavigationBarThemeData defaults', () {
const BottomNavigationBarThemeData themeData = BottomNavigationBarThemeData();
expect(themeData.backgroundColor, null);
expect(themeData.elevation, null);
expect(themeData.selectedIconTheme, null);
expect(themeData.unselectedIconTheme, null);
expect(themeData.selectedItemColor, null);
expect(themeData.unselectedItemColor, null);
expect(themeData.selectedLabelStyle, null);
expect(themeData.unselectedLabelStyle, null);
expect(themeData.showSelectedLabels, null);
expect(themeData.showUnselectedLabels, null);
expect(themeData.type, null);
const BottomNavigationBarTheme theme = BottomNavigationBarTheme(data: BottomNavigationBarThemeData(), child: SizedBox());
expect(theme.data.backgroundColor, null);
expect(theme.data.elevation, null);
expect(theme.data.selectedIconTheme, null);
expect(theme.data.unselectedIconTheme, null);
expect(theme.data.selectedItemColor, null);
expect(theme.data.unselectedItemColor, null);
expect(theme.data.selectedLabelStyle, null);
expect(theme.data.unselectedLabelStyle, null);
expect(theme.data.showSelectedLabels, null);
expect(theme.data.showUnselectedLabels, null);
expect(theme.data.type, null);
});
testWidgets('Default BottomNavigationBarThemeData debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const BottomNavigationBarThemeData().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('BottomNavigationBarThemeData implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const BottomNavigationBarThemeData(
backgroundColor: Color(0xfffffff0),
elevation: 10.0,
selectedIconTheme: IconThemeData(size: 1.0),
unselectedIconTheme: IconThemeData(size: 2.0),
selectedItemColor: Color(0xfffffff1),
unselectedItemColor: Color(0xfffffff2),
selectedLabelStyle: TextStyle(fontSize: 3.0),
unselectedLabelStyle: TextStyle(fontSize: 4.0),
showSelectedLabels: true,
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description[0], 'backgroundColor: Color(0xfffffff0)');
expect(description[1], 'elevation: 10.0');
// Ignore instance address for IconThemeData.
expect(description[2].contains('selectedIconTheme: IconThemeData'), isTrue);
expect(description[2].contains('(size: 1.0)'), isTrue);
expect(description[3].contains('unselectedIconTheme: IconThemeData'), isTrue);
expect(description[3].contains('(size: 2.0)'), isTrue);
expect(description[4], 'selectedItemColor: Color(0xfffffff1)');
expect(description[5], 'unselectedItemColor: Color(0xfffffff2)');
expect(description[6], 'selectedLabelStyle: TextStyle(inherit: true, size: 3.0)');
expect(description[7], 'unselectedLabelStyle: TextStyle(inherit: true, size: 4.0)');
expect(description[8], 'showSelectedLabels: true');
expect(description[9], 'showUnselectedLabels: true');
expect(description[10], 'type: BottomNavigationBarType.fixed');
});
testWidgets('BottomNavigationBar is themeable', (WidgetTester tester) async {
const Color backgroundColor = Color(0xFF000001);
const Color selectedItemColor = Color(0xFF000002);
const Color unselectedItemColor = Color(0xFF000003);
const IconThemeData selectedIconTheme = IconThemeData(size: 10);
const IconThemeData unselectedIconTheme = IconThemeData(size: 11);
const TextStyle selectedTextStyle = TextStyle(fontSize: 22);
const TextStyle unselectedTextStyle = TextStyle(fontSize: 21);
const double elevation = 9.0;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: backgroundColor,
selectedItemColor: selectedItemColor,
unselectedItemColor: unselectedItemColor,
selectedIconTheme: selectedIconTheme,
unselectedIconTheme: unselectedIconTheme,
elevation: elevation,
showUnselectedLabels: true,
showSelectedLabels: true,
type: BottomNavigationBarType.fixed,
selectedLabelStyle: selectedTextStyle,
unselectedLabelStyle: unselectedTextStyle,
),
),
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
),
),
),
);
final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);
expect(selectedFontStyle.fontSize, selectedFontStyle.fontSize);
// Unselected label has a font size of 22 but is scaled down to be font size 21.
expect(
tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
equals(Matrix4.diagonal3(Vector3.all(unselectedTextStyle.fontSize! / selectedTextStyle.fontSize!))),
);
expect(selectedIcon.color, equals(selectedItemColor));
expect(selectedIcon.fontSize, equals(selectedIconTheme.size));
expect(unselectedIcon.color, equals(unselectedItemColor));
expect(unselectedIcon.fontSize, equals(unselectedIconTheme.size));
// There should not be any [Opacity] or [FadeTransition] widgets
// since showUnselectedLabels and showSelectedLabels are true.
final Finder findOpacity = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(Opacity),
);
final Finder findFadeTransition = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(FadeTransition),
);
expect(findOpacity, findsNothing);
expect(findFadeTransition, findsNothing);
expect(_material(tester).elevation, equals(elevation));
expect(_material(tester).color, equals(backgroundColor));
});
testWidgets('BottomNavigationBar properties are taken over the theme values', (WidgetTester tester) async {
const Color themeBackgroundColor = Color(0xFF000001);
const Color themeSelectedItemColor = Color(0xFF000002);
const Color themeUnselectedItemColor = Color(0xFF000003);
const IconThemeData themeSelectedIconTheme = IconThemeData(size: 10);
const IconThemeData themeUnselectedIconTheme = IconThemeData(size: 11);
const TextStyle themeSelectedTextStyle = TextStyle(fontSize: 22);
const TextStyle themeUnselectedTextStyle = TextStyle(fontSize: 21);
const double themeElevation = 9.0;
const Color backgroundColor = Color(0xFF000004);
const Color selectedItemColor = Color(0xFF000005);
const Color unselectedItemColor = Color(0xFF000006);
const IconThemeData selectedIconTheme = IconThemeData(size: 15);
const IconThemeData unselectedIconTheme = IconThemeData(size: 16);
const TextStyle selectedTextStyle = TextStyle(fontSize: 25);
const TextStyle unselectedTextStyle = TextStyle(fontSize: 26);
const double elevation = 7.0;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: themeBackgroundColor,
selectedItemColor: themeSelectedItemColor,
unselectedItemColor: themeUnselectedItemColor,
selectedIconTheme: themeSelectedIconTheme,
unselectedIconTheme: themeUnselectedIconTheme,
elevation: themeElevation,
showUnselectedLabels: false,
showSelectedLabels: false,
type: BottomNavigationBarType.shifting,
selectedLabelStyle: themeSelectedTextStyle,
unselectedLabelStyle: themeUnselectedTextStyle,
),
),
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
backgroundColor: backgroundColor,
selectedItemColor: selectedItemColor,
unselectedItemColor: unselectedItemColor,
selectedIconTheme: selectedIconTheme,
unselectedIconTheme: unselectedIconTheme,
elevation: elevation,
showUnselectedLabels: true,
showSelectedLabels: true,
type: BottomNavigationBarType.fixed,
selectedLabelStyle: selectedTextStyle,
unselectedLabelStyle: unselectedTextStyle,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: 'AC',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
label: 'Alarm',
),
],
),
),
),
);
final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);
expect(selectedFontStyle.fontSize, selectedFontStyle.fontSize);
// Unselected label has a font size of 22 but is scaled down to be font size 21.
expect(
tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
equals(Matrix4.diagonal3(Vector3.all(unselectedTextStyle.fontSize! / selectedTextStyle.fontSize!))),
);
expect(selectedIcon.color, equals(selectedItemColor));
expect(selectedIcon.fontSize, equals(selectedIconTheme.size));
expect(unselectedIcon.color, equals(unselectedItemColor));
expect(unselectedIcon.fontSize, equals(unselectedIconTheme.size));
// There should not be any [Opacity] or [FadeTransition] widgets
// since showUnselectedLabels and showSelectedLabels are true.
final Finder findOpacity = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(Opacity),
);
final Finder findFadeTransition = find.descendant(
of: find.byType(BottomNavigationBar),
matching: find.byType(FadeTransition),
);
expect(findOpacity, findsNothing);
expect(findFadeTransition, findsNothing);
expect(_material(tester).elevation, equals(elevation));
expect(_material(tester).color, equals(backgroundColor));
});
}
TextStyle _iconStyle(WidgetTester tester, IconData icon) {
final RichText iconRichText = tester.widget<RichText>(
find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)),
);
return iconRichText.text.style!;
}
Material _material(WidgetTester tester) {
return tester.firstWidget<Material>(
find.descendant(of: find.byType(BottomNavigationBar), matching: find.byType(Material)),
);
}