Skip to content

Commit ff05917

Browse files
committed
Add regression test for FormattableNoticonRange UTF-16 shift
Tests that apply() returns the correct UTF-16 code unit count (12) rather than grapheme cluster count (2) when the noticon value is a multi-byte emoji like πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦.
1 parent 30c3ab4 commit ff05917

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

β€ŽTests/KeystoneTests/Tests/Features/Notifications/FormattableNotIconTests.swiftβ€Ž

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,35 @@ final class FormattableNotIconTests: XCTestCase {
3434
XCTAssertEqual(subject?.value, Constants.icon)
3535
}
3636

37+
// MARK: - apply(_:to:withShift:)
38+
39+
func testApplyReturnsUTF16ShiftForMultiByteNoticon() {
40+
// πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ is 1 grapheme cluster but 11 UTF-16 code units.
41+
// The noticon string is value + " ", so 12 UTF-16 code units total.
42+
// With the old .count code, the shift would have been 2 (1 emoji + 1 space).
43+
let familyEmoji = "πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦"
44+
let noticonRange = FormattableNoticonRange(value: familyEmoji, range: NSRange(location: 0, length: 0))
45+
46+
let baseText = "Hello World"
47+
let string = NSMutableAttributedString(string: baseText)
48+
49+
let styles = SnippetsContentStyles(rangeStylesMap: [
50+
.noticon: [.foregroundColor: UIColor.red]
51+
])
52+
53+
let shift = noticonRange.apply(styles, to: string, withShift: 0)
54+
55+
// The noticon is familyEmoji + " " = 12 UTF-16 code units
56+
let expectedShift = (familyEmoji + " ").utf16.count
57+
XCTAssertEqual(shift, expectedShift, "Shift should equal the UTF-16 count of the noticon, not the grapheme cluster count")
58+
59+
// Verify styles were applied to the full noticon range
60+
var effectiveRange = NSRange()
61+
let color = string.attribute(.foregroundColor, at: 0, effectiveRange: &effectiveRange)
62+
XCTAssertNotNil(color)
63+
XCTAssertEqual(effectiveRange.length, expectedShift, "Style should cover the full UTF-16 range of the inserted noticon")
64+
}
65+
3766
private func mockProperties() -> NotificationContentRange.Properties {
3867
return NotificationContentRange.Properties(range: Constants.range)
3968
}

0 commit comments

Comments
Β (0)