Preserve failure messages in noGuardInTests rule

This commit is contained in:
Nick Lockwood
2025-10-15 19:24:53 +01:00
parent 31aee81c3a
commit 19bc687945
2 changed files with 87 additions and 2 deletions
+13
View File
@@ -75,6 +75,17 @@ public extension FormatRule {
guard isValidElseBlock else { continue }
// Preserve the assertion message (if any)
let assertionMessage: [Token] = {
guard let startIndex = formatter.index(of: .startOfScope("("), after: elseBraceIndex),
let endIndex = formatter.endOfScope(at: startIndex),
formatter.index(after: startIndex, where: { $0.isStringDelimiter }) != nil
else {
return []
}
return [.delimiter(","), .space(" ")] + formatter.tokens[startIndex + 1 ..< endIndex]
}()
// Check for variable shadowing
let scopeStart = bodyRange.lowerBound
let searchRange = scopeStart ..< guardIndex
@@ -174,6 +185,7 @@ public extension FormatRule {
.startOfScope("("),
])
replacementStatements.append(contentsOf: expressionTokens)
replacementStatements.append(contentsOf: assertionMessage)
replacementStatements.append(.endOfScope(")"))
addedTryStatement = true
@@ -183,6 +195,7 @@ public extension FormatRule {
replacementStatements.append(.identifier(assertFunctionName))
replacementStatements.append(.startOfScope("("))
replacementStatements.append(contentsOf: conditionTokens)
replacementStatements.append(contentsOf: assertionMessage)
replacementStatements.append(.endOfScope(")"))
case .patternMatching:
+74 -2
View File
@@ -56,7 +56,7 @@ final class NoGuardInTestsTests: XCTestCase {
class TestCase: XCTestCase {
func test_something() throws {
let value = try XCTUnwrap(optionalValue)
let value = try XCTUnwrap(optionalValue, "Expected value to be non-nil")
}
}
"""
@@ -264,6 +264,78 @@ final class NoGuardInTestsTests: XCTestCase {
testFormatting(for: input, output, rule: .noGuardInTests, exclude: [.blankLinesAfterGuardStatements])
}
func testPreserveFailMessage() {
let input = """
import XCTest
class TestCase: XCTestCase {
func test_something() {
guard let value1 = optionalValue1 else {
XCTFail("Failed")
return
}
guard optionalValue2 != nil else {
XCTFail("Value was nil")
return
}
}
}
"""
let output = """
import XCTest
class TestCase: XCTestCase {
func test_something() throws {
let value1 = try XCTUnwrap(optionalValue1, "Failed")
XCTAssert(optionalValue2 != nil, "Value was nil")
}
}
"""
testFormatting(for: input, output, rule: .noGuardInTests, exclude: [.blankLinesAfterGuardStatements])
}
func testPreserveFailMessageWithInterpolations() {
let input = """
import XCTest
class TestCase: XCTestCase {
func test_something() {
guard optionalValue2 == nil else {
XCTFail("Value was \\(String(describing: optionalValue2))")
return
}
}
}
"""
let output = """
import XCTest
class TestCase: XCTestCase {
func test_something() {
XCTAssert(optionalValue2 == nil, "Value was \\(String(describing: optionalValue2))")
}
}
"""
testFormatting(for: input, output, rule: .noGuardInTests, exclude: [.blankLinesAfterGuardStatements])
}
func testNoMangleNontrivialGuardBody() {
let input = """
import XCTest
class TestCase: XCTestCase {
func test_something() {
guard optionalValue2 == nil else {
let value = optionalValue2 ?? ""
XCTFail("Value was \\(value)")
return
}
}
}
"""
testFormatting(for: input, rule: .noGuardInTests, exclude: [.blankLinesAfterGuardStatements])
}
func testReplaceGuardWithMultipleConditionsXCTest() {
let input = """
import XCTest
@@ -819,7 +891,7 @@ final class NoGuardInTestsTests: XCTestCase {
struct SomeTests {
@Test
func something() throws {
let value = try #require(optionalValue)
let value = try #require(optionalValue, "Expected value to be non-nil")
}
}
"""