Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ type testExecModel struct {
err error
}

type testExecNoInputModel struct{ testExecModel }

func (m *testExecModel) Init() Cmd {
c := exec.Command(m.cmd) //nolint:gosec
return ExecProcess(c, func(err error) Msg {
return execFinishedMsg{err}
})
}

func (m *testExecNoInputModel) Init() Cmd {
return ExecProcess(successExecCommand(), func(err error) Msg {
return execFinishedMsg{err}
})
}

Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testExecNoInputModel embeds testExecModel, but it relies on the promoted Update method whose receiver is *testExecModel. That Update returns m (a *testExecModel), so after the first update the program’s model type changes from *testExecNoInputModel to *testExecModel. This is a bit brittle/confusing for a regression test; consider giving testExecNoInputModel its own Update/View (or avoid embedding) so it consistently returns the same concrete model type.

Suggested change
func (m *testExecNoInputModel) Update(msg Msg) (Model, Cmd) {
switch msg := msg.(type) {
case execFinishedMsg:
if msg.err != nil {
m.err = msg.err
}
return m, Quit
}
return m, nil
}
func (m *testExecNoInputModel) View() View {
return m.testExecModel.View()
}

Copilot uses AI. Check for mistakes.
func (m *testExecModel) Update(msg Msg) (Model, Cmd) {
switch msg := msg.(type) {
case execFinishedMsg:
Expand All @@ -42,6 +50,13 @@ type spyRenderer struct {
calledReset bool
}

func successExecCommand() *exec.Cmd {
if runtime.GOOS == "windows" {
return exec.Command("cmd", "/c", "exit 0")
}
return exec.Command("true")
}

func TestTeaExec(t *testing.T) {
type test struct {
name string
Expand Down Expand Up @@ -101,3 +116,20 @@ func TestTeaExec(t *testing.T) {
})
}
}

func TestTeaExecWithNilInput(t *testing.T) {
var buf bytes.Buffer

m := &testExecNoInputModel{}
p := NewProgram(m,
WithInput(nil),
WithOutput(&buf),
)

if _, err := p.Run(); err != nil {
t.Fatal(err)
}
if m.err != nil {
t.Fatalf("expected no error, got %v", m.err)
}
}
6 changes: 4 additions & 2 deletions tea.go
Original file line number Diff line number Diff line change
Expand Up @@ -1347,8 +1347,10 @@ func (p *Program) RestoreTerminal() error {
if err := p.initTerminal(); err != nil {
return err
}
if err := p.initInputReader(false); err != nil {
return err
if p.input != nil {
if err := p.initInputReader(false); err != nil {
return err
}
}

p.startRenderer()
Expand Down
Loading