diff --git a/commands.go b/commands.go index 117f7a6..5a4d3f0 100644 --- a/commands.go +++ b/commands.go @@ -51,3 +51,27 @@ func Tick(d time.Duration, fn func(time.Time) Msg) Cmd { return fn(<-t.C) } } + +// Sequentially produces a command that sequentially executes the given +// commands. +// The Msg returned is the first non-nil message returned by a Cmd. +// +// func saveStateCmd() Msg { +// if err := save(); err != nil { +// return errMsg{err} +// } +// return nil +// } +// +// cmd := Sequentially(saveStateCmd, Quit) +// +func Sequentially(cmds ...Cmd) Cmd { + return func() Msg { + for _, cmd := range cmds { + if msg := cmd(); msg != nil { + return msg + } + } + return nil + } +} diff --git a/commands_test.go b/commands_test.go new file mode 100644 index 0000000..2a11fbc --- /dev/null +++ b/commands_test.go @@ -0,0 +1,56 @@ +package tea + +import ( + "fmt" + "testing" +) + +func TestSequentially(t *testing.T) { + var expectedErrMsg = fmt.Errorf("some err") + var expectedStrMsg = "some msg" + + var nilReturnCmd = func() Msg { + return nil + } + + tests := []struct { + name string + cmds []Cmd + expected Msg + }{ + { + name: "all nil", + cmds: []Cmd{nilReturnCmd, nilReturnCmd}, + expected: nil, + }, + { + name: "one error", + cmds: []Cmd{ + nilReturnCmd, + func() Msg { + return expectedErrMsg + }, + nilReturnCmd, + }, + expected: expectedErrMsg, + }, + { + name: "some msg", + cmds: []Cmd{ + nilReturnCmd, + func() Msg { + return expectedStrMsg + }, + nilReturnCmd, + }, + expected: expectedStrMsg, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if msg := Sequentially(test.cmds...)(); msg != test.expected { + t.Fatalf("expected a msg %v but got %v", test.expected, msg) + } + }) + } +}