flutter/packages/unit/test/widget/build_scope_test.dart
Hixie fbf8174c87 Fix Focus
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().
2015-10-05 16:41:50 -07:00

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);
});
});
}