build_scope_test.dart 3.84 KB
Newer Older
Hixie's avatar
Hixie committed
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Adam Barth's avatar
Adam Barth committed
5
import 'package:flutter_test/flutter_test.dart';
6
import 'package:flutter/scheduler.dart';
7
import 'package:flutter/widgets.dart';
8 9
import 'package:test/test.dart';

Adam Barth's avatar
Adam Barth committed
10
import 'test_widgets.dart';
11

12
class ProbeWidget extends StatefulWidget {
13
  @override
14 15 16 17 18 19
  ProbeWidgetState createState() => new ProbeWidgetState();
}

class ProbeWidgetState extends State<ProbeWidget> {
  static int buildCount = 0;

20
  @override
21 22
  void initState() {
    super.initState();
23 24 25
    setState(() {});
  }

26
  @override
27 28 29 30
  void didUpdateConfig(ProbeWidget oldConfig) {
    setState(() {});
  }

31
  @override
32 33 34 35 36 37 38
  Widget build(BuildContext context) {
    setState(() {});
    buildCount++;
    return new Container();
  }
}

39
class BadWidget extends StatelessWidget {
40 41 42 43
  BadWidget(this.parentState);

  final State parentState;

44
  @override
45 46 47 48 49 50
  Widget build(BuildContext context) {
    parentState.setState(() {});
    return new Container();
  }
}

51
class BadWidgetParent extends StatefulWidget {
52
  @override
53 54 55 56
  BadWidgetParentState createState() => new BadWidgetParentState();
}

class BadWidgetParentState extends State<BadWidgetParent> {
57
  @override
58 59 60 61 62
  Widget build(BuildContext context) {
    return new BadWidget(this);
  }
}

63
class BadDisposeWidget extends StatefulWidget {
64
  @override
65 66 67 68
  BadDisposeWidgetState createState() => new BadDisposeWidgetState();
}

class BadDisposeWidgetState extends State<BadDisposeWidget> {
69
  @override
70 71 72 73
  Widget build(BuildContext context) {
    return new Container();
  }

74
  @override
75 76 77 78 79 80 81 82 83
  void dispose() {
    setState(() {});
    super.dispose();
  }
}

void main() {
  dynamic cachedException;

Hixie's avatar
Hixie committed
84 85 86 87
  // ** WARNING **
  // THIS TEST OVERRIDES THE NORMAL EXCEPTION HANDLING
  // AND DOES NOT REPORT EXCEPTIONS FROM THE FRAMEWORK

88 89 90 91 92
  setUp(() {
    assert(cachedException == null);
    debugWidgetsExceptionHandler = (String context, dynamic exception, StackTrace stack) {
      cachedException = exception;
    };
Hixie's avatar
Hixie committed
93
    debugSchedulerExceptionHandler = (dynamic exception, StackTrace stack) { throw exception; };
94 95 96 97 98 99
  });

  tearDown(() {
    assert(cachedException == null);
    cachedException = null;
    debugWidgetsExceptionHandler = null;
Hixie's avatar
Hixie committed
100
    debugSchedulerExceptionHandler = null;
101 102 103
  });

  test('Legal times for setState', () {
104 105 106 107 108 109 110
    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));
111
      tester.pumpWidget(new FlipWidget(
112 113 114 115 116
        key: flipKey,
        left: new Container(),
        right: new ProbeWidget()
      ));
      expect(ProbeWidgetState.buildCount, equals(2));
117
      FlipWidgetState flipState1 = flipKey.currentState;
Hixie's avatar
Hixie committed
118
      flipState1.flip();
119 120
      tester.pump();
      expect(ProbeWidgetState.buildCount, equals(3));
121
      FlipWidgetState flipState2 = flipKey.currentState;
Hixie's avatar
Hixie committed
122
      flipState2.flip();
123 124 125 126 127
      tester.pump();
      expect(ProbeWidgetState.buildCount, equals(3));
      tester.pumpWidget(new Container());
      expect(ProbeWidgetState.buildCount, equals(3));
    });
128 129 130
  });

  test('Setting parent state during build is forbidden', () {
131 132 133 134 135 136 137 138
    testWidgets((WidgetTester tester) {
      expect(cachedException, isNull);
      tester.pumpWidget(new BadWidgetParent());
      expect(cachedException, isNotNull);
      cachedException = null;
      tester.pumpWidget(new Container());
      expect(cachedException, isNull);
    });
139 140 141
  });

  test('Setting state during dispose is forbidden', () {
142 143 144 145 146 147
    testWidgets((WidgetTester tester) {
      tester.pumpWidget(new BadDisposeWidget());
      expect(() {
        tester.pumpWidget(new Container());
      }, throws);
    });
148 149
  });
}