import 'package:sky/src/fn3.dart'; import 'package:test/test.dart'; import '../fn3/widget_tester.dart'; class TestWidget extends StatefulComponent { TestWidget({ this.child, this.persistentState, this.syncedState }); final Widget child; final int persistentState; final int syncedState; TestWidgetState createState() => new TestWidgetState(); } class TestWidgetState extends State { int persistentState; int syncedState; int updates = 0; void initState(BuildContext context) { super.initState(context); persistentState = config.persistentState; syncedState = config.syncedState; } void didUpdateConfig(TestWidget oldConfig) { syncedState = config.syncedState; // we explicitly do NOT sync the persistentState from the new instance // because we're using that to track whether we got recreated updates += 1; } Widget build(BuildContext context) => config.child; } void main() { test('no change', () { WidgetTester tester = new WidgetTester(); tester.pumpFrame( new Container( child: new Container( child: new TestWidget( persistentState: 1, child: new Container() ) ) ) ); TestWidgetState state = tester.findStateOfType(TestWidgetState); expect(state.persistentState, equals(1)); expect(state.updates, equals(0)); tester.pumpFrame( new Container( child: new Container( child: new TestWidget( persistentState: 2, child: new Container() ) ) ) ); expect(state.persistentState, equals(1)); expect(state.updates, equals(1)); tester.pumpFrame(new Container()); }); test('remove one', () { WidgetTester tester = new WidgetTester(); tester.pumpFrame( new Container( child: new Container( child: new TestWidget( persistentState: 10, child: new Container() ) ) ) ); TestWidgetState state = tester.findStateOfType(TestWidgetState); expect(state.persistentState, equals(10)); expect(state.updates, equals(0)); tester.pumpFrame( new Container( child: new TestWidget( persistentState: 11, child: new Container() ) ) ); state = tester.findStateOfType(TestWidgetState); expect(state.persistentState, equals(11)); expect(state.updates, equals(0)); tester.pumpFrame(new Container()); }); test('swap instances around', () { WidgetTester tester = new WidgetTester(); Widget a = new TestWidget(persistentState: 0x61, syncedState: 0x41, child: new Text('apple')); Widget b = new TestWidget(persistentState: 0x62, syncedState: 0x42, child: new Text('banana')); tester.pumpFrame(new Column([])); GlobalKey keyA = new GlobalKey(); GlobalKey keyB = new GlobalKey(); tester.pumpFrame( new Column([ new Container( key: keyA, child: a ), new Container( key: keyB, child: b ) ]) ); TestWidgetState first, second; first = tester.findStateByConfig(a); second = tester.findStateByConfig(b); expect(first.config, equals(a)); expect(first.persistentState, equals(0x61)); expect(first.syncedState, equals(0x41)); expect(second.config, equals(b)); expect(second.persistentState, equals(0x62)); expect(second.syncedState, equals(0x42)); tester.pumpFrame( new Column([ new Container( key: keyA, child: a ), new Container( key: keyB, child: b ) ]) ); first = tester.findStateByConfig(a); second = tester.findStateByConfig(b); // same as before expect(first.config, equals(a)); expect(first.persistentState, equals(0x61)); expect(first.syncedState, equals(0x41)); expect(second.config, equals(b)); 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 tester.pumpFrame( new Column([ new Container( key: keyA, child: b ), new Container( key: keyB, child: a ) ]) ); first = tester.findStateByConfig(b); second = tester.findStateByConfig(a); expect(first.config, equals(b)); expect(first.persistentState, equals(0x61)); expect(first.syncedState, equals(0x42)); expect(second.config, equals(a)); expect(second.persistentState, equals(0x62)); expect(second.syncedState, equals(0x41)); }); }