package uv import ( "image" "image/color" "testing" "github.com/charmbracelet/x/ansi" "github.com/charmbracelet/x/ansi/kitty" ) // TestUnknownEventString tests String methods for all Unknown event types func TestUnknownEventString(t *testing.T) { tests := []struct { name string event interface{ String() string } want string }{ { name: "UnknownEvent", event: UnknownEvent("test"), want: `"test"`, }, { name: "UnknownCsiEvent", event: UnknownCsiEvent("csi"), want: `"csi"`, }, { name: "UnknownSs3Event", event: UnknownSs3Event("ss3"), want: `"ss3"`, }, { name: "UnknownOscEvent", event: UnknownOscEvent("osc"), want: `"osc"`, }, { name: "UnknownDcsEvent", event: UnknownDcsEvent("dcs"), want: `"dcs"`, }, { name: "UnknownSosEvent", event: UnknownSosEvent("sos"), want: `"sos"`, }, { name: "UnknownPmEvent", event: UnknownPmEvent("pm"), want: `"pm"`, }, { name: "UnknownApcEvent", event: UnknownApcEvent("apc"), want: `"apc"`, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := tt.event.String() if got != tt.want { t.Errorf("String() = %q, want %q", got, tt.want) } }) } } // TestMultiEventString tests the String method for MultiEvent func TestMultiEventString(t *testing.T) { events := MultiEvent{ KeyPressEvent{Code: 'a'}, KeyPressEvent{Code: 'b'}, KeyPressEvent{Code: 'c'}, } got := events.String() want := "a\nb\nc\n" if got != want { t.Errorf("MultiEvent.String() = %q, want %q", got, want) } } // TestSizeBounds tests the Bounds method for Size and related types func TestSizeBounds(t *testing.T) { tests := []struct { name string size interface{ Bounds() Rectangle } want Rectangle }{ { name: "Size", size: Size{Width: 80, Height: 24}, want: Rectangle{ Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 80, Y: 24}, }, }, { name: "WindowSizeEvent", size: WindowSizeEvent{Width: 100, Height: 50}, want: Rectangle{ Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 100, Y: 50}, }, }, { name: "WindowPixelSizeEvent", size: PixelSizeEvent{Width: 1920, Height: 1080}, want: Rectangle{ Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 1920, Y: 1080}, }, }, { name: "CellSizeEvent", size: CellSizeEvent{Width: 10, Height: 20}, want: Rectangle{ Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 10, Y: 20}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := tt.size.Bounds() if got != tt.want { t.Errorf("Bounds() = %v, want %v", got, tt.want) } }) } } // TestKeyPressEventMethods tests all methods of KeyPressEvent func TestKeyPressEventMethods(t *testing.T) { k := KeyPressEvent{Code: 'a', Mod: ModCtrl} t.Run("MatchString", func(t *testing.T) { if !k.MatchString("ctrl+a") { t.Error("MatchString(\"ctrl+a\") = false, want true") } if k.MatchString("ctrl+b") { t.Error("MatchString(\"ctrl+b\") = true, want false") } }) t.Run("MatchStrings", func(t *testing.T) { if !k.MatchString("ctrl+b", "ctrl+a", "ctrl+c") { t.Error("MatchStrings() = false, want true") } if k.MatchString("ctrl+b", "ctrl+c") { t.Error("MatchStrings() = true, want false") } }) t.Run("String", func(t *testing.T) { got := k.String() want := "ctrl+a" if got != want { t.Errorf("String() = %q, want %q", got, want) } }) t.Run("Keystroke", func(t *testing.T) { got := k.Keystroke() want := "ctrl+a" if got != want { t.Errorf("Keystroke() = %q, want %q", got, want) } }) t.Run("Key", func(t *testing.T) { got := k.Key() want := Key{Code: 'a', Mod: ModCtrl} if got != want { t.Errorf("Key() = %v, want %v", got, want) } }) } // TestKeyReleaseEventMethods tests all methods of KeyReleaseEvent func TestKeyReleaseEventMethods(t *testing.T) { k := KeyReleaseEvent{Code: 'b', Mod: ModAlt} t.Run("MatchString", func(t *testing.T) { if !k.MatchString("alt+b") { t.Error("MatchString(\"alt+b\") = false, want true") } if k.MatchString("alt+a") { t.Error("MatchString(\"alt+a\") = true, want false") } }) t.Run("MatchStrings", func(t *testing.T) { if !k.MatchString("alt+a", "alt+b", "alt+c") { t.Error("MatchStrings() = false, want true") } if k.MatchString("alt+a", "alt+c") { t.Error("MatchStrings() = true, want false") } }) t.Run("String", func(t *testing.T) { got := k.String() want := "alt+b" if got != want { t.Errorf("String() = %q, want %q", got, want) } }) t.Run("Keystroke", func(t *testing.T) { got := k.Keystroke() want := "alt+b" if got != want { t.Errorf("Keystroke() = %q, want %q", got, want) } }) t.Run("Key", func(t *testing.T) { got := k.Key() want := Key{Code: 'b', Mod: ModAlt} if got != want { t.Errorf("Key() = %v, want %v", got, want) } }) } // TestMouseEventMethods tests all mouse event types and their methods func TestMouseEventMethods(t *testing.T) { mouse := Mouse{X: 10, Y: 20, Button: MouseLeft} t.Run("MouseClickEvent", func(t *testing.T) { e := MouseClickEvent(mouse) if got := e.String(); got != "left" { t.Errorf("String() = %q, want %q", got, "left") } if got := e.Mouse(); got != mouse { t.Errorf("Mouse() = %v, want %v", got, mouse) } }) t.Run("MouseReleaseEvent", func(t *testing.T) { e := MouseReleaseEvent(mouse) if got := e.String(); got != "left" { t.Errorf("String() = %q, want %q", got, "left") } if got := e.Mouse(); got != mouse { t.Errorf("Mouse() = %v, want %v", got, mouse) } }) t.Run("MouseWheelEvent", func(t *testing.T) { e := MouseWheelEvent(Mouse{X: 10, Y: 20, Button: MouseWheelUp}) if got := e.String(); got != "wheelup" { t.Errorf("String() = %q, want %q", got, "wheelup") } if got := e.Mouse(); got.Button != MouseWheelUp { t.Errorf("Mouse().Button = %v, want %v", got.Button, MouseWheelUp) } }) t.Run("MouseMotionEvent", func(t *testing.T) { // Test with button e := MouseMotionEvent(mouse) if got := e.String(); got != "left+motion" { t.Errorf("String() = %q, want %q", got, "left+motion") } if got := e.Mouse(); got != mouse { t.Errorf("Mouse() = %v, want %v", got, mouse) } // Test without button e2 := MouseMotionEvent(Mouse{X: 10, Y: 20, Button: 0}) if got := e2.String(); got != "motion" { t.Errorf("String() = %q, want %q", got, "motion") } }) } // TestKittyEnhancementsEventContains tests the Contains method func TestKittyEnhancementsEventContains(t *testing.T) { e := KeyboardEnhancementsEvent{0b111} // Has bits 0, 1, and 2 set tests := []struct { name string enhancements int want bool }{ { name: "has single bit", enhancements: 0b001, want: true, }, { name: "has multiple bits", enhancements: 0b011, want: true, }, { name: "has all bits", enhancements: 0b111, want: true, }, { name: "missing bit", enhancements: 0b1000, want: false, }, { name: "partially missing bits", enhancements: 0b1011, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := e.Contains(tt.enhancements) if got != tt.want { t.Errorf("Contains(%b) = %v, want %v", tt.enhancements, got, tt.want) } }) } } // TestColorEventMethods tests color event methods func TestColorEventMethods(t *testing.T) { redColor := color.RGBA{R: 255, G: 0, B: 0, A: 255} blackColor := color.RGBA{R: 0, G: 0, B: 0, A: 255} whiteColor := color.RGBA{R: 255, G: 255, B: 255, A: 255} t.Run("ForegroundColorEvent", func(t *testing.T) { e := ForegroundColorEvent{redColor} if got := e.String(); got != "#ff0000" { t.Errorf("String() = %q, want %q", got, "#ff0000") } if got := e.IsDark(); got != false { t.Errorf("IsDark() = %v, want %v", got, false) } e2 := ForegroundColorEvent{blackColor} if got := e2.IsDark(); got != true { t.Errorf("IsDark() = %v, want %v", got, true) } }) t.Run("BackgroundColorEvent", func(t *testing.T) { e := BackgroundColorEvent{whiteColor} if got := e.String(); got != "#ffffff" { t.Errorf("String() = %q, want %q", got, "#ffffff") } if got := e.IsDark(); got != false { t.Errorf("IsDark() = %v, want %v", got, false) } e2 := BackgroundColorEvent{blackColor} if got := e2.IsDark(); got != true { t.Errorf("IsDark() = %v, want %v", got, true) } }) t.Run("CursorColorEvent", func(t *testing.T) { e := CursorColorEvent{redColor} if got := e.String(); got != "#ff0000" { t.Errorf("String() = %q, want %q", got, "#ff0000") } if got := e.IsDark(); got != false { t.Errorf("IsDark() = %v, want %v", got, false) } e2 := CursorColorEvent{blackColor} if got := e2.IsDark(); got != true { t.Errorf("IsDark() = %v, want %v", got, true) } }) } // TestClipboardEventString tests the String method for ClipboardEvent func TestClipboardEventString(t *testing.T) { e := ClipboardEvent{ Content: "test content", Selection: SystemClipboard, } got := e.String() want := "test content" if got != want { t.Errorf("String() = %q, want %q", got, want) } } // TestEventTypes tests that various event types exist and can be created func TestEventTypes(t *testing.T) { // Test that these types can be instantiated without panic _ = CursorPositionEvent(image.Point{X: 10, Y: 20}) _ = FocusEvent{} _ = BlurEvent{} _ = DarkColorSchemeEvent{} _ = LightColorSchemeEvent{} _ = PasteEvent{"pasted text"} _ = PasteStartEvent{} _ = PasteEndEvent{} _ = TerminalVersionEvent{"1.0.0"} _ = ModifyOtherKeysEvent{1} _ = KittyGraphicsEvent{ Options: kitty.Options{}, Payload: []byte("test"), } _ = PrimaryDeviceAttributesEvent{1, 2, 3} _ = SecondaryDeviceAttributesEvent{1, 2, 3} _ = TertiaryDeviceAttributesEvent("test") _ = ModeReportEvent{ Mode: ansi.DECMode(1000), Value: ansi.ModeSet, } _ = WindowOpEvent{ Op: 1, Args: []int{100, 200}, } _ = CapabilityEvent{"RGB"} _ = ignoredEvent("ignored") }