test(01-04): cover tool, output, watch loop and workspace modules

- Non-TTY widgets/prompts, flag parsing, secret non-leak and malicious IDs
- Real hello workspace rebuild latency line, debounce and ignored bin/tmp
- scripts/check-phase1.sh runs vet/test/race across root, hello, base, greeter, optional
This commit is contained in:
Jakub Zych
2026-09-16 14:14:05 +02:00
parent a43c734546
commit dc7997e45c
6 changed files with 542 additions and 2 deletions

View File

@@ -2,6 +2,8 @@ package bonfire
import (
"bytes"
"context"
"errors"
"io"
"strings"
"testing"
@@ -73,6 +75,58 @@ func TestSecretReadsPlainStdinLine(t *testing.T) {
}
}
func TestChoiceEOFUsesDefault(t *testing.T) {
var buf bytes.Buffer
out := NewOutput(strings.NewReader(""), &buf, &buf)
got, err := out.Choice("pick", []string{"a", "b", "c"}, 2)
if err != nil {
t.Fatal(err)
}
if got != "c" {
t.Fatalf("choice eof = %q", got)
}
}
func TestChoiceEmptyOptionsError(t *testing.T) {
var buf bytes.Buffer
out := NewOutput(strings.NewReader("1\n"), &buf, &buf)
_, err := out.Choice("pick", nil, 0)
if err == nil {
t.Fatal("expected empty choice error")
}
}
func TestSecretNotLeakedOnCommandError(t *testing.T) {
var stdout, stderr bytes.Buffer
root, err := NewRootIO("app", []Command{{
Name: "auth:login",
Description: "login",
Run: func(ctx context.Context, in Input, out Output) error {
secret, err := out.Secret("token")
if err != nil {
return err
}
if secret == "" {
return errors.New("empty token")
}
out.Error("login failed")
return errors.New("login failed")
},
}}, strings.NewReader("s3cret\n"), &stdout, &stderr)
if err != nil {
t.Fatal(err)
}
root.SetArgs([]string{"auth:login"})
runErr := root.Execute()
if runErr == nil {
t.Fatal("expected command error")
}
combined := stdout.String() + stderr.String() + runErr.Error()
if strings.Contains(combined, "s3cret") {
t.Fatalf("secret leaked into streams: stdout=%q stderr=%q err=%v", stdout.String(), stderr.String(), runErr)
}
}
func TestClosedStdinDoesNotHang(t *testing.T) {
var buf bytes.Buffer
out := NewOutput(io.NopCloser(strings.NewReader("")), &buf, &buf)