Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite53d1e5

Browse files
committed
fix: fix loss of buffered input on cliui.Prompt
1 parentf0a4de5 commite53d1e5

File tree

1 file changed

+54
-15
lines changed

1 file changed

+54
-15
lines changed

‎cli/cliui/prompt_test.go‎

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import (
77
"os"
88
"os/exec"
99
"testing"
10+
"time"
1011

1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
14+
"golang.org/x/xerrors"
1315

1416
"github.com/coder/coder/v2/cli/cliui"
1517
"github.com/coder/coder/v2/pty"
@@ -22,26 +24,29 @@ func TestPrompt(t *testing.T) {
2224
t.Parallel()
2325
t.Run("Success",func(t*testing.T) {
2426
t.Parallel()
27+
ctx:=testutil.Context(t,testutil.WaitShort)
2528
ptty:=ptytest.New(t)
2629
msgChan:=make(chanstring)
2730
gofunc() {
28-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
31+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
2932
Text:"Example",
3033
},nil)
3134
assert.NoError(t,err)
3235
msgChan<-resp
3336
}()
3437
ptty.ExpectMatch("Example")
3538
ptty.WriteLine("hello")
36-
require.Equal(t,"hello",<-msgChan)
39+
resp:=testutil.RequireRecvCtx(ctx,t,msgChan)
40+
require.Equal(t,"hello",resp)
3741
})
3842

3943
t.Run("Confirm",func(t*testing.T) {
4044
t.Parallel()
45+
ctx:=testutil.Context(t,testutil.WaitShort)
4146
ptty:=ptytest.New(t)
4247
doneChan:=make(chanstring)
4348
gofunc() {
44-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
49+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
4550
Text:"Example",
4651
IsConfirm:true,
4752
},nil)
@@ -50,18 +55,20 @@ func TestPrompt(t *testing.T) {
5055
}()
5156
ptty.ExpectMatch("Example")
5257
ptty.WriteLine("yes")
53-
require.Equal(t,"yes",<-doneChan)
58+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
59+
require.Equal(t,"yes",resp)
5460
})
5561

5662
t.Run("Skip",func(t*testing.T) {
5763
t.Parallel()
64+
ctx:=testutil.Context(t,testutil.WaitShort)
5865
ptty:=ptytest.New(t)
5966
varbuf bytes.Buffer
6067

6168
// Copy all data written out to a buffer. When we close the ptty, we can
6269
// no longer read from the ptty.Output(), but we can read what was
6370
// written to the buffer.
64-
dataRead,doneReading:=context.WithTimeout(context.Background(),testutil.WaitShort)
71+
dataRead,doneReading:=context.WithCancel(ctx)
6572
gofunc() {
6673
// This will throw an error sometimes. The underlying ptty
6774
// has its own cleanup routines in t.Cleanup. Instead of
@@ -74,7 +81,7 @@ func TestPrompt(t *testing.T) {
7481

7582
doneChan:=make(chanstring)
7683
gofunc() {
77-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
84+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
7885
Text:"ShouldNotSeeThis",
7986
IsConfirm:true,
8087
},func(inv*serpent.Invocation) {
@@ -85,7 +92,8 @@ func TestPrompt(t *testing.T) {
8592
doneChan<-resp
8693
}()
8794

88-
require.Equal(t,"yes",<-doneChan)
95+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
96+
require.Equal(t,"yes",resp)
8997
// Close the reader to end the io.Copy
9098
require.NoError(t,ptty.Close(),"close eof reader")
9199
// Wait for the IO copy to finish
@@ -96,42 +104,47 @@ func TestPrompt(t *testing.T) {
96104
})
97105
t.Run("JSON",func(t*testing.T) {
98106
t.Parallel()
107+
ctx:=testutil.Context(t,testutil.WaitShort)
99108
ptty:=ptytest.New(t)
100109
doneChan:=make(chanstring)
101110
gofunc() {
102-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
111+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
103112
Text:"Example",
104113
},nil)
105114
assert.NoError(t,err)
106115
doneChan<-resp
107116
}()
108117
ptty.ExpectMatch("Example")
109118
ptty.WriteLine("{}")
110-
require.Equal(t,"{}",<-doneChan)
119+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
120+
require.Equal(t,"{}",resp)
111121
})
112122

113123
t.Run("BadJSON",func(t*testing.T) {
114124
t.Parallel()
125+
ctx:=testutil.Context(t,testutil.WaitShort)
115126
ptty:=ptytest.New(t)
116127
doneChan:=make(chanstring)
117128
gofunc() {
118-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
129+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
119130
Text:"Example",
120131
},nil)
121132
assert.NoError(t,err)
122133
doneChan<-resp
123134
}()
124135
ptty.ExpectMatch("Example")
125136
ptty.WriteLine("{a")
126-
require.Equal(t,"{a",<-doneChan)
137+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
138+
require.Equal(t,"{a",resp)
127139
})
128140

129141
t.Run("MultilineJSON",func(t*testing.T) {
130142
t.Parallel()
143+
ctx:=testutil.Context(t,testutil.WaitShort)
131144
ptty:=ptytest.New(t)
132145
doneChan:=make(chanstring)
133146
gofunc() {
134-
resp,err:=newPrompt(ptty, cliui.PromptOptions{
147+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
135148
Text:"Example",
136149
},nil)
137150
assert.NoError(t,err)
@@ -141,11 +154,37 @@ func TestPrompt(t *testing.T) {
141154
ptty.WriteLine(`{
142155
"test": "wow"
143156
}`)
144-
require.Equal(t,`{"test":"wow"}`,<-doneChan)
157+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
158+
require.Equal(t,`{"test":"wow"}`,resp)
159+
})
160+
161+
t.Run("InvalidValid",func(t*testing.T) {
162+
t.Parallel()
163+
ctx:=testutil.Context(t,time.Minute*5)
164+
ptty:=ptytest.New(t)
165+
doneChan:=make(chanstring)
166+
gofunc() {
167+
resp,err:=newPrompt(ctx,ptty, cliui.PromptOptions{
168+
Text:"Example",
169+
Validate:func(sstring)error {
170+
t.Logf("validate: %q",s)
171+
ifs!="valid" {
172+
returnxerrors.New("invalid")
173+
}
174+
returnnil
175+
},
176+
},nil)
177+
assert.NoError(t,err)
178+
doneChan<-resp
179+
}()
180+
ptty.ExpectMatch("Example")
181+
ptty.WriteLine("foo\nbar\nbaz\n\n\nvalid\n")
182+
resp:=testutil.RequireRecvCtx(ctx,t,doneChan)
183+
require.Equal(t,"valid",resp)
145184
})
146185
}
147186

148-
funcnewPrompt(ptty*ptytest.PTY,opts cliui.PromptOptions,invOptfunc(inv*serpent.Invocation)) (string,error) {
187+
funcnewPrompt(ctx context.Context,ptty*ptytest.PTY,opts cliui.PromptOptions,invOptfunc(inv*serpent.Invocation)) (string,error) {
149188
value:=""
150189
cmd:=&serpent.Command{
151190
Handler:func(inv*serpent.Invocation)error {
@@ -163,7 +202,7 @@ func newPrompt(ptty *ptytest.PTY, opts cliui.PromptOptions, invOpt func(inv *ser
163202
inv.Stdout=ptty.Output()
164203
inv.Stderr=ptty.Output()
165204
inv.Stdin=ptty.Input()
166-
returnvalue,inv.WithContext(context.Background()).Run()
205+
returnvalue,inv.WithContext(ctx).Run()
167206
}
168207

169208
funcTestPasswordTerminalState(t*testing.T) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp