Skip to content

Commit 9fcb7ad

Browse files
authored
Record Attachments in Never mode (#943)
* Record Attachments in Never mode * PR Feedback
1 parent 58773b2 commit 9fcb7ad

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
matrix:
1515
xcode:
1616
- 15.4
17-
- '16.0'
17+
- '16.1'
1818

1919
name: macOS
2020
runs-on: macos-14

Sources/SnapshotTesting/AssertSnapshot.swift

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -352,42 +352,69 @@ public func verifySnapshot<Value, Format>(
352352
return "Couldn't snapshot value"
353353
}
354354

355-
func recordSnapshot() throws {
356-
try snapshotting.diffing.toData(diffable).write(to: snapshotFileUrl)
355+
func recordSnapshot(writeToDisk: Bool) throws {
356+
let snapshotData = snapshotting.diffing.toData(diffable)
357+
358+
if writeToDisk {
359+
try snapshotData.write(to: snapshotFileUrl)
360+
}
361+
357362
#if !os(Linux) && !os(Windows)
358363
if !isSwiftTesting,
359364
ProcessInfo.processInfo.environment.keys.contains("__XCODE_BUILT_PRODUCTS_DIR_PATHS")
360365
{
361366
XCTContext.runActivity(named: "Attached Recorded Snapshot") { activity in
362-
let attachment = XCTAttachment(contentsOfFile: snapshotFileUrl)
363-
activity.add(attachment)
367+
if writeToDisk {
368+
// Snapshot was written to disk. Create attachment from file
369+
let attachment = XCTAttachment(contentsOfFile: snapshotFileUrl)
370+
activity.add(attachment)
371+
} else {
372+
// Snapshot was not written to disk. Create attachment from data and path extension
373+
let typeIdentifier = snapshotting.pathExtension.flatMap(uniformTypeIdentifier(fromExtension:))
374+
375+
let attachment = XCTAttachment(
376+
uniformTypeIdentifier: typeIdentifier,
377+
name: snapshotFileUrl.lastPathComponent,
378+
payload: snapshotData
379+
)
380+
381+
activity.add(attachment)
382+
}
364383
}
365384
}
366385
#endif
367386
}
368387

369-
guard
370-
record != .all,
371-
(record != .missing && record != .failed)
372-
|| fileManager.fileExists(atPath: snapshotFileUrl.path)
373-
else {
374-
try recordSnapshot()
388+
if record == .all {
389+
try recordSnapshot(writeToDisk: true)
375390

376-
return SnapshotTestingConfiguration.current?.record == .all
377-
? """
391+
return """
378392
Record mode is on. Automatically recorded snapshot: …
379393
380394
open "\(snapshotFileUrl.absoluteString)"
381395
382396
Turn record mode off and re-run "\(testName)" to assert against the newly-recorded snapshot
383397
"""
384-
: """
398+
}
399+
400+
guard fileManager.fileExists(atPath: snapshotFileUrl.path) else {
401+
if record == .never {
402+
try recordSnapshot(writeToDisk: false)
403+
404+
return """
405+
No reference was found on disk. New snapshot was not recorded because recording is disabled
406+
"""
407+
} else {
408+
try recordSnapshot(writeToDisk: true)
409+
410+
return """
385411
No reference was found on disk. Automatically recorded snapshot: …
386412
387413
open "\(snapshotFileUrl.absoluteString)"
388414
389415
Re-run "\(testName)" to assert against the newly-recorded snapshot.
390416
"""
417+
}
391418
}
392419

393420
let data = try Data(contentsOf: snapshotFileUrl)
@@ -444,7 +471,7 @@ public func verifySnapshot<Value, Format>(
444471
}
445472

446473
if record == .failed {
447-
try recordSnapshot()
474+
try recordSnapshot(writeToDisk: true)
448475
failureMessage += " A new snapshot was automatically recorded."
449476
}
450477

@@ -473,6 +500,19 @@ func sanitizePathComponent(_ string: String) -> String {
473500
.replacingOccurrences(of: "^-|-$", with: "", options: .regularExpression)
474501
}
475502

503+
#if !os(Linux) && !os(Windows)
504+
func uniformTypeIdentifier(fromExtension pathExtension: String) -> String? {
505+
// This can be much cleaner in macOS 11+ using UTType
506+
let unmanagedString = UTTypeCreatePreferredIdentifierForTag(
507+
kUTTagClassFilenameExtension as CFString,
508+
pathExtension as CFString,
509+
nil
510+
)
511+
512+
return unmanagedString?.takeRetainedValue() as String?
513+
}
514+
#endif
515+
476516
// We need to clean counter between tests executions in order to support test-iterations.
477517
private class CleanCounterBetweenTestCases: NSObject, XCTestObservation {
478518
private static var registered = false

Tests/SnapshotTestingTests/RecordTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class RecordTests: XCTestCase {
4444
}
4545
} issueMatcher: {
4646
$0.compactDescription == """
47-
failed - The file “testRecordNever.1.json” couldn’t be opened because there is no such file.
47+
failed - No reference was found on disk. New snapshot was not recorded because recording is disabled
4848
"""
4949
}
5050

0 commit comments

Comments
 (0)