Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions Plugins/BridgeJS/Tests/BridgeJSToolTests/SnapshotTesting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,26 @@ func assertSnapshot(

if FileManager.default.fileExists(atPath: snapshotPath.path) {
let existingSnapshot = try String(contentsOf: snapshotPath, encoding: .utf8)
let ok = existingSnapshot == String(data: input, 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
func buildComment() -> Comment {
"Snapshot mismatch: \(actualFilePath) \(snapshotPath.path)"
}

if !updateSnapshots {
#expect(ok, buildComment(), sourceLocation: sourceLocation)
if !ok {
try input.write(to: URL(fileURLWithPath: actualFilePath))
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)
}
Expand All @@ -41,3 +50,23 @@ func assertSnapshot(
#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()
Comment on lines +58 to +67
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.standardError is set to a Pipe() but never read. This can both drop useful error output (e.g., diff errors) and has the same pipe-buffer deadlock risk as stdout. Either read stderr as well, or redirect stderr to stdout / a file, and consider checking terminationStatus (0=same, 1=different, 2=error) to decide what to return.

Copilot uses AI. Check for mistakes.

let data = output.fileHandleForReading.readDataToEndOfFile()
Comment on lines +55 to +69
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unifiedDiff runs diff with Pipe() output but waits for the process to exit before reading. If the unified diff is large enough to fill the pipe buffer, the child process can block on write and waitUntilExit() can hang the test run. Consider draining stdout/stderr while the process runs (e.g., readabilityHandler like invokeTS2Swift does) or redirecting output to a temporary file and reading it after exit.

Copilot uses AI. Check for mistakes.
guard !data.isEmpty else { return nil }
return String(data: data, encoding: .utf8)
}