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 }