mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
WIP Commits separated as follows: - Update lints in analysis_options files - Run `dart fix --apply` - Clean up leftover analysis issues - Run `dart format .` in the right places. Local analysis and testing passes. Checking CI now. Part of https://github.com/flutter/flutter/issues/178827 - Adoption of flutter_lints in examples/api coming in a separate change (cc @loic-sharma) ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
583 lines
22 KiB
Dart
583 lines
22 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/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
test('CheckboxThemeData copyWith, ==, hashCode basics', () {
|
|
expect(const CheckboxThemeData(), const CheckboxThemeData().copyWith());
|
|
expect(const CheckboxThemeData().hashCode, const CheckboxThemeData().copyWith().hashCode);
|
|
});
|
|
|
|
test('CheckboxThemeData lerp special cases', () {
|
|
expect(CheckboxThemeData.lerp(null, null, 0), const CheckboxThemeData());
|
|
const data = CheckboxThemeData();
|
|
expect(identical(CheckboxThemeData.lerp(data, data, 0.5), data), true);
|
|
});
|
|
|
|
test('CheckboxThemeData defaults', () {
|
|
const themeData = CheckboxThemeData();
|
|
expect(themeData.mouseCursor, null);
|
|
expect(themeData.fillColor, null);
|
|
expect(themeData.checkColor, null);
|
|
expect(themeData.overlayColor, null);
|
|
expect(themeData.splashRadius, null);
|
|
expect(themeData.materialTapTargetSize, null);
|
|
expect(themeData.visualDensity, null);
|
|
|
|
const theme = CheckboxTheme(data: CheckboxThemeData(), child: SizedBox());
|
|
expect(theme.data.mouseCursor, null);
|
|
expect(theme.data.fillColor, null);
|
|
expect(theme.data.checkColor, null);
|
|
expect(theme.data.overlayColor, null);
|
|
expect(theme.data.splashRadius, null);
|
|
expect(theme.data.materialTapTargetSize, null);
|
|
expect(theme.data.visualDensity, null);
|
|
});
|
|
|
|
testWidgets('Default CheckboxThemeData debugFillProperties', (WidgetTester tester) async {
|
|
final builder = DiagnosticPropertiesBuilder();
|
|
const CheckboxThemeData().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('CheckboxThemeData implements debugFillProperties', (WidgetTester tester) async {
|
|
final builder = DiagnosticPropertiesBuilder();
|
|
const CheckboxThemeData(
|
|
mouseCursor: MaterialStatePropertyAll<MouseCursor?>(SystemMouseCursors.click),
|
|
fillColor: MaterialStatePropertyAll<Color>(Color(0xfffffff0)),
|
|
checkColor: MaterialStatePropertyAll<Color>(Color(0xfffffff1)),
|
|
overlayColor: MaterialStatePropertyAll<Color>(Color(0xfffffff2)),
|
|
splashRadius: 1.0,
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
visualDensity: VisualDensity.standard,
|
|
).debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(
|
|
description,
|
|
equalsIgnoringHashCodes(<String>[
|
|
'mouseCursor: WidgetStatePropertyAll(SystemMouseCursor(click))',
|
|
'fillColor: WidgetStatePropertyAll(${const Color(0xfffffff0)})',
|
|
'checkColor: WidgetStatePropertyAll(${const Color(0xfffffff1)})',
|
|
'overlayColor: WidgetStatePropertyAll(${const Color(0xfffffff2)})',
|
|
'splashRadius: 1.0',
|
|
'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap',
|
|
'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)',
|
|
]),
|
|
);
|
|
});
|
|
|
|
testWidgets('Checkbox is themeable', (WidgetTester tester) async {
|
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
|
|
|
const MouseCursor mouseCursor = SystemMouseCursors.text;
|
|
const defaultFillColor = Color(0xfffffff0);
|
|
const selectedFillColor = Color(0xfffffff1);
|
|
const defaultCheckColor = Color(0xfffffff2);
|
|
const focusedCheckColor = Color(0xfffffff3);
|
|
const focusOverlayColor = Color(0xfffffff4);
|
|
const hoverOverlayColor = Color(0xfffffff5);
|
|
const splashRadius = 1.0;
|
|
const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
|
|
const visualDensity = VisualDensity(vertical: 1.0, horizontal: 1.0);
|
|
|
|
Widget buildCheckbox({bool selected = false, bool autofocus = false}) {
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
checkboxTheme: CheckboxThemeData(
|
|
mouseCursor: const MaterialStatePropertyAll<MouseCursor?>(mouseCursor),
|
|
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
return selectedFillColor;
|
|
}
|
|
return defaultFillColor;
|
|
}),
|
|
checkColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.focused)) {
|
|
return focusedCheckColor;
|
|
}
|
|
return defaultCheckColor;
|
|
}),
|
|
overlayColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.focused)) {
|
|
return focusOverlayColor;
|
|
}
|
|
if (states.contains(WidgetState.hovered)) {
|
|
return hoverOverlayColor;
|
|
}
|
|
return null;
|
|
}),
|
|
splashRadius: splashRadius,
|
|
materialTapTargetSize: materialTapTargetSize,
|
|
visualDensity: visualDensity,
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: Checkbox(onChanged: (bool? value) {}, value: selected, autofocus: autofocus),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Checkbox.
|
|
await tester.pumpWidget(buildCheckbox());
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: defaultFillColor));
|
|
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
|
|
expect(
|
|
tester.getSize(find.byType(Checkbox)),
|
|
const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment,
|
|
);
|
|
|
|
// Selected checkbox.
|
|
await tester.pumpWidget(buildCheckbox(selected: true));
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: selectedFillColor));
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints
|
|
..path(color: selectedFillColor)
|
|
..path(color: defaultCheckColor),
|
|
);
|
|
|
|
// Checkbox with hover.
|
|
await tester.pumpWidget(buildCheckbox());
|
|
await _pointGestureToCheckbox(tester);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
|
|
SystemMouseCursors.text,
|
|
);
|
|
expect(_getCheckboxMaterial(tester), paints..circle(color: hoverOverlayColor));
|
|
|
|
// Checkbox with focus.
|
|
await tester.pumpWidget(buildCheckbox(autofocus: true, selected: true));
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints..circle(color: focusOverlayColor, radius: splashRadius),
|
|
);
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints
|
|
..path(color: selectedFillColor)
|
|
..path(color: focusedCheckColor),
|
|
);
|
|
});
|
|
|
|
testWidgets('Checkbox properties are taken over the theme values', (WidgetTester tester) async {
|
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
|
|
|
const MouseCursor themeMouseCursor = SystemMouseCursors.click;
|
|
const themeDefaultFillColor = Color(0xfffffff0);
|
|
const themeSelectedFillColor = Color(0xfffffff1);
|
|
const themeCheckColor = Color(0xfffffff2);
|
|
const themeFocusOverlayColor = Color(0xfffffff3);
|
|
const themeHoverOverlayColor = Color(0xfffffff4);
|
|
const themeSplashRadius = 1.0;
|
|
const MaterialTapTargetSize themeMaterialTapTargetSize = MaterialTapTargetSize.padded;
|
|
const VisualDensity themeVisualDensity = VisualDensity.standard;
|
|
|
|
const MouseCursor mouseCursor = SystemMouseCursors.text;
|
|
const defaultFillColor = Color(0xfffffff5);
|
|
const selectedFillColor = Color(0xfffffff6);
|
|
const checkColor = Color(0xfffffff7);
|
|
const focusColor = Color(0xfffffff8);
|
|
const hoverColor = Color(0xfffffff9);
|
|
const splashRadius = 2.0;
|
|
const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
|
|
const VisualDensity visualDensity = VisualDensity.standard;
|
|
|
|
Widget buildCheckbox({bool selected = false, bool autofocus = false}) {
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
checkboxTheme: CheckboxThemeData(
|
|
mouseCursor: const MaterialStatePropertyAll<MouseCursor?>(themeMouseCursor),
|
|
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
return themeSelectedFillColor;
|
|
}
|
|
return themeDefaultFillColor;
|
|
}),
|
|
checkColor: const MaterialStatePropertyAll<Color?>(themeCheckColor),
|
|
overlayColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.focused)) {
|
|
return themeFocusOverlayColor;
|
|
}
|
|
if (states.contains(WidgetState.hovered)) {
|
|
return themeHoverOverlayColor;
|
|
}
|
|
return null;
|
|
}),
|
|
splashRadius: themeSplashRadius,
|
|
materialTapTargetSize: themeMaterialTapTargetSize,
|
|
visualDensity: themeVisualDensity,
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: Checkbox(
|
|
onChanged: (bool? value) {},
|
|
value: selected,
|
|
autofocus: autofocus,
|
|
mouseCursor: mouseCursor,
|
|
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
return selectedFillColor;
|
|
}
|
|
return defaultFillColor;
|
|
}),
|
|
checkColor: checkColor,
|
|
focusColor: focusColor,
|
|
hoverColor: hoverColor,
|
|
splashRadius: splashRadius,
|
|
materialTapTargetSize: materialTapTargetSize,
|
|
visualDensity: visualDensity,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Checkbox.
|
|
await tester.pumpWidget(buildCheckbox());
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: defaultFillColor));
|
|
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
|
|
expect(
|
|
tester.getSize(find.byType(Checkbox)),
|
|
const Size(40.0, 40.0) + visualDensity.baseSizeAdjustment,
|
|
);
|
|
|
|
// Selected checkbox.
|
|
await tester.pumpWidget(buildCheckbox(selected: true));
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: selectedFillColor));
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints
|
|
..path(color: selectedFillColor)
|
|
..path(color: checkColor),
|
|
);
|
|
|
|
// Checkbox with hover.
|
|
await tester.pumpWidget(buildCheckbox());
|
|
await _pointGestureToCheckbox(tester);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
|
|
SystemMouseCursors.text,
|
|
);
|
|
expect(_getCheckboxMaterial(tester), paints..circle(color: hoverColor));
|
|
|
|
// Checkbox with focus.
|
|
await tester.pumpWidget(buildCheckbox(autofocus: true));
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..circle(color: focusColor, radius: splashRadius));
|
|
});
|
|
|
|
testWidgets('Checkbox activeColor property is taken over the theme', (WidgetTester tester) async {
|
|
const themeSelectedFillColor = Color(0xfffffff1);
|
|
const themeDefaultFillColor = Color(0xfffffff0);
|
|
const selectedFillColor = Color(0xfffffff6);
|
|
|
|
Widget buildCheckbox({bool selected = false}) {
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
checkboxTheme: CheckboxThemeData(
|
|
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
return themeSelectedFillColor;
|
|
}
|
|
return themeDefaultFillColor;
|
|
}),
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: Checkbox(
|
|
onChanged: (bool? value) {},
|
|
value: selected,
|
|
activeColor: selectedFillColor,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Unselected checkbox.
|
|
await tester.pumpWidget(buildCheckbox());
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: themeDefaultFillColor));
|
|
|
|
// Selected checkbox.
|
|
await tester.pumpWidget(buildCheckbox(selected: true));
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: selectedFillColor));
|
|
});
|
|
|
|
testWidgets('Checkbox theme overlay color resolves in active/pressed states', (
|
|
WidgetTester tester,
|
|
) async {
|
|
const activePressedOverlayColor = Color(0xFF000001);
|
|
const inactivePressedOverlayColor = Color(0xFF000002);
|
|
|
|
Color? getOverlayColor(Set<WidgetState> states) {
|
|
if (states.contains(WidgetState.pressed)) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
return activePressedOverlayColor;
|
|
}
|
|
return inactivePressedOverlayColor;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const splashRadius = 24.0;
|
|
|
|
Widget buildCheckbox({required bool active}) {
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
checkboxTheme: CheckboxThemeData(
|
|
overlayColor: WidgetStateProperty.resolveWith(getOverlayColor),
|
|
splashRadius: splashRadius,
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: Checkbox(value: active, onChanged: (_) {}),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildCheckbox(active: false));
|
|
final TestGesture gesture1 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints..circle(color: inactivePressedOverlayColor, radius: splashRadius),
|
|
reason: 'Inactive pressed Checkbox should have overlay color: $inactivePressedOverlayColor',
|
|
);
|
|
|
|
await tester.pumpWidget(buildCheckbox(active: true));
|
|
final TestGesture gesture2 = await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints..circle(color: activePressedOverlayColor, radius: splashRadius),
|
|
reason: 'Active pressed Checkbox should have overlay color: $activePressedOverlayColor',
|
|
);
|
|
|
|
// Finish gesture to release resources.
|
|
await gesture1.up();
|
|
await gesture2.up();
|
|
await tester.pumpAndSettle();
|
|
});
|
|
|
|
testWidgets('Local CheckboxTheme can override global CheckboxTheme', (WidgetTester tester) async {
|
|
const globalThemeFillColor = Color(0xfffffff1);
|
|
const globalThemeCheckColor = Color(0xff000000);
|
|
const localThemeFillColor = Color(0xffff0000);
|
|
const localThemeCheckColor = Color(0xffffffff);
|
|
|
|
Widget buildCheckbox({required bool active}) {
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
checkboxTheme: const CheckboxThemeData(
|
|
checkColor: MaterialStatePropertyAll<Color>(globalThemeCheckColor),
|
|
fillColor: MaterialStatePropertyAll<Color>(globalThemeFillColor),
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: CheckboxTheme(
|
|
data: const CheckboxThemeData(
|
|
fillColor: MaterialStatePropertyAll<Color>(localThemeFillColor),
|
|
checkColor: MaterialStatePropertyAll<Color>(localThemeCheckColor),
|
|
),
|
|
child: Checkbox(value: active, onChanged: (_) {}),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildCheckbox(active: true));
|
|
await tester.pumpAndSettle();
|
|
expect(_getCheckboxMaterial(tester), paints..path(color: localThemeFillColor));
|
|
expect(
|
|
_getCheckboxMaterial(tester),
|
|
paints
|
|
..path(color: localThemeFillColor)
|
|
..path(color: localThemeCheckColor),
|
|
);
|
|
});
|
|
|
|
test('CheckboxThemeData lerp with null parameters', () {
|
|
final CheckboxThemeData lerped = CheckboxThemeData.lerp(null, null, 0.25);
|
|
|
|
expect(lerped.mouseCursor, null);
|
|
expect(lerped.fillColor, null);
|
|
expect(lerped.checkColor, null);
|
|
expect(lerped.overlayColor, null);
|
|
expect(lerped.splashRadius, null);
|
|
expect(lerped.materialTapTargetSize, null);
|
|
expect(lerped.visualDensity, null);
|
|
expect(lerped.shape, null);
|
|
expect(lerped.side, null);
|
|
});
|
|
|
|
test('CheckboxThemeData lerp from populated to null parameters', () {
|
|
final theme = CheckboxThemeData(
|
|
fillColor: WidgetStateProperty.all(const Color(0xfffffff0)),
|
|
checkColor: WidgetStateProperty.all(const Color(0xfffffff1)),
|
|
overlayColor: WidgetStateProperty.all(const Color(0xfffffff2)),
|
|
splashRadius: 3.0,
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
visualDensity: const VisualDensity(vertical: 1.0, horizontal: 1.0),
|
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))),
|
|
side: const BorderSide(width: 4.0),
|
|
);
|
|
final CheckboxThemeData lerped = CheckboxThemeData.lerp(theme, null, 0.5);
|
|
|
|
expect(lerped.fillColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0x80fffff0)));
|
|
expect(lerped.checkColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0x80fffff1)));
|
|
expect(lerped.overlayColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0x80fffff2)));
|
|
expect(lerped.splashRadius, 1.5);
|
|
expect(lerped.materialTapTargetSize, null);
|
|
expect(lerped.visualDensity, null);
|
|
expect(
|
|
lerped.shape,
|
|
const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))),
|
|
);
|
|
expect(lerped.side!.width, 2.0);
|
|
expect(lerped.side!.color, isSameColorAs(const Color(0x80000000)));
|
|
});
|
|
|
|
test('CheckboxThemeData lerp from null to populated parameters', () {
|
|
final theme = CheckboxThemeData(
|
|
fillColor: WidgetStateProperty.all(const Color(0xfffffff0)),
|
|
checkColor: WidgetStateProperty.all(const Color(0xfffffff1)),
|
|
overlayColor: WidgetStateProperty.all(const Color(0xfffffff2)),
|
|
splashRadius: 4.0,
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
visualDensity: const VisualDensity(vertical: 1.0, horizontal: 1.0),
|
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))),
|
|
side: const BorderSide(width: 4.0),
|
|
);
|
|
final CheckboxThemeData lerped = CheckboxThemeData.lerp(null, theme, 0.25);
|
|
|
|
expect(
|
|
lerped.fillColor!.resolve(const <WidgetState>{}),
|
|
isSameColorAs(const Color(0x40fffff0)),
|
|
);
|
|
expect(
|
|
lerped.checkColor!.resolve(const <WidgetState>{}),
|
|
isSameColorAs(const Color(0x40fffff1)),
|
|
);
|
|
expect(
|
|
lerped.overlayColor!.resolve(const <WidgetState>{}),
|
|
isSameColorAs(const Color(0x40fffff2)),
|
|
);
|
|
expect(lerped.splashRadius, 1);
|
|
expect(lerped.materialTapTargetSize, null);
|
|
expect(lerped.visualDensity, null);
|
|
expect(
|
|
lerped.shape,
|
|
const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(1.0))),
|
|
);
|
|
expect(lerped.side!.width, 1.0);
|
|
expect(lerped.side!.color, isSameColorAs(const Color(0x40000000)));
|
|
});
|
|
|
|
test('CheckboxThemeData lerp from populated parameters', () {
|
|
final themeA = CheckboxThemeData(
|
|
fillColor: WidgetStateProperty.all(const Color(0xfffffff0)),
|
|
checkColor: WidgetStateProperty.all(const Color(0xfffffff1)),
|
|
overlayColor: WidgetStateProperty.all(const Color(0xfffffff2)),
|
|
splashRadius: 3.0,
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
visualDensity: const VisualDensity(vertical: 1.0, horizontal: 1.0),
|
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))),
|
|
side: const BorderSide(width: 4.0),
|
|
);
|
|
final themeB = CheckboxThemeData(
|
|
fillColor: WidgetStateProperty.all(const Color(0xfffffff3)),
|
|
checkColor: WidgetStateProperty.all(const Color(0xfffffff4)),
|
|
overlayColor: WidgetStateProperty.all(const Color(0xfffffff5)),
|
|
splashRadius: 9.0,
|
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
visualDensity: const VisualDensity(vertical: 2.0, horizontal: 2.0),
|
|
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(1.0))),
|
|
side: const BorderSide(width: 3.0),
|
|
);
|
|
final CheckboxThemeData lerped = CheckboxThemeData.lerp(themeA, themeB, 0.5);
|
|
|
|
expect(lerped.fillColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0xfffffff1)));
|
|
expect(lerped.checkColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0xfffffff2)));
|
|
expect(lerped.overlayColor!.resolve(<WidgetState>{}), isSameColorAs(const Color(0xfffffff3)));
|
|
expect(lerped.splashRadius, 6);
|
|
expect(lerped.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
|
|
expect(lerped.visualDensity, const VisualDensity(vertical: 2.0, horizontal: 2.0));
|
|
expect(
|
|
lerped.shape,
|
|
const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.5))),
|
|
);
|
|
expect(lerped.side, const BorderSide(width: 3.5));
|
|
});
|
|
|
|
testWidgets('WidgetStateBorderSide properly lerp in CheckboxThemeData.side', (
|
|
WidgetTester tester,
|
|
) async {
|
|
late ColorScheme colorScheme;
|
|
|
|
Widget buildCheckbox({required Color seedColor}) {
|
|
colorScheme = ColorScheme.fromSeed(seedColor: seedColor);
|
|
return MaterialApp(
|
|
theme: ThemeData(
|
|
colorScheme: colorScheme,
|
|
checkboxTheme: CheckboxThemeData(
|
|
side: WidgetStateBorderSide.resolveWith((Set<WidgetState> states) {
|
|
return BorderSide(color: colorScheme.primary, width: 4.0);
|
|
}),
|
|
),
|
|
),
|
|
home: Scaffold(body: Checkbox(value: false, onChanged: (_) {})),
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildCheckbox(seedColor: Colors.red));
|
|
await tester.pumpAndSettle();
|
|
|
|
RenderBox getCheckboxRenderBox() {
|
|
return tester.renderObject<RenderBox>(find.byType(Checkbox));
|
|
}
|
|
|
|
expect(getCheckboxRenderBox(), paints..drrect(color: colorScheme.primary));
|
|
|
|
await tester.pumpWidget(buildCheckbox(seedColor: Colors.blue));
|
|
await tester.pump(kPressTimeout);
|
|
|
|
expect(getCheckboxRenderBox(), paints..drrect(color: colorScheme.primary));
|
|
});
|
|
}
|
|
|
|
Future<void> _pointGestureToCheckbox(WidgetTester tester) async {
|
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
|
await gesture.addPointer();
|
|
addTearDown(gesture.removePointer);
|
|
await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
|
|
}
|
|
|
|
MaterialInkController? _getCheckboxMaterial(WidgetTester tester) {
|
|
return Material.of(tester.element(find.byType(Checkbox)));
|
|
}
|