github.com/alecthomas/golangci-lint@v1.4.2-0.20180609094924-581a3564ff68/pkg/fsutils/path_resolver_test.go (about)

     1  package fsutils
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  type fsPreparer struct {
    14  	t      *testing.T
    15  	root   string
    16  	prevWD string
    17  }
    18  
    19  func (fp fsPreparer) clean() {
    20  	err := os.Chdir(fp.prevWD)
    21  	assert.NoError(fp.t, err)
    22  
    23  	err = os.RemoveAll(fp.root)
    24  	assert.NoError(fp.t, err)
    25  }
    26  
    27  func prepareFS(t *testing.T, paths ...string) *fsPreparer {
    28  	root, err := ioutil.TempDir("/tmp", "golangci.test.path_resolver")
    29  	assert.NoError(t, err)
    30  
    31  	prevWD, err := os.Getwd()
    32  	assert.NoError(t, err)
    33  
    34  	err = os.Chdir(root)
    35  	assert.NoError(t, err)
    36  
    37  	for _, p := range paths {
    38  		err = os.MkdirAll(filepath.Dir(p), os.ModePerm)
    39  		assert.NoError(t, err)
    40  
    41  		if strings.HasSuffix(p, "/") {
    42  			continue
    43  		}
    44  
    45  		err = ioutil.WriteFile(p, []byte("test"), os.ModePerm)
    46  		assert.NoError(t, err)
    47  	}
    48  
    49  	return &fsPreparer{
    50  		root:   root,
    51  		t:      t,
    52  		prevWD: prevWD,
    53  	}
    54  }
    55  
    56  func newPR(t *testing.T) *PathResolver {
    57  	pr, err := NewPathResolver([]string{}, []string{}, false)
    58  	assert.NoError(t, err)
    59  
    60  	return pr
    61  }
    62  
    63  func TestPathResolverNoPaths(t *testing.T) {
    64  	_, err := newPR(t).Resolve()
    65  	assert.EqualError(t, err, "no paths are set")
    66  }
    67  
    68  func TestPathResolverNotExistingPath(t *testing.T) {
    69  	fp := prepareFS(t)
    70  	defer fp.clean()
    71  
    72  	_, err := newPR(t).Resolve("a")
    73  	assert.EqualError(t, err, "can't find path a: stat a: no such file or directory")
    74  }
    75  
    76  func TestPathResolverCommonCases(t *testing.T) {
    77  	type testCase struct {
    78  		name         string
    79  		prepare      []string
    80  		resolve      []string
    81  		expFiles     []string
    82  		expDirs      []string
    83  		includeTests bool
    84  	}
    85  
    86  	testCases := []testCase{
    87  		{
    88  			name:    "empty root recursively",
    89  			resolve: []string{"./..."},
    90  		},
    91  		{
    92  			name:    "empty root",
    93  			resolve: []string{"./"},
    94  		},
    95  		{
    96  			name:    "vendor is excluded recursively",
    97  			prepare: []string{"vendor/a/b.go"},
    98  			resolve: []string{"./..."},
    99  		},
   100  		{
   101  			name:    "vendor is excluded",
   102  			prepare: []string{"vendor/a.go"},
   103  			resolve: []string{"./..."},
   104  		},
   105  		{
   106  			name:     "vendor implicitely resolved",
   107  			prepare:  []string{"vendor/a.go"},
   108  			resolve:  []string{"./vendor"},
   109  			expDirs:  []string{"vendor"},
   110  			expFiles: []string{"vendor/a.go"},
   111  		},
   112  		{
   113  			name:     "extensions filter recursively",
   114  			prepare:  []string{"a/b.go", "a/c.txt", "d.go", "e.csv"},
   115  			resolve:  []string{"./..."},
   116  			expDirs:  []string{".", "a"},
   117  			expFiles: []string{"a/b.go", "d.go"},
   118  		},
   119  		{
   120  			name:     "extensions filter",
   121  			prepare:  []string{"a/b.go", "a/c.txt", "d.go"},
   122  			resolve:  []string{"a"},
   123  			expDirs:  []string{"a"},
   124  			expFiles: []string{"a/b.go"},
   125  		},
   126  		{
   127  			name:     "one level dirs exclusion",
   128  			prepare:  []string{"a/b/d.go", "a/c.go"},
   129  			resolve:  []string{"./a"},
   130  			expDirs:  []string{"a"},
   131  			expFiles: []string{"a/c.go"},
   132  		},
   133  		{
   134  			name:     "implicitely resolved files",
   135  			prepare:  []string{"a/b/c.go", "a/d.txt"},
   136  			resolve:  []string{"./a/...", "a/d.txt"},
   137  			expDirs:  []string{"a", "a/b"},
   138  			expFiles: []string{"a/b/c.go", "a/d.txt"},
   139  		},
   140  		{
   141  			name:    ".* dotfiles are always ignored",
   142  			prepare: []string{".git/a.go", ".circleci/b.go"},
   143  			resolve: []string{"./..."},
   144  		},
   145  		{
   146  			name:     "exclude dirs on any depth level",
   147  			prepare:  []string{"ok/.git/a.go", "ok/b.go"},
   148  			resolve:  []string{"./..."},
   149  			expDirs:  []string{"ok"},
   150  			expFiles: []string{"ok/b.go"},
   151  		},
   152  		{
   153  			name:    "ignore _*",
   154  			prepare: []string{"_any/a.go"},
   155  			resolve: []string{"./..."},
   156  		},
   157  		{
   158  			name:         "include tests",
   159  			prepare:      []string{"a/b.go", "a/b_test.go"},
   160  			resolve:      []string{"./..."},
   161  			expDirs:      []string{"a"},
   162  			expFiles:     []string{"a/b.go", "a/b_test.go"},
   163  			includeTests: true,
   164  		},
   165  		{
   166  			name:     "exclude tests",
   167  			prepare:  []string{"a/b.go", "a/b_test.go"},
   168  			resolve:  []string{"./..."},
   169  			expDirs:  []string{"a"},
   170  			expFiles: []string{"a/b.go"},
   171  		},
   172  		{
   173  			name:     "exclude tests except explicitly set",
   174  			prepare:  []string{"a/b.go", "a/b_test.go", "a/c_test.go"},
   175  			resolve:  []string{"./...", "a/c_test.go"},
   176  			expDirs:  []string{"a"},
   177  			expFiles: []string{"a/b.go", "a/c_test.go"},
   178  		},
   179  		{
   180  			name:     "exclude dirs with no go files",
   181  			prepare:  []string{"a/b.txt", "a/c/d.go"},
   182  			resolve:  []string{"./..."},
   183  			expDirs:  []string{"a/c"},
   184  			expFiles: []string{"a/c/d.go"},
   185  		},
   186  		{
   187  			name:     "exclude dirs with no go files with root dir",
   188  			prepare:  []string{"a/b.txt", "a/c/d.go", "e.go"},
   189  			resolve:  []string{"./..."},
   190  			expDirs:  []string{".", "a/c"},
   191  			expFiles: []string{"a/c/d.go", "e.go"},
   192  		},
   193  		{
   194  			name:    "vendor dir is excluded by regexp, not the exact match",
   195  			prepare: []string{"vendors/a.go", "novendor/b.go"},
   196  			resolve: []string{"./..."},
   197  		},
   198  	}
   199  
   200  	for _, tc := range testCases {
   201  		t.Run(tc.name, func(t *testing.T) {
   202  			fp := prepareFS(t, tc.prepare...)
   203  			defer fp.clean()
   204  
   205  			pr, err := NewPathResolver([]string{"vendor"}, []string{".go"}, tc.includeTests)
   206  			assert.NoError(t, err)
   207  
   208  			res, err := pr.Resolve(tc.resolve...)
   209  			assert.NoError(t, err)
   210  
   211  			if tc.expFiles == nil {
   212  				assert.Empty(t, res.files)
   213  			} else {
   214  				assert.Equal(t, tc.expFiles, res.files)
   215  			}
   216  
   217  			if tc.expDirs == nil {
   218  				assert.Empty(t, res.dirs)
   219  			} else {
   220  				assert.Equal(t, tc.expDirs, res.dirs)
   221  			}
   222  		})
   223  	}
   224  }