okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
cc6ab84
main
1//go:build unix 2 3// Ctrl-click opens the file a transcript row names in the editor, at its 4// line. The rows come from the real renderer and a real files.write diff, 5// and the click lands on screen coordinates, so a change to how rows are 6// drawn or clicks are mapped breaks this test rather than the feature. 7package e2e 8 9import ( 10"os" 11"path/filepath" 12"strings" 13"testing" 14"time" 15 16"albedo/cli/internal/daemon" 17"albedo/cli/internal/tui" 18 19 tea"charm.land/bubbletea/v2" 20) 21 22func TestTUICtrlClickOpensTheNamedFileInTheEditor (t * testing.T ) { 23profile := providerRoute (t ,func (request map [string ]any )string { 24if toolAnswered (request ) { 25return "I fixed main.go:3:6 for you." 26 } 27return pythonCall (`files.write("main.go", "package main\n\nfunc main() {}\n")` ) 28 }) 29workspace := t .TempDir () 30session := daemonSession (t ,newSession (t ,workspace )) 31if _ ,err := daemon .NewChatClient (conn (t ),session .ID ).Send (t .Context (),"fix main" ,nil );err != nil { 32t .Fatal (err ) 33 } 34waitIdle (t ,session .ID ,profile ,2 ) 35 36// albedo runs in Zed's terminal, so the file opens through zed, which 37// here only writes down what it was asked to open. 38bin ,opened := t .TempDir (),filepath .Join (t .TempDir (),"opened" ) 39script := "#!/bin/sh\nprintf '%s\\n' \"$@\" > " + opened + ".tmp && mv " + opened + ".tmp " + opened + "\n" 40if err := os .WriteFile (filepath .Join (bin ,"zed" ), []byte (script ),0o755 );err != nil { 41t .Fatal (err ) 42 } 43t .Setenv ("PATH" ,bin + string (os .PathListSeparator )+ os .Getenv ("PATH" )) 44t .Setenv ("TERM_PROGRAM" ,"zed" ) 45t .Setenv ("EDITOR" ,"false" ) 46 47d := driveTUI (t ,& session ) 48t .Cleanup (d .App .Chat .Close ) 49d .Update (tea.WindowSizeMsg {Width :100 ,Height :50 }) 50pumpStreamUntil (t ,d ,func (msg tea.Msg )bool { 51event ,ok := msg .(tui.ChatStreamEventMsg ) 52return ok && strings .Contains (event .Event .Text ,"I fixed main.go" ) 53 }) 54file := filepath .Join (workspace ,"main.go" ) 55 56// at is the screen cell of text's third character. 57at := func (text string ) (x ,y int ) { 58t .Helper () 59view := d .View () 60for y ,row := range strings .Split (view ,"\n" ) { 61if i := strings .Index (row ,text );i >= 0 { 62return len ([]rune (row [:i ]))+ 2 ,y 63 } 64 } 65t .Fatalf ("no row shows %q:\n%s" ,text ,view ) 66return 0 ,0 67 } 68ctrlClick := func (text string )string { 69t .Helper () 70x ,y := at (text ) 71_ = os .Remove (opened ) 72d .Update (tea.MouseClickMsg {X :x ,Y :y ,Button :tea .MouseLeft ,Mod :tea .ModCtrl }) 73result := d .Send (tea.MouseReleaseMsg {X :x ,Y :y ,Button :tea .MouseLeft ,Mod :tea .ModCtrl }) 74if done ,ok := result .(tui.FileOpenResultMsg );! ok || done .Err != nil { 75t .Fatalf ("ctrl-click on %q did not open a file: %#v\n%s" ,text ,result ,d .View ()) 76 } 77for deadline := time .Now ().Add (10 * time .Second );time .Now ().Before (deadline );time .Sleep (20 * time .Millisecond ) { 78if got ,err := os .ReadFile (opened );err == nil { 79return strings .TrimSpace (string (got )) 80 } 81 } 82t .Fatalf ("the editor never ran for %q" ,text ) 83return "" 84 } 85 86if got ,want := ctrlClick ("main.go:3:6" ),file + ":3:6" ;got != want { 87t .Fatalf ("a reply's path opened %q, want %q" ,got ,want ) 88 } 89if got := ctrlClick ("edited main.go" );got != file { 90t .Fatalf ("the folded edit row opened %q, want %q" ,got ,file ) 91 } 92// ctrl+j shows diffs, and a diff row names its line 93d .Dispatch (tea.KeyPressMsg {Code :'j' ,Mod :tea .ModCtrl }) 94if got ,want := ctrlClick ("func main() {}" ),file + ":3" ;got != want { 95t .Fatalf ("a diff row opened %q, want %q" ,got ,want ) 96 } 97}