github.com/gwaycc/gometalinter@v3.0.0+incompatible/main_test.go (about) 1 package main 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 "gopkg.in/alecthomas/kingpin.v3-unstable" 13 ) 14 15 func TestRelativePackagePath(t *testing.T) { 16 var testcases = []struct { 17 dir string 18 expected string 19 }{ 20 { 21 dir: "/abs/path", 22 expected: "/abs/path", 23 }, 24 { 25 dir: ".", 26 expected: ".", 27 }, 28 { 29 dir: "./foo", 30 expected: "./foo", 31 }, 32 { 33 dir: "relative/path", 34 expected: "./relative/path", 35 }, 36 } 37 38 for _, testcase := range testcases { 39 assert.Equal(t, testcase.expected, relativePackagePath(testcase.dir)) 40 } 41 } 42 43 func TestResolvePathsNoPaths(t *testing.T) { 44 paths := resolvePaths(nil, nil) 45 assert.Equal(t, []string{"."}, paths) 46 } 47 48 func TestResolvePathsNoExpands(t *testing.T) { 49 // Non-expanded paths should not be filtered by the skip path list 50 paths := resolvePaths([]string{".", "foo", "foo/bar"}, []string{"foo/bar"}) 51 expected := []string{".", "./foo", "./foo/bar"} 52 assert.Equal(t, expected, paths) 53 } 54 55 func TestResolvePathsWithExpands(t *testing.T) { 56 tmpdir, cleanup := setupTempDir(t) 57 defer cleanup() 58 59 mkGoFile(t, tmpdir, "file.go") 60 mkDir(t, tmpdir, "exclude") 61 mkDir(t, tmpdir, "other", "exclude") 62 mkDir(t, tmpdir, "include") 63 mkDir(t, tmpdir, "include", "foo") 64 mkDir(t, tmpdir, "duplicate") 65 mkDir(t, tmpdir, ".exclude") 66 mkDir(t, tmpdir, "include", ".exclude") 67 mkDir(t, tmpdir, "_exclude") 68 mkDir(t, tmpdir, "include", "_exclude") 69 70 filterPaths := []string{"exclude", "other/exclude"} 71 paths := resolvePaths([]string{"./...", "foo", "duplicate"}, filterPaths) 72 73 expected := []string{ 74 ".", 75 "./duplicate", 76 "./foo", 77 "./include", 78 "./include/foo", 79 } 80 assert.Equal(t, expected, paths) 81 } 82 83 func setupTempDir(t *testing.T) (string, func()) { 84 tmpdir, err := ioutil.TempDir("", "test-expand-paths") 85 require.NoError(t, err) 86 87 tmpdir, err = filepath.EvalSymlinks(tmpdir) 88 require.NoError(t, err) 89 90 oldwd, err := os.Getwd() 91 require.NoError(t, err) 92 require.NoError(t, os.Chdir(tmpdir)) 93 94 return tmpdir, func() { 95 os.RemoveAll(tmpdir) 96 require.NoError(t, os.Chdir(oldwd)) 97 } 98 } 99 100 func mkDir(t *testing.T, paths ...string) { 101 fullPath := filepath.Join(paths...) 102 require.NoError(t, os.MkdirAll(fullPath, 0755)) 103 mkGoFile(t, fullPath, "file.go") 104 } 105 106 func mkFile(t *testing.T, path string, filename string, content string) { 107 err := ioutil.WriteFile(filepath.Join(path, filename), []byte(content), 0644) 108 require.NoError(t, err) 109 } 110 111 func mkGoFile(t *testing.T, path string, filename string) { 112 mkFile(t, path, filename, "package foo") 113 } 114 115 func TestPathFilter(t *testing.T) { 116 skip := []string{"exclude", "skip.go"} 117 pathFilter := newPathFilter(skip) 118 119 var testcases = []struct { 120 path string 121 expected bool 122 }{ 123 {path: "exclude", expected: true}, 124 {path: "something/skip.go", expected: true}, 125 {path: "skip.go", expected: true}, 126 {path: ".git", expected: true}, 127 {path: "_ignore", expected: true}, 128 {path: "include.go", expected: false}, 129 {path: ".", expected: false}, 130 {path: "..", expected: false}, 131 } 132 133 for _, testcase := range testcases { 134 assert.Equal(t, testcase.expected, pathFilter(testcase.path), testcase.path) 135 } 136 } 137 138 func TestLoadDefaultConfig(t *testing.T) { 139 originalConfig := *config 140 defer func() { config = &originalConfig }() 141 142 tmpdir, cleanup := setupTempDir(t) 143 defer cleanup() 144 145 mkFile(t, tmpdir, defaultConfigPath, `{"Deadline": "3m"}`) 146 147 app := kingpin.New("test-app", "") 148 app.Action(loadDefaultConfig) 149 setupFlags(app) 150 151 _, err := app.Parse([]string{}) 152 require.NoError(t, err) 153 require.Equal(t, 3*time.Minute, config.Deadline.Duration()) 154 } 155 156 func TestNoConfigFlag(t *testing.T) { 157 originalConfig := *config 158 defer func() { config = &originalConfig }() 159 160 tmpdir, cleanup := setupTempDir(t) 161 defer cleanup() 162 163 mkFile(t, tmpdir, defaultConfigPath, `{"Deadline": "3m"}`) 164 165 app := kingpin.New("test-app", "") 166 app.Action(loadDefaultConfig) 167 setupFlags(app) 168 169 _, err := app.Parse([]string{"--no-config"}) 170 require.NoError(t, err) 171 require.Equal(t, 30*time.Second, config.Deadline.Duration()) 172 } 173 174 func TestConfigFlagSkipsDefault(t *testing.T) { 175 originalConfig := *config 176 defer func() { config = &originalConfig }() 177 178 tmpdir, cleanup := setupTempDir(t) 179 defer cleanup() 180 181 mkFile(t, tmpdir, defaultConfigPath, `{"Deadline": "3m"}`) 182 mkFile(t, tmpdir, "test-config", `{"Fast": true}`) 183 184 app := kingpin.New("test-app", "") 185 app.Action(loadDefaultConfig) 186 setupFlags(app) 187 188 _, err := app.Parse([]string{"--config", filepath.Join(tmpdir, "test-config")}) 189 require.NoError(t, err) 190 require.Equal(t, 30*time.Second, config.Deadline.Duration()) 191 require.Equal(t, true, config.Fast) 192 } 193 194 func TestLoadConfigWithDeadline(t *testing.T) { 195 originalConfig := *config 196 defer func() { config = &originalConfig }() 197 198 tmpfile, err := ioutil.TempFile("", "test-config") 199 require.NoError(t, err) 200 defer os.Remove(tmpfile.Name()) 201 202 _, err = tmpfile.Write([]byte(`{"Deadline": "3m"}`)) 203 require.NoError(t, err) 204 require.NoError(t, tmpfile.Close()) 205 206 filename := tmpfile.Name() 207 err = loadConfig(nil, &kingpin.ParseElement{Value: &filename}, nil) 208 require.NoError(t, err) 209 210 require.Equal(t, 3*time.Minute, config.Deadline.Duration()) 211 } 212 213 func TestDeadlineFlag(t *testing.T) { 214 app := kingpin.New("test-app", "") 215 setupFlags(app) 216 _, err := app.Parse([]string{"--deadline", "2m"}) 217 require.NoError(t, err) 218 require.Equal(t, 2*time.Minute, config.Deadline.Duration()) 219 } 220 221 func TestAddPath(t *testing.T) { 222 paths := []string{"existing"} 223 assert.Equal(t, paths, addPath(paths, "existing")) 224 expected := []string{"existing", "new"} 225 assert.Equal(t, expected, addPath(paths, "new")) 226 } 227 228 func TestSetupFlagsLinterFlag(t *testing.T) { 229 originalConfig := *config 230 defer func() { config = &originalConfig }() 231 232 app := kingpin.New("test-app", "") 233 setupFlags(app) 234 _, err := app.Parse([]string{"--linter", "a:b:c"}) 235 require.NoError(t, err) 236 linter, ok := config.Linters["a"] 237 assert.True(t, ok) 238 assert.Equal(t, "b", linter.Command) 239 assert.Equal(t, "c", linter.Pattern) 240 } 241 242 func TestSetupFlagsConfigWithLinterString(t *testing.T) { 243 originalConfig := *config 244 defer func() { config = &originalConfig }() 245 246 tmpfile, err := ioutil.TempFile("", "test-config") 247 require.NoError(t, err) 248 defer os.Remove(tmpfile.Name()) 249 250 _, err = tmpfile.Write([]byte(`{"Linters": {"linter": "command:path"} }`)) 251 require.NoError(t, err) 252 require.NoError(t, tmpfile.Close()) 253 254 app := kingpin.New("test-app", "") 255 setupFlags(app) 256 257 _, err = app.Parse([]string{"--config", tmpfile.Name()}) 258 require.NoError(t, err) 259 linter, ok := config.Linters["linter"] 260 assert.True(t, ok) 261 assert.Equal(t, "command", linter.Command) 262 assert.Equal(t, "path", linter.Pattern) 263 } 264 265 func TestSetupFlagsConfigWithLinterMap(t *testing.T) { 266 originalConfig := *config 267 defer func() { config = &originalConfig }() 268 269 tmpfile, err := ioutil.TempFile("", "test-config") 270 require.NoError(t, err) 271 defer os.Remove(tmpfile.Name()) 272 273 _, err = tmpfile.Write([]byte(`{"Linters": 274 {"linter": 275 { "Command": "command" }}}`)) 276 require.NoError(t, err) 277 require.NoError(t, tmpfile.Close()) 278 279 app := kingpin.New("test-app", "") 280 setupFlags(app) 281 282 _, err = app.Parse([]string{"--config", tmpfile.Name()}) 283 require.NoError(t, err) 284 linter, ok := config.Linters["linter"] 285 assert.True(t, ok) 286 assert.Equal(t, "command", linter.Command) 287 assert.Equal(t, "", linter.Pattern) 288 } 289 290 func TestSetupFlagsConfigAndLinterFlag(t *testing.T) { 291 originalConfig := *config 292 defer func() { config = &originalConfig }() 293 294 tmpfile, err := ioutil.TempFile("", "test-config") 295 require.NoError(t, err) 296 defer os.Remove(tmpfile.Name()) 297 298 _, err = tmpfile.Write([]byte(`{"Linters": 299 {"linter": { "Command": "some-command" }}}`)) 300 require.NoError(t, err) 301 require.NoError(t, tmpfile.Close()) 302 303 app := kingpin.New("test-app", "") 304 setupFlags(app) 305 306 _, err = app.Parse([]string{ 307 "--config", tmpfile.Name(), 308 "--linter", "linter:command:pattern"}) 309 require.NoError(t, err) 310 linter, ok := config.Linters["linter"] 311 assert.True(t, ok) 312 assert.Equal(t, "command", linter.Command) 313 assert.Equal(t, "pattern", linter.Pattern) 314 }