refactor: prompt tests

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
This commit is contained in:
Alano Terblanche 2024-03-26 10:07:01 +01:00
parent d2ea5adfe4
commit 7ea10d5ced
No known key found for this signature in database
GPG Key ID: 0E8FACD1BA98DE27
1 changed files with 35 additions and 102 deletions

View File

@ -106,91 +106,33 @@ func TestPromptForConfirmation(t *testing.T) {
}() }()
for _, tc := range []struct { for _, tc := range []struct {
desc string desc string
f func(*testing.T, context.Context, chan promptResult) f func() error
expected promptResult
}{ }{
{"SIGINT", func(t *testing.T, ctx context.Context, c chan promptResult) { {"SIGINT", func() error {
t.Helper()
syscall.Kill(syscall.Getpid(), syscall.SIGINT) syscall.Kill(syscall.Getpid(), syscall.SIGINT)
return nil
select { }, promptResult{false, command.ErrPromptTerminated}},
case <-ctx.Done(): {"no", func() error {
t.Fatal("PromptForConfirmation did not return after SIGINT")
case r := <-c:
assert.Check(t, !r.result)
assert.ErrorContains(t, r.err, "prompt terminated")
}
}},
{"no", func(t *testing.T, ctx context.Context, c chan promptResult) {
t.Helper()
_, err := fmt.Fprint(promptWriter, "n\n") _, err := fmt.Fprint(promptWriter, "n\n")
assert.NilError(t, err) return err
}, promptResult{false, nil}},
select { {"yes", func() error {
case <-ctx.Done():
t.Fatal("PromptForConfirmation did not return after user input `n`")
case r := <-c:
assert.Check(t, !r.result)
assert.NilError(t, r.err)
}
}},
{"yes", func(t *testing.T, ctx context.Context, c chan promptResult) {
t.Helper()
_, err := fmt.Fprint(promptWriter, "y\n") _, err := fmt.Fprint(promptWriter, "y\n")
assert.NilError(t, err) return err
}, promptResult{true, nil}},
select { {"any", func() error {
case <-ctx.Done():
t.Fatal("PromptForConfirmation did not return after user input `y`")
case r := <-c:
assert.Check(t, r.result)
assert.NilError(t, r.err)
}
}},
{"any", func(t *testing.T, ctx context.Context, c chan promptResult) {
t.Helper()
_, err := fmt.Fprint(promptWriter, "a\n") _, err := fmt.Fprint(promptWriter, "a\n")
assert.NilError(t, err) return err
}, promptResult{false, nil}},
select { {"with space", func() error {
case <-ctx.Done():
t.Fatal("PromptForConfirmation did not return after user input `a`")
case r := <-c:
assert.Check(t, !r.result)
assert.NilError(t, r.err)
}
}},
{"with space", func(t *testing.T, ctx context.Context, c chan promptResult) {
t.Helper()
_, err := fmt.Fprint(promptWriter, " y\n") _, err := fmt.Fprint(promptWriter, " y\n")
assert.NilError(t, err) return err
}, promptResult{true, nil}},
select { {"reader closed", func() error {
case <-ctx.Done(): return promptReader.Close()
t.Fatal("PromptForConfirmation did not return after user input ` y`") }, promptResult{false, nil}},
case r := <-c:
assert.Check(t, r.result)
assert.NilError(t, r.err)
}
}},
{"reader closed", func(t *testing.T, ctx context.Context, c chan promptResult) {
t.Helper()
assert.NilError(t, promptReader.Close())
select {
case <-ctx.Done():
t.Fatal("PromptForConfirmation did not return after promptReader was closed")
case r := <-c:
assert.Check(t, !r.result)
assert.NilError(t, r.err)
}
}},
} { } {
t.Run("case="+tc.desc, func(t *testing.T) { t.Run("case="+tc.desc, func(t *testing.T) {
buf.Reset() buf.Reset()
@ -207,17 +149,25 @@ func TestPromptForConfirmation(t *testing.T) {
result <- promptResult{r, err} result <- promptResult{r, err}
}() }()
// wait for the Prompt to write to the buffer select {
pollForPromptOutput(ctx, t, wroteHook) case <-time.After(100 * time.Millisecond):
drainChannel(ctx, wroteHook) case <-wroteHook:
}
assert.NilError(t, bufioWriter.Flush()) assert.NilError(t, bufioWriter.Flush())
assert.Equal(t, strings.TrimSpace(buf.String()), "Are you sure you want to proceed? [y/N]") assert.Equal(t, strings.TrimSpace(buf.String()), "Are you sure you want to proceed? [y/N]")
resultCtx, resultCancel := context.WithTimeout(ctx, 500*time.Millisecond) // wait for the Prompt to write to the buffer
defer resultCancel() drainChannel(ctx, wroteHook)
tc.f(t, resultCtx, result) assert.NilError(t, tc.f())
select {
case <-time.After(500 * time.Millisecond):
t.Fatal("timeout waiting for prompt result")
case r := <-result:
assert.Equal(t, r, tc.expected)
}
}) })
} }
} }
@ -233,20 +183,3 @@ func drainChannel(ctx context.Context, ch <-chan struct{}) {
} }
}() }()
} }
func pollForPromptOutput(ctx context.Context, t *testing.T, wroteHook <-chan struct{}) {
t.Helper()
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
for {
select {
case <-ctx.Done():
t.Fatal("Prompt output was not written to before ctx was cancelled")
return
case <-wroteHook:
return
}
}
}