okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
979f217
main
1package terminal 2 3import ( 4"context" 5"errors" 6"os" 7"strings" 8"sync" 9"testing" 10"time" 11 12"albedo/cli/internal/daemon" 13) 14 15// Real-daemon PTY tests cover approval. This checks cancellation while input is 16// blocked, where a leaked reader would otherwise survive the caller's wait. 17func TestRestartConfirmationCancelsBlockedInput (t * testing.T ) { 18input ,writer ,err := os .Pipe () 19if err != nil { 20t .Fatal (err ) 21 } 22defer input .Close () 23defer writer .Close () 24output := & promptSignal {ready :make (chan struct {})} 25service := Service {In :input ,Out :output ,Capable :true } 26ctx ,cancel := context .WithCancel (context .Background ()) 27defer cancel () 28result := make (chan error ,1 ) 29go func () { 30approved ,err := service .ConfirmRestart (ctx , daemon.ConnectionSnapshot {Pid :42 }, daemon.BuildIdentity {}) 31if approved { 32result <- errors .New ("cancellation approved restart" ) 33return 34 } 35result <- err 36 }() 37select { 38case <- output .ready : 39case err := <- result : 40t .Fatalf ("confirmation exited before waiting: %v" ,err ) 41case <- time .After (5 * time .Second ): 42t .Fatal ("confirmation did not begin reading input" ) 43 } 44cancel () 45select { 46case err := <- result : 47if ! errors .Is (err ,context .Canceled ) { 48t .Fatalf ("want canceled confirmation, got %v" ,err ) 49 } 50case <- time .After (5 * time .Second ): 51t .Fatal ("confirmation kept waiting after cancellation" ) 52 } 53} 54 55type promptSignal struct { 56ready chan struct {} 57once sync.Once 58} 59 60func (s * promptSignal )Write (data []byte ) (int ,error ) { 61// Bubble Tea starts the input program with terminal control sequences. 62if strings .Contains (string (data ),"\x1b" ) { 63s .once .Do (func () {close (s .ready ) }) 64 } 65return len (data ),nil 66}