diff --git a/cmd/init.go b/cmd/init.go index 23c0acb1173..4026011d1e5 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "path" "text/template" @@ -13,7 +14,10 @@ import ( const defaultNewScriptName = "script.js" -var defaultNewScriptTemplate = template.Must(template.New("init").Parse(`import http from 'k6/http'; +//nolint:gochecknoglobals +var ( + errFileExists = errors.New("file already exists") + defaultNewScriptTemplate = template.Must(template.New("init").Parse(`import http from 'k6/http'; import { sleep } from 'k6'; export const options = { @@ -69,6 +73,7 @@ export default function() { sleep(1); } `)) +) type initScriptTemplateArgs struct { ScriptName string @@ -88,7 +93,7 @@ func (c *initCmd) flagSet() *pflag.FlagSet { return flags } -func (c *initCmd) run(cmd *cobra.Command, args []string) error { +func (c *initCmd) run(cmd *cobra.Command, args []string) error { //nolint:revive target := defaultNewScriptName if len(args) > 0 { target = args[0] @@ -101,14 +106,14 @@ func (c *initCmd) run(cmd *cobra.Command, args []string) error { if fileExists && !c.overwriteFiles { c.gs.Logger.Errorf("%s already exists", target) - return err + return errFileExists } fd, err := c.gs.FS.Create(target) if err != nil { return err } - defer fd.Close() + defer fd.Close() //nolint:errcheck if err := defaultNewScriptTemplate.Execute(fd, initScriptTemplateArgs{ ScriptName: path.Base(target), diff --git a/cmd/init_test.go b/cmd/init_test.go new file mode 100644 index 00000000000..da34f6b26e0 --- /dev/null +++ b/cmd/init_test.go @@ -0,0 +1,97 @@ +package cmd + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.k6.io/k6/cmd/tests" + "go.k6.io/k6/lib/fsext" +) + +func TestInitScript(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + scriptNameArg string + expectedCloudName string + expectedFilePath string + }{ + { + name: "default script name", + expectedCloudName: "script.js", + expectedFilePath: defaultNewScriptName, + }, + { + name: "user-specified script name", + scriptNameArg: "mytest.js", + expectedCloudName: "mytest.js", + expectedFilePath: "mytest.js", + }, + { + name: "script outside of current working directory", + scriptNameArg: "../mytest.js", + expectedCloudName: "mytest.js", + expectedFilePath: "../mytest.js", + }, + } + + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + ts := tests.NewGlobalTestState(t) + ts.CmdArgs = []string{"k6", "init"} + if testCase.scriptNameArg != "" { + ts.CmdArgs = append(ts.CmdArgs, testCase.scriptNameArg) + } + + newRootCommand(ts.GlobalState).execute() + + data, err := fsext.ReadFile(ts.FS, testCase.expectedFilePath) + require.NoError(t, err) + + jsData := string(data) + assert.Contains(t, jsData, "export const options = {") + assert.Contains(t, jsData, fmt.Sprintf(`name: "%s"`, testCase.expectedCloudName)) + assert.Contains(t, jsData, "export default function() {") + }) + } +} + +func TestInitScript_FileExists_NoOverwrite(t *testing.T) { + t.Parallel() + + ts := tests.NewGlobalTestState(t) + require.NoError(t, fsext.WriteFile(ts.FS, defaultNewScriptName, []byte("untouched"), 0o644)) + + ts.CmdArgs = []string{"k6", "init"} + ts.ExpectedExitCode = -1 + + newRootCommand(ts.GlobalState).execute() + + data, err := fsext.ReadFile(ts.FS, defaultNewScriptName) + require.NoError(t, err) + + assert.Contains(t, string(data), "untouched") +} + +func TestInitScript_FileExists_Overwrite(t *testing.T) { + t.Parallel() + + ts := tests.NewGlobalTestState(t) + require.NoError(t, fsext.WriteFile(ts.FS, defaultNewScriptName, []byte("untouched"), 0o644)) + + ts.CmdArgs = []string{"k6", "init", "-f"} + + newRootCommand(ts.GlobalState).execute() + + data, err := fsext.ReadFile(ts.FS, defaultNewScriptName) + require.NoError(t, err) + + assert.Contains(t, string(data), "export const options = {") + assert.Contains(t, string(data), "export default function() {") +}