Skip to content

Commit 0099d79

Browse files
committed
add UTF-8 handling tests for PostalAddress escape and parse methods
1 parent ba2cbf4 commit 0099d79

2 files changed

Lines changed: 58 additions & 7 deletions

File tree

v3/postaladdress.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,14 @@ func (p *PostalAddress) Escape() string {
4343
builder := &strings.Builder{}
4444

4545
for _, line := range p.lines {
46-
for i := range line {
47-
char := line[i]
48-
46+
for _, char := range line {
4947
switch char {
5048
case '\\':
5149
builder.WriteString("\\5C")
5250
case '$':
5351
builder.WriteString("\\24")
5452
default:
55-
builder.WriteByte(char)
53+
builder.WriteRune(char)
5654
}
5755
}
5856

@@ -65,8 +63,9 @@ func (p *PostalAddress) Escape() string {
6563
// ParsePostalAddress parses an RFC 4517 escaped postal address string into a PostalAddress object or returns an error.
6664
func ParsePostalAddress(escaped string) (*PostalAddress, error) {
6765
lines := strings.Split(escaped, "$")
66+
var parsedLines []string
6867

69-
for lineIndex, line := range lines {
68+
for _, line := range lines {
7069
if line == "" {
7170
// Skip empty lines
7271
continue
@@ -92,8 +91,8 @@ func ParsePostalAddress(escaped string) (*PostalAddress, error) {
9291
builder.WriteByte(char)
9392
}
9493
}
95-
lines[lineIndex] = builder.String()
94+
parsedLines = append(parsedLines, builder.String())
9695
}
9796

98-
return &PostalAddress{lines: lines}, nil
97+
return &PostalAddress{lines: parsedLines}, nil
9998
}

v3/postaladdress_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,55 @@ func TestPostalAddressRoundTrip(t *testing.T) {
3131
})
3232
}
3333
}
34+
35+
func TestPostalAddressUTF8Handling(t *testing.T) {
36+
testCases := []struct {
37+
name string
38+
lines []string
39+
expected string
40+
}{
41+
{
42+
name: "emoji characters",
43+
lines: []string{"123 Main St 🏠", "Tokyo 🗾", "Japan 🇯🇵"},
44+
expected: "123 Main St 🏠$Tokyo 🗾$Japan 🇯🇵$",
45+
},
46+
{
47+
name: "cyrillic characters",
48+
lines: []string{"Красная площадь", "Москва 101000", "Россия"},
49+
expected: "Красная площадь$Москва 101000$Россия$",
50+
},
51+
{
52+
name: "chinese characters",
53+
lines: []string{"北京市东城区", "天安门广场", "中国"},
54+
expected: "北京市东城区$天安门广场$中国$",
55+
},
56+
{
57+
name: "arabic characters",
58+
lines: []string{"شارع الملك فهد", "الرياض", "المملكة العربية السعودية"},
59+
expected: "شارع الملك فهد$الرياض$المملكة العربية السعودية$",
60+
},
61+
{
62+
name: "mixed scripts with special chars",
63+
lines: []string{"Café René ☕", "Zürich $1000\\month", "Schweiz 🇨🇭"},
64+
expected: "Café René ☕$Zürich \\241000\\5Cmonth$Schweiz 🇨🇭$",
65+
},
66+
{
67+
name: "mathematical symbols",
68+
lines: []string{"∑ ∫ ∂", "π ≈ 3.14159", "∞ ≠ 0"},
69+
expected: "∑ ∫ ∂$π ≈ 3.14159$∞ ≠ 0$",
70+
},
71+
}
72+
73+
for _, tc := range testCases {
74+
t.Run(tc.name, func(t *testing.T) {
75+
addr := NewPostalAddress(tc.lines)
76+
escaped := addr.Escape()
77+
assert.Equal(t, tc.expected, escaped, "UTF-8 characters should be preserved in escaped output")
78+
79+
// Round-trip test
80+
parsed, err := ParsePostalAddress(escaped)
81+
assert.NoError(t, err)
82+
assert.Equal(t, tc.lines, parsed.Lines(), "UTF-8 characters should survive round-trip")
83+
})
84+
}
85+
}

0 commit comments

Comments
 (0)