okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
5ae5e3d
main
1// Trimming must release old descriptors without clearing surviving text. 2// Daemon E2E cannot inspect the TUI's retained memory. 3package tui 4 5import ( 6"fmt" 7"slices" 8"strings" 9"testing" 10) 11 12func TestTrimSettledLinesReleasesDescriptors (t * testing.T ) { 13for _ ,test := range []struct { 14name string 15rows []string 16kept int 17 }{ 18 {name :"row cap" ,rows :slices .Repeat ([]string {"│ short" },MaxSettledLines + 3 ),kept :MaxSettledLines }, 19 {name :"byte cap" ,rows :slices .Repeat ([]string {"│ " + strings .Repeat ("x" ,512 )},600 ),kept :MaxSettledLinesBytes / (len ("│ " )+ 512 + 3 )}, 20 {name :"all rows" ,rows : []string {"small" ,strings .Repeat ("x" ,MaxSettledLinesBytes + 1 )},kept :0 }, 21 } { 22t .Run (test .name ,func (t * testing.T ) { 23// Fixed-width suffixes make survivor ordering observable. 24for i := range test .rows { 25test .rows [i ]+= fmt .Sprintf ("%03d" ,i ) 26 } 27old := test .rows 28want := slices .Clone (old [len (old )- test .kept :]) 29m := ChatModel {Follow :true ,settledLines :old ,settledLinesBytes :rowBytes (old )} 30m .trimSettledLines () 31if ! slices .Equal (m .settledLines ,want )|| m .settledLinesBytes != rowBytes (want )|| m .droppedSettledLines != len (old )- test .kept { 32t .Fatalf ("survivors=%d bytes=%d dropped=%d" ,len (m .settledLines ),m .settledLinesBytes ,m .droppedSettledLines ) 33 } 34for i ,row := range old { 35if row != "" { 36t .Fatalf ("old descriptor %d still holds text" ,i ) 37 } 38 } 39if len (want )> 0 { 40old [len (old )- 1 ]= "changed old slice" 41if ! slices .Equal (m .settledLines ,want ) { 42t .Fatal ("survivors share the old descriptor slice" ) 43 } 44 } 45 }) 46 } 47} 48 49func BenchmarkTrimSettledLinesFullDisplay (b * testing.B ) { 50for _ ,width := range []int {80 ,512 } { 51b .Run (fmt .Sprintf ("ascii%d" ,width ),func (b * testing.B ) { 52row := "│ " + strings .Repeat ("x" ,width ) 53count := min (MaxSettledLines ,MaxSettledLinesBytes / len (row )) 54m := ChatModel {Follow :true ,settledLines :slices .Repeat ([]string {row },count ),settledLinesBytes :int64 (count * len (row ))} 55b .ReportAllocs () 56b .ResetTimer () 57for i := 0 ;i < b .N ;i ++ { 58m .settledLines = append (m .settledLines ,row ) 59m .settledLinesBytes += int64 (len (row )) 60m .trimSettledLines () 61 } 62 }) 63 } 64}