package cli //nolint:testpackage // shares programName and the capture helpers import ( "os" "testing" "github.com/stretchr/testify/assert" ) // TestEntryReturnsStatusCode pins the contract main() relies on for // issue #75: Entry reports success or failure through its return value // and never calls os.Exit. An os.Exit from inside Entry would skip // main's deferred profile writers and truncate the profile of a failing // command. main turns this code into os.Exit only after those defers // run, so a failing command must come back with a non-zero code rather // than ending the process here. // // Stdout is captured only to keep the banner and command output off the // test log; the assertion is on the returned code. // //nolint:paralleltest // replaces os.Args and rootFlags func TestEntryReturnsStatusCode(t *testing.T) { for _, testCase := range []struct { name string args []string want int }{ { // version is self-contained: it needs no config and no // destination store, so it exercises the success path. name: "successful command returns zero", args: []string{programName, "version"}, want: 0, }, { name: "unknown command returns one", args: []string{programName, "no-such-command"}, want: 1, }, } { t.Run(testCase.name, func(t *testing.T) { previousArgs := os.Args t.Cleanup(func() { os.Args = previousArgs rootFlags = RootFlags{} }) os.Args = testCase.args var code int _ = captureProcessStdout(t, func() { code = Entry() }) assert.Equal(t, testCase.want, code) }) } }