-
-
Notifications
You must be signed in to change notification settings - Fork 73
Expand file tree
/
Copy pathSnapshotTesting.swift
More file actions
72 lines (64 loc) · 2.75 KB
/
SnapshotTesting.swift
File metadata and controls
72 lines (64 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import Testing
import Foundation
func assertSnapshot(
name: String? = nil,
filePath: String = #filePath,
function: String = #function,
sourceLocation: SourceLocation = #_sourceLocation,
variant: String? = nil,
input: Data,
fileExtension: String = "json"
) throws {
let testFileName = URL(fileURLWithPath: filePath).deletingPathExtension().lastPathComponent
let snapshotDir = URL(fileURLWithPath: filePath)
.deletingLastPathComponent()
.appendingPathComponent("__Snapshots__")
.appendingPathComponent(testFileName)
try FileManager.default.createDirectory(at: snapshotDir, withIntermediateDirectories: true)
let snapshotName = name ?? String(function[..<function.firstIndex(of: "(")!])
let snapshotFileName: String = "\(snapshotName)\(variant.map { "_\($0)" } ?? "").\(fileExtension)"
let snapshotPath = snapshotDir.appendingPathComponent(snapshotFileName)
if FileManager.default.fileExists(atPath: snapshotPath.path) {
let existingSnapshot = try String(contentsOf: snapshotPath, encoding: .utf8)
let actual = String(data: input, encoding: .utf8)!
let ok = existingSnapshot == actual
let actualFilePath = snapshotPath.path + ".actual"
let updateSnapshots = ProcessInfo.processInfo.environment["UPDATE_SNAPSHOTS"] != nil
if !updateSnapshots {
if !ok {
try actual.write(toFile: actualFilePath, atomically: true, encoding: .utf8)
}
let diff = ok ? nil : unifiedDiff(expectedPath: snapshotPath.path, actualPath: actualFilePath)
func buildComment() -> Comment {
var message = "Snapshot mismatch: \(actualFilePath) \(snapshotPath.path)"
if let diff {
message.append("\n\n" + diff)
}
return Comment(rawValue: message)
}
#expect(ok, buildComment(), sourceLocation: sourceLocation)
} else {
try input.write(to: snapshotPath)
}
} else {
try input.write(to: snapshotPath)
#expect(Bool(false), "Snapshot created at \(snapshotPath.path)", sourceLocation: sourceLocation)
}
}
private func unifiedDiff(expectedPath: String, actualPath: String) -> String? {
let process = Process()
process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
process.arguments = ["diff", "-u", expectedPath, actualPath]
let output = Pipe()
process.standardOutput = output
process.standardError = Pipe()
do {
try process.run()
} catch {
return nil
}
process.waitUntilExit()
let data = output.fileHandleForReading.readDataToEndOfFile()
guard !data.isEmpty else { return nil }
return String(data: data, encoding: .utf8)
}