1package cmd
2
3import (
4	"errors"
5	"io/ioutil"
6	"os"
7	"path/filepath"
8	"testing"
9
10	"github.com/spf13/viper"
11)
12
13// TestGoldenAddCmd initializes the project "github.com/spf13/testproject"
14// in GOPATH, adds "test" command
15// and compares the content of all files in cmd directory of testproject
16// with appropriate golden files.
17// Use -update to update existing golden files.
18func TestGoldenAddCmd(t *testing.T) {
19	projectName := "github.com/spf13/testproject"
20	project := NewProject(projectName)
21	defer os.RemoveAll(project.AbsPath())
22
23	viper.Set("author", "NAME HERE <EMAIL ADDRESS>")
24	viper.Set("license", "apache")
25	viper.Set("year", 2017)
26	defer viper.Set("author", nil)
27	defer viper.Set("license", nil)
28	defer viper.Set("year", nil)
29
30	// Initialize the project first.
31	initializeProject(project)
32
33	// Then add the "test" command.
34	cmdName := "test"
35	cmdPath := filepath.Join(project.CmdPath(), cmdName+".go")
36	createCmdFile(project.License(), cmdPath, cmdName)
37
38	expectedFiles := []string{".", "root.go", "test.go"}
39	gotFiles := []string{}
40
41	// Check project file hierarchy and compare the content of every single file
42	// with appropriate golden file.
43	err := filepath.Walk(project.CmdPath(), func(path string, info os.FileInfo, err error) error {
44		if err != nil {
45			return err
46		}
47
48		// Make path relative to project.CmdPath().
49		// E.g. path = "/home/user/go/src/github.com/spf13/testproject/cmd/root.go"
50		// then it returns just "root.go".
51		relPath, err := filepath.Rel(project.CmdPath(), path)
52		if err != nil {
53			return err
54		}
55		relPath = filepath.ToSlash(relPath)
56		gotFiles = append(gotFiles, relPath)
57		goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden")
58
59		switch relPath {
60		// Known directories.
61		case ".":
62			return nil
63		// Known files.
64		case "root.go", "test.go":
65			if *update {
66				got, err := ioutil.ReadFile(path)
67				if err != nil {
68					return err
69				}
70				ioutil.WriteFile(goldenPath, got, 0644)
71			}
72			return compareFiles(path, goldenPath)
73		}
74		// Unknown file.
75		return errors.New("unknown file: " + path)
76	})
77	if err != nil {
78		t.Fatal(err)
79	}
80
81	// Check if some files lack.
82	if err := checkLackFiles(expectedFiles, gotFiles); err != nil {
83		t.Fatal(err)
84	}
85}
86
87func TestValidateCmdName(t *testing.T) {
88	testCases := []struct {
89		input    string
90		expected string
91	}{
92		{"cmdName", "cmdName"},
93		{"cmd_name", "cmdName"},
94		{"cmd-name", "cmdName"},
95		{"cmd______Name", "cmdName"},
96		{"cmd------Name", "cmdName"},
97		{"cmd______name", "cmdName"},
98		{"cmd------name", "cmdName"},
99		{"cmdName-----", "cmdName"},
100		{"cmdname-", "cmdname"},
101	}
102
103	for _, testCase := range testCases {
104		got := validateCmdName(testCase.input)
105		if testCase.expected != got {
106			t.Errorf("Expected %q, got %q", testCase.expected, got)
107		}
108	}
109}
110