mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Focus.at() and company should be on Focus, not FocusState. _notifyDescendants() was using the wrong runtimeType. Let InheritedWidget update the descendants during build. When you setState() during build, assert that you're not markNeedsBuild()ing someone who isn't a descendant. Typo in Widget.toString().
131 lines
3.3 KiB
Dart
131 lines
3.3 KiB
Dart
import 'package:sky/widgets.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import 'widget_tester.dart';
|
|
import 'test_widgets.dart';
|
|
|
|
class ProbeWidget extends StatefulComponent {
|
|
ProbeWidgetState createState() => new ProbeWidgetState();
|
|
}
|
|
|
|
class ProbeWidgetState extends State<ProbeWidget> {
|
|
static int buildCount = 0;
|
|
|
|
void initState() {
|
|
super.initState();
|
|
setState(() {});
|
|
}
|
|
|
|
void didUpdateConfig(ProbeWidget oldConfig) {
|
|
setState(() {});
|
|
}
|
|
|
|
Widget build(BuildContext context) {
|
|
setState(() {});
|
|
buildCount++;
|
|
return new Container();
|
|
}
|
|
}
|
|
|
|
class BadWidget extends StatelessComponent {
|
|
BadWidget(this.parentState);
|
|
|
|
final State parentState;
|
|
|
|
Widget build(BuildContext context) {
|
|
parentState.setState(() {});
|
|
return new Container();
|
|
}
|
|
}
|
|
|
|
class BadWidgetParent extends StatefulComponent {
|
|
BadWidgetParentState createState() => new BadWidgetParentState();
|
|
}
|
|
|
|
class BadWidgetParentState extends State<BadWidgetParent> {
|
|
Widget build(BuildContext context) {
|
|
return new BadWidget(this);
|
|
}
|
|
}
|
|
|
|
class BadDisposeWidget extends StatefulComponent {
|
|
BadDisposeWidgetState createState() => new BadDisposeWidgetState();
|
|
}
|
|
|
|
class BadDisposeWidgetState extends State<BadDisposeWidget> {
|
|
Widget build(BuildContext context) {
|
|
return new Container();
|
|
}
|
|
|
|
void dispose() {
|
|
setState(() {});
|
|
super.dispose();
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
dynamic cachedException;
|
|
|
|
// ** WARNING **
|
|
// THIS TEST OVERRIDES THE NORMAL EXCEPTION HANDLING
|
|
// AND DOES NOT REPORT EXCEPTIONS FROM THE FRAMEWORK
|
|
|
|
setUp(() {
|
|
assert(cachedException == null);
|
|
debugWidgetsExceptionHandler = (String context, dynamic exception, StackTrace stack) {
|
|
cachedException = exception;
|
|
};
|
|
});
|
|
|
|
tearDown(() {
|
|
assert(cachedException == null);
|
|
cachedException = null;
|
|
debugWidgetsExceptionHandler = null;
|
|
});
|
|
|
|
test('Legal times for setState', () {
|
|
testWidgets((WidgetTester tester) {
|
|
GlobalKey flipKey = new GlobalKey();
|
|
expect(ProbeWidgetState.buildCount, equals(0));
|
|
tester.pumpWidget(new ProbeWidget());
|
|
expect(ProbeWidgetState.buildCount, equals(1));
|
|
tester.pumpWidget(new ProbeWidget());
|
|
expect(ProbeWidgetState.buildCount, equals(2));
|
|
tester.pumpWidget(new FlipComponent(
|
|
key: flipKey,
|
|
left: new Container(),
|
|
right: new ProbeWidget()
|
|
));
|
|
expect(ProbeWidgetState.buildCount, equals(2));
|
|
(flipKey.currentState as FlipComponentState).flip();
|
|
tester.pump();
|
|
expect(ProbeWidgetState.buildCount, equals(3));
|
|
(flipKey.currentState as FlipComponentState).flip();
|
|
tester.pump();
|
|
expect(ProbeWidgetState.buildCount, equals(3));
|
|
tester.pumpWidget(new Container());
|
|
expect(ProbeWidgetState.buildCount, equals(3));
|
|
});
|
|
});
|
|
|
|
test('Setting parent state during build is forbidden', () {
|
|
testWidgets((WidgetTester tester) {
|
|
expect(cachedException, isNull);
|
|
tester.pumpWidget(new BadWidgetParent());
|
|
expect(cachedException, isNotNull);
|
|
cachedException = null;
|
|
tester.pumpWidget(new Container());
|
|
expect(cachedException, isNull);
|
|
});
|
|
});
|
|
|
|
test('Setting state during dispose is forbidden', () {
|
|
testWidgets((WidgetTester tester) {
|
|
tester.pumpWidget(new BadDisposeWidget());
|
|
expect(() {
|
|
tester.pumpWidget(new Container());
|
|
}, throws);
|
|
});
|
|
});
|
|
}
|