Skip to content

Commit 7cd8cb3

Browse files
committed
fix tests for capitalization by locale
1 parent a197d5f commit 7cd8cb3

File tree

3 files changed

+17
-20
lines changed

3 files changed

+17
-20
lines changed

Sources/SwiftDocC/Utility/FoundationExtensions/String+Capitalization.swift

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,24 @@ import Foundation
1212

1313
extension String {
1414

15+
/// Precomputes the CharacterSet to use in capitalizeFirstWord().
16+
private static let charactersPreventingWordCapitalization = CharacterSet.lowercaseLetters.union(.punctuationCharacters).inverted
17+
1518
/// Returns the string with the first letter capitalized.
1619
/// This auto-capitalization only occurs if the first word is all lowercase and contains only lowercase letters.
1720
/// The first word can also contain punctuation (e.g. a period, comma, hyphen, semi-colon, colon).
1821
func capitalizeFirstWord() -> String {
19-
20-
guard !self.isEmpty else { return self }
21-
2222
guard let firstWordStartIndex = self.firstIndex(where: { !$0.isWhitespace && !$0.isNewline }) else { return self }
23-
24-
// Find where the first word starts: this is additional processing to handle white spaces before the first word.
2523
let firstWord = self[firstWordStartIndex...].prefix(while: { !$0.isWhitespace && !$0.isNewline})
2624

27-
28-
guard firstWord.count > 0 else { return self }
29-
let firstWordCharacters = CharacterSet.init(charactersIn: String(firstWord))
30-
let acceptableCharacters = CharacterSet.lowercaseLetters.union(CharacterSet.punctuationCharacters)
31-
guard firstWordCharacters.isSubset(of: acceptableCharacters) else {
25+
guard firstWord.rangeOfCharacter(from: Self.charactersPreventingWordCapitalization) == nil else {
3226
return self
3327
}
3428

35-
// Create the result string and make sure it's big enough to contain all the characters
36-
var resultString = String()
29+
var resultString = String()
3730
resultString.reserveCapacity(self.count)
38-
39-
// Add the white spaces before the first word
4031
resultString.append(contentsOf: self[..<firstWordStartIndex])
41-
42-
// Add the capitalized first word (based on the locale)
4332
resultString.append(contentsOf: String(firstWord).localizedCapitalized)
44-
45-
// Add the rest of the string
4633
let restStartIndex = self.index(firstWordStartIndex, offsetBy: firstWord.count)
4734
resultString.append(contentsOf: self[restStartIndex...])
4835

Tests/SwiftDocCTests/Infrastructure/AutoCapitalizationTests.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,12 @@ class AutoCapitalizationTests: XCTestCase {
111111
let translatedParameters = parameterSectionTranslator.translateSection(for: symbol, renderNode: &renderNode, renderNodeTranslator: &renderNodeTranslator)
112112
let paramsRenderSection = translatedParameters?.defaultValue?.section as! ParametersRenderSection
113113

114+
// Different locales treat capitalization of hyphenated words differently (e.g. Upper-Cased vs Upper-cased).
115+
let hyphenatedString = "upper-cased"
116+
let hyphenatedCapitalizedResult = hyphenatedString.localizedCapitalized + " first parameter description."
117+
114118
XCTAssertEqual(paramsRenderSection.parameters.map(\.content), [
115-
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("Upper-Cased first parameter description.")]))],
119+
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text(hyphenatedCapitalizedResult)]))],
116120
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("The second parameter has extra white spaces")]))],
117121
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("inValid third parameter will not be capitalized")]))],
118122
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text(""), SwiftDocC.RenderInlineContent.codeVoice(code: "code block"), SwiftDocC.RenderInlineContent.text(" will not be capitalized")]))],
@@ -151,8 +155,12 @@ class AutoCapitalizationTests: XCTestCase {
151155
let translatedParameters = parameterSectionTranslator.translateSection(for: symbol, renderNode: &renderNode, renderNodeTranslator: &renderNodeTranslator)
152156
let paramsRenderSection = translatedParameters?.defaultValue?.section as! ParametersRenderSection
153157

158+
// Different locales treat capitalization of hyphenated words differently (e.g. Upper-Cased vs Upper-cased).
159+
let hyphenatedString = "upper-cased"
160+
let hyphenatedCapitalizedResult = hyphenatedString.localizedCapitalized + " first parameter description."
161+
154162
XCTAssertEqual(paramsRenderSection.parameters.map(\.content), [
155-
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("Upper-Cased first parameter description.")]))],
163+
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text(hyphenatedCapitalizedResult)]))],
156164
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("The second parameter has extra white spaces")]))],
157165
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text("inValid third parameter will not be capitalized")]))],
158166
[SwiftDocC.RenderBlockContent.paragraph(SwiftDocC.RenderBlockContent.Paragraph(inlineContent: [SwiftDocC.RenderInlineContent.text(""), SwiftDocC.RenderInlineContent.codeVoice(code: "code block"), SwiftDocC.RenderInlineContent.text(" will not be capitalized")]))],

Tests/SwiftDocCTests/Utility/String+CapitalizationTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ class String_CapitalizationTests: XCTestCase {
4444
func testWhiteSpaces() {
4545
let testString1 = " has many spaces"
4646
let testString2 = " has a tab"
47+
let testString3 = " has many spaces "
4748
XCTAssertEqual(" Has many spaces", testString1.capitalizeFirstWord())
4849
XCTAssertEqual(" Has a tab", testString2.capitalizeFirstWord())
50+
XCTAssertEqual(" Has many spaces ", testString3.capitalizeFirstWord())
4951
}
5052

5153

0 commit comments

Comments
 (0)