package cli_test import ( "strings" "testing" "git.eeqj.de/sneak/secret/internal/cli" "git.eeqj.de/sneak/secret/internal/secret" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // usageHeading starts the usage text cobra prints after an error. const usageHeading = "Usage:" // A command called wrongly gets usage after its error; a command that // fails while running gets its error alone. Either way the command fails // and its error is shown exactly once. // //nolint:paralleltest // executes the CLI in-process and sets the environment func TestUsageOnlyForCallErrors(t *testing.T) { // No vault in the state directory, so `get x` fails while running. env := map[string]string{secret.EnvStateDir: t.TempDir()} tests := []struct { args []string wantUsage bool }{ {args: []string{"get"}, wantUsage: true}, {args: []string{"get", "x", "y"}, wantUsage: true}, {args: []string{"get", "--no-such-flag", "x"}, wantUsage: true}, {args: []string{"generate", "secret", "x", "--length", "abc"}, wantUsage: true}, {args: []string{"import", "x"}, wantUsage: true}, {args: []string{"get", "x"}, wantUsage: false}, } for _, tt := range tests { output, err := cli.ExecuteCommandInProcess(tt.args, "", env) require.Error(t, err, "%v should fail", tt.args) assert.Equal(t, 1, strings.Count(output, err.Error()), "%v should show its error once:\n%s", tt.args, output) assert.Equal(t, tt.wantUsage, strings.Contains(output, usageHeading), "usage shown for %v:\n%s", tt.args, output) } }