
* Make Flex,Row,Column const for real * dart fix --apply * fix snippets * fix integration test * add comment
626 lines
20 KiB
Dart
626 lines
20 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';
|
|
|
|
import '../rendering/mock_canvas.dart';
|
|
|
|
Widget boilerplate({required Widget child}) {
|
|
return Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(child: child),
|
|
);
|
|
}
|
|
|
|
void main() {
|
|
test('ToggleButtonsThemeData copyWith, ==, hashCode basics', () {
|
|
expect(const ToggleButtonsThemeData(), const ToggleButtonsThemeData().copyWith());
|
|
expect(const ToggleButtonsThemeData().hashCode, const ToggleButtonsThemeData().copyWith().hashCode);
|
|
});
|
|
|
|
test('ToggleButtonsThemeData defaults', () {
|
|
const ToggleButtonsThemeData themeData = ToggleButtonsThemeData();
|
|
expect(themeData.textStyle, null);
|
|
expect(themeData.constraints, null);
|
|
expect(themeData.color, null);
|
|
expect(themeData.selectedColor, null);
|
|
expect(themeData.disabledColor, null);
|
|
expect(themeData.fillColor, null);
|
|
expect(themeData.focusColor, null);
|
|
expect(themeData.highlightColor, null);
|
|
expect(themeData.hoverColor, null);
|
|
expect(themeData.splashColor, null);
|
|
expect(themeData.borderColor, null);
|
|
expect(themeData.selectedBorderColor, null);
|
|
expect(themeData.disabledBorderColor, null);
|
|
expect(themeData.borderRadius, null);
|
|
expect(themeData.borderWidth, null);
|
|
|
|
const ToggleButtonsTheme theme = ToggleButtonsTheme(data: ToggleButtonsThemeData(), child: SizedBox());
|
|
expect(theme.data.textStyle, null);
|
|
expect(theme.data.constraints, null);
|
|
expect(theme.data.color, null);
|
|
expect(theme.data.selectedColor, null);
|
|
expect(theme.data.disabledColor, null);
|
|
expect(theme.data.fillColor, null);
|
|
expect(theme.data.focusColor, null);
|
|
expect(theme.data.highlightColor, null);
|
|
expect(theme.data.hoverColor, null);
|
|
expect(theme.data.splashColor, null);
|
|
expect(theme.data.borderColor, null);
|
|
expect(theme.data.selectedBorderColor, null);
|
|
expect(theme.data.disabledBorderColor, null);
|
|
expect(theme.data.borderRadius, null);
|
|
expect(theme.data.borderWidth, null);
|
|
});
|
|
|
|
testWidgets('Default ToggleButtonsThemeData debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
const ToggleButtonsThemeData().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('ToggleButtonsThemeData implements debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
const ToggleButtonsThemeData(
|
|
textStyle: TextStyle(fontSize: 10),
|
|
constraints: BoxConstraints(minHeight: 10.0, maxHeight: 20.0),
|
|
color: Color(0xfffffff0),
|
|
selectedColor: Color(0xfffffff1),
|
|
disabledColor: Color(0xfffffff2),
|
|
fillColor: Color(0xfffffff3),
|
|
focusColor: Color(0xfffffff4),
|
|
highlightColor: Color(0xfffffff5),
|
|
hoverColor: Color(0xfffffff6),
|
|
splashColor: Color(0xfffffff7),
|
|
borderColor: Color(0xfffffff8),
|
|
selectedBorderColor: Color(0xfffffff9),
|
|
disabledBorderColor: Color(0xfffffffa),
|
|
borderRadius: BorderRadius.all(Radius.circular(4.0)),
|
|
borderWidth: 2.0,
|
|
).debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(description, <String>[
|
|
'textStyle.inherit: true',
|
|
'textStyle.size: 10.0',
|
|
'constraints: BoxConstraints(0.0<=w<=Infinity, 10.0<=h<=20.0)',
|
|
'color: Color(0xfffffff0)',
|
|
'selectedColor: Color(0xfffffff1)',
|
|
'disabledColor: Color(0xfffffff2)',
|
|
'fillColor: Color(0xfffffff3)',
|
|
'focusColor: Color(0xfffffff4)',
|
|
'highlightColor: Color(0xfffffff5)',
|
|
'hoverColor: Color(0xfffffff6)',
|
|
'splashColor: Color(0xfffffff7)',
|
|
'borderColor: Color(0xfffffff8)',
|
|
'selectedBorderColor: Color(0xfffffff9)',
|
|
'disabledBorderColor: Color(0xfffffffa)',
|
|
'borderRadius: BorderRadius.circular(4.0)',
|
|
'borderWidth: 2.0',
|
|
]);
|
|
});
|
|
|
|
testWidgets('Theme text style, except color, is applied', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
textStyle: TextStyle(
|
|
color: Colors.orange,
|
|
textBaseline: TextBaseline.ideographic,
|
|
fontSize: 20.0,
|
|
),
|
|
),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[false, true],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
Text('Second child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
TextStyle textStyle;
|
|
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
|
of: find.widgetWithText(TextButton, 'First child'),
|
|
matching: find.byType(DefaultTextStyle),
|
|
)).style;
|
|
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
|
expect(textStyle.fontSize, 20.0);
|
|
expect(textStyle.color, isNot(Colors.orange));
|
|
|
|
textStyle = tester.widget<DefaultTextStyle>(find.descendant(
|
|
of: find.widgetWithText(TextButton, 'Second child'),
|
|
matching: find.byType(DefaultTextStyle),
|
|
)).style;
|
|
expect(textStyle.textBaseline, TextBaseline.ideographic);
|
|
expect(textStyle.fontSize, 20.0);
|
|
expect(textStyle.color, isNot(Colors.orange));
|
|
});
|
|
|
|
testWidgets('Custom BoxConstraints', (WidgetTester tester) async {
|
|
// Test for minimum constraints
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
constraints: BoxConstraints(
|
|
minWidth: 50.0,
|
|
minHeight: 60.0,
|
|
),
|
|
),
|
|
child: ToggleButtons(
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
isSelected: const <bool>[false, false, false],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Icon(Icons.check),
|
|
Icon(Icons.access_alarm),
|
|
Icon(Icons.cake),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
Rect firstRect = tester.getRect(find.byType(TextButton).at(0));
|
|
expect(firstRect.width, 50.0);
|
|
expect(firstRect.height, 60.0);
|
|
Rect secondRect = tester.getRect(find.byType(TextButton).at(1));
|
|
expect(secondRect.width, 50.0);
|
|
expect(secondRect.height, 60.0);
|
|
Rect thirdRect = tester.getRect(find.byType(TextButton).at(2));
|
|
expect(thirdRect.width, 50.0);
|
|
expect(thirdRect.height, 60.0);
|
|
|
|
// Test for maximum constraints
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
constraints: BoxConstraints(
|
|
maxWidth: 20.0,
|
|
maxHeight: 10.0,
|
|
),
|
|
),
|
|
child: ToggleButtons(
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
isSelected: const <bool>[false, false, false],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Icon(Icons.check),
|
|
Icon(Icons.access_alarm),
|
|
Icon(Icons.cake),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
firstRect = tester.getRect(find.byType(TextButton).at(0));
|
|
expect(firstRect.width, 20.0);
|
|
expect(firstRect.height, 10.0);
|
|
secondRect = tester.getRect(find.byType(TextButton).at(1));
|
|
expect(secondRect.width, 20.0);
|
|
expect(secondRect.height, 10.0);
|
|
thirdRect = tester.getRect(find.byType(TextButton).at(2));
|
|
expect(thirdRect.width, 20.0);
|
|
expect(thirdRect.height, 10.0);
|
|
});
|
|
|
|
testWidgets(
|
|
'Theme text/icon colors for enabled, selected and disabled states',
|
|
(WidgetTester tester) async {
|
|
TextStyle buttonTextStyle(String text) {
|
|
return tester.widget<DefaultTextStyle>(find.descendant(
|
|
of: find.widgetWithText(TextButton, text),
|
|
matching: find.byType(DefaultTextStyle),
|
|
)).style;
|
|
}
|
|
IconTheme iconTheme(IconData icon) {
|
|
return tester.widget(find.descendant(
|
|
of: find.widgetWithIcon(TextButton, icon),
|
|
matching: find.byType(IconTheme),
|
|
));
|
|
}
|
|
final ThemeData theme = ThemeData();
|
|
const Color enabledColor = Colors.lime;
|
|
const Color selectedColor = Colors.green;
|
|
const Color disabledColor = Colors.yellow;
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(),
|
|
child: ToggleButtons(
|
|
color: enabledColor,
|
|
isSelected: const <bool>[false],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
// This Row is used like this to test for both TextStyle
|
|
// and IconTheme for Text and Icon widgets respectively.
|
|
Row(children: <Widget>[
|
|
Text('First child'),
|
|
Icon(Icons.check),
|
|
]),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
// Custom theme enabled color
|
|
expect(theme.colorScheme.onSurface, isNot(enabledColor));
|
|
expect(buttonTextStyle('First child').color, enabledColor);
|
|
expect(iconTheme(Icons.check).data.color, enabledColor);
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
selectedColor: selectedColor,
|
|
),
|
|
child: ToggleButtons(
|
|
color: enabledColor,
|
|
isSelected: const <bool>[true],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Row(children: <Widget>[
|
|
Text('First child'),
|
|
Icon(Icons.check),
|
|
]),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
// Custom theme selected color
|
|
expect(theme.colorScheme.primary, isNot(selectedColor));
|
|
expect(buttonTextStyle('First child').color, selectedColor);
|
|
expect(iconTheme(Icons.check).data.color, selectedColor);
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
disabledColor: disabledColor,
|
|
),
|
|
child: ToggleButtons(
|
|
color: enabledColor,
|
|
isSelected: const <bool>[false],
|
|
children: const <Widget>[
|
|
Row(children: <Widget>[
|
|
Text('First child'),
|
|
Icon(Icons.check),
|
|
]),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
// Custom theme disabled color
|
|
expect(theme.disabledColor, isNot(disabledColor));
|
|
expect(buttonTextStyle('First child').color, disabledColor);
|
|
expect(iconTheme(Icons.check).data.color, disabledColor);
|
|
},
|
|
);
|
|
|
|
testWidgets('Theme button fillColor', (WidgetTester tester) async {
|
|
const Color customFillColor = Colors.green;
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(fillColor: customFillColor),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[true],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Row(children: <Widget>[
|
|
Text('First child'),
|
|
]),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = tester.widget<Material>(find.descendant(
|
|
of: find.byType(TextButton),
|
|
matching: find.byType(Material),
|
|
));
|
|
expect(material.color, customFillColor);
|
|
expect(material.type, MaterialType.button);
|
|
});
|
|
|
|
testWidgets('Custom Theme button fillColor in different states', (WidgetTester tester) async {
|
|
Material buttonColor(String text) {
|
|
return tester.widget<Material>(
|
|
find.descendant(
|
|
of: find.byType(TextButton),
|
|
matching: find.widgetWithText(Material, text),
|
|
),
|
|
);
|
|
}
|
|
|
|
const Color enabledFillColor = Colors.green;
|
|
const Color selectedFillColor = Colors.blue;
|
|
const Color disabledFillColor = Colors.yellow;
|
|
|
|
Color getColor(Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return selectedFillColor;
|
|
} else if (states.contains(MaterialState.disabled)) {
|
|
return disabledFillColor;
|
|
}
|
|
return enabledFillColor;
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: ToggleButtonsThemeData(fillColor: MaterialStateColor.resolveWith(getColor)),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[true, false],
|
|
onPressed: (int index) {},
|
|
children: const <Widget> [
|
|
Text('First child'),
|
|
Text('Second child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(buttonColor('First child').color, selectedFillColor);
|
|
expect(buttonColor('Second child').color, enabledFillColor);
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: ToggleButtonsThemeData(fillColor: MaterialStateColor.resolveWith(getColor)),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[true, false],
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
Text('Second child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(buttonColor('First child').color, disabledFillColor);
|
|
expect(buttonColor('Second child').color, disabledFillColor);
|
|
});
|
|
|
|
testWidgets('Theme InkWell colors', (WidgetTester tester) async {
|
|
const Color splashColor = Color(0xff4caf50);
|
|
const Color highlightColor = Color(0xffcddc39);
|
|
const Color hoverColor = Color(0xffffeb3b);
|
|
const Color focusColor = Color(0xffffff00);
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
splashColor: splashColor,
|
|
highlightColor: highlightColor,
|
|
hoverColor: hoverColor,
|
|
focusColor: focusColor,
|
|
),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[true],
|
|
onPressed: (int index) {},
|
|
focusNodes: <FocusNode>[focusNode],
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Offset center = tester.getCenter(find.text('First child'));
|
|
|
|
// splashColor
|
|
// highlightColor
|
|
final TestGesture touchGesture = await tester.createGesture();
|
|
await touchGesture.down(center);
|
|
await tester.pumpAndSettle();
|
|
|
|
RenderObject inkFeatures;
|
|
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_RenderInkFeatures';
|
|
});
|
|
expect(
|
|
inkFeatures,
|
|
paints
|
|
..circle(color: splashColor)
|
|
);
|
|
|
|
await touchGesture.up();
|
|
await tester.pumpAndSettle();
|
|
|
|
// hoverColor
|
|
final TestGesture hoverGesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await hoverGesture.addPointer();
|
|
await hoverGesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
|
|
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_RenderInkFeatures';
|
|
});
|
|
expect(inkFeatures, paints..rect(color: hoverColor));
|
|
await hoverGesture.moveTo(Offset.zero);
|
|
|
|
// focusColor
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_RenderInkFeatures';
|
|
});
|
|
expect(inkFeatures, paints..rect(color: focusColor));
|
|
|
|
await hoverGesture.removePointer();
|
|
});
|
|
|
|
testWidgets(
|
|
'Theme border width and border colors for enabled, selected and disabled states',
|
|
(WidgetTester tester) async {
|
|
const Color borderColor = Color(0xff4caf50);
|
|
const Color selectedBorderColor = Color(0xffcddc39);
|
|
const Color disabledBorderColor = Color(0xffffeb3b);
|
|
const double customWidth = 2.0;
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
borderColor: borderColor,
|
|
borderWidth: customWidth,
|
|
),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[false],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
RenderObject toggleButtonRenderObject;
|
|
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
|
});
|
|
expect(
|
|
toggleButtonRenderObject,
|
|
paints
|
|
// physical model layer paint
|
|
..path()
|
|
..path(
|
|
style: PaintingStyle.stroke,
|
|
color: borderColor,
|
|
strokeWidth: customWidth,
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
selectedBorderColor: selectedBorderColor,
|
|
borderWidth: customWidth,
|
|
),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[true],
|
|
onPressed: (int index) {},
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
|
});
|
|
expect(
|
|
toggleButtonRenderObject,
|
|
paints
|
|
// physical model layer paint
|
|
..path()
|
|
..path(
|
|
style: PaintingStyle.stroke,
|
|
color: selectedBorderColor,
|
|
strokeWidth: customWidth,
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
Material(
|
|
child: boilerplate(
|
|
child: ToggleButtonsTheme(
|
|
data: const ToggleButtonsThemeData(
|
|
disabledBorderColor: disabledBorderColor,
|
|
borderWidth: customWidth,
|
|
),
|
|
child: ToggleButtons(
|
|
isSelected: const <bool>[false],
|
|
children: const <Widget>[
|
|
Text('First child'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
|
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
|
});
|
|
expect(
|
|
toggleButtonRenderObject,
|
|
paints
|
|
// physical model layer paint
|
|
..path()
|
|
..path(
|
|
style: PaintingStyle.stroke,
|
|
color: disabledBorderColor,
|
|
strokeWidth: customWidth,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|