syncing_test.dart 5.25 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
Hixie's avatar
Hixie committed
2 3 4
// 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/widgets.dart';
7

8
class TestWidget extends StatefulWidget {
9
  const TestWidget({
10 11 12 13
    Key? key,
    required this.child,
    required this.persistentState,
    required this.syncedState,
14
  }) : super(key: key);
15 16 17 18 19

  final Widget child;
  final int persistentState;
  final int syncedState;

20
  @override
21
  TestWidgetState createState() => TestWidgetState();
22 23 24
}

class TestWidgetState extends State<TestWidget> {
25 26
  late int persistentState;
  late int syncedState;
27 28
  int updates = 0;

29
  @override
30 31
  void initState() {
    super.initState();
32 33
    persistentState = widget.persistentState;
    syncedState = widget.syncedState;
34 35
  }

36
  @override
37
  void didUpdateWidget(TestWidget oldWidget) {
38
    super.didUpdateWidget(oldWidget);
39
    syncedState = widget.syncedState;
40
    // we explicitly do NOT sync the persistentState from the new instance
41
    // because we're using that to track whether we got recreated
42
    updates += 1;
43
  }
44

45
  @override
46
  Widget build(BuildContext context) => widget.child;
47 48 49 50
}

void main() {

51 52
  testWidgets('no change', (WidgetTester tester) async {
    await tester.pumpWidget(
53 54 55
      Container(
        child: Container(
          child: TestWidget(
56
            persistentState: 1,
57
            syncedState: 0,
58 59 60
            child: Container(),
          ),
        ),
61
      ),
62
    );
63

64
    final TestWidgetState state = tester.state(find.byType(TestWidget));
65

66 67
    expect(state.persistentState, equals(1));
    expect(state.updates, equals(0));
68

69
    await tester.pumpWidget(
70 71 72
      Container(
        child: Container(
          child: TestWidget(
73
            persistentState: 2,
74
            syncedState: 0,
75 76 77
            child: Container(),
          ),
        ),
78
      ),
79
    );
80

81 82
    expect(state.persistentState, equals(1));
    expect(state.updates, equals(1));
83

84
    await tester.pumpWidget(Container());
85 86
  });

87 88
  testWidgets('remove one', (WidgetTester tester) async {
    await tester.pumpWidget(
89 90 91
      Container(
        child: Container(
          child: TestWidget(
92
            persistentState: 10,
93
            syncedState: 0,
94 95 96
            child: Container(),
          ),
        ),
97
      ),
98
    );
99

100
    TestWidgetState state = tester.state(find.byType(TestWidget));
101

102 103
    expect(state.persistentState, equals(10));
    expect(state.updates, equals(0));
104

105
    await tester.pumpWidget(
106 107
      Container(
        child: TestWidget(
108
          persistentState: 11,
109
          syncedState: 0,
110 111
          child: Container(),
        ),
112
      ),
113
    );
114

115
    state = tester.state(find.byType(TestWidget));
116

117 118
    expect(state.persistentState, equals(11));
    expect(state.updates, equals(0));
119

120
    await tester.pumpWidget(Container());
121
  });
122

123
  testWidgets('swap instances around', (WidgetTester tester) async {
124 125
    const Widget a = TestWidget(persistentState: 0x61, syncedState: 0x41, child: Text('apple', textDirection: TextDirection.ltr));
    const Widget b = TestWidget(persistentState: 0x62, syncedState: 0x42, child: Text('banana', textDirection: TextDirection.ltr));
126
    await tester.pumpWidget(Column());
127

128 129
    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();
130

131
    await tester.pumpWidget(
132
      Column(
133
        children: <Widget>[
134
          Container(
135
            key: keyA,
136
            child: a,
137
          ),
138
          Container(
139
            key: keyB,
140 141 142
            child: b,
          ),
        ],
143
      ),
144 145 146 147
    );

    TestWidgetState first, second;

148 149
    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));
150

151
    expect(first.widget, equals(a));
152 153
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
154
    expect(second.widget, equals(b));
155 156 157
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

158
    await tester.pumpWidget(
159
      Column(
160
        children: <Widget>[
161
          Container(
162
            key: keyA,
163
            child: a,
164
          ),
165
          Container(
166
            key: keyB,
167 168 169
            child: b,
          ),
        ],
170
      ),
171 172
    );

173 174
    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));
175 176

    // same as before
177
    expect(first.widget, equals(a));
178 179
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
180
    expect(second.widget, equals(b));
181 182 183 184 185 186
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

    // now we swap the nodes over
    // since they are both "old" nodes, they shouldn't sync with each other even though they look alike

187
    await tester.pumpWidget(
188
      Column(
189
        children: <Widget>[
190
          Container(
191
            key: keyA,
192
            child: b,
193
          ),
194
          Container(
195
            key: keyB,
196 197 198
            child: a,
          ),
        ],
199
      ),
200 201
    );

202 203
    first = tester.state(find.byWidget(b));
    second = tester.state(find.byWidget(a));
204

205
    expect(first.widget, equals(b));
206 207
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x42));
208
    expect(second.widget, equals(a));
209 210
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x41));
211
  });
212
}