| // Copyright 2014 Google Inc. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package pathtools |
| |
| import ( |
| "os" |
| "path/filepath" |
| "reflect" |
| "testing" |
| ) |
| |
| var pwd, _ = os.Getwd() |
| |
| var globTestCases = []struct { |
| pattern string |
| matches []string |
| excludes []string |
| dirs []string |
| err error |
| }{ |
| // Current directory tests |
| { |
| pattern: "*", |
| matches: []string{"a", "b", "c", "d.ext", "e.ext"}, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "*.ext", |
| matches: []string{"d.ext", "e.ext"}, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "*/a", |
| matches: []string{"a/a", "b/a"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "*/*/a", |
| matches: []string{"a/a/a"}, |
| dirs: []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "*/a/a", |
| matches: []string{"a/a/a"}, |
| dirs: []string{".", "a", "b", "c", "a/a"}, |
| }, |
| |
| // ./ directory tests |
| { |
| pattern: "./*", |
| matches: []string{"a", "b", "c", "d.ext", "e.ext"}, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "./*.ext", |
| matches: []string{"d.ext", "e.ext"}, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "./*/a", |
| matches: []string{"a/a", "b/a"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "./[ac]/a", |
| matches: []string{"a/a"}, |
| dirs: []string{".", "a", "c"}, |
| }, |
| |
| // subdirectory tests |
| { |
| pattern: "c/*/*.ext", |
| matches: []string{"c/f/f.ext", "c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "a/*/a", |
| matches: []string{"a/a/a"}, |
| dirs: []string{"a", "a/a", "a/b"}, |
| }, |
| |
| // absolute tests |
| { |
| pattern: filepath.Join(pwd, "testdata/c/*/*.ext"), |
| matches: []string{ |
| filepath.Join(pwd, "testdata/c/f/f.ext"), |
| filepath.Join(pwd, "testdata/c/g/g.ext"), |
| }, |
| dirs: []string{ |
| filepath.Join(pwd, "testdata/c"), |
| filepath.Join(pwd, "testdata/c/f"), |
| filepath.Join(pwd, "testdata/c/g"), |
| filepath.Join(pwd, "testdata/c/h"), |
| }, |
| }, |
| |
| // no-wild tests |
| { |
| pattern: "a", |
| matches: []string{"a"}, |
| dirs: nil, |
| }, |
| { |
| pattern: "a/a", |
| matches: []string{"a/a"}, |
| dirs: nil, |
| }, |
| |
| // clean tests |
| { |
| pattern: "./c/*/*.ext", |
| matches: []string{"c/f/f.ext", "c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "c/../c/*/*.ext", |
| matches: []string{"c/f/f.ext", "c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| |
| // recursive tests |
| { |
| pattern: "**/a", |
| matches: []string{"a", "a/a", "a/a/a", "b/a"}, |
| dirs: []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "a/**/a", |
| matches: []string{"a/a", "a/a/a"}, |
| dirs: []string{"a", "a/a", "a/b"}, |
| }, |
| { |
| pattern: "a/**/*", |
| matches: []string{"a/a", "a/b", "a/a/a", "a/b/b"}, |
| dirs: []string{"a", "a/a", "a/b"}, |
| }, |
| |
| // absolute recursive tests |
| { |
| pattern: filepath.Join(pwd, "testdata/**/*.ext"), |
| matches: []string{ |
| filepath.Join(pwd, "testdata/d.ext"), |
| filepath.Join(pwd, "testdata/e.ext"), |
| filepath.Join(pwd, "testdata/c/f/f.ext"), |
| filepath.Join(pwd, "testdata/c/g/g.ext"), |
| }, |
| dirs: []string{ |
| filepath.Join(pwd, "testdata"), |
| filepath.Join(pwd, "testdata/a"), |
| filepath.Join(pwd, "testdata/a/a"), |
| filepath.Join(pwd, "testdata/a/b"), |
| filepath.Join(pwd, "testdata/b"), |
| filepath.Join(pwd, "testdata/c"), |
| filepath.Join(pwd, "testdata/c/f"), |
| filepath.Join(pwd, "testdata/c/g"), |
| filepath.Join(pwd, "testdata/c/h"), |
| }, |
| }, |
| |
| // recursive error tests |
| { |
| pattern: "**/**/*", |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "a/**/**/*", |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/a/**/*", |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/**/a/*", |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "a/**", |
| err: GlobLastRecursiveErr, |
| }, |
| { |
| pattern: "**/**", |
| err: GlobLastRecursiveErr, |
| }, |
| |
| // exclude tests |
| { |
| pattern: "*.ext", |
| excludes: []string{"d.ext"}, |
| matches: []string{"e.ext"}, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"a/b"}, |
| matches: []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"a/b", "c/c"}, |
| matches: []string{"a/a", "b/a", "c/f", "c/g", "c/h"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"c/*", "*/a"}, |
| matches: []string{"a/b"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"*/*"}, |
| matches: nil, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| |
| // absolute exclude tests |
| { |
| pattern: filepath.Join(pwd, "testdata/c/*/*.ext"), |
| excludes: []string{filepath.Join(pwd, "testdata/c/*/f.ext")}, |
| matches: []string{ |
| filepath.Join(pwd, "testdata/c/g/g.ext"), |
| }, |
| dirs: []string{ |
| filepath.Join(pwd, "testdata/c"), |
| filepath.Join(pwd, "testdata/c/f"), |
| filepath.Join(pwd, "testdata/c/g"), |
| filepath.Join(pwd, "testdata/c/h"), |
| }, |
| }, |
| { |
| pattern: filepath.Join(pwd, "testdata/c/*/*.ext"), |
| excludes: []string{filepath.Join(pwd, "testdata/c/f/*.ext")}, |
| matches: []string{ |
| filepath.Join(pwd, "testdata/c/g/g.ext"), |
| }, |
| dirs: []string{ |
| filepath.Join(pwd, "testdata/c"), |
| filepath.Join(pwd, "testdata/c/f"), |
| filepath.Join(pwd, "testdata/c/g"), |
| filepath.Join(pwd, "testdata/c/h"), |
| }, |
| }, |
| |
| // recursive exclude tests |
| { |
| pattern: "*.ext", |
| excludes: []string{"**/*.ext"}, |
| matches: nil, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"**/b"}, |
| matches: []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "*/*", |
| excludes: []string{"a/**/*"}, |
| matches: []string{"b/a", "c/c", "c/f", "c/g", "c/h"}, |
| dirs: []string{".", "a", "b", "c"}, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"**/*"}, |
| matches: nil, |
| dirs: []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "*/*/*", |
| excludes: []string{"a/**/a"}, |
| matches: []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"}, |
| dirs: []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "*/*/*", |
| excludes: []string{"**/a"}, |
| matches: []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"}, |
| dirs: []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "c/*/*.ext", |
| excludes: []string{"c/**/f.ext"}, |
| matches: []string{"c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| |
| // absoulte recursive exclude tests |
| { |
| pattern: filepath.Join(pwd, "testdata/c/*/*.ext"), |
| excludes: []string{filepath.Join(pwd, "testdata/**/f.ext")}, |
| matches: []string{ |
| filepath.Join(pwd, "testdata/c/g/g.ext"), |
| }, |
| dirs: []string{ |
| filepath.Join(pwd, "testdata/c"), |
| filepath.Join(pwd, "testdata/c/f"), |
| filepath.Join(pwd, "testdata/c/g"), |
| filepath.Join(pwd, "testdata/c/h"), |
| }, |
| }, |
| |
| // clean exclude tests |
| { |
| pattern: "./c/*/*.ext", |
| excludes: []string{"./c/*/f.ext"}, |
| matches: []string{"c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "c/*/*.ext", |
| excludes: []string{"./c/*/f.ext"}, |
| matches: []string{"c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| { |
| pattern: "./c/*/*.ext", |
| excludes: []string{"c/*/f.ext"}, |
| matches: []string{"c/g/g.ext"}, |
| dirs: []string{"c", "c/f", "c/g", "c/h"}, |
| }, |
| |
| // non-existant non-wild path tests |
| { |
| pattern: "d/*", |
| matches: nil, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "d", |
| matches: nil, |
| dirs: []string{"."}, |
| }, |
| { |
| pattern: "a/d/*", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| { |
| pattern: "a/d", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| { |
| pattern: "a/a/d/*", |
| matches: nil, |
| dirs: []string{"a/a"}, |
| }, |
| { |
| pattern: "a/a/d", |
| matches: nil, |
| dirs: []string{"a/a"}, |
| }, |
| { |
| pattern: "a/d/a/*", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| { |
| pattern: "a/d/a", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| { |
| pattern: "a/d/a/*/a", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| { |
| pattern: "a/d/a/**/a", |
| matches: nil, |
| dirs: []string{"a"}, |
| }, |
| |
| // recursive exclude error tests |
| { |
| pattern: "**/*", |
| excludes: []string{"**/**/*"}, |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"a/**/**/*"}, |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"**/a/**/*"}, |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"**/**/a/*"}, |
| err: GlobMultipleRecursiveErr, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"a/**"}, |
| err: GlobLastRecursiveErr, |
| }, |
| { |
| pattern: "**/*", |
| excludes: []string{"**/**"}, |
| err: GlobLastRecursiveErr, |
| }, |
| } |
| |
| func TestGlob(t *testing.T) { |
| os.Chdir("testdata") |
| defer os.Chdir("..") |
| for _, testCase := range globTestCases { |
| matches, dirs, err := GlobWithExcludes(testCase.pattern, testCase.excludes) |
| if err != testCase.err { |
| t.Errorf(" pattern: %q", testCase.pattern) |
| if testCase.excludes != nil { |
| t.Errorf("excludes: %q", testCase.excludes) |
| } |
| t.Errorf(" error: %s", err) |
| continue |
| } |
| |
| if !reflect.DeepEqual(matches, testCase.matches) { |
| t.Errorf("incorrect matches list:") |
| t.Errorf(" pattern: %q", testCase.pattern) |
| if testCase.excludes != nil { |
| t.Errorf("excludes: %q", testCase.excludes) |
| } |
| t.Errorf(" got: %#v", matches) |
| t.Errorf("expected: %#v", testCase.matches) |
| } |
| if !reflect.DeepEqual(dirs, testCase.dirs) { |
| t.Errorf("incorrect dirs list:") |
| t.Errorf(" pattern: %q", testCase.pattern) |
| if testCase.excludes != nil { |
| t.Errorf("excludes: %q", testCase.excludes) |
| } |
| t.Errorf(" got: %#v", dirs) |
| t.Errorf("expected: %#v", testCase.dirs) |
| } |
| } |
| } |