package cmd import ( "errors" "os" "strings" "testing" "github.com/snyk/driftctl/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestGenDriftIgnoreCmd_Input(t *testing.T) { cases := []struct { name string args []string output string err error }{ { name: "test error on invalid input", args: []string{"-i", "./testdata/input_stdin_invalid.json"}, output: "./testdata/output_stdin_empty.txt", err: errors.New("invalid character 'i' looking for beginning of value"), }, { name: "test empty driftignore with valid input", args: []string{"-i", "./testdata/input_stdin_empty.json"}, output: "./testdata/output_stdin_empty.txt", err: nil, }, { name: "test driftignore content with valid input", args: []string{"-i", "./testdata/input_stdin_valid.json"}, output: "./testdata/output_stdin_valid.txt", err: nil, }, { name: "test driftignore content with valid input and filter missing & changed only", args: []string{"-i", "./testdata/input_stdin_valid.json", "--exclude-unmanaged"}, output: "./testdata/output_stdin_valid_filter.txt", err: nil, }, { name: "test driftignore content with valid input and filter unmanaged only", args: []string{"-i", "./testdata/input_stdin_valid.json", "--exclude-missing", "--exclude-changed"}, output: "./testdata/output_stdin_valid_filter2.txt", err: nil, }, { name: "test error when input file does not exist", args: []string{"-i", "doesnotexist"}, output: "./testdata/output_stdin_valid_filter2.txt", err: errors.New("open doesnotexist: no such file or directory"), }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { rootCmd := &cobra.Command{Use: "root"} rootCmd.AddCommand(NewGenDriftIgnoreCmd()) f, err := os.CreateTemp("", "TestGenDriftIgnoreCmd_Input") require.Nil(t, err) defer func() { f.Close() os.Remove(f.Name()) }() args := append([]string{"gen-driftignore", "-o", f.Name()}, c.args...) _, err = test.Execute(rootCmd, args...) if c.err != nil { assert.EqualError(t, err, c.err.Error()) return } else { assert.Equal(t, c.err, err) } output, err := os.ReadFile(f.Name()) require.Nil(t, err) if c.output != "" { expectedOutput, err := os.ReadFile(c.output) require.Nil(t, err) assert.Equal(t, string(expectedOutput), trimLeadingComment(string(output))) } }) } } func TestGenDriftIgnoreCmd_ValidFlags(t *testing.T) { rootCmd := &cobra.Command{Use: "root"} genDriftIgnoreCmd := NewGenDriftIgnoreCmd() genDriftIgnoreCmd.RunE = func(_ *cobra.Command, args []string) error { return nil } rootCmd.AddCommand(genDriftIgnoreCmd) cases := []struct { args []string }{ {args: []string{"gen-driftignore"}}, {args: []string{"gen-driftignore", "--exclude-unmanaged"}}, {args: []string{"gen-driftignore", "--exclude-missing"}}, {args: []string{"gen-driftignore", "--exclude-changed"}}, {args: []string{"gen-driftignore", "--exclude-changed=false", "--exclude-missing=false", "--exclude-unmanaged=true"}}, {args: []string{"gen-driftignore", "--input", "-"}}, {args: []string{"gen-driftignore", "-i", "/dev/stdout"}}, } for _, tt := range cases { output, err := test.Execute(rootCmd, tt.args...) if output != "" { t.Errorf("Unexpected output: %v", output) } if err != nil { t.Errorf("Unexpected error: %v", err) } } } func TestGenDriftIgnoreCmd_InvalidFlags(t *testing.T) { rootCmd := &cobra.Command{Use: "root"} genDriftIgnoreCmd := NewGenDriftIgnoreCmd() genDriftIgnoreCmd.RunE = func(_ *cobra.Command, args []string) error { return nil } rootCmd.AddCommand(genDriftIgnoreCmd) cases := []struct { args []string err error }{ {args: []string{"gen-driftignore", "--deleted"}, err: errors.New("unknown flag: --deleted")}, {args: []string{"gen-driftignore", "--drifted"}, err: errors.New("unknown flag: --drifted")}, {args: []string{"gen-driftignore", "--changed"}, err: errors.New("unknown flag: --changed")}, {args: []string{"gen-driftignore", "--missing"}, err: errors.New("unknown flag: --missing")}, {args: []string{"gen-driftignore", "--input"}, err: errors.New("flag needs an argument: --input")}, {args: []string{"gen-driftignore", "-i"}, err: errors.New("flag needs an argument: 'i' in -i")}, } for _, tt := range cases { _, err := test.Execute(rootCmd, tt.args...) assert.EqualError(t, err, tt.err.Error()) } } // The leading comment, "Generated by gen-driftignore..." contains a timestamp, // that we don't care to assert on. func trimLeadingComment(content string) string { lines := strings.Split(content, "\n") return strings.Join(lines[1:], "\n") }