CodeCoverage++
This commit is contained in:
@@ -14,7 +14,13 @@ public extension Path {
|
|||||||
private let enumerator: FileManager.DirectoryEnumerator!
|
private let enumerator: FileManager.DirectoryEnumerator!
|
||||||
|
|
||||||
/// The range of directory depths for which the find operation will return entries.
|
/// The range of directory depths for which the find operation will return entries.
|
||||||
private(set) public var depth: ClosedRange<Int> = 1...Int.max
|
private(set) public var depth: ClosedRange<Int> = 1...Int.max {
|
||||||
|
didSet {
|
||||||
|
if depth.lowerBound < 0 {
|
||||||
|
depth = 0...depth.upperBound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The kinds of filesystem entries find operations will return.
|
/// The kinds of filesystem entries find operations will return.
|
||||||
public var types: Set<EntryType> {
|
public var types: Set<EntryType> {
|
||||||
@@ -42,11 +48,7 @@ extension Path.Finder: Sequence, IteratorProtocol {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if enumerator.level < depth.lowerBound {
|
if enumerator.level < depth.lowerBound {
|
||||||
if path == self.path, depth.lowerBound == 0 {
|
continue
|
||||||
return path
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,90 @@ extension PathTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFindMinDepth() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
try tmpdir.a.touch()
|
||||||
|
try tmpdir.b.mkdir().join("c").touch()
|
||||||
|
try tmpdir.b.d.mkdir().join("e").touch()
|
||||||
|
try tmpdir.b.d.f.mkdir().join("g").touch()
|
||||||
|
|
||||||
|
do {
|
||||||
|
let finder = tmpdir.find().depth(min: 2)
|
||||||
|
XCTAssertEqual(finder.depth, 2...Int.max)
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(finder),
|
||||||
|
Set([tmpdir.b.c, tmpdir.b.d, tmpdir.b.d.e, tmpdir.b.d.f, tmpdir.b.d.f.g].map(Path.init)),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFindDepth0() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
try tmpdir.a.touch()
|
||||||
|
try tmpdir.b.mkdir().join("c").touch()
|
||||||
|
try tmpdir.b.d.mkdir().join("e").touch()
|
||||||
|
try tmpdir.b.d.f.mkdir().join("g").touch()
|
||||||
|
|
||||||
|
do {
|
||||||
|
let finder = tmpdir.find().depth(min: 0)
|
||||||
|
XCTAssertEqual(finder.depth, 0...Int.max)
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(finder),
|
||||||
|
Set([tmpdir.a, tmpdir.b, tmpdir.b.c, tmpdir.b.d, tmpdir.b.d.e, tmpdir.b.d.f, tmpdir.b.d.f.g].map(Path.init)),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
// this should work, even though it’s weird
|
||||||
|
let finder = tmpdir.find().depth(min: -1)
|
||||||
|
XCTAssertEqual(finder.depth, 0...Int.max)
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(finder),
|
||||||
|
Set([tmpdir.a, tmpdir.b, tmpdir.b.c, tmpdir.b.d, tmpdir.b.d.e, tmpdir.b.d.f, tmpdir.b.d.f.g].map(Path.init)),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFindDepthRange() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
try tmpdir.a.touch()
|
||||||
|
try tmpdir.b.mkdir().join("c").touch()
|
||||||
|
try tmpdir.b.d.mkdir().join("e").touch()
|
||||||
|
try tmpdir.b.d.f.mkdir().join("g").touch()
|
||||||
|
|
||||||
|
do {
|
||||||
|
let range = 2...3
|
||||||
|
let finder = tmpdir.find().depth(range)
|
||||||
|
XCTAssertEqual(finder.depth, range)
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(finder),
|
||||||
|
Set([tmpdir.b.d, tmpdir.b.c, tmpdir.b.d.e, tmpdir.b.d.f].map(Path.init)),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let range = 2..<4
|
||||||
|
let finder = tmpdir.find().depth(range)
|
||||||
|
XCTAssertEqual(finder.depth, 2...3)
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(finder),
|
||||||
|
Set([tmpdir.b.d, tmpdir.b.c, tmpdir.b.d.e, tmpdir.b.d.f].map(Path.init)),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testFindExtension() throws {
|
func testFindExtension() throws {
|
||||||
try Path.mktemp { tmpdir in
|
try Path.mktemp { tmpdir in
|
||||||
try tmpdir.join("foo.json").touch()
|
try tmpdir.join("foo.json").touch()
|
||||||
@@ -66,6 +150,53 @@ extension PathTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NOTE this is how iterators work, so we have a test to validate that behavior
|
||||||
|
func testFindCallingExecuteTwice() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
try tmpdir.join("foo.json").touch()
|
||||||
|
try tmpdir.join("bar.txt").touch()
|
||||||
|
|
||||||
|
let finder = tmpdir.find()
|
||||||
|
|
||||||
|
XCTAssertEqual(finder.map{ $0 }.count, 2)
|
||||||
|
XCTAssertEqual(finder.map{ $0 }.count, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFindExecute() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
try tmpdir.a.touch()
|
||||||
|
try tmpdir.b.mkdir().join("c").touch()
|
||||||
|
try tmpdir.b.d.mkdir().join("e").touch()
|
||||||
|
try tmpdir.b.d.f.mkdir().join("g").touch()
|
||||||
|
|
||||||
|
do {
|
||||||
|
var rv = Set<Path>()
|
||||||
|
|
||||||
|
tmpdir.find().execute {
|
||||||
|
switch $0 {
|
||||||
|
case Path(tmpdir.b.d): return .skip
|
||||||
|
default:
|
||||||
|
rv.insert($0)
|
||||||
|
return .continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(rv, Set([tmpdir.a, tmpdir.b, tmpdir.b.c].map(Path.init)))
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
var x = 0
|
||||||
|
|
||||||
|
tmpdir.find().execute { _ in
|
||||||
|
x += 1
|
||||||
|
return .abort
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(x, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testFindTypes() throws {
|
func testFindTypes() throws {
|
||||||
try Path.mktemp { tmpdir in
|
try Path.mktemp { tmpdir in
|
||||||
try tmpdir.foo.mkdir()
|
try tmpdir.foo.mkdir()
|
||||||
@@ -82,4 +213,16 @@ extension PathTests {
|
|||||||
Set(["foo", "bar"].map(tmpdir.join)))
|
Set(["foo", "bar"].map(tmpdir.join)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testLsOnNonexistentDirectoryReturnsEmptyArray() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
XCTAssertEqual(tmpdir.a.ls(), [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFindOnNonexistentDirectoryHasNoContent() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
XCTAssertNil(tmpdir.a.find().next())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,15 +146,21 @@ class PathTests: XCTestCase {
|
|||||||
].map(Path.init)
|
].map(Path.init)
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
encoder.userInfo[.relativePath] = root
|
|
||||||
let data = try encoder.encode(input)
|
|
||||||
|
|
||||||
XCTAssertEqual(try JSONSerialization.jsonObject(with: data) as? [String], ["..", "", "bar"])
|
func test<P: Pathish>(relativePath: P, line: UInt = #line) throws {
|
||||||
|
encoder.userInfo[.relativePath] = relativePath
|
||||||
|
let data = try encoder.encode(input)
|
||||||
|
|
||||||
let decoder = JSONDecoder()
|
XCTAssertEqual(try JSONSerialization.jsonObject(with: data) as? [String], ["..", "", "bar"], line: line)
|
||||||
XCTAssertThrowsError(try decoder.decode([Path].self, from: data))
|
|
||||||
decoder.userInfo[.relativePath] = root
|
let decoder = JSONDecoder()
|
||||||
XCTAssertEqual(try decoder.decode([Path].self, from: data), input)
|
XCTAssertThrowsError(try decoder.decode([Path].self, from: data), line: line)
|
||||||
|
decoder.userInfo[.relativePath] = relativePath
|
||||||
|
XCTAssertEqual(try decoder.decode([Path].self, from: data), input, line: line)
|
||||||
|
}
|
||||||
|
|
||||||
|
try test(relativePath: root) // DynamicPath
|
||||||
|
try test(relativePath: Path(root)) // Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJoin() {
|
func testJoin() {
|
||||||
@@ -313,6 +319,8 @@ class PathTests: XCTestCase {
|
|||||||
func testStringConvertibles() {
|
func testStringConvertibles() {
|
||||||
XCTAssertEqual(Path.root.description, "/")
|
XCTAssertEqual(Path.root.description, "/")
|
||||||
XCTAssertEqual(Path.root.debugDescription, "Path(/)")
|
XCTAssertEqual(Path.root.debugDescription, "Path(/)")
|
||||||
|
XCTAssertEqual(Path(Path.root).description, "/")
|
||||||
|
XCTAssertEqual(Path(Path.root).debugDescription, "Path(/)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFilesystemAttributes() throws {
|
func testFilesystemAttributes() throws {
|
||||||
@@ -405,6 +413,9 @@ class PathTests: XCTestCase {
|
|||||||
XCTAssertNoThrow(try bar7.delete())
|
XCTAssertNoThrow(try bar7.delete())
|
||||||
XCTAssertEqual(bar7.type, nil)
|
XCTAssertEqual(bar7.type, nil)
|
||||||
XCTAssertEqual(tmpdir.bar6.type, .file)
|
XCTAssertEqual(tmpdir.bar6.type, .file)
|
||||||
|
|
||||||
|
// for code-coverage
|
||||||
|
XCTAssertEqual(tmpdir.bar6.kind, .file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,15 @@ extension PathTests {
|
|||||||
("testFileHandleExtensions", testFileHandleExtensions),
|
("testFileHandleExtensions", testFileHandleExtensions),
|
||||||
("testFileReference", testFileReference),
|
("testFileReference", testFileReference),
|
||||||
("testFilesystemAttributes", testFilesystemAttributes),
|
("testFilesystemAttributes", testFilesystemAttributes),
|
||||||
|
("testFindCallingExecuteTwice", testFindCallingExecuteTwice),
|
||||||
|
("testFindDepth0", testFindDepth0),
|
||||||
|
("testFindDepthRange", testFindDepthRange),
|
||||||
|
("testFindExecute", testFindExecute),
|
||||||
("testFindExtension", testFindExtension),
|
("testFindExtension", testFindExtension),
|
||||||
("testFindMaxDepth1", testFindMaxDepth1),
|
("testFindMaxDepth1", testFindMaxDepth1),
|
||||||
("testFindMaxDepth2", testFindMaxDepth2),
|
("testFindMaxDepth2", testFindMaxDepth2),
|
||||||
|
("testFindMinDepth", testFindMinDepth),
|
||||||
|
("testFindOnNonexistentDirectoryHasNoContent", testFindOnNonexistentDirectoryHasNoContent),
|
||||||
("testFindTypes", testFindTypes),
|
("testFindTypes", testFindTypes),
|
||||||
("testFlatMap", testFlatMap),
|
("testFlatMap", testFlatMap),
|
||||||
("testInitializerForRelativePath", testInitializerForRelativePath),
|
("testInitializerForRelativePath", testInitializerForRelativePath),
|
||||||
@@ -34,6 +40,7 @@ extension PathTests {
|
|||||||
("testJoin", testJoin),
|
("testJoin", testJoin),
|
||||||
("testKind", testKind),
|
("testKind", testKind),
|
||||||
("testLock", testLock),
|
("testLock", testLock),
|
||||||
|
("testLsOnNonexistentDirectoryReturnsEmptyArray", testLsOnNonexistentDirectoryReturnsEmptyArray),
|
||||||
("testMkpathIfExists", testMkpathIfExists),
|
("testMkpathIfExists", testMkpathIfExists),
|
||||||
("testMktemp", testMktemp),
|
("testMktemp", testMktemp),
|
||||||
("testMoveInto", testMoveInto),
|
("testMoveInto", testMoveInto),
|
||||||
|
|||||||
11
Tests/PathTests/etc.swift
Normal file
11
Tests/PathTests/etc.swift
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import XCTest
|
||||||
|
import Path
|
||||||
|
|
||||||
|
func XCTAssertEqual<P: Pathish>(_ set1: Set<Path>, _ set2: Set<Path>, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line, relativeTo: P) {
|
||||||
|
if set1 != set2 {
|
||||||
|
let cvt: (Path) -> String = { $0.relative(to: relativeTo) }
|
||||||
|
let out1 = set1.map(cvt).sorted()
|
||||||
|
let out2 = set1.map(cvt).sorted()
|
||||||
|
XCTFail("Set(\(out1)) is not equal to Set(\(out2))", file: file, line: line)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user