|
import XCTest |
|
|
|
struct Sample: Codable { |
|
let name: String |
|
} |
|
|
|
final class ResourceTests: XCTestCase { |
|
let rootFilename = "Package.swift" |
|
let resourcesDir = "Resources" |
|
|
|
func testFindingSampleJson() throws { |
|
let filename = "Sample.json" |
|
guard let sampleJsonURL = findResource(filename: filename) else { |
|
XCTFail("Failed to find JSON URL for \(filename)") |
|
return |
|
} |
|
|
|
let exists = FileManager.default.fileExists(atPath: sampleJsonURL.path) |
|
print("URL: \(sampleJsonURL.path)") |
|
XCTAssertTrue(exists) |
|
} |
|
|
|
func testLoadingSampleJson() throws { |
|
let filename = "Sample.json" |
|
guard let data = loadResource(filename: filename) else { |
|
XCTFail("Failed to load JSON URL for \(filename)") |
|
return |
|
} |
|
XCTAssertFalse(data.isEmpty) |
|
} |
|
|
|
func testDecodingSampleJson() throws { |
|
let filename = "Sample.json" |
|
var sample: Sample? = nil |
|
XCTAssertNoThrow(sample = try decodeResource(filename: filename, type: Sample.self)) |
|
XCTAssertNotNil(sample) |
|
XCTAssertEqual(sample?.name, "Sample") |
|
} |
|
|
|
func decodeResource<T>(filename: String, type: T.Type) throws -> T? where T : Decodable { |
|
guard let data = loadResource(filename: filename) else { |
|
XCTFail("Failed to load JSON URL for \(filename)") |
|
return nil |
|
} |
|
|
|
let resource = try JSONDecoder().decode(type.self, from: data) |
|
return resource |
|
} |
|
|
|
func loadResource(filename: String) -> Data? { |
|
guard let resourceURL = findResource(filename: filename) else { |
|
return nil |
|
} |
|
let data = try? Data(contentsOf: resourceURL) |
|
return data |
|
} |
|
|
|
func findResource(filename: String) -> URL? { |
|
guard let resourcesURL = resourcesURL else { |
|
return nil |
|
} |
|
let fileURL = resourcesURL.appendingPathComponent(filename) |
|
guard FileManager.default.fileExists(atPath: fileURL.path) else { |
|
return nil |
|
} |
|
|
|
return fileURL |
|
} |
|
|
|
lazy var resourcesURL: URL? = { |
|
guard let rootURL = findUp(filename: rootFilename) else { |
|
return nil |
|
} |
|
return rootURL.appendingPathComponent(resourcesDir) |
|
}() |
|
|
|
func findUp(filename: String, baseURL: URL = URL(fileURLWithPath: #file).deletingLastPathComponent()) -> URL? { |
|
let fileURL = baseURL.appendingPathComponent(filename) |
|
if FileManager.default.fileExists(atPath: fileURL.path) { |
|
return baseURL |
|
} else { |
|
return baseURL.pathComponents.count > 1 |
|
? findUp(filename: filename, baseURL: baseURL.deletingLastPathComponent()) |
|
: nil |
|
} |
|
} |
|
|
|
} |