// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package input import ( "testing" "time" ) func TestIntentTracksModifiersAndExpires(t *testing.T) { tracker := &IntentTracker{} for _, step := range []struct { name string pressed bool want Intent }{ {"Down", true, LineIntent}, {"Down", false, LineIntent}, {"Right", true, CharacterIntent}, {"Control_L", true, OtherIntent}, {"Right", true, WordIntent}, {"Control_R", true, OtherIntent}, {"Control_L", false, OtherIntent}, {"Left", true, WordIntent}, {"Control_R", false, WordIntent}, {"Left", true, CharacterIntent}, {"s", true, TypingIntent}, {"period", true, TypingIntent}, {"BackSpace", true, DeleteIntent}, {"Return", true, OtherIntent}, {"Alt_L", true, OtherIntent}, {"Down", true, OtherIntent}, } { tracker.Observe(NewKeyEvent(0, step.pressed, step.name)) if got := tracker.RecentIntent(); got != step.want { t.Fatalf("%s pressed=%v: %v, want %v", step.name, step.pressed, got, step.want) } } tracker.at = time.Now().Add(-2 * time.Second) if tracker.RecentIntent() != NoIntent { t.Fatal("stale input reused") } } func TestIntentTracksClipboardChords(t *testing.T) { tracker := &IntentTracker{} press := func(name string) Activity { tracker.Observe(NewKeyEvent(0, true, name)) return tracker.RecentInput() } press("Shift_L") if got := press("Right"); got.Intent != CharacterIntent || !got.Selecting { t.Fatalf("Shift+Right = %+v", got) } press("Control_L") if got := press("Left"); got.Intent != WordIntent || !got.Selecting { t.Fatalf("Ctrl+Shift+Left = %+v", got) } tracker.Observe(NewKeyEvent(0, false, "Shift_L")) for _, tc := range []struct { key string want ClipboardAction }{ {"c", CopyAction}, {"x", CutAction}, {"v", PasteAction}, } { if got := press(tc.key); got.Clipboard != tc.want { t.Fatalf("Ctrl+%s = %+v", tc.key, got) } } if got := press("Right"); got.Clipboard != NoClipboardAction { t.Fatalf("next key retained clipboard action: %+v", got) } tracker.Observe(NewKeyEvent(0, false, "Control_L")) if got := press("v"); got.Clipboard != NoClipboardAction { t.Fatalf("plain v = %+v", got) } } func TestSelectionIntentEndsWithPlainNavigation(t *testing.T) { tracker := &IntentTracker{} tracker.Observe(NewKeyEvent(0, true, "Shift_L")) tracker.Observe(NewKeyEvent(0, true, "Down")) if got := tracker.RecentInput(); !got.Selecting || got.Intent != LineIntent { t.Fatalf("Shift+Down = %+v", got) } tracker.Observe(NewKeyEvent(0, false, "Shift_L")) tracker.Observe(NewKeyEvent(0, true, "Right")) if got := tracker.RecentInput(); got.Selecting || got.Intent != CharacterIntent { t.Fatalf("Right = %+v", got) } } func TestTitleInterruptionTracksFreshPressesAndStopKeys(t *testing.T) { tracker := &IntentTracker{} for _, step := range []struct { name string pressed bool repeat bool want uint64 }{ {"a", true, false, 1}, {"a", false, false, 1}, {"a", true, true, 1}, {"Down", true, false, 2}, {"Down", true, true, 2}, {"Control_L", true, true, 3}, {"Control_R", true, true, 4}, {"Escape", true, true, 5}, } { event := NewKeyEvent(0, step.pressed, step.name) event.Repeat = step.repeat tracker.Observe(event) if got := tracker.RecentInput().TitleInterruptionSequence; got != step.want { t.Fatalf("%+v: title interruption sequence = %d", step, got) } } tracker.at = time.Now().Add(-2 * time.Second) if got := tracker.RecentInput(); got.Intent != NoIntent || got.TitleInterruptionSequence != 5 { t.Fatalf("expired activity = %+v", got) } tracker.Reset() if got := tracker.RecentInput().TitleInterruptionSequence; got != 5 { t.Fatalf("reset lost interruption history: %d", got) } }