okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
3a9b1e4
main
1package uv 2 3import ( 4"io" 5"testing" 6 7"github.com/charmbracelet/x/ansi" 8) 9 10// warningSign is U+26A0 followed by a VS16 emoji-presentation selector 11// (U+FE0F). Terminals in Unicode core mode (DEC mode 2027) measure it as a 12// wide, width-2 glyph. 13const warningSign = "\u26a0\ufe0f" 14 15func TestGraphemeWidthNegotiation (t * testing.T ) { 16s := NewTerminalScreen (io .Discard ,Environ {"TERM=xterm-256color" }) 17 18if got := s .StringWidth (warningSign );got != 1 { 19t .Fatalf ("default width method: StringWidth(%q) = %d, want 1" ,warningSign ,got ) 20 } 21 22s .enableGraphemeWidth () 23 24if got := s .StringWidth (warningSign );got != 2 { 25t .Fatalf ("grapheme mode: StringWidth(%q) = %d, want 2" ,warningSign ,got ) 26 } 27if s .WidthMethod ()!= ansi .GraphemeWidth { 28t .Fatalf ("grapheme mode: WidthMethod() = %v, want GraphemeWidth" ,s .WidthMethod ()) 29 } 30if ! s .rend .flags .Contains (tGraphemeWidth ) { 31t .Fatal ("grapheme mode: renderer tGraphemeWidth flag not set" ) 32 } 33if s .rend .method != ansi .GraphemeWidth { 34t .Fatalf ("grapheme mode: renderer method = %v, want GraphemeWidth" ,s .rend .method ) 35 } 36} 37 38func TestGraphemeWidthOverride (t * testing.T ) { 39s := NewTerminalScreen (io .Discard ,Environ {"TERM=xterm-256color" }) 40 41s .SetWidthMethod (ansi .GraphemeWidth ) 42if got := s .StringWidth (warningSign );got != 2 { 43t .Fatalf ("override: StringWidth(%q) = %d, want 2" ,warningSign ,got ) 44 } 45if s .rend .method != ansi .GraphemeWidth { 46t .Fatalf ("override: renderer method = %v, want GraphemeWidth" ,s .rend .method ) 47 } 48 49s .SetWidthMethod (ansi .WcWidth ) 50if got := s .StringWidth (warningSign );got != 1 { 51t .Fatalf ("override back: StringWidth(%q) = %d, want 1" ,warningSign ,got ) 52 } 53} 54 55// TestGraphemeWidthGating verifies that the mode-2027 report only switches the 56// width method to grapheme clustering for settable or active states, and never 57// for not-recognized or permanently-reset terminals. 58func TestGraphemeWidthGating (t * testing.T ) { 59tests := []struct { 60name string 61value ansi.ModeSetting 62enabled bool 63 }{ 64 {"set" ,ansi .ModeSet ,true }, 65 {"reset" ,ansi .ModeReset ,true }, 66 {"permanently set" ,ansi .ModePermanentlySet ,true }, 67 {"not recognized" ,ansi .ModeNotRecognized ,false }, 68 {"permanently reset" ,ansi .ModePermanentlyReset ,false }, 69 } 70 71for _ ,tt := range tests { 72t .Run (tt .name ,func (t * testing.T ) { 73s := NewTerminalScreen (io .Discard ,Environ {"TERM=xterm-256color" }) 74tm := & Terminal {scr :s } 75 76tm .handleEvent (ModeReportEvent {Mode :ansi .ModeUnicodeCore ,Value :tt .value }) 77 78wantWidth := 1 79wantMethod := ansi .Method (ansi .WcWidth ) 80if tt .enabled { 81wantWidth = 2 82wantMethod = ansi .GraphemeWidth 83 } 84 85if got := s .StringWidth (warningSign );got != wantWidth { 86t .Fatalf ("StringWidth(%q) = %d, want %d" ,warningSign ,got ,wantWidth ) 87 } 88if s .rend .method != wantMethod { 89t .Fatalf ("renderer method = %v, want %v" ,s .rend .method ,wantMethod ) 90 } 91if got := s .rend .flags .Contains (tGraphemeWidth );got != tt .enabled { 92t .Fatalf ("renderer tGraphemeWidth flag = %v, want %v" ,got ,tt .enabled ) 93 } 94 }) 95 } 96} 97 98// TestGraphemeWidthGatingPreservesOverride verifies that a late mode-2027 99// report does not clobber a width method the application set explicitly. 100func TestGraphemeWidthGatingPreservesOverride (t * testing.T ) { 101s := NewTerminalScreen (io .Discard ,Environ {"TERM=xterm-256color" }) 102tm := & Terminal {scr :s } 103 104s .SetWidthMethod (ansi .WcWidth ) 105 106tm .handleEvent (ModeReportEvent {Mode :ansi .ModeUnicodeCore ,Value :ansi .ModeSet }) 107 108if got := s .StringWidth (warningSign );got != 1 { 109t .Fatalf ("explicit override clobbered: StringWidth(%q) = %d, want 1" ,warningSign ,got ) 110 } 111if s .rend .method != ansi .WcWidth { 112t .Fatalf ("explicit override clobbered: renderer method = %v, want WcWidth" ,s .rend .method ) 113 } 114if s .rend .flags .Contains (tGraphemeWidth ) { 115t .Fatal ("explicit override clobbered: renderer tGraphemeWidth flag set" ) 116 } 117}