diff --git a/command.go b/command.go index 10d66b1..7dd6b52 100644 --- a/command.go +++ b/command.go @@ -100,6 +100,10 @@ func (c *Command) With(opts ...Option) *Command { // Run run command with input and output. func (c *Command) Run(ctx context.Context, in input.Input, out output.Output) error { + if c.Execute == nil { + return fmt.Errorf("%w", ErrExecuteNil) + } + if c.Handle != nil { return c.Handle(ctx, in, out, c.Execute) } diff --git a/command_test.go b/command_test.go index 62e593e..7579fbe 100644 --- a/command_test.go +++ b/command_test.go @@ -2,6 +2,7 @@ package console_test import ( "context" + "errors" "strings" "sync/atomic" "testing" @@ -125,3 +126,21 @@ func TestChainHandle(t *testing.T) { } } } + +func TestRunEmptyExecute(t *testing.T) { + t.Parallel() + + ctx := context.Background() + empty := console.Command{ + Name: "empty", + } + in := &input.Array{ + Map: input.Map{}, + } + out := output.Stdout() + + err := empty.Run(ctx, in, out) + if !errors.Is(err, console.ErrExecuteNil) { + t.Fatalf("expected: %v, got: %v ", console.ErrExecuteNil, err) + } +} diff --git a/error.go b/error.go new file mode 100644 index 0000000..6e29f34 --- /dev/null +++ b/error.go @@ -0,0 +1,31 @@ +package console + +import ( + "errors" + "fmt" + "strings" +) + +var ( + ErrNotFound = errors.New("command not found") + ErrCommandNil = errors.New("console: Register command is nil") + ErrExecuteNil = errors.New("console: execute is nil") + ErrCommandDuplicate = errors.New("console: duplicate command") +) + +type AlternativesError struct { + Alt []string + Err error +} + +func (e AlternativesError) Error() string { + return fmt.Sprintf("%s, alternatives: [%s]", e.Err, strings.Join(e.Alt, ",")) +} + +func (e AlternativesError) Is(err error) bool { + return errors.Is(e.Err, err) +} + +func (e AlternativesError) Unwrap() error { + return e.Err +} diff --git a/register.go b/register.go index 8cddd5d..7ed1a8a 100644 --- a/register.go +++ b/register.go @@ -5,7 +5,6 @@ import ( "fmt" "regexp" "sort" - "strings" "sync" ) @@ -14,12 +13,6 @@ const ( CommandList = "list" ) -var ( - ErrNotFound = errors.New("command not found") - ErrCommandNil = errors.New("console: Register command is nil") - ErrCommandDuplicate = errors.New("console: duplicate command") -) - //nolint:gochecknoglobals var ( commandsMu sync.RWMutex @@ -27,27 +20,6 @@ var ( findCommand = regexp.MustCompile("([^:]+|)") ) -type AlternativesError struct { - alt []string - err error -} - -func (e AlternativesError) Error() string { - return fmt.Sprintf("%s, alternatives: [%s]", e.err, strings.Join(e.alt, ",")) -} - -func (e AlternativesError) Is(err error) bool { - return errors.Is(e.err, err) -} - -func (e AlternativesError) Unwrap() error { - return e.err -} - -func (e AlternativesError) Alternatives() []string { - return e.alt -} - // MustRegister register command or panic if err. func MustRegister(cmd *Command) { if err := Register(cmd); err != nil { @@ -134,7 +106,7 @@ func Find(name string) (*Command, error) { names[i] = findCommands[i].Name } - return nil, AlternativesError{alt: names, err: ErrNotFound} + return nil, AlternativesError{Alt: names, Err: ErrNotFound} } return nil, ErrNotFound