test sweep: cover gesture_handler / gesture_detector selection paths (T-91)
test / unit + widget + golden + a11y (push) Failing after 34s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m2s
test / unit + widget + golden + a11y (push) Failing after 34s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m2s
Adds three widget tests under TerminalView — selection gestures: double-tap selects a word; long-press (touch) selects a word and keeps the selection across move-update; mouse drag selects characters across drag-start and drag-update. Each verifies the side-effect on the externally-supplied TerminalController. Coverage: gesture_detector.dart 42/50 -> 50/50; gesture_handler.dart 39/59 -> 55/59. The 4 remaining uncovered lines (147, 148, 151, 152) are the dead tertiary-tap state methods filed as T-95 — same shape as T-93 but on middle-click. Floor stays at 69 (69.79% measured; integer threshold unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -339,6 +339,85 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('TerminalView — selection gestures', () {
|
||||
// Cover the gesture_handler.dart selection paths and the gesture_detector
|
||||
// double-tap detection branch. Each test sets up a TerminalView with a
|
||||
// controller it can inspect; the gestures are wired into the
|
||||
// RenderTerminal which mutates `controller.selection`.
|
||||
// Empty cells (codepoint 0) and ASCII space are word separators in
|
||||
// `defaultWordSeparators`, so taps must land on a non-separator cell for
|
||||
// selectWord to return non-null. Write a wide stripe of 'a's at row 0
|
||||
// and tap near the top-left so the gesture lands on actual content.
|
||||
Offset contentPosition(WidgetTester tester) {
|
||||
final tl = tester.getTopLeft(find.byType(TerminalView));
|
||||
return tl + const Offset(20, 5);
|
||||
}
|
||||
|
||||
testWidgets('double-tap sets a word selection on the controller', (tester) async {
|
||||
final t = _OutputRecorder().build();
|
||||
t.write('a' * 30);
|
||||
final controller = TerminalController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(_host(TerminalView(t, controller: controller)));
|
||||
await tester.pump();
|
||||
final pos = contentPosition(tester);
|
||||
// Two tap-up cycles within kDoubleTapTimeout (~300 ms). The second
|
||||
// tap-down hits the within-tolerance branch in gesture_detector and
|
||||
// fires onDoubleTapDown, which in turn calls renderTerminal.selectWord.
|
||||
await tester.tapAt(pos);
|
||||
await tester.tapAt(pos);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(controller.selection, isNotNull);
|
||||
});
|
||||
|
||||
testWidgets('long-press (touch) selects a word', (tester) async {
|
||||
final t = _OutputRecorder().build();
|
||||
t.write('a' * 30);
|
||||
final controller = TerminalController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(_host(TerminalView(t, controller: controller)));
|
||||
await tester.pump();
|
||||
final pos = contentPosition(tester);
|
||||
final gesture = await tester.startGesture(pos, kind: PointerDeviceKind.touch);
|
||||
// LongPressGestureRecognizer's threshold is kLongPressTimeout (~500 ms);
|
||||
// pump past it to win the gesture.
|
||||
await tester.pump(const Duration(milliseconds: 600));
|
||||
// onLongPressStart → renderTerminal.selectWord → controller.selection set.
|
||||
expect(controller.selection, isNotNull);
|
||||
// Move during long-press → onLongPressMoveUpdate, second branch of
|
||||
// selectWord with two offsets.
|
||||
await gesture.moveBy(const Offset(40, 0));
|
||||
await tester.pump();
|
||||
expect(controller.selection, isNotNull);
|
||||
await gesture.up();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
});
|
||||
|
||||
testWidgets('mouse drag selects characters (selectCharacters branch)', (tester) async {
|
||||
final t = _OutputRecorder().build();
|
||||
t.write('a' * 30);
|
||||
final controller = TerminalController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(_host(TerminalView(t, controller: controller)));
|
||||
await tester.pump();
|
||||
final pos = contentPosition(tester);
|
||||
final gesture = await tester.startGesture(pos, kind: PointerDeviceKind.mouse);
|
||||
// PanGestureRecognizer needs movement beyond kPanSlop to win — push
|
||||
// past it before reading the selection.
|
||||
await gesture.moveBy(const Offset(40, 0));
|
||||
await tester.pump();
|
||||
// onDragStart fired with mouse kind → selectCharacters(from); subsequent
|
||||
// onDragUpdate → selectCharacters(from, to). Either way, controller has
|
||||
// a selection.
|
||||
expect(controller.selection, isNotNull);
|
||||
await gesture.moveBy(const Offset(20, 0));
|
||||
await tester.pump();
|
||||
expect(controller.selection, isNotNull);
|
||||
await gesture.up();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
});
|
||||
});
|
||||
|
||||
group('TerminalView — keyboard visibility', () {
|
||||
testWidgets('platform keyboard show fires _onKeyboardShow on the focused view', (tester) async {
|
||||
final t = _OutputRecorder().build();
|
||||
|
||||
Reference in New Issue
Block a user