mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
261 lines
9.4 KiB
Dart
261 lines
9.4 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);
|
|
});
|
|
|
|
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);
|
|
}
|