1
2
3
4
5 package japanese
6
7 import (
8 "fmt"
9 "strings"
10 "testing"
11 "unicode/utf8"
12
13 "golang.org/x/text/encoding"
14 "golang.org/x/text/encoding/internal"
15 "golang.org/x/text/encoding/internal/enctest"
16 "golang.org/x/text/transform"
17 "golang.org/x/text/unicode/norm"
18 )
19
20 func dec(e encoding.Encoding) (dir string, t transform.Transformer, err error) {
21 return "Decode", e.NewDecoder(), nil
22 }
23 func enc(e encoding.Encoding) (dir string, t transform.Transformer, err error) {
24 return "Encode", e.NewEncoder(), internal.ErrASCIIReplacement
25 }
26
27 func TestNonRepertoire(t *testing.T) {
28
29 const n = 100
30 long := strings.Repeat(".", n)
31 testCases := []struct {
32 init func(e encoding.Encoding) (string, transform.Transformer, error)
33 e encoding.Encoding
34 src, want string
35 }{
36 {enc, EUCJP, "갂", ""},
37 {enc, EUCJP, "a갂", "a"},
38 {enc, EUCJP, "丌갂", "\x8f\xb0\xa4"},
39
40 {enc, ISO2022JP, "갂", ""},
41 {enc, ISO2022JP, "a갂", "a"},
42 {enc, ISO2022JP, "朗갂", "\x1b$BzF\x1b(B"},
43
44 {enc, ShiftJIS, "갂", ""},
45 {enc, ShiftJIS, "a갂", "a"},
46 {enc, ShiftJIS, "\u2190갂", "\x81\xa9"},
47
48
49 {dec, EUCJP, "\x8e\xa0", "\ufffd\ufffd"},
50 {dec, EUCJP, "\x8e\xe0", "\ufffd"},
51 {dec, EUCJP, "\x8e\xff", "\ufffd\ufffd"},
52 {dec, EUCJP, "\x8ea", "\ufffda"},
53 {dec, EUCJP, "\x8f\xa0", "\ufffd\ufffd"},
54 {dec, EUCJP, "\x8f\xa1\xa0", "\ufffd\ufffd"},
55 {dec, EUCJP, "\x8f\xa1a", "\ufffda"},
56 {dec, EUCJP, "\x8f\xa1a", "\ufffda"},
57 {dec, EUCJP, "\x8f\xa1a", "\ufffda"},
58 {dec, EUCJP, "\x8f\xa2\xa2", "\ufffd"},
59 {dec, EUCJP, "\xfe", "\ufffd"},
60 {dec, EUCJP, "\xfe\xfc", "\ufffd"},
61 {dec, EUCJP, "\xfe\xff", "\ufffd\ufffd"},
62
63 {dec, EUCJP, strings.Repeat("\x8e", n), strings.Repeat("\ufffd", n)},
64 {dec, EUCJP, strings.Repeat("\x8f", n), strings.Repeat("\ufffd", n)},
65 {dec, EUCJP, strings.Repeat("\x8f\xa0", n), strings.Repeat("\ufffd", 2*n)},
66 {dec, EUCJP, "a" + strings.Repeat("\x8f\xa1", n), "a" + strings.Repeat("\ufffd", n)},
67 {dec, EUCJP, "a" + strings.Repeat("\x8f\xa1\xff", n), "a" + strings.Repeat("\ufffd", 2*n)},
68
69
70 {dec, ShiftJIS, "\x80", "\u0080"},
71 {dec, ShiftJIS, "\x81", "\ufffd"},
72 {dec, ShiftJIS, "\x81\x7f", "\ufffd\u007f"},
73 {dec, ShiftJIS, "\xe0", "\ufffd"},
74 {dec, ShiftJIS, "\xe0\x39", "\ufffd\u0039"},
75 {dec, ShiftJIS, "\xe0\x9f", "燹"},
76 {dec, ShiftJIS, "\xe0\xfd", "\ufffd"},
77 {dec, ShiftJIS, "\xef\xfc", "\ufffd"},
78 {dec, ShiftJIS, "\xfc\xfc", "\ufffd"},
79 {dec, ShiftJIS, "\xfc\xfd", "\ufffd"},
80 {dec, ShiftJIS, "\xfdaa", "\ufffdaa"},
81
82 {dec, ShiftJIS, strings.Repeat("\x81\x81", n), strings.Repeat("=", n)},
83 {dec, ShiftJIS, strings.Repeat("\xe0\xfd", n), strings.Repeat("\ufffd", n)},
84 {dec, ShiftJIS, "a" + strings.Repeat("\xe0\xfd", n), "a" + strings.Repeat("\ufffd", n)},
85
86 {dec, ISO2022JP, "\x1b$", "\ufffd$"},
87 {dec, ISO2022JP, "\x1b(", "\ufffd("},
88 {dec, ISO2022JP, "\x1b@", "\ufffd@"},
89 {dec, ISO2022JP, "\x1bZ", "\ufffdZ"},
90
91 {dec, ISO2022JP, "\x1b$", "\ufffd$"},
92 {dec, ISO2022JP, "\x1b$J.", "\ufffd$J."},
93 {dec, ISO2022JP, "\x1b$B.", "\ufffd"},
94 {dec, ISO2022JP, "\x1b$(", "\ufffd$("},
95 {dec, ISO2022JP, "\x1b$(..", "\ufffd$(.."},
96 {dec, ISO2022JP, "\x1b$(" + long, "\ufffd$(" + long},
97 {dec, ISO2022JP, "\x1b$(D.", "\ufffd"},
98 {dec, ISO2022JP, "\x1b$(D..", "\ufffd"},
99 {dec, ISO2022JP, "\x1b$(D...", "\ufffd\ufffd"},
100 {dec, ISO2022JP, "\x1b(B.", "."},
101 {dec, ISO2022JP, "\x1b(B..", ".."},
102 {dec, ISO2022JP, "\x1b(J.", "."},
103 {dec, ISO2022JP, "\x1b(J..", ".."},
104 {dec, ISO2022JP, "\x1b(I\x20", "\ufffd"},
105 {dec, ISO2022JP, "\x1b(I\x20\x20", "\ufffd\ufffd"},
106
107 {dec, ISO2022JP, "\x1b(B\x1b.", "\ufffd."},
108 {dec, ISO2022JP, "\x1b(I\x1b.", "\ufffdョ"},
109 {dec, ISO2022JP, "\x1b(I\x1b$.", "\ufffd、ョ"},
110 {dec, ISO2022JP, "\x1b(I\x1b(.", "\ufffdィョ"},
111 {dec, ISO2022JP, "\x1b$B\x7e\x7e", "\ufffd"},
112 {dec, ISO2022JP, "\x1b$@\x0a.", "\x0a."},
113 {dec, ISO2022JP, "\x1b$B\x0a.", "\x0a."},
114 {dec, ISO2022JP, "\x1b$(D\x0a.", "\x0a."},
115 {dec, ISO2022JP, "\x1b$(D\x7e\x7e", "\ufffd"},
116 {dec, ISO2022JP, "\x80", "\ufffd"},
117
118
119
120
121
122 {dec, ISO2022JP, "\x1b(B\x5C", "\u005C"},
123 {dec, ISO2022JP, "\x1b(B\x7E", "\u007E"},
124
125
126
127
128 }
129 for _, tc := range testCases {
130 dir, tr, wantErr := tc.init(tc.e)
131 t.Run(fmt.Sprintf("%s/%v/%q", dir, tc.e, shortNFC(tc.src)), func(t *testing.T) {
132 dst := make([]byte, 100000)
133 src := []byte(tc.src)
134 for i := 0; i <= len(tc.src); i++ {
135 nDst, nSrc, err := tr.Transform(dst, src[:i], false)
136 if err != nil && err != transform.ErrShortSrc && err != wantErr {
137 t.Fatalf("error on first call to Transform: %v", err)
138 }
139 n, _, err := tr.Transform(dst[nDst:], src[nSrc:], true)
140 nDst += n
141 if err != wantErr {
142 t.Fatalf("(%q|%q): got %v; want %v", tc.src[:i], tc.src[i:], err, wantErr)
143 }
144 if got := string(dst[:nDst]); got != tc.want {
145 t.Errorf("(%q|%q):\ngot %q\nwant %q", tc.src[:i], tc.src[i:], got, tc.want)
146 }
147 }
148 })
149 }
150 }
151
152 func shortNFC(s string) string {
153 s = norm.NFC.String(s)
154 if len(s) <= 50 {
155 return s
156 }
157 var i int
158 for i = 1; i < utf8.UTFMax && !utf8.RuneStart(s[50-i]); i++ {
159 }
160 return s[:50-i] + "…"
161 }
162
163 func TestCorrect(t *testing.T) {
164 testCases := []struct {
165 init func(e encoding.Encoding) (string, transform.Transformer, error)
166 e encoding.Encoding
167 src, want string
168 }{
169 {dec, ShiftJIS, "\x9f\xfc", "滌"},
170 {dec, ShiftJIS, "\xfb\xfc", "髙"},
171 {dec, ShiftJIS, "\xfa\xb1", "﨑"},
172 {enc, ShiftJIS, "滌", "\x9f\xfc"},
173 {enc, ShiftJIS, "﨑", "\xed\x95"},
174 }
175 for _, tc := range testCases {
176 dir, tr, _ := tc.init(tc.e)
177
178 dst, _, err := transform.String(tr, tc.src)
179 if err != nil {
180 t.Errorf("%s %v(%q): got %v; want %v", dir, tc.e, tc.src, err, nil)
181 }
182 if got := string(dst); got != tc.want {
183 t.Errorf("%s %v(%q):\ngot %q\nwant %q", dir, tc.e, tc.src, got, tc.want)
184 }
185 }
186 }
187
188 func TestBasics(t *testing.T) {
189
190
191 testCases := []struct {
192 e encoding.Encoding
193 encPrefix string
194 encSuffix string
195 encoded string
196 utf8 string
197 }{{
198
199
200
201
202
203
204 e: EUCJP,
205 encoded: "A\x8e\xa1\x8e\xb6\x8e\xdf " +
206 "0208: \xa1\xa1\xa1\xa2\xa1\xdf\xa1\xe0\xa1\xfd\xa1\xfe\xa2\xa1\xa2\xa2\xf4\xa6 " +
207 "0212: \x8f\xa2\xaf\x8f\xed\xe3",
208 utf8: "A。カ゚ " +
209 "0208: \u3000\u3001\u00d7\u00f7\u25ce\u25c7\u25c6\u25a1\u7199 " +
210 "0212: \u02d8\u9fa5",
211 }, {
212 e: EUCJP,
213 encoded: "\xb7\xee\xc6\xfc\xa4\xcf\xc9\xb4\xc2\xe5\xa4\xce\xb2\xe1\xb5\xd2" +
214 "\xa4\xcb\xa4\xb7\xa4\xc6\xa1\xa2\xb9\xd4\xa4\xab\xa4\xd5\xc7\xaf" +
215 "\xa4\xe2\xcb\xf4\xce\xb9\xbf\xcd\xcc\xe9\xa1\xa3",
216 utf8: "月日は百代の過客にして、行かふ年も又旅人也。",
217 }, {
218 e: ISO2022JP,
219 encSuffix: "\x1b\x28\x42",
220 encoded: "\x1b\x28\x49\x21\x36\x5f\x1b\x28\x42 " +
221 "0208: \x1b\x24\x42\x21\x21\x21\x22\x21\x5f\x21\x60\x21\x7d\x21\x7e\x22\x21\x22\x22\x74\x26",
222 utf8: "。カ゚ " +
223 "0208: \u3000\u3001\u00d7\u00f7\u25ce\u25c7\u25c6\u25a1\u7199",
224 }, {
225 e: ISO2022JP,
226 encPrefix: "\x1b\x24\x42",
227 encSuffix: "\x1b\x28\x42",
228 encoded: "\x37\x6e\x46\x7c\x24\x4f\x49\x34\x42\x65\x24\x4e\x32\x61\x35\x52" +
229 "\x24\x4b\x24\x37\x24\x46\x21\x22\x39\x54\x24\x2b\x24\x55\x47\x2f" +
230 "\x24\x62\x4b\x74\x4e\x39\x3f\x4d\x4c\x69\x21\x23",
231 utf8: "月日は百代の過客にして、行かふ年も又旅人也。",
232 }, {
233 e: ShiftJIS,
234 encoded: "A\xa1\xb6\xdf " +
235 "0208: \x81\x40\x81\x41\x81\x7e\x81\x80\x81\x9d\x81\x9e\x81\x9f\x81\xa0\xea\xa4",
236 utf8: "A。カ゚ " +
237 "0208: \u3000\u3001\u00d7\u00f7\u25ce\u25c7\u25c6\u25a1\u7199",
238 }, {
239 e: ShiftJIS,
240 encoded: "\x8c\x8e\x93\xfa\x82\xcd\x95\x53\x91\xe3\x82\xcc\x89\xdf\x8b\x71" +
241 "\x82\xc9\x82\xb5\x82\xc4\x81\x41\x8d\x73\x82\xa9\x82\xd3\x94\x4e" +
242 "\x82\xe0\x96\x94\x97\xb7\x90\x6c\x96\xe7\x81\x42",
243 utf8: "月日は百代の過客にして、行かふ年も又旅人也。",
244 }}
245
246 for _, tc := range testCases {
247 enctest.TestEncoding(t, tc.e, tc.encoded, tc.utf8, tc.encPrefix, tc.encSuffix)
248 }
249 }
250
251 func TestFiles(t *testing.T) {
252 enctest.TestFile(t, EUCJP)
253 enctest.TestFile(t, ISO2022JP)
254 enctest.TestFile(t, ShiftJIS)
255 }
256
257 func BenchmarkEncoding(b *testing.B) {
258 enctest.Benchmark(b, EUCJP)
259 enctest.Benchmark(b, ISO2022JP)
260 enctest.Benchmark(b, ShiftJIS)
261 }
262
View as plain text