Skip to content

Commit 7ab92b1

Browse files
committed
add unicode tests
1 parent 9a79a6d commit 7ab92b1

File tree

2 files changed

+110
-7
lines changed

2 files changed

+110
-7
lines changed

unicode.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ package gp
44
#include <Python.h>
55
*/
66
import "C"
7-
import (
8-
"reflect"
9-
"unsafe"
10-
)
7+
import "unsafe"
118

129
type Str struct {
1310
Object
@@ -18,9 +15,8 @@ func newStr(obj *PyObject) Str {
1815
}
1916

2017
func MakeStr(s string) Str {
21-
hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
22-
ptr := (*C.char)(unsafe.Pointer(hdr.Data))
23-
length := C.long(hdr.Len)
18+
ptr := (*C.char)(unsafe.Pointer(unsafe.StringData(s)))
19+
length := C.long(len(s))
2420
return newStr(C.PyUnicode_FromStringAndSize(ptr, length))
2521
}
2622

@@ -31,6 +27,10 @@ func (s Str) String() string {
3127
}
3228

3329
func (s Str) Len() int {
30+
return int(C.PyUnicode_GetLength(s.obj))
31+
}
32+
33+
func (s Str) ByteLen() int {
3434
var l C.long
3535
C.PyUnicode_AsUTF8AndSize(s.obj, &l)
3636
return int(l)

unicode_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package gp
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestMakeStr(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
input string
11+
expected string
12+
length int
13+
byteCount int
14+
}{
15+
{
16+
name: "empty string",
17+
input: "",
18+
expected: "",
19+
length: 0,
20+
byteCount: 0,
21+
},
22+
{
23+
name: "ascii string",
24+
input: "hello",
25+
expected: "hello",
26+
length: 5,
27+
byteCount: 5, // ASCII字符每个占1字节
28+
},
29+
{
30+
name: "unicode string",
31+
input: "你好世界",
32+
expected: "你好世界",
33+
length: 4,
34+
byteCount: 12, // 中文字符每个占3字节
35+
},
36+
{
37+
name: "mixed string",
38+
input: "hello世界",
39+
expected: "hello世界",
40+
length: 7,
41+
byteCount: 11, // 5个ASCII字符(5字节) + 2个中文字符(6字节)
42+
},
43+
{
44+
name: "special unicode",
45+
input: "π∑€",
46+
expected: "π∑€",
47+
length: 3,
48+
byteCount: 8, // π(2字节) + ∑(3字节) + €(3字节) = 8字节
49+
},
50+
}
51+
52+
for _, tt := range tests {
53+
t.Run(tt.name, func(t *testing.T) {
54+
pyStr := MakeStr(tt.input)
55+
56+
// Test String() method
57+
if got := pyStr.String(); got != tt.expected {
58+
t.Errorf("MakeStr(%q).String() = %q, want %q", tt.input, got, tt.expected)
59+
}
60+
61+
// Test Len() method
62+
if got := pyStr.Len(); got != tt.length {
63+
t.Errorf("MakeStr(%q).Len() = %d, want %d", tt.input, got, tt.length)
64+
}
65+
66+
// Test ByteLen() method
67+
if got := pyStr.ByteLen(); got != tt.byteCount {
68+
t.Errorf("MakeStr(%q).ByteLen() = %d, want %d", tt.input, got, tt.byteCount)
69+
}
70+
})
71+
}
72+
}
73+
74+
func TestStrEncode(t *testing.T) {
75+
tests := []struct {
76+
name string
77+
input string
78+
encoding string
79+
}{
80+
{
81+
name: "utf-8 encoding",
82+
input: "hello世界",
83+
encoding: "utf-8",
84+
},
85+
{
86+
name: "ascii encoding",
87+
input: "hello",
88+
encoding: "ascii",
89+
},
90+
}
91+
92+
for _, tt := range tests {
93+
t.Run(tt.name, func(t *testing.T) {
94+
pyStr := MakeStr(tt.input)
95+
encoded := pyStr.Encode(tt.encoding)
96+
decoded := encoded.Decode(tt.encoding)
97+
98+
if got := decoded.String(); got != tt.input {
99+
t.Errorf("String encode/decode roundtrip failed: got %q, want %q", got, tt.input)
100+
}
101+
})
102+
}
103+
}

0 commit comments

Comments
 (0)