okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
78011da
main
1// The context inspector shows the prepared request's standing and each 2// section's facts without enter, filters sections by typing, and scrolls a 3// section's content in its own reader. The reader's body height is only known 4// to the frame, so these drive View first and then assert the scroll it allows. 5package tui 6 7import ( 8"albedo/cli/internal/daemon" 9"strings" 10"testing" 11 12 tea"charm.land/bubbletea/v2" 13"github.com/charmbracelet/x/ansi" 14) 15 16func contextFixture (t * testing.T )ContextInspectorModel { 17t .Helper () 18m := NewContextInspectorModel (nil ,"s" ) 19m .SetSize (120 ,30 ) 20m ,_ = m .Update (contextSnapshotLoadedMsg {Gen :m .Generation ,Snapshot :& daemon.ContextSnapshot { 21State :"ready" ,Provider :"claude" ,Model :"claude-x" ,Protocol :"messages" , 22Sections : []daemon.ContextSection { 23 {ID :"history" ,Label :"History" ,Kind :"history" ,Source :"transcript" ,Pages :2 ,ByteCount :4096 ,Preview :"user: hello" }, 24 {ID :"system" ,Label :"System" ,Kind :"system" ,Source :"instructions" }, 25 }, 26 }}) 27if m .Snapshot == nil || len (m .shown )!= 2 { 28t .Fatal ("fixture snapshot did not load" ) 29 } 30return m 31} 32 33func TestContextShowsRequestAndSectionFactsWithoutEnter (t * testing.T ) { 34m := contextFixture (t ) 35view := ansi .Strip (m .View ()) 36if ! strings .Contains (view ,"claude · claude-x · messages" )|| ! strings .Contains (view ,"read-only" ) { 37t .Fatalf ("the prepared request should show above the sections:\n%s" ,view ) 38 } 39if ! strings .Contains (view ,"2 pages" )|| ! strings .Contains (view ,"transcript" ) { 40t .Fatalf ("the highlighted section's facts should show without opening it:\n%s" ,view ) 41 } 42} 43 44func TestContextFilterSectionsByTyping (t * testing.T ) { 45m := contextFixture (t ) 46for _ ,r := range "sys" { 47m ,_ = m .Update (tea.KeyPressMsg {Code :r ,Text :string (r )}) 48 } 49view := ansi .Strip (m .View ()) 50if strings .Contains (view ,"History" )|| ! strings .Contains (view ,"System" ) { 51t .Fatalf ("typing should filter the sections:\n%s" ,view ) 52 } 53if row ,_ := m .highlighted ();row .key != "system" { 54t .Fatalf ("the filter left %q under the cursor" ,row .key ) 55 } 56} 57 58func TestContextReaderScrollsAndReturnsOnEsc (t * testing.T ) { 59m := contextFixture (t ) 60m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyEnter }) 61if m .Detail == nil { 62t .Fatal ("enter should open the section reader" ) 63 } 64content := strings .Repeat ("history line\n" ,80 ) 65m ,_ = m .Update (contextPageLoadedMsg {Gen :m .Generation ,SectionID :"history" ,Data :& daemon.ContextPage {Content :content }}) 66m .View () 67m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyDown }) 68m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyDown }) 69m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyDown }) 70if m .Detail .Scroll != 3 { 71t .Fatalf ("down should scroll one line each press, got %d" ,m .Detail .Scroll ) 72 } 73m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyPgDown }) 74if m .Detail .Scroll <= 3 || m .Detail .Scroll > len (m .Detail .wrapped ) { 75t .Fatalf ("pgdown should jump by a body of rows, stayed inside the content: %d" ,m .Detail .Scroll ) 76 } 77m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyEscape }) 78if m .Detail != nil || ! strings .Contains (ansi .Strip (m .View ()),"claude-x" ) { 79t .Fatal ("esc should return to the sections" ) 80 } 81}