syncing_test.dart 5.44 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.

5
import 'package:flutter/material.dart';
Adam Barth's avatar
Adam Barth committed
6
import 'package:flutter_test/flutter_test.dart';
7

8
class TestWidget extends StatefulWidget {
9
  const TestWidget({
10
    super.key,
11 12 13
    required this.child,
    required this.persistentState,
    required this.syncedState,
14
  });
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
      Container(
54
        color: Colors.blue,
55
        child: Container(
56
          color: Colors.blue,
57
          child: TestWidget(
58
            persistentState: 1,
59
            syncedState: 0,
60 61 62
            child: Container(),
          ),
        ),
63
      ),
64
    );
65

66
    final TestWidgetState state = tester.state(find.byType(TestWidget));
67

68 69
    expect(state.persistentState, equals(1));
    expect(state.updates, equals(0));
70

71
    await tester.pumpWidget(
72
      Container(
73
        color: Colors.blue,
74
        child: Container(
75
          color: Colors.blue,
76
          child: TestWidget(
77
            persistentState: 2,
78
            syncedState: 0,
79 80 81
            child: Container(),
          ),
        ),
82
      ),
83
    );
84

85 86
    expect(state.persistentState, equals(1));
    expect(state.updates, equals(1));
87

88
    await tester.pumpWidget(Container());
89 90
  });

91 92
  testWidgets('remove one', (WidgetTester tester) async {
    await tester.pumpWidget(
93
      Container(
94
        color: Colors.blue,
95
        child: Container(
96
          color: Colors.blue,
97
          child: TestWidget(
98
            persistentState: 10,
99
            syncedState: 0,
100 101 102
            child: Container(),
          ),
        ),
103
      ),
104
    );
105

106
    TestWidgetState state = tester.state(find.byType(TestWidget));
107

108 109
    expect(state.persistentState, equals(10));
    expect(state.updates, equals(0));
110

111
    await tester.pumpWidget(
112
      Container(
113
        color: Colors.green,
114
        child: TestWidget(
115
          persistentState: 11,
116
          syncedState: 0,
117 118
          child: Container(),
        ),
119
      ),
120
    );
121

122
    state = tester.state(find.byType(TestWidget));
123

124 125
    expect(state.persistentState, equals(11));
    expect(state.updates, equals(0));
126

127
    await tester.pumpWidget(Container());
128
  });
129

130
  testWidgets('swap instances around', (WidgetTester tester) async {
131 132
    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));
133
    await tester.pumpWidget(Column());
134

135 136
    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();
137

138
    await tester.pumpWidget(
139
      Column(
140
        children: <Widget>[
141
          Container(
142
            key: keyA,
143
            child: a,
144
          ),
145
          Container(
146
            key: keyB,
147 148 149
            child: b,
          ),
        ],
150
      ),
151 152 153 154
    );

    TestWidgetState first, second;

155 156
    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));
157

158
    expect(first.widget, equals(a));
159 160
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
161
    expect(second.widget, equals(b));
162 163 164
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

165
    await tester.pumpWidget(
166
      Column(
167
        children: <Widget>[
168
          Container(
169
            key: keyA,
170
            child: a,
171
          ),
172
          Container(
173
            key: keyB,
174 175 176
            child: b,
          ),
        ],
177
      ),
178 179
    );

180 181
    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));
182 183

    // same as before
184
    expect(first.widget, equals(a));
185 186
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
187
    expect(second.widget, equals(b));
188 189 190 191 192 193
    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

194
    await tester.pumpWidget(
195
      Column(
196
        children: <Widget>[
197
          Container(
198
            key: keyA,
199
            child: b,
200
          ),
201
          Container(
202
            key: keyB,
203 204 205
            child: a,
          ),
        ],
206
      ),
207 208
    );

209 210
    first = tester.state(find.byWidget(b));
    second = tester.state(find.byWidget(a));
211

212
    expect(first.widget, equals(b));
213 214
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x42));
215
    expect(second.widget, equals(a));
216 217
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x41));
218
  });
219
}