290 lines
10 KiB
Dart
290 lines
10 KiB
Dart
// 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);
|
|
expect(theme.applyThemeToAll, false);
|
|
});
|
|
|
|
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 originalTheme = CupertinoThemeData(brightness: Brightness.dark, applyThemeToAll: true);
|
|
|
|
final CupertinoThemeData theme = await testTheme(
|
|
tester,
|
|
originalTheme.copyWith(primaryColor: CupertinoColors.systemGreen, applyThemeToAll: false),
|
|
);
|
|
|
|
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));
|
|
|
|
expect(theme.applyThemeToAll, false);
|
|
});
|
|
|
|
testWidgets("Theme has default IconThemeData, which is derived from the theme's primary color", (
|
|
WidgetTester tester,
|
|
) async {
|
|
const CupertinoDynamicColor primaryColor = CupertinoColors.systemRed;
|
|
const 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 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',
|
|
'applyThemeToAll',
|
|
'textStyle',
|
|
'actionTextStyle',
|
|
'actionSmallTextStyle',
|
|
'tabLabelTextStyle',
|
|
'navTitleTextStyle',
|
|
'navLargeTitleTextStyle',
|
|
'navActionTextStyle',
|
|
'pickerTextStyle',
|
|
'dateTimePickerTextStyle',
|
|
'selectionHandleColor',
|
|
}),
|
|
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: CupertinoColors.transparent),
|
|
child: SizedBox(),
|
|
).toStringDeep().trimRight(),
|
|
isNot(contains('\n')),
|
|
);
|
|
});
|
|
|
|
testWidgets('CupertinoThemeData equality', (WidgetTester tester) async {
|
|
const a = CupertinoThemeData(brightness: Brightness.dark);
|
|
final CupertinoThemeData b = a.copyWith();
|
|
final CupertinoThemeData c = a.copyWith(brightness: Brightness.light);
|
|
expect(a, equals(b));
|
|
expect(b, equals(a));
|
|
expect(a, isNot(equals(c)));
|
|
expect(c, isNot(equals(a)));
|
|
expect(b, isNot(equals(c)));
|
|
expect(c, isNot(equals(b)));
|
|
});
|
|
|
|
testWidgets('NoDefaultCupertinoThemeData equality', (WidgetTester tester) async {
|
|
const a = NoDefaultCupertinoThemeData();
|
|
final NoDefaultCupertinoThemeData b = a.copyWith();
|
|
final NoDefaultCupertinoThemeData c = a.copyWith(brightness: Brightness.light);
|
|
expect(a, equals(b));
|
|
expect(a, isNot(c));
|
|
});
|
|
|
|
late Brightness currentBrightness;
|
|
void colorMatches(Color? componentColor, Color expectedDynamicColor) {
|
|
if (expectedDynamicColor is CupertinoDynamicColor) {
|
|
switch (currentBrightness) {
|
|
case Brightness.light:
|
|
expect(componentColor, isSameColorAs(expectedDynamicColor.color));
|
|
case Brightness.dark:
|
|
expect(componentColor, isSameColorAs(expectedDynamicColor.darkColor));
|
|
}
|
|
} else {
|
|
expect(componentColor, isSameColorAs(expectedDynamicColor));
|
|
}
|
|
}
|
|
|
|
void dynamicColorsTestGroup() {
|
|
testWidgets('CupertinoTheme.of resolves colors', (WidgetTester tester) async {
|
|
final 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 data = CupertinoThemeData(brightness: currentBrightness, primaryColor: primaryColor);
|
|
|
|
const barBackgroundColor = CupertinoDynamicColor.withBrightness(
|
|
color: Color(0xF0F9F9F9),
|
|
darkColor: Color(0xF01D1D1D),
|
|
);
|
|
|
|
final CupertinoThemeData theme = await testTheme(tester, data);
|
|
|
|
colorMatches(theme.primaryContrastingColor, CupertinoColors.white);
|
|
colorMatches(theme.barBackgroundColor, barBackgroundColor);
|
|
colorMatches(theme.scaffoldBackgroundColor, CupertinoColors.systemBackground);
|
|
colorMatches(theme.selectionHandleColor, CupertinoColors.systemBlue);
|
|
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);
|
|
}
|