Home | History | Annotate | Download | only in pathtools
      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 	"testing"
     22 )
     23 
     24 var pwd, _ = os.Getwd()
     25 
     26 var globTestCases = []struct {
     27 	pattern  string
     28 	matches  []string
     29 	excludes []string
     30 	deps     []string
     31 	err      error
     32 }{
     33 	// Current directory tests
     34 	{
     35 		pattern: "*",
     36 		matches: []string{"a", "b", "c", "d.ext", "e.ext"},
     37 		deps:    []string{"."},
     38 	},
     39 	{
     40 		pattern: "*.ext",
     41 		matches: []string{"d.ext", "e.ext"},
     42 		deps:    []string{"."},
     43 	},
     44 	{
     45 		pattern: "*/a",
     46 		matches: []string{"a/a", "b/a"},
     47 		deps:    []string{".", "a", "b", "c"},
     48 	},
     49 	{
     50 		pattern: "*/*/a",
     51 		matches: []string{"a/a/a"},
     52 		deps:    []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
     53 	},
     54 	{
     55 		pattern: "*/a/a",
     56 		matches: []string{"a/a/a"},
     57 		deps:    []string{".", "a", "b", "c", "a/a"},
     58 	},
     59 
     60 	// ./ directory tests
     61 	{
     62 		pattern: "./*",
     63 		matches: []string{"a", "b", "c", "d.ext", "e.ext"},
     64 		deps:    []string{"."},
     65 	},
     66 	{
     67 		pattern: "./*.ext",
     68 		matches: []string{"d.ext", "e.ext"},
     69 		deps:    []string{"."},
     70 	},
     71 	{
     72 		pattern: "./*/a",
     73 		matches: []string{"a/a", "b/a"},
     74 		deps:    []string{".", "a", "b", "c"},
     75 	},
     76 	{
     77 		pattern: "./[ac]/a",
     78 		matches: []string{"a/a"},
     79 		deps:    []string{".", "a", "c"},
     80 	},
     81 
     82 	// subdirectory tests
     83 	{
     84 		pattern: "c/*/*.ext",
     85 		matches: []string{"c/f/f.ext", "c/g/g.ext"},
     86 		deps:    []string{"c", "c/f", "c/g", "c/h"},
     87 	},
     88 	{
     89 		pattern: "a/*/a",
     90 		matches: []string{"a/a/a"},
     91 		deps:    []string{"a", "a/a", "a/b"},
     92 	},
     93 
     94 	// absolute tests
     95 	{
     96 		pattern: filepath.Join(pwd, "testdata/c/*/*.ext"),
     97 		matches: []string{
     98 			filepath.Join(pwd, "testdata/c/f/f.ext"),
     99 			filepath.Join(pwd, "testdata/c/g/g.ext"),
    100 		},
    101 		deps: []string{
    102 			filepath.Join(pwd, "testdata/c"),
    103 			filepath.Join(pwd, "testdata/c/f"),
    104 			filepath.Join(pwd, "testdata/c/g"),
    105 			filepath.Join(pwd, "testdata/c/h"),
    106 		},
    107 	},
    108 
    109 	// no-wild tests
    110 	{
    111 		pattern: "a",
    112 		matches: []string{"a"},
    113 		deps:    []string{"a"},
    114 	},
    115 	{
    116 		pattern: "a/a",
    117 		matches: []string{"a/a"},
    118 		deps:    []string{"a/a"},
    119 	},
    120 
    121 	// clean tests
    122 	{
    123 		pattern: "./c/*/*.ext",
    124 		matches: []string{"c/f/f.ext", "c/g/g.ext"},
    125 		deps:    []string{"c", "c/f", "c/g", "c/h"},
    126 	},
    127 	{
    128 		pattern: "c/../c/*/*.ext",
    129 		matches: []string{"c/f/f.ext", "c/g/g.ext"},
    130 		deps:    []string{"c", "c/f", "c/g", "c/h"},
    131 	},
    132 
    133 	// recursive tests
    134 	{
    135 		pattern: "**/a",
    136 		matches: []string{"a", "a/a", "a/a/a", "b/a"},
    137 		deps:    []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
    138 	},
    139 	{
    140 		pattern: "a/**/a",
    141 		matches: []string{"a/a", "a/a/a"},
    142 		deps:    []string{"a", "a/a", "a/b"},
    143 	},
    144 	{
    145 		pattern: "a/**/*",
    146 		matches: []string{"a/a", "a/b", "a/a/a", "a/b/b"},
    147 		deps:    []string{"a", "a/a", "a/b"},
    148 	},
    149 
    150 	// absolute recursive tests
    151 	{
    152 		pattern: filepath.Join(pwd, "testdata/**/*.ext"),
    153 		matches: []string{
    154 			filepath.Join(pwd, "testdata/d.ext"),
    155 			filepath.Join(pwd, "testdata/e.ext"),
    156 			filepath.Join(pwd, "testdata/c/f/f.ext"),
    157 			filepath.Join(pwd, "testdata/c/g/g.ext"),
    158 		},
    159 		deps: []string{
    160 			filepath.Join(pwd, "testdata"),
    161 			filepath.Join(pwd, "testdata/a"),
    162 			filepath.Join(pwd, "testdata/a/a"),
    163 			filepath.Join(pwd, "testdata/a/b"),
    164 			filepath.Join(pwd, "testdata/b"),
    165 			filepath.Join(pwd, "testdata/c"),
    166 			filepath.Join(pwd, "testdata/c/f"),
    167 			filepath.Join(pwd, "testdata/c/g"),
    168 			filepath.Join(pwd, "testdata/c/h"),
    169 		},
    170 	},
    171 
    172 	// recursive error tests
    173 	{
    174 		pattern: "**/**/*",
    175 		err:     GlobMultipleRecursiveErr,
    176 	},
    177 	{
    178 		pattern: "a/**/**/*",
    179 		err:     GlobMultipleRecursiveErr,
    180 	},
    181 	{
    182 		pattern: "**/a/**/*",
    183 		err:     GlobMultipleRecursiveErr,
    184 	},
    185 	{
    186 		pattern: "**/**/a/*",
    187 		err:     GlobMultipleRecursiveErr,
    188 	},
    189 	{
    190 		pattern: "a/**",
    191 		err:     GlobLastRecursiveErr,
    192 	},
    193 	{
    194 		pattern: "**/**",
    195 		err:     GlobLastRecursiveErr,
    196 	},
    197 
    198 	// exclude tests
    199 	{
    200 		pattern:  "*.ext",
    201 		excludes: []string{"d.ext"},
    202 		matches:  []string{"e.ext"},
    203 		deps:     []string{"."},
    204 	},
    205 	{
    206 		pattern:  "*/*",
    207 		excludes: []string{"a/b"},
    208 		matches:  []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"},
    209 		deps:     []string{".", "a", "b", "c"},
    210 	},
    211 	{
    212 		pattern:  "*/*",
    213 		excludes: []string{"a/b", "c/c"},
    214 		matches:  []string{"a/a", "b/a", "c/f", "c/g", "c/h"},
    215 		deps:     []string{".", "a", "b", "c"},
    216 	},
    217 	{
    218 		pattern:  "*/*",
    219 		excludes: []string{"c/*", "*/a"},
    220 		matches:  []string{"a/b"},
    221 		deps:     []string{".", "a", "b", "c"},
    222 	},
    223 	{
    224 		pattern:  "*/*",
    225 		excludes: []string{"*/*"},
    226 		matches:  nil,
    227 		deps:     []string{".", "a", "b", "c"},
    228 	},
    229 
    230 	// absolute exclude tests
    231 	{
    232 		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
    233 		excludes: []string{filepath.Join(pwd, "testdata/c/*/f.ext")},
    234 		matches: []string{
    235 			filepath.Join(pwd, "testdata/c/g/g.ext"),
    236 		},
    237 		deps: []string{
    238 			filepath.Join(pwd, "testdata/c"),
    239 			filepath.Join(pwd, "testdata/c/f"),
    240 			filepath.Join(pwd, "testdata/c/g"),
    241 			filepath.Join(pwd, "testdata/c/h"),
    242 		},
    243 	},
    244 	{
    245 		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
    246 		excludes: []string{filepath.Join(pwd, "testdata/c/f/*.ext")},
    247 		matches: []string{
    248 			filepath.Join(pwd, "testdata/c/g/g.ext"),
    249 		},
    250 		deps: []string{
    251 			filepath.Join(pwd, "testdata/c"),
    252 			filepath.Join(pwd, "testdata/c/f"),
    253 			filepath.Join(pwd, "testdata/c/g"),
    254 			filepath.Join(pwd, "testdata/c/h"),
    255 		},
    256 	},
    257 
    258 	// recursive exclude tests
    259 	{
    260 		pattern:  "*.ext",
    261 		excludes: []string{"**/*.ext"},
    262 		matches:  nil,
    263 		deps:     []string{"."},
    264 	},
    265 	{
    266 		pattern:  "*/*",
    267 		excludes: []string{"**/b"},
    268 		matches:  []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"},
    269 		deps:     []string{".", "a", "b", "c"},
    270 	},
    271 	{
    272 		pattern:  "*/*",
    273 		excludes: []string{"a/**/*"},
    274 		matches:  []string{"b/a", "c/c", "c/f", "c/g", "c/h"},
    275 		deps:     []string{".", "a", "b", "c"},
    276 	},
    277 	{
    278 		pattern:  "**/*",
    279 		excludes: []string{"**/*"},
    280 		matches:  nil,
    281 		deps:     []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
    282 	},
    283 	{
    284 		pattern:  "*/*/*",
    285 		excludes: []string{"a/**/a"},
    286 		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
    287 		deps:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
    288 	},
    289 	{
    290 		pattern:  "*/*/*",
    291 		excludes: []string{"**/a"},
    292 		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
    293 		deps:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
    294 	},
    295 	{
    296 		pattern:  "c/*/*.ext",
    297 		excludes: []string{"c/**/f.ext"},
    298 		matches:  []string{"c/g/g.ext"},
    299 		deps:     []string{"c", "c/f", "c/g", "c/h"},
    300 	},
    301 
    302 	// absoulte recursive exclude tests
    303 	{
    304 		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
    305 		excludes: []string{filepath.Join(pwd, "testdata/**/f.ext")},
    306 		matches: []string{
    307 			filepath.Join(pwd, "testdata/c/g/g.ext"),
    308 		},
    309 		deps: []string{
    310 			filepath.Join(pwd, "testdata/c"),
    311 			filepath.Join(pwd, "testdata/c/f"),
    312 			filepath.Join(pwd, "testdata/c/g"),
    313 			filepath.Join(pwd, "testdata/c/h"),
    314 		},
    315 	},
    316 
    317 	// clean exclude tests
    318 	{
    319 		pattern:  "./c/*/*.ext",
    320 		excludes: []string{"./c/*/f.ext"},
    321 		matches:  []string{"c/g/g.ext"},
    322 		deps:     []string{"c", "c/f", "c/g", "c/h"},
    323 	},
    324 	{
    325 		pattern:  "c/*/*.ext",
    326 		excludes: []string{"./c/*/f.ext"},
    327 		matches:  []string{"c/g/g.ext"},
    328 		deps:     []string{"c", "c/f", "c/g", "c/h"},
    329 	},
    330 	{
    331 		pattern:  "./c/*/*.ext",
    332 		excludes: []string{"c/*/f.ext"},
    333 		matches:  []string{"c/g/g.ext"},
    334 		deps:     []string{"c", "c/f", "c/g", "c/h"},
    335 	},
    336 
    337 	// non-existant non-wild path tests
    338 	{
    339 		pattern: "d/*",
    340 		matches: nil,
    341 		deps:    []string{"."},
    342 	},
    343 	{
    344 		pattern: "d",
    345 		matches: nil,
    346 		deps:    []string{"."},
    347 	},
    348 	{
    349 		pattern: "a/d/*",
    350 		matches: nil,
    351 		deps:    []string{"a"},
    352 	},
    353 	{
    354 		pattern: "a/d",
    355 		matches: nil,
    356 		deps:    []string{"a"},
    357 	},
    358 	{
    359 		pattern: "a/a/d/*",
    360 		matches: nil,
    361 		deps:    []string{"a/a"},
    362 	},
    363 	{
    364 		pattern: "a/a/d",
    365 		matches: nil,
    366 		deps:    []string{"a/a"},
    367 	},
    368 	{
    369 		pattern: "a/d/a/*",
    370 		matches: nil,
    371 		deps:    []string{"a"},
    372 	},
    373 	{
    374 		pattern: "a/d/a",
    375 		matches: nil,
    376 		deps:    []string{"a"},
    377 	},
    378 	{
    379 		pattern: "a/d/a/*/a",
    380 		matches: nil,
    381 		deps:    []string{"a"},
    382 	},
    383 	{
    384 		pattern: "a/d/a/**/a",
    385 		matches: nil,
    386 		deps:    []string{"a"},
    387 	},
    388 
    389 	// recursive exclude error tests
    390 	{
    391 		pattern:  "**/*",
    392 		excludes: []string{"**/**/*"},
    393 		err:      GlobMultipleRecursiveErr,
    394 	},
    395 	{
    396 		pattern:  "**/*",
    397 		excludes: []string{"a/**/**/*"},
    398 		err:      GlobMultipleRecursiveErr,
    399 	},
    400 	{
    401 		pattern:  "**/*",
    402 		excludes: []string{"**/a/**/*"},
    403 		err:      GlobMultipleRecursiveErr,
    404 	},
    405 	{
    406 		pattern:  "**/*",
    407 		excludes: []string{"**/**/a/*"},
    408 		err:      GlobMultipleRecursiveErr,
    409 	},
    410 	{
    411 		pattern:  "**/*",
    412 		excludes: []string{"a/**"},
    413 		err:      GlobLastRecursiveErr,
    414 	},
    415 	{
    416 		pattern:  "**/*",
    417 		excludes: []string{"**/**"},
    418 		err:      GlobLastRecursiveErr,
    419 	},
    420 
    421 	// If names are excluded by default, but referenced explicitly, they should return results
    422 	{
    423 		pattern: ".test/*",
    424 		matches: []string{".test/a"},
    425 		deps:    []string{".test"},
    426 	},
    427 	{
    428 		pattern: ".t*/a",
    429 		matches: []string{".test/a"},
    430 		deps:    []string{".", ".test"},
    431 	},
    432 	{
    433 		pattern: ".*/.*",
    434 		matches: []string{".test/.ing"},
    435 		deps:    []string{".", ".test"},
    436 	},
    437 	{
    438 		pattern: ".t*",
    439 		matches: []string{".test", ".testing"},
    440 		deps:    []string{"."},
    441 	},
    442 }
    443 
    444 func TestGlob(t *testing.T) {
    445 	os.Chdir("testdata")
    446 	defer os.Chdir("..")
    447 	for _, testCase := range globTestCases {
    448 		matches, deps, err := Glob(testCase.pattern, testCase.excludes)
    449 		if err != testCase.err {
    450 			t.Errorf(" pattern: %q", testCase.pattern)
    451 			if testCase.excludes != nil {
    452 				t.Errorf("excludes: %q", testCase.excludes)
    453 			}
    454 			t.Errorf("   error: %s", err)
    455 			continue
    456 		}
    457 
    458 		if !reflect.DeepEqual(matches, testCase.matches) {
    459 			t.Errorf("incorrect matches list:")
    460 			t.Errorf(" pattern: %q", testCase.pattern)
    461 			if testCase.excludes != nil {
    462 				t.Errorf("excludes: %q", testCase.excludes)
    463 			}
    464 			t.Errorf("     got: %#v", matches)
    465 			t.Errorf("expected: %#v", testCase.matches)
    466 		}
    467 		if !reflect.DeepEqual(deps, testCase.deps) {
    468 			t.Errorf("incorrect deps list:")
    469 			t.Errorf(" pattern: %q", testCase.pattern)
    470 			if testCase.excludes != nil {
    471 				t.Errorf("excludes: %q", testCase.excludes)
    472 			}
    473 			t.Errorf("     got: %#v", deps)
    474 			t.Errorf("expected: %#v", testCase.deps)
    475 		}
    476 	}
    477 }
    478