]> git.giacomolli.uk - onechat/blobdiff - terminal_test.go
Keep recovery advice out of log events
[onechat] / terminal_test.go
index 47791efae5cee4f791c97a23e5d01531eaee2c8b..7f83b575dd42f427994dfc5223f1610ed2de023f 100644 (file)
@@ -47,34 +47,56 @@ func TestEventText(t *testing.T) {
                text  string
        }{
                {
                text  string
        }{
                {
-                       name:  "reply as it is",
-                       event: Event{Kind: "reply", Text: "Done."},
-                       text:  "Done.",
+                       name: "keeps the complete reply text",
+                       event: Event{
+                               Kind: "reply",
+                               Text: "Done.",
+                       },
+                       text: "Done.",
                },
                {
                },
                {
-                       name:  "own user message not shown",
-                       event: Event{Kind: "user", Text: "typed", Source: terminalSource},
-                       text:  "",
+                       name: "hides the current terminal user message",
+                       event: Event{
+                               Kind:   "user",
+                               Text:   "typed",
+                               Source: terminalSource,
+                       },
+                       text: "",
                },
                {
                },
                {
-                       name:  "user message of another source marked",
-                       event: Event{Kind: "user", Text: "from the phone", Source: "telegram"},
-                       text:  "[telegram] from the phone",
+                       name: "marks a user message from another source",
+                       event: Event{
+                               Kind:   "user",
+                               Text:   "from the phone",
+                               Source: "telegram",
+                       },
+                       text: "[telegram] from the phone",
                },
                {
                },
                {
-                       name:  "start of a subagent",
-                       event: Event{Kind: "subagent", Text: "GreenOtter"},
-                       text:  "[GreenOtter] started",
+                       name: "marks the start of a subagent",
+                       event: Event{
+                               Kind: "subagent",
+                               Text: "GreenOtter",
+                       },
+                       text: "[GreenOtter] started",
                },
                {
                },
                {
-                       name:  "report of a subagent whole",
-                       event: Event{Kind: "work", Text: "[GreenOtter]\nThere are 3 files.\n\nFull chat: zoom(\"GreenOtter\")", Source: "GreenOtter", Status: subagentFinished},
-                       text:  "[GreenOtter]\nThere are 3 files.\n\nFull chat: zoom(\"GreenOtter\")",
+                       name: "keeps the complete subagent report",
+                       event: Event{
+                               Kind:   "work",
+                               Text:   "[GreenOtter]\nThere are 3 files.\n\nFull chat: zoom(\"GreenOtter\")",
+                               Source: "GreenOtter",
+                               Status: subagentFinished,
+                       },
+                       text: "[GreenOtter]\nThere are 3 files.\n\nFull chat: zoom(\"GreenOtter\")",
                },
                {
                },
                {
-                       name:  "long result cut",
-                       event: Event{Kind: "echo", Text: strings.Repeat("line\n", 12)},
-                       text:  "[result] " + strings.Repeat("line\n", 9) + "line\n[2 more lines]",
+                       name: "clips a long tool result with its omitted count",
+                       event: Event{
+                               Kind: "echo",
+                               Text: strings.Repeat("line\n", 12),
+                       },
+                       text: "[result] " + strings.Repeat("line\n", 9) + "line\n[2 more lines]",
                },
        }
 
                },
        }
 
@@ -96,6 +118,7 @@ func TestTerminalEventsKeepMarkdownInNonterminalOutput(t *testing.T) {
                Kind: "work",
                Text: "[BlueBird]\n" + text,
        })
                Kind: "work",
                Text: "[BlueBird]\n" + text,
        })
+
        require.Equal(t, text+"\n[BlueBird]\n"+text+"\n", out.String())
 }
 
        require.Equal(t, text+"\n[BlueBird]\n"+text+"\n", out.String())
 }
 
@@ -112,6 +135,7 @@ func TestTerminalFileOutputKeepsMarkdown(t *testing.T) {
                Kind: "reply",
                Text: text,
        })
                Kind: "reply",
                Text: text,
        })
+
        require.Zero(t, terminalColumns(out))
 
        contents, err := os.ReadFile(out.Name())
        require.Zero(t, terminalColumns(out))
 
        contents, err := os.ReadFile(out.Name())
@@ -132,6 +156,7 @@ func TestTerminalStylesOnlyRepliesAndWork(t *testing.T) {
        out := TerminalTestOutput{fd: fd}
        require.Equal(t, 12, terminalColumns(&out))
        terminalTestShowEvents(t, &out,
        out := TerminalTestOutput{fd: fd}
        require.Equal(t, 12, terminalColumns(&out))
        terminalTestShowEvents(t, &out,
+               Event{Kind: "busy"},
                Event{
                        Kind: "reply",
                        Text: "**first next last**",
                Event{
                        Kind: "reply",
                        Text: "**first next last**",
@@ -172,9 +197,10 @@ func TestTerminalStylesOnlyRepliesAndWork(t *testing.T) {
                Event{Kind: "busy"},
                Event{Kind: "idle"},
        )
                Event{Kind: "busy"},
                Event{Kind: "idle"},
        )
-       require.Equal(t, "\x1b[1mfirst next\x1b[0m\n\x1b[1mlast\x1b[0m\n[BlueBird]\n\x1b[1mReport\x1b[0m\n"+
+
+       require.Equal(t, "[working]\n\x1b[1mfirst next\x1b[0m\n\x1b[1mlast\x1b[0m\n[BlueBird]\n\x1b[1mReport\x1b[0m\n"+
                "[tool] **raw tool**\n[result] **raw result**\n[error] **raw error**\n**raw notice**\n[telegram] **raw input**\n"+
                "[tool] **raw tool**\n[result] **raw result**\n[error] **raw error**\n**raw notice**\n[telegram] **raw input**\n"+
-               "[connected to **raw agent**]\n[BlueBird] started\n[working]\n[done]\n", out.String())
+               "[connected to **raw agent**]\n[BlueBird] started\n[working]\n[done]\n> ", out.String())
 }
 
 func TestTerminalZeroWidthUsesEightyAndReadsChanges(t *testing.T) {
 }
 
 func TestTerminalZeroWidthUsesEightyAndReadsChanges(t *testing.T) {
@@ -192,11 +218,94 @@ func TestTerminalZeroWidthUsesEightyAndReadsChanges(t *testing.T) {
                Kind: "reply",
                Text: strings.Repeat("a", 81),
        })
                Kind: "reply",
                Text: strings.Repeat("a", 81),
        })
-       require.Equal(t, strings.Repeat("a", 80)+"\na\n", out.String())
+
+       require.Equal(t, strings.Repeat("a", 80)+"\na\n> ", out.String())
        require.NoError(t, unix.IoctlSetWinsize(fd, unix.TIOCSWINSZ, &unix.Winsize{Col: 40}))
        require.Equal(t, 40, terminalColumns(&out))
 }
 
        require.NoError(t, unix.IoctlSetWinsize(fd, unix.TIOCSWINSZ, &unix.Winsize{Col: 40}))
        require.Equal(t, 40, terminalColumns(&out))
 }
 
+func TestTerminalPromptsAfterIdleEventsAndClearsBeforeShownEvents(t *testing.T) {
+       fd, err := unix.Open("/dev/ptmx", unix.O_RDWR|unix.O_NOCTTY, 0)
+       require.NoError(t, err)
+
+       defer func() {
+               require.NoError(t, unix.Close(fd))
+       }()
+
+       out := TerminalTestOutput{fd: fd}
+       terminalTestShowEvents(t, &out,
+               Event{
+                       Kind: "ready",
+                       Text: "Example",
+               },
+               Event{
+                       Kind:   "user",
+                       Source: terminalSource,
+                       Text:   "hidden",
+               },
+               Event{Kind: "unknown"},
+               Event{
+                       Kind: "notice",
+                       Text: "Idle notice",
+               },
+               Event{
+                       Kind: "work",
+                       Text: "**Idle report**",
+               },
+               Event{Kind: "busy"},
+               Event{
+                       Kind: "notice",
+                       Text: "Busy notice",
+               },
+               Event{
+                       Kind: "reply",
+                       Text: "**Answer**",
+               },
+               Event{Kind: "idle"},
+               Event{
+                       Kind: "error",
+                       Text: "Idle error",
+               },
+       )
+
+       require.Equal(t, "[connected to Example]\n> "+
+               "\r\x1b[2KIdle notice\n> "+
+               "\r\x1b[2K\x1b[1mIdle report\x1b[0m\n> "+
+               "\r\x1b[2K[working]\nBusy notice\n\x1b[1mAnswer\x1b[0m\n[done]\n> "+
+               "\r\x1b[2K[error] Idle error\n> ", out.String())
+}
+
+func TestTerminalNonterminalEventsHaveNoPromptOrClearCommands(t *testing.T) {
+       var out strings.Builder
+
+       terminalTestShowEvents(t, &out,
+               Event{
+                       Kind: "ready",
+                       Text: "Example",
+               },
+               Event{
+                       Kind: "notice",
+                       Text: "Idle notice",
+               },
+               Event{Kind: "busy"},
+               Event{
+                       Kind: "notice",
+                       Text: "Busy notice",
+               },
+               Event{
+                       Kind: "reply",
+                       Text: "**Answer**",
+               },
+               Event{Kind: "idle"},
+               Event{
+                       Kind: "notice",
+                       Text: "Idle again",
+               },
+       )
+
+       require.Equal(t, "[connected to Example]\nIdle notice\n[working]\nBusy notice\n**Answer**\n[done]\nIdle again\n", out.String())
+}
+
 // TerminalTestOutput captures text while it supplies a test terminal
 // descriptor.
 type TerminalTestOutput struct {
 // TerminalTestOutput captures text while it supplies a test terminal
 // descriptor.
 type TerminalTestOutput struct {