44package temporalcloudcli_test
55
66import (
7- "bytes"
87 "context"
98 "errors"
10- "fmt"
119 "io"
1210 "math/rand"
1311 "os"
14- "regexp"
15- "strings"
1612 "testing"
17- "time"
1813
1914 "github.com/stretchr/testify/assert"
2015 "github.com/stretchr/testify/require"
@@ -27,132 +22,6 @@ import (
2722 "github.com/temporalio/cloud-cli/temporalcloudcli/internal/printer"
2823)
2924
30- type CommandHarness struct {
31- * require.Assertions
32- t * testing.T
33- Options temporalcloudcli.CommandOptions
34- // Defaults to a context closed on close or test complete
35- Context context.Context
36- // Can be used to cancel context given to commands (simulating interrupt)
37- CancelContext context.CancelFunc
38- Stdin bytes.Buffer
39- }
40-
41- func NewCommandHarness (t * testing.T ) * CommandHarness {
42- h := & CommandHarness {Assertions : require .New (t ), t : t }
43- h .Context , h .CancelContext = context .WithCancel (context .Background ())
44- t .Cleanup (h .Close )
45- return h
46- }
47-
48- // Reentrant, called after test by default, cancels context
49- func (h * CommandHarness ) Close () {
50- // Cancel context
51- if h .CancelContext != nil {
52- h .CancelContext ()
53- }
54- }
55-
56- // Pieces must appear in order on the line and not overlap
57- func (h * CommandHarness ) ContainsOnSameLine (text string , pieces ... string ) {
58- h .NoError (AssertContainsOnSameLine (text , pieces ... ))
59- }
60-
61- func AssertContainsOnSameLine (text string , pieces ... string ) error {
62- // Build regex pattern based on pieces
63- pattern := ""
64- for _ , piece := range pieces {
65- if pattern != "" {
66- pattern += ".*"
67- }
68- pattern += regexp .QuoteMeta (piece )
69- }
70- regex , err := regexp .Compile (pattern )
71- if err != nil {
72- return err
73- }
74- // Split into lines, then check each piece is present
75- lines := strings .Split (text , "\n " )
76- for _ , line := range lines {
77- if regex .MatchString (line ) {
78- return nil
79- }
80- }
81- return fmt .Errorf ("pieces not found in order on any line together" )
82- }
83-
84- func TestAssertContainsOnSameLine (t * testing.T ) {
85- require .Error (t , AssertContainsOnSameLine ("a b c" , "b" , "a" ))
86- require .Error (t , AssertContainsOnSameLine ("a\n b c" , "a" , "b" ))
87- require .NoError (t , AssertContainsOnSameLine ("aba" , "b" , "a" ))
88- require .NoError (t , AssertContainsOnSameLine ("a b a" , "b" , "a" ))
89- require .NoError (t , AssertContainsOnSameLine ("axb" , "a" , "b" ))
90- require .NoError (t , AssertContainsOnSameLine ("a a" , "a" , "a" ))
91- }
92-
93- func (h * CommandHarness ) Eventually (
94- condition func () bool ,
95- waitFor time.Duration ,
96- tick time.Duration ,
97- msgAndArgs ... interface {},
98- ) {
99- h .t .Helper ()
100- // We cannot use require.Eventually because it was poorly developed to run the
101- // condition function in a goroutine which means it can run after complete or
102- // have other race conditions. Don't even need a complicated ticker because it
103- // doesn't need to be interruptible.
104- for start := time .Now (); time .Since (start ) < waitFor ; {
105- if condition () {
106- return
107- }
108- time .Sleep (tick )
109- }
110- h .Fail ("condition did not evaluate to true within timeout" , msgAndArgs ... )
111- }
112-
113- func (h * CommandHarness ) T () * testing.T {
114- return h .t
115- }
116-
117- type CommandResult struct {
118- Err error
119- Stdout bytes.Buffer
120- Stderr bytes.Buffer
121- }
122-
123- func (h * CommandHarness ) Execute (args ... string ) * CommandResult {
124- // Copy options, update as needed
125- res := & CommandResult {}
126- options := h .Options
127- // Set stdio
128- options .Stdin = & h .Stdin
129- options .Stdout = & res .Stdout
130- options .Stderr = & res .Stderr
131- // Set args
132- options .Args = args
133- // Capture error
134- options .Fail = func (err error ) {
135- if res .Err != nil {
136- panic ("fail called twice, just failed with " + err .Error ())
137- }
138- res .Err = err
139- }
140-
141- // Run
142- ctx , cancel := context .WithCancel (h .Context )
143- h .t .Cleanup (cancel )
144- defer cancel ()
145- h .t .Logf ("Calling: %v" , strings .Join (args , " " ))
146- temporalcloudcli .Execute (ctx , options )
147- if res .Stdout .Len () > 0 {
148- h .t .Logf ("Stdout:\n -----\n %s\n -----" , & res .Stdout )
149- }
150- if res .Stderr .Len () > 0 {
151- h .t .Logf ("Stderr:\n -----\n %s\n -----" , & res .Stderr )
152- }
153- return res
154- }
155-
15625type EnvLookupMap map [string ]string
15726
15827func (e EnvLookupMap ) Environ () []string {
0 commit comments