blob: 87b8665abc4aaa5240ad1d28514a799a6b2c83d3 [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/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
int buildCount = 0;
CupertinoThemeData? actualTheme;
IconThemeData? actualIconTheme;
final Widget singletonThemeSubtree = Builder(
builder: (BuildContext context) {
buildCount++;
actualTheme = CupertinoTheme.of(context);
actualIconTheme = IconTheme.of(context);
return const Placeholder();
},
);
Future<CupertinoThemeData> testTheme(WidgetTester tester, CupertinoThemeData theme) async {
await tester.pumpWidget(
CupertinoTheme(
data: theme,
child: singletonThemeSubtree,
),
);
return actualTheme!;
}
Future<IconThemeData> testIconTheme(WidgetTester tester, CupertinoThemeData theme) async {
await tester.pumpWidget(
CupertinoTheme(
data: theme,
child: singletonThemeSubtree,
),
);
return actualIconTheme!;
}
void main() {
setUp(() {
buildCount = 0;
actualTheme = null;
actualIconTheme = null;
});
testWidgets('Default theme has defaults', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, const CupertinoThemeData());
expect(theme.brightness, isNull);
expect(theme.primaryColor, CupertinoColors.activeBlue);
expect(theme.textTheme.textStyle.fontSize, 17.0);
});
testWidgets('Theme attributes cascade', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, const CupertinoThemeData(
primaryColor: CupertinoColors.systemRed,
));
expect(theme.textTheme.actionTextStyle.color, isSameColorAs(CupertinoColors.systemRed.color));
});
testWidgets('Dependent attribute can be overridden from cascaded value', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, const CupertinoThemeData(
brightness: Brightness.dark,
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(color: CupertinoColors.black),
),
));
// The brightness still cascaded down to the background color.
expect(theme.scaffoldBackgroundColor, isSameColorAs(CupertinoColors.black));
// But not to the font color which we overrode.
expect(theme.textTheme.textStyle.color, isSameColorAs(CupertinoColors.black));
});
testWidgets(
'Reading themes creates dependencies',
(WidgetTester tester) async {
// Reading the theme creates a dependency.
CupertinoThemeData theme = await testTheme(tester, const CupertinoThemeData(
// Default brightness is light,
barBackgroundColor: Color(0x11223344),
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(fontFamily: 'Skeuomorphic'),
),
));
expect(buildCount, 1);
expect(theme.textTheme.textStyle.fontFamily, 'Skeuomorphic');
// Changing another property also triggers a rebuild.
theme = await testTheme(tester, const CupertinoThemeData(
brightness: Brightness.light,
barBackgroundColor: Color(0x11223344),
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(fontFamily: 'Skeuomorphic'),
),
));
expect(buildCount, 2);
// Re-reading the same value doesn't change anything.
expect(theme.textTheme.textStyle.fontFamily, 'Skeuomorphic');
theme = await testTheme(tester, const CupertinoThemeData(
brightness: Brightness.light,
barBackgroundColor: Color(0x11223344),
textTheme: CupertinoTextThemeData(
textStyle: TextStyle(fontFamily: 'Flat'),
),
));
expect(buildCount, 3);
expect(theme.textTheme.textStyle.fontFamily, 'Flat');
},
);
testWidgets(
'copyWith works',
(WidgetTester tester) async {
const CupertinoThemeData originalTheme = CupertinoThemeData(
brightness: Brightness.dark,
);
final CupertinoThemeData theme = await testTheme(tester, originalTheme.copyWith(
primaryColor: CupertinoColors.systemGreen,
));
expect(theme.brightness, Brightness.dark);
expect(theme.primaryColor, isSameColorAs(CupertinoColors.systemGreen.darkColor));
// Now check calculated derivatives.
expect(theme.textTheme.actionTextStyle.color, isSameColorAs(CupertinoColors.systemGreen.darkColor));
expect(theme.scaffoldBackgroundColor, isSameColorAs(CupertinoColors.black));
},
);
testWidgets("Theme has default IconThemeData, which is derived from the theme's primary color", (WidgetTester tester) async {
const CupertinoDynamicColor primaryColor = CupertinoColors.systemRed;
const CupertinoThemeData themeData = CupertinoThemeData(primaryColor: primaryColor);
final IconThemeData resultingIconTheme = await testIconTheme(tester, themeData);
expect(resultingIconTheme.color, isSameColorAs(primaryColor));
// Works in dark mode if primaryColor is a CupertinoDynamicColor.
final Color darkColor = (await testIconTheme(
tester,
themeData.copyWith(brightness: Brightness.dark),
)).color!;
expect(darkColor, isSameColorAs(primaryColor.darkColor));
});
testWidgets('IconTheme.of creates a dependency on iconTheme', (WidgetTester tester) async {
IconThemeData iconTheme = await testIconTheme(tester, const CupertinoThemeData(primaryColor: CupertinoColors.destructiveRed));
expect(buildCount, 1);
expect(iconTheme.color, CupertinoColors.destructiveRed);
iconTheme = await testIconTheme(tester, const CupertinoThemeData(primaryColor: CupertinoColors.activeOrange));
expect(buildCount, 2);
expect(iconTheme.color, CupertinoColors.activeOrange);
});
testWidgets('CupertinoTheme diagnostics', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const CupertinoThemeData().debugFillProperties(builder);
final Set<String> description = builder.properties
.map((DiagnosticsNode node) => node.name.toString())
.toSet();
expect(
setEquals(
description,
<String>{
'brightness',
'primaryColor',
'primaryContrastingColor',
'barBackgroundColor',
'scaffoldBackgroundColor',
'textStyle',
'actionTextStyle',
'tabLabelTextStyle',
'navTitleTextStyle',
'navLargeTitleTextStyle',
'navActionTextStyle',
'pickerTextStyle',
'dateTimePickerTextStyle',
},
),
isTrue,
);
});
testWidgets('CupertinoTheme.toStringDeep uses single-line style', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/47651.
expect(
const CupertinoTheme(
data: CupertinoThemeData(primaryColor: Color(0x00000000)),
child: SizedBox(),
).toStringDeep().trimRight(),
isNot(contains('\n')),
);
});
late Brightness currentBrightness;
void colorMatches(Color? componentColor, CupertinoDynamicColor expectedDynamicColor) {
switch (currentBrightness) {
case Brightness.light:
expect(componentColor, isSameColorAs(expectedDynamicColor.color));
break;
case Brightness.dark:
expect(componentColor, isSameColorAs(expectedDynamicColor.darkColor));
break;
}
}
void dynamicColorsTestGroup() {
testWidgets('CupertinoTheme.of resolves colors', (WidgetTester tester) async {
final CupertinoThemeData data = CupertinoThemeData(brightness: currentBrightness, primaryColor: CupertinoColors.systemRed);
final CupertinoThemeData theme = await testTheme(tester, data);
expect(data.primaryColor, isSameColorAs(CupertinoColors.systemRed));
colorMatches(theme.primaryColor, CupertinoColors.systemRed);
});
testWidgets('CupertinoTheme.of resolves default values', (WidgetTester tester) async {
const CupertinoDynamicColor primaryColor = CupertinoColors.systemRed;
final CupertinoThemeData data = CupertinoThemeData(brightness: currentBrightness, primaryColor: primaryColor);
const CupertinoDynamicColor barBackgroundColor = CupertinoDynamicColor.withBrightness(
color: Color(0xF0F9F9F9),
darkColor: Color(0xF01D1D1D),
);
final CupertinoThemeData theme = await testTheme(tester, data);
colorMatches(theme.primaryContrastingColor, CupertinoColors.systemBackground);
colorMatches(theme.barBackgroundColor, barBackgroundColor);
colorMatches(theme.scaffoldBackgroundColor, CupertinoColors.systemBackground);
colorMatches(theme.textTheme.textStyle.color, CupertinoColors.label);
colorMatches(theme.textTheme.actionTextStyle.color, primaryColor);
colorMatches(theme.textTheme.tabLabelTextStyle.color, CupertinoColors.inactiveGray);
colorMatches(theme.textTheme.navTitleTextStyle.color, CupertinoColors.label);
colorMatches(theme.textTheme.navLargeTitleTextStyle.color, CupertinoColors.label);
colorMatches(theme.textTheme.navActionTextStyle.color, primaryColor);
colorMatches(theme.textTheme.pickerTextStyle.color, CupertinoColors.label);
colorMatches(theme.textTheme.dateTimePickerTextStyle.color, CupertinoColors.label);
});
}
currentBrightness = Brightness.light;
group('light colors', dynamicColorsTestGroup);
currentBrightness = Brightness.dark;
group('dark colors', dynamicColorsTestGroup);
}