mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-05-17 10:30:35 +00:00
Improve handling of acronyms in swiftTestingTestCaseNames rule (#2413)
Co-authored-by: calda <1811727+calda@users.noreply.github.com>
This commit is contained in:
@@ -213,18 +213,47 @@ extension String {
|
||||
words.append(contentsOf: String(segment).splitCamelCase())
|
||||
}
|
||||
|
||||
return words.joined(separator: " ").lowercased()
|
||||
// Merge a lone single lowercase leading character with a following all-uppercase word.
|
||||
// This handles acronym-first names after test prefix removal, e.g. "uUID" (from "testUUID") → "UUID".
|
||||
if words.count >= 2,
|
||||
words[0].count == 1,
|
||||
words[0].first?.isLowercase == true,
|
||||
words[1].allSatisfy(\.isUppercase)
|
||||
{
|
||||
words = [words[0].uppercased() + words[1]] + Array(words.dropFirst(2))
|
||||
}
|
||||
|
||||
// Lowercase each word, but preserve all-uppercase words (acronyms like UUID, URL, ABC).
|
||||
return words.map { $0.allSatisfy(\.isUppercase) ? $0 : $0.lowercased() }.joined(separator: " ")
|
||||
}
|
||||
|
||||
/// Splits a camelCase string into individual words.
|
||||
/// Splits a camelCase string into individual words, treating consecutive uppercase letters as acronyms.
|
||||
/// For example: "UUIDIsValid" → ["UUID", "Is", "Valid"], "alphabetStartsWithABC" → ["alphabet", "Starts", "With", "ABC"].
|
||||
func splitCamelCase() -> [String] {
|
||||
var words: [String] = []
|
||||
var currentWord = ""
|
||||
let chars = Array(self)
|
||||
|
||||
for char in self {
|
||||
if char.isUppercase, !currentWord.isEmpty {
|
||||
words.append(currentWord)
|
||||
currentWord = String(char)
|
||||
for i in 0 ..< chars.count {
|
||||
let char = chars[i]
|
||||
let nextChar = i + 1 < chars.count ? chars[i + 1] : nil
|
||||
|
||||
if char.isUppercase {
|
||||
if currentWord.isEmpty {
|
||||
currentWord.append(char)
|
||||
} else if currentWord.last!.isLowercase {
|
||||
// Lower→Upper transition: start a new word
|
||||
words.append(currentWord)
|
||||
currentWord = String(char)
|
||||
} else if let next = nextChar, next.isLowercase {
|
||||
// Uppercase sequence followed by lowercase: this char starts a new word
|
||||
// e.g. "UUIDIs" → "UUID" + "Is"
|
||||
words.append(currentWord)
|
||||
currentWord = String(char)
|
||||
} else {
|
||||
// Continue accumulating the uppercase sequence (acronym)
|
||||
currentWord.append(char)
|
||||
}
|
||||
} else {
|
||||
currentWord.append(char)
|
||||
}
|
||||
|
||||
@@ -1100,4 +1100,85 @@ final class SwiftTestingTestCaseNamesTests: XCTestCase {
|
||||
swiftVersion: "6.2"),
|
||||
exclude: [.enumNamespaces])
|
||||
}
|
||||
|
||||
func testConvertsAcronymAtStartToRawIdentifier() {
|
||||
let input = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func testUUIDIsValid() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
let output = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func `UUID is valid`() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
testFormatting(for: input, output, rule: .swiftTestingTestCaseNames,
|
||||
options: FormatOptions(swiftVersion: "6.2"))
|
||||
}
|
||||
|
||||
func testConvertsTrailingAcronymToRawIdentifier() {
|
||||
let input = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func testAlphabetStartsWithABC() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
let output = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func `alphabet starts with ABC`() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
testFormatting(for: input, output, rule: .swiftTestingTestCaseNames,
|
||||
options: FormatOptions(swiftVersion: "6.2"))
|
||||
}
|
||||
|
||||
func testConvertsMiddleAcronymToRawIdentifier() {
|
||||
let input = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func testMyURLIsValid() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
let output = """
|
||||
import Testing
|
||||
|
||||
struct MyFeatureTests {
|
||||
@Test
|
||||
func `my URL is valid`() {
|
||||
#expect(true)
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
testFormatting(for: input, output, rule: .swiftTestingTestCaseNames,
|
||||
options: FormatOptions(swiftVersion: "6.2"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user