Skip to content

Commit

Permalink
Fixed .failed record mode in inline snapshots. (#874)
Browse files Browse the repository at this point in the history
* Fixed .failed record mode in inline snapshots.

* wip

* wip

* add some test coverage

* wip
  • Loading branch information
mbrandonw authored Jul 18, 2024
1 parent c097f95 commit 7690acc
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 23 deletions.
54 changes: 32 additions & 22 deletions Sources/InlineSnapshotTesting/AssertInlineSnapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,25 @@ import Foundation
}
}
let expected = expected?()
guard
record != .all,
record != .missing || expected != nil
else {
func recordSnapshot() {
// NB: Write snapshot state before calling `XCTFail` in case `continueAfterFailure = false`
inlineSnapshotState[File(path: filePath), default: []].append(
InlineSnapshot(
expected: expected,
actual: actual,
wasRecording: record == .all,
wasRecording: record == .all || record == .failed,
syntaxDescriptor: syntaxDescriptor,
function: "\(function)",
line: line,
column: column
)
)
}
guard
record != .all,
(record != .missing && record != .failed) || expected != nil
else {
recordSnapshot()

var failure: String
if syntaxDescriptor.trailingClosureLabel
Expand Down Expand Up @@ -162,12 +165,19 @@ import Foundation
else { return }

let message = message()
syntaxDescriptor.fail(
"""
var failureMessage = """
\(message.isEmpty ? "Snapshot did not match. Difference: …" : message)
\(difference.indenting(by: 2))
""",
"""

if record == .failed {
recordSnapshot()
failureMessage += "\n\nA new snapshot was automatically recorded."
}

syntaxDescriptor.fail(
failureMessage,
fileID: fileID,
file: filePath,
line: line,
Expand Down Expand Up @@ -352,27 +362,27 @@ public struct InlineSnapshotSyntaxDescriptor: Hashable {
}
}

private struct File: Hashable {
let path: StaticString
static func == (lhs: Self, rhs: Self) -> Bool {
@_spi(Internals) public struct File: Hashable {
public let path: StaticString
public static func == (lhs: Self, rhs: Self) -> Bool {
"\(lhs.path)" == "\(rhs.path)"
}
func hash(into hasher: inout Hasher) {
public func hash(into hasher: inout Hasher) {
hasher.combine("\(self.path)")
}
}

private struct InlineSnapshot: Hashable {
var expected: String?
var actual: String?
var wasRecording: Bool
var syntaxDescriptor: InlineSnapshotSyntaxDescriptor
var function: String
var line: UInt
var column: UInt
@_spi(Internals) public struct InlineSnapshot: Hashable {
public var expected: String?
public var actual: String?
public var wasRecording: Bool
public var syntaxDescriptor: InlineSnapshotSyntaxDescriptor
public var function: String
public var line: UInt
public var column: UInt
}

private var inlineSnapshotState: [File: [InlineSnapshot]] = [:]
@_spi(Internals) public var inlineSnapshotState: [File: [InlineSnapshot]] = [:]

private struct TestSource {
let source: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import InlineSnapshotTesting
@_spi(Internals) import InlineSnapshotTesting
import SnapshotTesting
import XCTest

Expand Down Expand Up @@ -286,6 +286,70 @@ final class InlineSnapshotTestingTests: XCTestCase {
"""##
}
}

#if canImport(Darwin)
func testRecordFailed_IncorrectExpectation() throws {
let initialInlineSnapshotState = inlineSnapshotState
defer { inlineSnapshotState = initialInlineSnapshotState }

XCTExpectFailure {
withSnapshotTesting(record: .failed) {
assertInlineSnapshot(of: 42, as: .json) {
"""
4
"""
}
}
} issueMatcher: {
$0.compactDescription == """
failed - Snapshot did not match. Difference: …
@@ −1,1 +1,1 @@
−4
+42
A new snapshot was automatically recorded.
"""
}

XCTAssertEqual(inlineSnapshotState.count, 1)
XCTAssertEqual(
String(describing: inlineSnapshotState.keys.first!.path)
.hasSuffix("InlineSnapshotTestingTests.swift"),
true
)
}
#endif

#if canImport(Darwin)
func testRecordFailed_MissingExpectation() throws {
let initialInlineSnapshotState = inlineSnapshotState
defer { inlineSnapshotState = initialInlineSnapshotState }

XCTExpectFailure {
withSnapshotTesting(record: .failed) {
assertInlineSnapshot(of: 42, as: .json)
}
} issueMatcher: {
$0.compactDescription == """
failed - Automatically recorded a new snapshot. Difference: …
@@ −1,1 +1,1 @@
+42
Re-run "testRecordFailed_MissingExpectation()" to assert against the newly-recorded snapshot.
"""
}

XCTAssertEqual(inlineSnapshotState.count, 1)
XCTAssertEqual(
String(describing: inlineSnapshotState.keys.first!.path)
.hasSuffix("InlineSnapshotTestingTests.swift"),
true
)
}
#endif
}

private func assertCustomInlineSnapshot(
Expand Down

0 comments on commit 7690acc

Please sign in to comment.