]> git.giacomolli.uk - onechat/blob - terminal_client_helper_test.go
Show styled replies only on terminal output
[onechat] / terminal_client_helper_test.go
1 package main
2
3 import (
4         "fmt"
5         "io"
6         "net"
7         "strings"
8         "testing"
9         "time"
10
11         "github.com/stretchr/testify/require"
12 )
13
14 // TerminalTestClient is a terminal client of a test daemon, with a pipe as its
15 // input.
16 type TerminalTestClient struct {
17         input *io.PipeWriter
18         done  chan error
19         out   *SyncBuffer
20 }
21
22 // Type writes one line to the input of the client.
23 func (c *TerminalTestClient) Type(line string) {
24         _, err := io.WriteString(c.input, line+"\n")
25         if err != nil {
26                 panic(err)
27         }
28 }
29
30 // Output returns what the client showed.
31 func (c *TerminalTestClient) Output() string {
32         return c.out.String()
33 }
34
35 // WaitFor waits until the client showed text.
36 func (c *TerminalTestClient) WaitFor(t *testing.T, text string) {
37         t.Helper()
38
39         require.Eventually(t, func() bool {
40                 return strings.Contains(c.Output(), text)
41         }, 10*time.Second, time.Millisecond, "output so far: %q", c.Output())
42 }
43
44 // Close ends the input and waits for the client.
45 func (c *TerminalTestClient) Close() error {
46         err := c.input.Close()
47         if err != nil {
48                 return fmt.Errorf("close terminal input: %w", err)
49         }
50
51         return <-c.done
52 }
53
54 // terminalStartTestClient connects a client to the daemon at socket.
55 func terminalStartTestClient(t *testing.T, socket string) *TerminalTestClient {
56         t.Helper()
57
58         conn, err := net.Dial("unix", socket)
59         require.NoError(t, err)
60
61         reader, writer := io.Pipe()
62         client := &TerminalTestClient{
63                 input: writer,
64                 done:  make(chan error, 1),
65                 out:   &SyncBuffer{},
66         }
67
68         go func() {
69                 client.done <- terminalSession(t.Context(), conn, reader, client.out)
70         }()
71
72         t.Cleanup(func() {
73                 _ = writer.Close()
74         })
75
76         return client
77 }