Files
plezy/test/focus/focus_node_ownership_test.dart

109 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/focus/focusable_action_bar.dart';
import 'package:plezy/focus/focusable_text_field.dart';
import 'package:plezy/focus/focusable_wrapper.dart';
void main() {
testWidgets('FocusableWrapper never disposes caller-owned nodes across swaps', (tester) async {
final first = _TrackingFocusNode();
final second = _TrackingFocusNode();
late StateSetter rebuild;
var node = first;
await tester.pumpWidget(
MaterialApp(
home: StatefulBuilder(
builder: (context, setState) {
rebuild = setState;
return FocusableWrapper(focusNode: node, child: const SizedBox(width: 10, height: 10));
},
),
),
);
rebuild(() => node = second);
await tester.pump();
await tester.pumpWidget(const SizedBox.shrink());
expect(first.disposeCalls, 0);
expect(second.disposeCalls, 0);
first.dispose();
second.dispose();
});
testWidgets('FocusableActionBar never disposes caller-owned nodes across swaps', (tester) async {
final first = _TrackingFocusNode();
final second = _TrackingFocusNode();
late StateSetter rebuild;
var node = first;
await tester.pumpWidget(
MaterialApp(
home: StatefulBuilder(
builder: (context, setState) {
rebuild = setState;
return FocusableActionBar(
actions: [FocusableAction(focusNode: node, onPressed: () {})],
);
},
),
),
);
rebuild(() => node = second);
await tester.pump();
await tester.pumpWidget(const SizedBox.shrink());
expect(first.disposeCalls, 0);
expect(second.disposeCalls, 0);
first.dispose();
second.dispose();
});
testWidgets('FocusableTextField never disposes caller-owned nodes across swaps', (tester) async {
final first = _TrackingFocusNode();
final second = _TrackingFocusNode();
final controller = TextEditingController();
late StateSetter rebuild;
var node = first;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: StatefulBuilder(
builder: (context, setState) {
rebuild = setState;
return FocusableTextField(
controller: controller,
focusNode: node,
tvTextInputPresentation: TvTextInputPresentation.platform,
);
},
),
),
),
);
rebuild(() => node = second);
await tester.pump();
await tester.pumpWidget(const SizedBox.shrink());
expect(first.disposeCalls, 0);
expect(second.disposeCalls, 0);
first.dispose();
second.dispose();
controller.dispose();
});
}
class _TrackingFocusNode extends FocusNode {
int disposeCalls = 0;
@override
void dispose() {
disposeCalls++;
super.dispose();
}
}