// // Created by Eric Firestone on 3/22/16. // Copyright © 2016 Square, Inc. All rights reserved. // Released under the Apache v2 License. // // Adapted from https://gist.github.com/blakemerryman/76312e1cbf8aec248167 // Adapted from https://gist.github.com/efirestone/ce01ae109e08772647eb061b3bb387c3 import XCTest @testable import XcodeGenCore class GlobTests: XCTestCase { let tmpFiles = ["foo", "bar", "baz", "dir1/file1.ext", "dir1/dir2/dir3/file2.ext", "dir1/file1.extfoo"] var tmpDir = "" override func setUp() { super.setUp() tmpDir = newTmpDir() let flags = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH mkdir("\(tmpDir)/dir1/", flags) mkdir("\(tmpDir)/dir1/dir2", flags) mkdir("\(tmpDir)/dir1/dir2/dir3", flags) for file in tmpFiles { close(open("\(tmpDir)/\(file)", O_CREAT)) } } override func tearDown() { for file in tmpFiles { unlink("\(tmpDir)/\(file)") } rmdir("\(tmpDir)/dir1/dir2/dir3") rmdir("\(tmpDir)/dir1/dir2") rmdir("\(tmpDir)/dir1") rmdir(tmpDir) super.tearDown() } private func newTmpDir() -> String { var tmpDirTmpl = "/tmp/glob-test.XXXXXX".cString(using: .utf8)! return String(validatingUTF8: mkdtemp(&tmpDirTmpl))! } func testBraces() { let pattern = "\(tmpDir)/ba{r,y,z}" let glob = Glob(pattern: pattern) var contents = [String]() for file in glob { contents.append(file) } XCTAssertEqual(contents, ["\(tmpDir)/bar", "\(tmpDir)/baz"], "matching with braces failed") } func testNothingMatches() { let pattern = "\(tmpDir)/nothing" let glob = Glob(pattern: pattern) var contents = [String]() for file in glob { contents.append(file) } XCTAssertEqual(contents, [], "expected empty list of files") } func testDirectAccess() { let pattern = "\(tmpDir)/ba{r,y,z}" let glob = Glob(pattern: pattern) XCTAssertEqual(glob.paths, ["\(tmpDir)/bar", "\(tmpDir)/baz"], "matching with braces failed") } func testIterateTwice() { let pattern = "\(tmpDir)/ba{r,y,z}" let glob = Glob(pattern: pattern) var contents1 = [String]() var contents2 = [String]() for file in glob { contents1.append(file) } let filesAfterOnce = glob.paths for file in glob { contents2.append(file) } XCTAssertEqual(contents1, contents2, "results for calling for-in twice are the same") XCTAssertEqual(glob.paths, filesAfterOnce, "calling for-in twice doesn't only memoizes once") } func testIndexing() { let pattern = "\(tmpDir)/ba{r,y,z}" let glob = Glob(pattern: pattern) XCTAssertEqual(glob[0], "\(tmpDir)/bar", "indexing") } // MARK: - Globstar - Bash v3 func testGlobstarBashV3NoSlash() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**" let pattern = "\(tmpDir)/**" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV3) XCTAssertEqual(glob.paths, ["\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/", "\(tmpDir)/foo"]) } func testGlobstarBashV3WithSlash() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**/" let pattern = "\(tmpDir)/**/" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV3) XCTAssertEqual(glob.paths, ["\(tmpDir)/dir1/"]) } func testGlobstarBashV3WithSlashAndWildcard() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**/*" let pattern = "\(tmpDir)/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV3) XCTAssertEqual(glob.paths, ["\(tmpDir)/dir1/dir2/", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo"]) } func testDoubleGlobstarBashV3() { let pattern = "\(tmpDir)/**/dir2/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV3) XCTAssertEqual(glob.paths, ["\(tmpDir)/dir1/dir2/dir3/file2.ext"]) } // MARK: - Globstar - Bash v4 func testGlobstarBashV4NoSlash() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**" let pattern = "\(tmpDir)/**" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV4) XCTAssertEqual(glob.paths, [ "\(tmpDir)/", "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/", "\(tmpDir)/dir1/dir2/", "\(tmpDir)/dir1/dir2/dir3/", "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo", "\(tmpDir)/foo", ]) } func testGlobstarBashV4WithSlash() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**/" let pattern = "\(tmpDir)/**/" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV4) XCTAssertEqual(glob.paths, [ "\(tmpDir)/", "\(tmpDir)/dir1/", "\(tmpDir)/dir1/dir2/", "\(tmpDir)/dir1/dir2/dir3/", ]) } func testGlobstarBashV4WithSlashAndWildcard() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**/*" let pattern = "\(tmpDir)/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV4) XCTAssertEqual(glob.paths, [ "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/", "\(tmpDir)/dir1/dir2/", "\(tmpDir)/dir1/dir2/dir3/", "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo", "\(tmpDir)/foo", ]) } func testDoubleGlobstarBashV4() { let pattern = "\(tmpDir)/**/dir2/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV4) XCTAssertEqual(glob.paths, [ "\(tmpDir)/dir1/dir2/dir3/", "\(tmpDir)/dir1/dir2/dir3/file2.ext", ]) } func testDoubleGlobstarBashV4WithFileExtension() { // Should be the equivalent of "ls -d -1 /(tmpdir)/**/*.ext" // Should not find "\(tmpDir)/dir1/file1.extfoo" which the file extension prefix is .ext let pattern = "\(tmpDir)/**/*.ext" let glob = Glob(pattern: pattern, behavior: GlobBehaviorBashV4) XCTAssertEqual(glob.paths, [ "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", ]) } // MARK: - Globstar - Gradle func testGlobstarGradleNoSlash() { // Should be the equivalent of // FileTree tree = project.fileTree((Object)'/tmp') { // include 'glob-test.7m0Lp/**' // } // // Note that the sort order currently matches Bash and not Gradle let pattern = "\(tmpDir)/**" let glob = Glob(pattern: pattern, behavior: GlobBehaviorGradle) XCTAssertEqual(glob.paths, [ "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo", "\(tmpDir)/foo", ]) } func testGlobstarGradleWithSlash() { // Should be the equivalent of // FileTree tree = project.fileTree((Object)'/tmp') { // include 'glob-test.7m0Lp/**/' // } // // Note that the sort order currently matches Bash and not Gradle let pattern = "\(tmpDir)/**/" let glob = Glob(pattern: pattern, behavior: GlobBehaviorGradle) XCTAssertEqual(glob.paths, [ "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo", "\(tmpDir)/foo", ]) } func testGlobstarGradleWithSlashAndWildcard() { // Should be the equivalent of // FileTree tree = project.fileTree((Object)'/tmp') { // include 'glob-test.7m0Lp/**/*' // } // // Note that the sort order currently matches Bash and not Gradle let pattern = "\(tmpDir)/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorGradle) XCTAssertEqual(glob.paths, [ "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/dir1/dir2/dir3/file2.ext", "\(tmpDir)/dir1/file1.ext", "\(tmpDir)/dir1/file1.extfoo", "\(tmpDir)/foo", ]) } func testDoubleGlobstarGradle() { // Should be the equivalent of // FileTree tree = project.fileTree((Object)'/tmp') { // include 'glob-test.7m0Lp/**/dir2/**/*' // } // // Note that the sort order currently matches Bash and not Gradle let pattern = "\(tmpDir)/**/dir2/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorGradle) XCTAssertEqual(glob.paths, [ "\(tmpDir)/dir1/dir2/dir3/file2.ext", ]) } func testBlacklistedDirectories() { let pattern = "\(tmpDir)/**/*" let glob = Glob(pattern: pattern, behavior: GlobBehaviorGradle, blacklistedDirectories: ["dir1"]) XCTAssertEqual(glob.paths, [ "\(tmpDir)/bar", "\(tmpDir)/baz", "\(tmpDir)/foo", ]) } }