Unverified Commit 67edb63d authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Re-land "Toggable Refactor (#76745)" (#77263)

parent 90f353f9
...@@ -238,12 +238,7 @@ void main() { ...@@ -238,12 +238,7 @@ void main() {
test('Checkbox has correct Android semantics', () async { test('Checkbox has correct Android semantics', () async {
Future<AndroidSemanticsNode> getCheckboxSemantics(String key) async { Future<AndroidSemanticsNode> getCheckboxSemantics(String key) async {
return getSemantics( return getSemantics(find.byValueKey(key));
find.descendant(
of: find.byValueKey(key),
matching: find.byType('_CheckboxRenderObjectWidget'),
),
);
} }
expect( expect(
await getCheckboxSemantics(checkboxKeyValue), await getCheckboxSemantics(checkboxKeyValue),
...@@ -290,12 +285,7 @@ void main() { ...@@ -290,12 +285,7 @@ void main() {
}); });
test('Radio has correct Android semantics', () async { test('Radio has correct Android semantics', () async {
Future<AndroidSemanticsNode> getRadioSemantics(String key) async { Future<AndroidSemanticsNode> getRadioSemantics(String key) async {
return getSemantics( return getSemantics(find.byValueKey(key));
find.descendant(
of: find.byValueKey(key),
matching: find.byType('_RadioRenderObjectWidget'),
),
);
} }
expect( expect(
await getRadioSemantics(radio2KeyValue), await getRadioSemantics(radio2KeyValue),
...@@ -331,12 +321,7 @@ void main() { ...@@ -331,12 +321,7 @@ void main() {
}); });
test('Switch has correct Android semantics', () async { test('Switch has correct Android semantics', () async {
Future<AndroidSemanticsNode> getSwitchSemantics(String key) async { Future<AndroidSemanticsNode> getSwitchSemantics(String key) async {
return getSemantics( return getSemantics(find.byValueKey(key));
find.descendant(
of: find.byValueKey(key),
matching: find.byType('_SwitchRenderObjectWidget'),
),
);
} }
expect( expect(
await getSwitchSemantics(switchKeyValue), await getSwitchSemantics(switchKeyValue),
...@@ -374,12 +359,7 @@ void main() { ...@@ -374,12 +359,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/20820. // Regression test for https://github.com/flutter/flutter/issues/20820.
test('Switch can be labeled', () async { test('Switch can be labeled', () async {
Future<AndroidSemanticsNode> getSwitchSemantics(String key) async { Future<AndroidSemanticsNode> getSwitchSemantics(String key) async {
return getSemantics( return getSemantics(find.byValueKey(key));
find.descendant(
of: find.byValueKey(key),
matching: find.byType('_SwitchRenderObjectWidget'),
),
);
} }
expect( expect(
await getSwitchSemantics(labeledSwitchKeyValue), await getSwitchSemantics(labeledSwitchKeyValue),
......
...@@ -99,7 +99,7 @@ void main() { ...@@ -99,7 +99,7 @@ void main() {
), ),
)); ));
expect(tester.getSemantics(find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_CheckboxRenderObjectWidget')), matchesSemantics( expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true, hasCheckedState: true,
hasEnabledState: true, hasEnabledState: true,
// isFocusable is delayed by 1 frame. // isFocusable is delayed by 1 frame.
...@@ -108,7 +108,7 @@ void main() { ...@@ -108,7 +108,7 @@ void main() {
await tester.pump(); await tester.pump();
// isFocusable should be false now after the 1 frame delay. // isFocusable should be false now after the 1 frame delay.
expect(tester.getSemantics(find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_CheckboxRenderObjectWidget')), matchesSemantics( expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true, hasCheckedState: true,
hasEnabledState: true, hasEnabledState: true,
)); ));
...@@ -120,7 +120,7 @@ void main() { ...@@ -120,7 +120,7 @@ void main() {
), ),
)); ));
expect(tester.getSemantics(find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_CheckboxRenderObjectWidget')), matchesSemantics( expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true, hasCheckedState: true,
hasEnabledState: true, hasEnabledState: true,
isChecked: true, isChecked: true,
...@@ -290,7 +290,7 @@ void main() { ...@@ -290,7 +290,7 @@ void main() {
); );
await tester.tap(find.byType(Checkbox)); await tester.tap(find.byType(Checkbox));
final RenderObject object = tester.firstRenderObject(find.byType(Focus)); final RenderObject object = tester.firstRenderObject(find.byType(Checkbox));
expect(checkboxValue, true); expect(checkboxValue, true);
expect(semanticEvent, <String, dynamic>{ expect(semanticEvent, <String, dynamic>{
...@@ -319,10 +319,8 @@ void main() { ...@@ -319,10 +319,8 @@ void main() {
); );
} }
RenderToggleable getCheckboxRenderer() { RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderToggleable>(find.byWidgetPredicate((Widget widget) { return tester.renderObject<RenderBox>(find.byType(Checkbox));
return widget.runtimeType.toString() == '_CheckboxRenderObjectWidget';
}));
} }
await tester.pumpWidget(buildFrame(false)); await tester.pumpWidget(buildFrame(false));
...@@ -377,10 +375,8 @@ void main() { ...@@ -377,10 +375,8 @@ void main() {
); );
} }
RenderToggleable getCheckboxRenderer() { RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderToggleable>(find.byWidgetPredicate((Widget widget) { return tester.renderObject<RenderBox>(find.byType(Checkbox));
return widget.runtimeType.toString() == '_CheckboxRenderObjectWidget';
}));
} }
await tester.pumpWidget(buildFrame(checkColor: checkColor)); await tester.pumpWidget(buildFrame(checkColor: checkColor));
...@@ -453,11 +449,10 @@ void main() { ...@@ -453,11 +449,10 @@ void main() {
paints paints
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..drrect( ..drrect(
color: const Color(0x8a000000), color: const Color(0x8a000000),
outer: RRect.fromLTRBR( outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
391.0, 291.0, 409.0, 309.0, const Radius.circular(1.0)), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, const Radius.circular(-1.0)),
inner: RRect.fromLTRBR(393.0, ),
293.0, 407.0, 307.0, const Radius.circular(-1.0))),
); );
// Check what happens when disabled. // Check what happens when disabled.
...@@ -469,11 +464,10 @@ void main() { ...@@ -469,11 +464,10 @@ void main() {
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
paints paints
..drrect( ..drrect(
color: const Color(0x61000000), color: const Color(0x61000000),
outer: RRect.fromLTRBR( outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
391.0, 291.0, 409.0, 309.0, const Radius.circular(1.0)), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, const Radius.circular(-1.0)),
inner: RRect.fromLTRBR(393.0, ),
293.0, 407.0, 307.0, const Radius.circular(-1.0))),
); );
}); });
...@@ -825,10 +819,8 @@ void main() { ...@@ -825,10 +819,8 @@ void main() {
); );
} }
RenderToggleable getCheckboxRenderer() { RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderToggleable>(find.byWidgetPredicate((Widget widget) { return tester.renderObject<RenderBox>(find.byType(Checkbox));
return widget.runtimeType.toString() == '_CheckboxRenderObjectWidget';
}));
} }
await tester.pumpWidget(buildFrame(enabled: true)); await tester.pumpWidget(buildFrame(enabled: true));
...@@ -878,10 +870,8 @@ void main() { ...@@ -878,10 +870,8 @@ void main() {
); );
} }
RenderToggleable getCheckboxRenderer() { RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderToggleable>(find.byWidgetPredicate((Widget widget) { return tester.renderObject<RenderBox>(find.byType(Checkbox));
return widget.runtimeType.toString() == '_CheckboxRenderObjectWidget';
}));
} }
await tester.pumpWidget(buildFrame()); await tester.pumpWidget(buildFrame());
...@@ -937,11 +927,9 @@ void main() { ...@@ -937,11 +927,9 @@ void main() {
paints paints
..drrect( ..drrect(
color: const Color(0xfff44336), color: const Color(0xfff44336),
outer: RRect.fromLTRBR( outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(5)),
391.0, 291.0, 409.0, 309.0, const Radius.circular(5)), inner: RRect.fromLTRBR(19.0, 19.0, 29.0, 29.0, const Radius.circular(1)),
inner: RRect.fromLTRBR( ),
395.0, 295.0, 405.0, 305.0, const Radius.circular(1)))
,
); );
}); });
...@@ -1184,6 +1172,29 @@ void main() { ...@@ -1184,6 +1172,29 @@ void main() {
await gesture.up(); await gesture.up();
}); });
testWidgets('Do not crash when widget disappears while pointer is down', (WidgetTester tester) async {
Widget buildCheckbox(bool show) {
return MaterialApp(
home: Material(
child: Center(
child: show ? Checkbox(value: true, onChanged: (_) { }) : Container(),
),
),
);
}
await tester.pumpWidget(buildCheckbox(true));
final Offset center = tester.getCenter(find.byType(Checkbox));
// Put a pointer down on the screen.
final TestGesture gesture = await tester.startGesture(center);
await tester.pump();
// While the pointer is down, the widget disappears.
await tester.pumpWidget(buildCheckbox(false));
expect(find.byType(Checkbox), findsNothing);
// Release pointer after widget disappeared.
gesture.up();
});
} }
class _SelectedGrabMouseCursor extends MaterialStateMouseCursor { class _SelectedGrabMouseCursor extends MaterialStateMouseCursor {
......
...@@ -308,7 +308,7 @@ void main() { ...@@ -308,7 +308,7 @@ void main() {
)); ));
await tester.tap(find.byKey(key)); await tester.tap(find.byKey(key));
final RenderObject object = tester.firstRenderObject(find.byType(Focus)); final RenderObject object = tester.firstRenderObject(find.byKey(key));
expect(radioValue, 1); expect(radioValue, 1);
expect(semanticEvent, <String, dynamic>{ expect(semanticEvent, <String, dynamic>{
...@@ -1078,4 +1078,29 @@ void main() { ...@@ -1078,4 +1078,29 @@ void main() {
reason: 'Hovered Radio should use overlay color $hoverOverlayColor over $hoverColor', reason: 'Hovered Radio should use overlay color $hoverOverlayColor over $hoverColor',
); );
}); });
testWidgets('Do not crash when widget disappears while pointer is down', (WidgetTester tester) async {
final Key key = UniqueKey();
Widget buildRadio(bool show) {
return MaterialApp(
home: Material(
child: Center(
child: show ? Radio<bool>(key: key, value: true, groupValue: false, onChanged: (_) { }) : Container(),
)
),
);
}
await tester.pumpWidget(buildRadio(true));
final Offset center = tester.getCenter(find.byKey(key));
// Put a pointer down on the screen.
final TestGesture gesture = await tester.startGesture(center);
await tester.pump();
// While the pointer is down, the widget disappears.
await tester.pumpWidget(buildRadio(false));
expect(find.byKey(key), findsNothing);
// Release pointer after widget disappeared.
gesture.up();
});
} }
...@@ -37,7 +37,7 @@ void main() { ...@@ -37,7 +37,7 @@ void main() {
expect(log, equals(<dynamic>[false, '-', false])); expect(log, equals(<dynamic>[false, '-', false]));
}); });
testWidgets('SwitchListTile control test', (WidgetTester tester) async { testWidgets('SwitchListTile semantics test', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: Column( child: Column(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment