From c956febfe4fae41d6509258ad9454c2c316a51ed Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Thu, 13 Feb 2025 00:00:55 +0100 Subject: [PATCH] add test workflows to cmd pkg (#2665) * add test workflows to cmd pkg * list-options as well * add more tests * test entrypoint as well * update exit code 1 test --- cmd/execute_test.go | 45 ++++++++++++++++++++++++++++++++++++ cmd/root.go | 15 ++++++++---- cmd/root_test.go | 56 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 cmd/execute_test.go diff --git a/cmd/execute_test.go b/cmd/execute_test.go new file mode 100644 index 0000000..90f43fd --- /dev/null +++ b/cmd/execute_test.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "context" + "os" + "testing" +) + +// Helper function to test main with different os.Args +func testMain(args []string) (exitCode int) { + // Save original os.Args and defer restoring it + origArgs := os.Args + defer func() { os.Args = origArgs }() + + // Save original os.Exit and defer restoring it + defer func() { exitFunc = os.Exit }() + + // Mock os.Exit + fakeExit := func(code int) { + exitCode = code + } + exitFunc = fakeExit + + // Mock os.Args + os.Args = args + + // Run the main function + Execute(context.Background(), "") + + return exitCode +} + +func TestMainHelp(t *testing.T) { + exitCode := testMain([]string{"cmd", "--help"}) + if exitCode != 0 { + t.Errorf("Expected exit code 0, got %d", exitCode) + } +} + +func TestMainNoArgsError(t *testing.T) { + exitCode := testMain([]string{"cmd"}) + if exitCode != 1 { + t.Errorf("Expected exit code 1, got %d", exitCode) + } +} diff --git a/cmd/root.go b/cmd/root.go index be7ec47..e18e26e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -41,9 +41,19 @@ type Flag struct { Description string `json:"description"` } +var exitFunc = os.Exit + // Execute is the entry point to running the CLI func Execute(ctx context.Context, version string) { input := new(Input) + rootCmd := createRootCommand(ctx, input, version) + + if err := rootCmd.Execute(); err != nil { + exitFunc(1) + } +} + +func createRootCommand(ctx context.Context, input *Input, version string) *cobra.Command { rootCmd := &cobra.Command{ Use: "act [event name to run] [flags]\n\nIf no event name passed, will default to \"on: push\"\nIf actions handles only one event it will be used as default instead of \"on: push\"", Short: "Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.", @@ -117,10 +127,7 @@ func Execute(ctx context.Context, version string) { rootCmd.PersistentFlags().StringArrayVarP(&input.localRepository, "local-repository", "", []string{}, "Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)") rootCmd.PersistentFlags().BoolVar(&input.listOptions, "list-options", false, "Print a json structure of compatible options") rootCmd.SetArgs(args()) - - if err := rootCmd.Execute(); err != nil { - os.Exit(1) - } + return rootCmd } // Return locations where Act's config can be found in order: XDG spec, .actrc in HOME directory, .actrc in invocation directory diff --git a/cmd/root_test.go b/cmd/root_test.go index fa4f8bd..ec95385 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "path" "testing" @@ -26,3 +27,58 @@ line2 line3 `, secrets["mysecret"]) } + +func TestListOptions(t *testing.T) { + rootCmd := createRootCommand(context.Background(), &Input{}, "") + err := newRunCommand(context.Background(), &Input{ + listOptions: true, + })(rootCmd, []string{}) + assert.NoError(t, err) +} + +func TestRun(t *testing.T) { + rootCmd := createRootCommand(context.Background(), &Input{}, "") + err := newRunCommand(context.Background(), &Input{ + platforms: []string{"ubuntu-latest=node:16-buster-slim"}, + workdir: "../pkg/runner/testdata/", + workflowsPath: "./basic/push.yml", + })(rootCmd, []string{}) + assert.NoError(t, err) +} + +func TestRunPush(t *testing.T) { + rootCmd := createRootCommand(context.Background(), &Input{}, "") + err := newRunCommand(context.Background(), &Input{ + platforms: []string{"ubuntu-latest=node:16-buster-slim"}, + workdir: "../pkg/runner/testdata/", + workflowsPath: "./basic/push.yml", + })(rootCmd, []string{"push"}) + assert.NoError(t, err) +} + +func TestRunPushJsonLogger(t *testing.T) { + rootCmd := createRootCommand(context.Background(), &Input{}, "") + err := newRunCommand(context.Background(), &Input{ + platforms: []string{"ubuntu-latest=node:16-buster-slim"}, + workdir: "../pkg/runner/testdata/", + workflowsPath: "./basic/push.yml", + jsonLogger: true, + })(rootCmd, []string{"push"}) + assert.NoError(t, err) +} + +func TestFlags(t *testing.T) { + for _, f := range []string{"graph", "list", "bug-report", "man-page"} { + t.Run("TestFlag-"+f, func(t *testing.T) { + rootCmd := createRootCommand(context.Background(), &Input{}, "") + err := rootCmd.Flags().Set(f, "true") + assert.NoError(t, err) + err = newRunCommand(context.Background(), &Input{ + platforms: []string{"ubuntu-latest=node:16-buster-slim"}, + workdir: "../pkg/runner/testdata/", + workflowsPath: "./basic/push.yml", + })(rootCmd, []string{}) + assert.NoError(t, err) + }) + } +}