Files
clide/test/terminal/ui/ui_widget_test.dart
T
jpmschweitzerandClaude Opus 4.7 94ff623708 remove dead Scrollable-era widgets + simulateScroll param
Three widgets under lib/src/terminal/src/ui/ and one TerminalView
parameter were leftovers from the era when TerminalView wrapped its
viewport in a real Scrollable. The Scrollable path was replaced with
PointerScrollEvent → PgUp/PgDown translation (alive, well-tested in
terminal_view_test.dart); these helpers stayed behind with tests but
zero production callers.

Drops:
- TerminalScrollGestureHandler (scroll_handler.dart, 100 LOC)
- InfiniteScrollView (infinite_scroll_view.dart, 117 LOC)
- KeyboardVisibilty (keyboard_visibility.dart, 59 LOC) — last
  production caller was removed in 048e835
- TerminalView.simulateScroll parameter — declared, never read
- The matching test groups + imports in ui_widget_test.dart
- The KeyboardVisibilty export from the terminal barrel

Net: -585 lines from lib/ + test/, no behavior change, and
infinite_scroll_view.dart stops being the 90%-coverage outlier we
were apologising for in the previous test sweep.

Same shape as T-93 (dead onTapUp wiring), T-95 (dead tertiary tap),
and 048e835 (dead scrollController plumbing). Public-or-tested
surface that no caller exercised.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 18:20:50 +02:00

93 lines
3.1 KiB
Dart

/// Widget tests for `lib/src/terminal/src/ui/` widget-level helpers —
/// just CustomKeyboardListener now; the other widgets in this folder
/// either don't need a widget tree or were retired as dead surface.
library;
import 'package:clide/src/terminal/src/ui/keyboard_listener.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
Widget _host(Widget child, {double width = 400, double height = 200}) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: const MediaQueryData(),
child: Center(
child: SizedBox(width: width, height: height, child: child),
),
),
);
}
void main() {
group('CustomKeyboardListener', () {
testWidgets('falls through to onInsert when onKeyEvent returns ignored and a character is present', (tester) async {
final inserts = <String>[];
final composings = <String?>[];
final focus = FocusNode();
addTearDown(focus.dispose);
await tester.pumpWidget(_host(
CustomKeyboardListener(
focusNode: focus,
autofocus: true,
onInsert: inserts.add,
onComposing: composings.add,
onKeyEvent: (_, __) => KeyEventResult.ignored,
child: const ColoredBox(color: Color(0xFF000000), child: SizedBox.expand()),
),
));
await tester.pump();
// A character key with non-empty `character` triggers the insert path.
await tester.sendKeyEvent(LogicalKeyboardKey.keyA, character: 'a');
await tester.pump();
expect(inserts, contains('a'));
});
testWidgets('does not call onInsert when onKeyEvent returns handled', (tester) async {
final inserts = <String>[];
final focus = FocusNode();
addTearDown(focus.dispose);
await tester.pumpWidget(_host(
CustomKeyboardListener(
focusNode: focus,
autofocus: true,
onInsert: inserts.add,
onComposing: (_) {},
onKeyEvent: (_, __) => KeyEventResult.handled,
child: const ColoredBox(color: Color(0xFF000000), child: SizedBox.expand()),
),
));
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyA, character: 'a');
await tester.pump();
expect(inserts, isEmpty);
});
testWidgets('does not call onInsert when the key event has no character', (tester) async {
final inserts = <String>[];
final focus = FocusNode();
addTearDown(focus.dispose);
await tester.pumpWidget(_host(
CustomKeyboardListener(
focusNode: focus,
autofocus: true,
onInsert: inserts.add,
onComposing: (_) {},
onKeyEvent: (_, __) => KeyEventResult.ignored,
child: const ColoredBox(color: Color(0xFF000000), child: SizedBox.expand()),
),
));
await tester.pump();
// ArrowUp has no `character` — ignored result + no character means
// _onKeyEvent returns ignored without firing onInsert.
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
expect(inserts, isEmpty);
});
});
}