okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
d69fee1
main
1package uv 2 3import ( 4"image" 5"image/color" 6"testing" 7 8"github.com/charmbracelet/x/ansi" 9"github.com/charmbracelet/x/ansi/kitty" 10) 11 12// TestUnknownEventString tests String methods for all Unknown event types 13func TestUnknownEventString (t * testing.T ) { 14tests := []struct { 15name string 16event interface {String ()string } 17want string 18 }{ 19 { 20name :"UnknownEvent" , 21event :UnknownEvent ("test" ), 22want :`"test"` , 23 }, 24 { 25name :"UnknownCsiEvent" , 26event :UnknownCsiEvent ("csi" ), 27want :`"csi"` , 28 }, 29 { 30name :"UnknownSs3Event" , 31event :UnknownSs3Event ("ss3" ), 32want :`"ss3"` , 33 }, 34 { 35name :"UnknownOscEvent" , 36event :UnknownOscEvent ("osc" ), 37want :`"osc"` , 38 }, 39 { 40name :"UnknownDcsEvent" , 41event :UnknownDcsEvent ("dcs" ), 42want :`"dcs"` , 43 }, 44 { 45name :"UnknownSosEvent" , 46event :UnknownSosEvent ("sos" ), 47want :`"sos"` , 48 }, 49 { 50name :"UnknownPmEvent" , 51event :UnknownPmEvent ("pm" ), 52want :`"pm"` , 53 }, 54 { 55name :"UnknownApcEvent" , 56event :UnknownApcEvent ("apc" ), 57want :`"apc"` , 58 }, 59 } 60 61for _ ,tt := range tests { 62t .Run (tt .name ,func (t * testing.T ) { 63got := tt .event .String () 64if got != tt .want { 65t .Errorf ("String() = %q, want %q" ,got ,tt .want ) 66 } 67 }) 68 } 69} 70 71// TestMultiEventString tests the String method for MultiEvent 72func TestMultiEventString (t * testing.T ) { 73events := MultiEvent { 74KeyPressEvent {Code :'a' }, 75KeyPressEvent {Code :'b' }, 76KeyPressEvent {Code :'c' }, 77 } 78 79got := events .String () 80want := "a\nb\nc\n" 81if got != want { 82t .Errorf ("MultiEvent.String() = %q, want %q" ,got ,want ) 83 } 84} 85 86// TestSizeBounds tests the Bounds method for Size and related types 87func TestSizeBounds (t * testing.T ) { 88tests := []struct { 89name string 90size interface {Bounds ()Rectangle } 91want Rectangle 92 }{ 93 { 94name :"Size" , 95size :Size {Width :80 ,Height :24 }, 96want :Rectangle { 97Min : image.Point {X :0 ,Y :0 }, 98Max : image.Point {X :80 ,Y :24 }, 99 }, 100 }, 101 { 102name :"WindowSizeEvent" , 103size :WindowSizeEvent {Width :100 ,Height :50 }, 104want :Rectangle { 105Min : image.Point {X :0 ,Y :0 }, 106Max : image.Point {X :100 ,Y :50 }, 107 }, 108 }, 109 { 110name :"WindowPixelSizeEvent" , 111size :PixelSizeEvent {Width :1920 ,Height :1080 }, 112want :Rectangle { 113Min : image.Point {X :0 ,Y :0 }, 114Max : image.Point {X :1920 ,Y :1080 }, 115 }, 116 }, 117 { 118name :"CellSizeEvent" , 119size :CellSizeEvent {Width :10 ,Height :20 }, 120want :Rectangle { 121Min : image.Point {X :0 ,Y :0 }, 122Max : image.Point {X :10 ,Y :20 }, 123 }, 124 }, 125 } 126 127for _ ,tt := range tests { 128t .Run (tt .name ,func (t * testing.T ) { 129got := tt .size .Bounds () 130if got != tt .want { 131t .Errorf ("Bounds() = %v, want %v" ,got ,tt .want ) 132 } 133 }) 134 } 135} 136 137// TestKeyPressEventMethods tests all methods of KeyPressEvent 138func TestKeyPressEventMethods (t * testing.T ) { 139k := KeyPressEvent {Code :'a' ,Mod :ModCtrl } 140 141t .Run ("MatchString" ,func (t * testing.T ) { 142if ! k .MatchString ("ctrl+a" ) { 143t .Error ("MatchString(\"ctrl+a\") = false, want true" ) 144 } 145if k .MatchString ("ctrl+b" ) { 146t .Error ("MatchString(\"ctrl+b\") = true, want false" ) 147 } 148 }) 149 150t .Run ("MatchStrings" ,func (t * testing.T ) { 151if ! k .MatchString ("ctrl+b" ,"ctrl+a" ,"ctrl+c" ) { 152t .Error ("MatchStrings() = false, want true" ) 153 } 154if k .MatchString ("ctrl+b" ,"ctrl+c" ) { 155t .Error ("MatchStrings() = true, want false" ) 156 } 157 }) 158 159t .Run ("String" ,func (t * testing.T ) { 160got := k .String () 161want := "ctrl+a" 162if got != want { 163t .Errorf ("String() = %q, want %q" ,got ,want ) 164 } 165 }) 166 167t .Run ("Keystroke" ,func (t * testing.T ) { 168got := k .Keystroke () 169want := "ctrl+a" 170if got != want { 171t .Errorf ("Keystroke() = %q, want %q" ,got ,want ) 172 } 173 }) 174 175t .Run ("Key" ,func (t * testing.T ) { 176got := k .Key () 177want := Key {Code :'a' ,Mod :ModCtrl } 178if got != want { 179t .Errorf ("Key() = %v, want %v" ,got ,want ) 180 } 181 }) 182} 183 184// TestKeyReleaseEventMethods tests all methods of KeyReleaseEvent 185func TestKeyReleaseEventMethods (t * testing.T ) { 186k := KeyReleaseEvent {Code :'b' ,Mod :ModAlt } 187 188t .Run ("MatchString" ,func (t * testing.T ) { 189if ! k .MatchString ("alt+b" ) { 190t .Error ("MatchString(\"alt+b\") = false, want true" ) 191 } 192if k .MatchString ("alt+a" ) { 193t .Error ("MatchString(\"alt+a\") = true, want false" ) 194 } 195 }) 196 197t .Run ("MatchStrings" ,func (t * testing.T ) { 198if ! k .MatchString ("alt+a" ,"alt+b" ,"alt+c" ) { 199t .Error ("MatchStrings() = false, want true" ) 200 } 201if k .MatchString ("alt+a" ,"alt+c" ) { 202t .Error ("MatchStrings() = true, want false" ) 203 } 204 }) 205 206t .Run ("String" ,func (t * testing.T ) { 207got := k .String () 208want := "alt+b" 209if got != want { 210t .Errorf ("String() = %q, want %q" ,got ,want ) 211 } 212 }) 213 214t .Run ("Keystroke" ,func (t * testing.T ) { 215got := k .Keystroke () 216want := "alt+b" 217if got != want { 218t .Errorf ("Keystroke() = %q, want %q" ,got ,want ) 219 } 220 }) 221 222t .Run ("Key" ,func (t * testing.T ) { 223got := k .Key () 224want := Key {Code :'b' ,Mod :ModAlt } 225if got != want { 226t .Errorf ("Key() = %v, want %v" ,got ,want ) 227 } 228 }) 229} 230 231// TestMouseEventMethods tests all mouse event types and their methods 232func TestMouseEventMethods (t * testing.T ) { 233mouse := Mouse {X :10 ,Y :20 ,Button :MouseLeft } 234 235t .Run ("MouseClickEvent" ,func (t * testing.T ) { 236e := MouseClickEvent (mouse ) 237if got := e .String ();got != "left" { 238t .Errorf ("String() = %q, want %q" ,got ,"left" ) 239 } 240if got := e .Mouse ();got != mouse { 241t .Errorf ("Mouse() = %v, want %v" ,got ,mouse ) 242 } 243 }) 244 245t .Run ("MouseReleaseEvent" ,func (t * testing.T ) { 246e := MouseReleaseEvent (mouse ) 247if got := e .String ();got != "left" { 248t .Errorf ("String() = %q, want %q" ,got ,"left" ) 249 } 250if got := e .Mouse ();got != mouse { 251t .Errorf ("Mouse() = %v, want %v" ,got ,mouse ) 252 } 253 }) 254 255t .Run ("MouseWheelEvent" ,func (t * testing.T ) { 256e := MouseWheelEvent (Mouse {X :10 ,Y :20 ,Button :MouseWheelUp }) 257if got := e .String ();got != "wheelup" { 258t .Errorf ("String() = %q, want %q" ,got ,"wheelup" ) 259 } 260if got := e .Mouse ();got .Button != MouseWheelUp { 261t .Errorf ("Mouse().Button = %v, want %v" ,got .Button ,MouseWheelUp ) 262 } 263 }) 264 265t .Run ("MouseMotionEvent" ,func (t * testing.T ) { 266// Test with button 267e := MouseMotionEvent (mouse ) 268if got := e .String ();got != "left+motion" { 269t .Errorf ("String() = %q, want %q" ,got ,"left+motion" ) 270 } 271if got := e .Mouse ();got != mouse { 272t .Errorf ("Mouse() = %v, want %v" ,got ,mouse ) 273 } 274 275// Test without button 276e2 := MouseMotionEvent (Mouse {X :10 ,Y :20 ,Button :0 }) 277if got := e2 .String ();got != "motion" { 278t .Errorf ("String() = %q, want %q" ,got ,"motion" ) 279 } 280 }) 281} 282 283// TestKittyEnhancementsEventContains tests the Contains method 284func TestKittyEnhancementsEventContains (t * testing.T ) { 285e := KeyboardEnhancementsEvent {0b111 }// Has bits 0, 1, and 2 set 286 287tests := []struct { 288name string 289enhancements int 290want bool 291 }{ 292 { 293name :"has single bit" , 294enhancements :0b001 , 295want :true , 296 }, 297 { 298name :"has multiple bits" , 299enhancements :0b011 , 300want :true , 301 }, 302 { 303name :"has all bits" , 304enhancements :0b111 , 305want :true , 306 }, 307 { 308name :"missing bit" , 309enhancements :0b1000 , 310want :false , 311 }, 312 { 313name :"partially missing bits" , 314enhancements :0b1011 , 315want :false , 316 }, 317 } 318 319for _ ,tt := range tests { 320t .Run (tt .name ,func (t * testing.T ) { 321got := e .Contains (tt .enhancements ) 322if got != tt .want { 323t .Errorf ("Contains(%b) = %v, want %v" ,tt .enhancements ,got ,tt .want ) 324 } 325 }) 326 } 327} 328 329// TestColorEventMethods tests color event methods 330func TestColorEventMethods (t * testing.T ) { 331redColor := color.RGBA {R :255 ,G :0 ,B :0 ,A :255 } 332blackColor := color.RGBA {R :0 ,G :0 ,B :0 ,A :255 } 333whiteColor := color.RGBA {R :255 ,G :255 ,B :255 ,A :255 } 334 335t .Run ("ForegroundColorEvent" ,func (t * testing.T ) { 336e := ForegroundColorEvent {redColor } 337if got := e .String ();got != "#ff0000" { 338t .Errorf ("String() = %q, want %q" ,got ,"#ff0000" ) 339 } 340if got := e .IsDark ();got != false { 341t .Errorf ("IsDark() = %v, want %v" ,got ,false ) 342 } 343 344e2 := ForegroundColorEvent {blackColor } 345if got := e2 .IsDark ();got != true { 346t .Errorf ("IsDark() = %v, want %v" ,got ,true ) 347 } 348 }) 349 350t .Run ("BackgroundColorEvent" ,func (t * testing.T ) { 351e := BackgroundColorEvent {whiteColor } 352if got := e .String ();got != "#ffffff" { 353t .Errorf ("String() = %q, want %q" ,got ,"#ffffff" ) 354 } 355if got := e .IsDark ();got != false { 356t .Errorf ("IsDark() = %v, want %v" ,got ,false ) 357 } 358 359e2 := BackgroundColorEvent {blackColor } 360if got := e2 .IsDark ();got != true { 361t .Errorf ("IsDark() = %v, want %v" ,got ,true ) 362 } 363 }) 364 365t .Run ("CursorColorEvent" ,func (t * testing.T ) { 366e := CursorColorEvent {redColor } 367if got := e .String ();got != "#ff0000" { 368t .Errorf ("String() = %q, want %q" ,got ,"#ff0000" ) 369 } 370if got := e .IsDark ();got != false { 371t .Errorf ("IsDark() = %v, want %v" ,got ,false ) 372 } 373 374e2 := CursorColorEvent {blackColor } 375if got := e2 .IsDark ();got != true { 376t .Errorf ("IsDark() = %v, want %v" ,got ,true ) 377 } 378 }) 379} 380 381// TestClipboardEventString tests the String method for ClipboardEvent 382func TestClipboardEventString (t * testing.T ) { 383e := ClipboardEvent { 384Content :"test content" , 385Selection :SystemClipboard , 386 } 387 388got := e .String () 389want := "test content" 390if got != want { 391t .Errorf ("String() = %q, want %q" ,got ,want ) 392 } 393} 394 395// TestEventTypes tests that various event types exist and can be created 396func TestEventTypes (t * testing.T ) { 397// Test that these types can be instantiated without panic 398_ = CursorPositionEvent (image.Point {X :10 ,Y :20 }) 399_ = FocusEvent {} 400_ = BlurEvent {} 401_ = DarkColorSchemeEvent {} 402_ = LightColorSchemeEvent {} 403_ = PasteEvent {"pasted text" } 404_ = PasteStartEvent {} 405_ = PasteEndEvent {} 406_ = TerminalVersionEvent {"1.0.0" } 407_ = ModifyOtherKeysEvent {1 } 408_ = KittyGraphicsEvent { 409Options : kitty.Options {}, 410Payload : []byte ("test" ), 411 } 412_ = PrimaryDeviceAttributesEvent {1 ,2 ,3 } 413_ = SecondaryDeviceAttributesEvent {1 ,2 ,3 } 414_ = TertiaryDeviceAttributesEvent ("test" ) 415_ = ModeReportEvent { 416Mode :ansi .DECMode (1000 ), 417Value :ansi .ModeSet , 418 } 419_ = WindowOpEvent { 420Op :1 , 421Args : []int {100 ,200 }, 422 } 423_ = CapabilityEvent {"RGB" } 424_ = ignoredEvent ("ignored" ) 425}