github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/blueprint/pathtools/glob_test.go (about)

     1  // Copyright 2014 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package pathtools
    16  
    17  import (
    18  	"os"
    19  	"path/filepath"
    20  	"reflect"
    21  	"strconv"
    22  	"testing"
    23  )
    24  
    25  var pwd, _ = os.Getwd()
    26  
    27  type globTestCase struct {
    28  	pattern  string
    29  	matches  []string
    30  	excludes []string
    31  	deps     []string
    32  	err      error
    33  }
    34  
    35  var globTestCases = []globTestCase{
    36  	// Current directory tests
    37  	{
    38  		pattern: "*",
    39  		matches: []string{"a/", "b/", "c/", "d.ext", "e.ext"},
    40  		deps:    []string{"."},
    41  	},
    42  	{
    43  		pattern: "*.ext",
    44  		matches: []string{"d.ext", "e.ext"},
    45  		deps:    []string{"."},
    46  	},
    47  	{
    48  		pattern: "*/a",
    49  		matches: []string{"a/a/", "b/a"},
    50  		deps:    []string{".", "a", "b", "c"},
    51  	},
    52  	{
    53  		pattern: "*/*/a",
    54  		matches: []string{"a/a/a"},
    55  		deps:    []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
    56  	},
    57  	{
    58  		pattern: "*/a/a",
    59  		matches: []string{"a/a/a"},
    60  		deps:    []string{".", "a", "b", "c", "a/a"},
    61  	},
    62  
    63  	// ./ directory tests
    64  	{
    65  		pattern: "./*",
    66  		matches: []string{"a/", "b/", "c/", "d.ext", "e.ext"},
    67  		deps:    []string{"."},
    68  	},
    69  	{
    70  		pattern: "./*.ext",
    71  		matches: []string{"d.ext", "e.ext"},
    72  		deps:    []string{"."},
    73  	},
    74  	{
    75  		pattern: "./*/a",
    76  		matches: []string{"a/a/", "b/a"},
    77  		deps:    []string{".", "a", "b", "c"},
    78  	},
    79  	{
    80  		pattern: "./[ac]/a",
    81  		matches: []string{"a/a/"},
    82  		deps:    []string{".", "a", "c"},
    83  	},
    84  
    85  	// subdirectory tests
    86  	{
    87  		pattern: "c/*/*.ext",
    88  		matches: []string{"c/f/f.ext", "c/g/g.ext"},
    89  		deps:    []string{"c", "c/f", "c/g", "c/h"},
    90  	},
    91  	{
    92  		pattern: "a/*/a",
    93  		matches: []string{"a/a/a"},
    94  		deps:    []string{"a", "a/a", "a/b"},
    95  	},
    96  
    97  	// absolute tests
    98  	{
    99  		pattern: filepath.Join(pwd, "testdata/c/*/*.ext"),
   100  		matches: []string{
   101  			filepath.Join(pwd, "testdata/c/f/f.ext"),
   102  			filepath.Join(pwd, "testdata/c/g/g.ext"),
   103  		},
   104  		deps: []string{
   105  			filepath.Join(pwd, "testdata/c"),
   106  			filepath.Join(pwd, "testdata/c/f"),
   107  			filepath.Join(pwd, "testdata/c/g"),
   108  			filepath.Join(pwd, "testdata/c/h"),
   109  		},
   110  	},
   111  
   112  	// no-wild tests
   113  	{
   114  		pattern: "a",
   115  		matches: []string{"a/"},
   116  		deps:    []string{"a"},
   117  	},
   118  	{
   119  		pattern: "a/a",
   120  		matches: []string{"a/a/"},
   121  		deps:    []string{"a/a"},
   122  	},
   123  
   124  	// clean tests
   125  	{
   126  		pattern: "./c/*/*.ext",
   127  		matches: []string{"c/f/f.ext", "c/g/g.ext"},
   128  		deps:    []string{"c", "c/f", "c/g", "c/h"},
   129  	},
   130  	{
   131  		pattern: "c/../c/*/*.ext",
   132  		matches: []string{"c/f/f.ext", "c/g/g.ext"},
   133  		deps:    []string{"c", "c/f", "c/g", "c/h"},
   134  	},
   135  
   136  	// recursive tests
   137  	{
   138  		pattern: "**/a",
   139  		matches: []string{"a/", "a/a/", "a/a/a", "b/a"},
   140  		deps:    []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
   141  	},
   142  	{
   143  		pattern: "a/**/a",
   144  		matches: []string{"a/a/", "a/a/a"},
   145  		deps:    []string{"a", "a/a", "a/b"},
   146  	},
   147  	{
   148  		pattern: "a/**/*",
   149  		matches: []string{"a/a/", "a/b/", "a/a/a", "a/b/b"},
   150  		deps:    []string{"a", "a/a", "a/b"},
   151  	},
   152  
   153  	// absolute recursive tests
   154  	{
   155  		pattern: filepath.Join(pwd, "testdata/**/*.ext"),
   156  		matches: []string{
   157  			filepath.Join(pwd, "testdata/d.ext"),
   158  			filepath.Join(pwd, "testdata/e.ext"),
   159  			filepath.Join(pwd, "testdata/c/f/f.ext"),
   160  			filepath.Join(pwd, "testdata/c/g/g.ext"),
   161  		},
   162  		deps: []string{
   163  			filepath.Join(pwd, "testdata"),
   164  			filepath.Join(pwd, "testdata/a"),
   165  			filepath.Join(pwd, "testdata/a/a"),
   166  			filepath.Join(pwd, "testdata/a/b"),
   167  			filepath.Join(pwd, "testdata/b"),
   168  			filepath.Join(pwd, "testdata/c"),
   169  			filepath.Join(pwd, "testdata/c/f"),
   170  			filepath.Join(pwd, "testdata/c/g"),
   171  			filepath.Join(pwd, "testdata/c/h"),
   172  		},
   173  	},
   174  
   175  	// recursive error tests
   176  	{
   177  		pattern: "**/**/*",
   178  		err:     GlobMultipleRecursiveErr,
   179  	},
   180  	{
   181  		pattern: "a/**/**/*",
   182  		err:     GlobMultipleRecursiveErr,
   183  	},
   184  	{
   185  		pattern: "**/a/**/*",
   186  		err:     GlobMultipleRecursiveErr,
   187  	},
   188  	{
   189  		pattern: "**/**/a/*",
   190  		err:     GlobMultipleRecursiveErr,
   191  	},
   192  	{
   193  		pattern: "a/**",
   194  		err:     GlobLastRecursiveErr,
   195  	},
   196  	{
   197  		pattern: "**/**",
   198  		err:     GlobLastRecursiveErr,
   199  	},
   200  
   201  	// exclude tests
   202  	{
   203  		pattern:  "*.ext",
   204  		excludes: []string{"d.ext"},
   205  		matches:  []string{"e.ext"},
   206  		deps:     []string{"."},
   207  	},
   208  	{
   209  		pattern:  "*/*",
   210  		excludes: []string{"a/b"},
   211  		matches:  []string{"a/a/", "b/a", "c/c", "c/f/", "c/g/", "c/h/"},
   212  		deps:     []string{".", "a", "b", "c"},
   213  	},
   214  	{
   215  		pattern:  "*/*",
   216  		excludes: []string{"a/b", "c/c"},
   217  		matches:  []string{"a/a/", "b/a", "c/f/", "c/g/", "c/h/"},
   218  		deps:     []string{".", "a", "b", "c"},
   219  	},
   220  	{
   221  		pattern:  "*/*",
   222  		excludes: []string{"c/*", "*/a"},
   223  		matches:  []string{"a/b/"},
   224  		deps:     []string{".", "a", "b", "c"},
   225  	},
   226  	{
   227  		pattern:  "*/*",
   228  		excludes: []string{"*/*"},
   229  		matches:  nil,
   230  		deps:     []string{".", "a", "b", "c"},
   231  	},
   232  
   233  	// absolute exclude tests
   234  	{
   235  		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
   236  		excludes: []string{filepath.Join(pwd, "testdata/c/*/f.ext")},
   237  		matches: []string{
   238  			filepath.Join(pwd, "testdata/c/g/g.ext"),
   239  		},
   240  		deps: []string{
   241  			filepath.Join(pwd, "testdata/c"),
   242  			filepath.Join(pwd, "testdata/c/f"),
   243  			filepath.Join(pwd, "testdata/c/g"),
   244  			filepath.Join(pwd, "testdata/c/h"),
   245  		},
   246  	},
   247  	{
   248  		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
   249  		excludes: []string{filepath.Join(pwd, "testdata/c/f/*.ext")},
   250  		matches: []string{
   251  			filepath.Join(pwd, "testdata/c/g/g.ext"),
   252  		},
   253  		deps: []string{
   254  			filepath.Join(pwd, "testdata/c"),
   255  			filepath.Join(pwd, "testdata/c/f"),
   256  			filepath.Join(pwd, "testdata/c/g"),
   257  			filepath.Join(pwd, "testdata/c/h"),
   258  		},
   259  	},
   260  
   261  	// recursive exclude tests
   262  	{
   263  		pattern:  "*.ext",
   264  		excludes: []string{"**/*.ext"},
   265  		matches:  nil,
   266  		deps:     []string{"."},
   267  	},
   268  	{
   269  		pattern:  "*/*",
   270  		excludes: []string{"**/b"},
   271  		matches:  []string{"a/a/", "b/a", "c/c", "c/f/", "c/g/", "c/h/"},
   272  		deps:     []string{".", "a", "b", "c"},
   273  	},
   274  	{
   275  		pattern:  "*/*",
   276  		excludes: []string{"a/**/*"},
   277  		matches:  []string{"b/a", "c/c", "c/f/", "c/g/", "c/h/"},
   278  		deps:     []string{".", "a", "b", "c"},
   279  	},
   280  	{
   281  		pattern:  "**/*",
   282  		excludes: []string{"**/*"},
   283  		matches:  nil,
   284  		deps:     []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
   285  	},
   286  	{
   287  		pattern:  "*/*/*",
   288  		excludes: []string{"a/**/a"},
   289  		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
   290  		deps:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
   291  	},
   292  	{
   293  		pattern:  "*/*/*",
   294  		excludes: []string{"**/a"},
   295  		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
   296  		deps:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
   297  	},
   298  	{
   299  		pattern:  "c/*/*.ext",
   300  		excludes: []string{"c/**/f.ext"},
   301  		matches:  []string{"c/g/g.ext"},
   302  		deps:     []string{"c", "c/f", "c/g", "c/h"},
   303  	},
   304  
   305  	// absoulte recursive exclude tests
   306  	{
   307  		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
   308  		excludes: []string{filepath.Join(pwd, "testdata/**/f.ext")},
   309  		matches: []string{
   310  			filepath.Join(pwd, "testdata/c/g/g.ext"),
   311  		},
   312  		deps: []string{
   313  			filepath.Join(pwd, "testdata/c"),
   314  			filepath.Join(pwd, "testdata/c/f"),
   315  			filepath.Join(pwd, "testdata/c/g"),
   316  			filepath.Join(pwd, "testdata/c/h"),
   317  		},
   318  	},
   319  
   320  	// clean exclude tests
   321  	{
   322  		pattern:  "./c/*/*.ext",
   323  		excludes: []string{"./c/*/f.ext"},
   324  		matches:  []string{"c/g/g.ext"},
   325  		deps:     []string{"c", "c/f", "c/g", "c/h"},
   326  	},
   327  	{
   328  		pattern:  "c/*/*.ext",
   329  		excludes: []string{"./c/*/f.ext"},
   330  		matches:  []string{"c/g/g.ext"},
   331  		deps:     []string{"c", "c/f", "c/g", "c/h"},
   332  	},
   333  	{
   334  		pattern:  "./c/*/*.ext",
   335  		excludes: []string{"c/*/f.ext"},
   336  		matches:  []string{"c/g/g.ext"},
   337  		deps:     []string{"c", "c/f", "c/g", "c/h"},
   338  	},
   339  
   340  	// non-existant non-wild path tests
   341  	{
   342  		pattern: "d/*",
   343  		matches: nil,
   344  		deps:    []string{"."},
   345  	},
   346  	{
   347  		pattern: "d",
   348  		matches: nil,
   349  		deps:    []string{"."},
   350  	},
   351  	{
   352  		pattern: "a/d/*",
   353  		matches: nil,
   354  		deps:    []string{"a"},
   355  	},
   356  	{
   357  		pattern: "a/d",
   358  		matches: nil,
   359  		deps:    []string{"a"},
   360  	},
   361  	{
   362  		pattern: "a/a/d/*",
   363  		matches: nil,
   364  		deps:    []string{"a/a"},
   365  	},
   366  	{
   367  		pattern: "a/a/d",
   368  		matches: nil,
   369  		deps:    []string{"a/a"},
   370  	},
   371  	{
   372  		pattern: "a/d/a/*",
   373  		matches: nil,
   374  		deps:    []string{"a"},
   375  	},
   376  	{
   377  		pattern: "a/d/a",
   378  		matches: nil,
   379  		deps:    []string{"a"},
   380  	},
   381  	{
   382  		pattern: "a/d/a/*/a",
   383  		matches: nil,
   384  		deps:    []string{"a"},
   385  	},
   386  	{
   387  		pattern: "a/d/a/**/a",
   388  		matches: nil,
   389  		deps:    []string{"a"},
   390  	},
   391  
   392  	// recursive exclude error tests
   393  	{
   394  		pattern:  "**/*",
   395  		excludes: []string{"**/**/*"},
   396  		err:      GlobMultipleRecursiveErr,
   397  	},
   398  	{
   399  		pattern:  "**/*",
   400  		excludes: []string{"a/**/**/*"},
   401  		err:      GlobMultipleRecursiveErr,
   402  	},
   403  	{
   404  		pattern:  "**/*",
   405  		excludes: []string{"**/a/**/*"},
   406  		err:      GlobMultipleRecursiveErr,
   407  	},
   408  	{
   409  		pattern:  "**/*",
   410  		excludes: []string{"**/**/a/*"},
   411  		err:      GlobMultipleRecursiveErr,
   412  	},
   413  	{
   414  		pattern:  "**/*",
   415  		excludes: []string{"a/**"},
   416  		err:      GlobLastRecursiveErr,
   417  	},
   418  	{
   419  		pattern:  "**/*",
   420  		excludes: []string{"**/**"},
   421  		err:      GlobLastRecursiveErr,
   422  	},
   423  
   424  	// If names are excluded by default, but referenced explicitly, they should return results
   425  	{
   426  		pattern: ".test/*",
   427  		matches: []string{".test/a"},
   428  		deps:    []string{".test"},
   429  	},
   430  	{
   431  		pattern: ".t*/a",
   432  		matches: []string{".test/a"},
   433  		deps:    []string{".", ".test"},
   434  	},
   435  	{
   436  		pattern: ".*/.*",
   437  		matches: []string{".test/.ing"},
   438  		deps:    []string{".", ".test"},
   439  	},
   440  	{
   441  		pattern: ".t*",
   442  		matches: []string{".test/", ".testing"},
   443  		deps:    []string{"."},
   444  	},
   445  }
   446  
   447  func TestMockGlob(t *testing.T) {
   448  	files := []string{
   449  		"a/a/a",
   450  		"a/b/b",
   451  		"b/a",
   452  		"c/c",
   453  		"c/f/f.ext",
   454  		"c/g/g.ext",
   455  		"c/h/h",
   456  		"d.ext",
   457  		"e.ext",
   458  		".test/a",
   459  		".testing",
   460  		".test/.ing",
   461  	}
   462  
   463  	mockFiles := make(map[string][]byte)
   464  
   465  	for _, f := range files {
   466  		mockFiles[f] = nil
   467  		mockFiles[filepath.Join(pwd, "testdata", f)] = nil
   468  	}
   469  
   470  	mock := MockFs(mockFiles)
   471  
   472  	for i, testCase := range globTestCases {
   473  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   474  			testGlob(t, mock, testCase)
   475  		})
   476  	}
   477  }
   478  
   479  func TestGlob(t *testing.T) {
   480  	os.Chdir("testdata")
   481  	defer os.Chdir("..")
   482  	for i, testCase := range globTestCases {
   483  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   484  			testGlob(t, OsFs, testCase)
   485  		})
   486  	}
   487  }
   488  
   489  func testGlob(t *testing.T, fs FileSystem, testCase globTestCase) {
   490  	matches, deps, err := fs.Glob(testCase.pattern, testCase.excludes)
   491  	if err != testCase.err {
   492  		t.Errorf(" pattern: %q", testCase.pattern)
   493  		if testCase.excludes != nil {
   494  			t.Errorf("excludes: %q", testCase.excludes)
   495  		}
   496  		t.Errorf("   error: %s", err)
   497  		return
   498  	}
   499  
   500  	if !reflect.DeepEqual(matches, testCase.matches) {
   501  		t.Errorf("incorrect matches list:")
   502  		t.Errorf(" pattern: %q", testCase.pattern)
   503  		if testCase.excludes != nil {
   504  			t.Errorf("excludes: %q", testCase.excludes)
   505  		}
   506  		t.Errorf("     got: %#v", matches)
   507  		t.Errorf("expected: %#v", testCase.matches)
   508  	}
   509  	if !reflect.DeepEqual(deps, testCase.deps) {
   510  		t.Errorf("incorrect deps list:")
   511  		t.Errorf(" pattern: %q", testCase.pattern)
   512  		if testCase.excludes != nil {
   513  			t.Errorf("excludes: %q", testCase.excludes)
   514  		}
   515  		t.Errorf("     got: %#v", deps)
   516  		t.Errorf("expected: %#v", testCase.deps)
   517  	}
   518  }