github.com/zxy12/golang151_with_comment@v0.0.0-20190507085033-721809559d3c/mime/encodedword_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mime 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "io" 12 "io/ioutil" 13 "strings" 14 "testing" 15 ) 16 17 func ExampleWordEncoder_Encode() { 18 fmt.Println(QEncoding.Encode("utf-8", "¡Hola, señor!")) 19 fmt.Println(QEncoding.Encode("utf-8", "Hello!")) 20 fmt.Println(BEncoding.Encode("UTF-8", "¡Hola, señor!")) 21 fmt.Println(QEncoding.Encode("ISO-8859-1", "Caf\xE9")) 22 // Output: 23 // =?utf-8?q?=C2=A1Hola,_se=C3=B1or!?= 24 // Hello! 25 // =?UTF-8?b?wqFIb2xhLCBzZcOxb3Ih?= 26 // =?ISO-8859-1?q?Caf=E9?= 27 } 28 29 func ExampleWordDecoder_Decode() { 30 dec := new(WordDecoder) 31 header, err := dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=") 32 if err != nil { 33 panic(err) 34 } 35 fmt.Println(header) 36 37 dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) { 38 switch charset { 39 case "x-case": 40 // Fake character set for example. 41 // Real use would integrate with packages such 42 // as code.google.com/p/go-charset 43 content, err := ioutil.ReadAll(input) 44 if err != nil { 45 return nil, err 46 } 47 return bytes.NewReader(bytes.ToUpper(content)), nil 48 default: 49 return nil, fmt.Errorf("unhandled charset %q", charset) 50 } 51 } 52 header, err = dec.Decode("=?x-case?q?hello!?=") 53 if err != nil { 54 panic(err) 55 } 56 fmt.Println(header) 57 // Output: 58 // ¡Hola, señor! 59 // HELLO! 60 } 61 62 func ExampleWordDecoder_DecodeHeader() { 63 dec := new(WordDecoder) 64 header, err := dec.DecodeHeader("=?utf-8?q?=C3=89ric?= <eric@example.org>, =?utf-8?q?Ana=C3=AFs?= <anais@example.org>") 65 if err != nil { 66 panic(err) 67 } 68 fmt.Println(header) 69 70 header, err = dec.DecodeHeader("=?utf-8?q?=C2=A1Hola,?= =?utf-8?q?_se=C3=B1or!?=") 71 if err != nil { 72 panic(err) 73 } 74 fmt.Println(header) 75 76 dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) { 77 switch charset { 78 case "x-case": 79 // Fake character set for example. 80 // Real use would integrate with packages such 81 // as code.google.com/p/go-charset 82 content, err := ioutil.ReadAll(input) 83 if err != nil { 84 return nil, err 85 } 86 return bytes.NewReader(bytes.ToUpper(content)), nil 87 default: 88 return nil, fmt.Errorf("unhandled charset %q", charset) 89 } 90 } 91 header, err = dec.DecodeHeader("=?x-case?q?hello_?= =?x-case?q?world!?=") 92 if err != nil { 93 panic(err) 94 } 95 fmt.Println(header) 96 // Output: 97 // Éric <eric@example.org>, Anaïs <anais@example.org> 98 // ¡Hola, señor! 99 // HELLO WORLD! 100 } 101 102 func TestEncodeWord(t *testing.T) { 103 utf8, iso88591 := "utf-8", "iso-8859-1" 104 tests := []struct { 105 enc WordEncoder 106 charset string 107 src, exp string 108 }{ 109 {QEncoding, utf8, "François-Jérôme", "=?utf-8?q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?="}, 110 {BEncoding, utf8, "Café", "=?utf-8?b?Q2Fmw6k=?="}, 111 {QEncoding, iso88591, "La Seleção", "=?iso-8859-1?q?La_Sele=C3=A7=C3=A3o?="}, 112 {QEncoding, utf8, "", ""}, 113 {QEncoding, utf8, "A", "A"}, 114 {QEncoding, iso88591, "a", "a"}, 115 {QEncoding, utf8, "123 456", "123 456"}, 116 {QEncoding, utf8, "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~", "\t !\"#$%&'()*+,-./ :;<>?@[\\]^_`{|}~"}, 117 } 118 119 for _, test := range tests { 120 if s := test.enc.Encode(test.charset, test.src); s != test.exp { 121 t.Errorf("Encode(%q) = %q, want %q", test.src, s, test.exp) 122 } 123 } 124 } 125 126 func TestDecodeWord(t *testing.T) { 127 tests := []struct { 128 src, exp string 129 hasErr bool 130 }{ 131 {"=?UTF-8?Q?=C2=A1Hola,_se=C3=B1or!?=", "¡Hola, señor!", false}, 132 {"=?UTF-8?Q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?=", "François-Jérôme", false}, 133 {"=?UTF-8?q?ascii?=", "ascii", false}, 134 {"=?utf-8?B?QW5kcsOp?=", "André", false}, 135 {"=?ISO-8859-1?Q?Rapha=EBl_Dupont?=", "Raphaël Dupont", false}, 136 {"=?utf-8?b?IkFudG9uaW8gSm9zw6kiIDxqb3NlQGV4YW1wbGUub3JnPg==?=", `"Antonio José" <jose@example.org>`, false}, 137 {"=?UTF-8?A?Test?=", "", true}, 138 {"=?UTF-8?Q?A=B?=", "", true}, 139 {"=?UTF-8?Q?=A?=", "", true}, 140 {"=?UTF-8?A?A?=", "", true}, 141 } 142 143 for _, test := range tests { 144 dec := new(WordDecoder) 145 s, err := dec.Decode(test.src) 146 if test.hasErr && err == nil { 147 t.Errorf("Decode(%q) should return an error", test.src) 148 continue 149 } 150 if !test.hasErr && err != nil { 151 t.Errorf("Decode(%q): %v", test.src, err) 152 continue 153 } 154 if s != test.exp { 155 t.Errorf("Decode(%q) = %q, want %q", test.src, s, test.exp) 156 } 157 } 158 } 159 160 func TestDecodeHeader(t *testing.T) { 161 tests := []struct { 162 src, exp string 163 }{ 164 {"=?UTF-8?Q?=C2=A1Hola,_se=C3=B1or!?=", "¡Hola, señor!"}, 165 {"=?UTF-8?Q?Fran=C3=A7ois-J=C3=A9r=C3=B4me?=", "François-Jérôme"}, 166 {"=?UTF-8?q?ascii?=", "ascii"}, 167 {"=?utf-8?B?QW5kcsOp?=", "André"}, 168 {"=?ISO-8859-1?Q?Rapha=EBl_Dupont?=", "Raphaël Dupont"}, 169 {"Jean", "Jean"}, 170 {"=?utf-8?b?IkFudG9uaW8gSm9zw6kiIDxqb3NlQGV4YW1wbGUub3JnPg==?=", `"Antonio José" <jose@example.org>`}, 171 {"=?UTF-8?A?Test?=", "=?UTF-8?A?Test?="}, 172 {"=?UTF-8?Q?A=B?=", "=?UTF-8?Q?A=B?="}, 173 {"=?UTF-8?Q?=A?=", "=?UTF-8?Q?=A?="}, 174 {"=?UTF-8?A?A?=", "=?UTF-8?A?A?="}, 175 // Incomplete words 176 {"=?", "=?"}, 177 {"=?UTF-8?", "=?UTF-8?"}, 178 {"=?UTF-8?=", "=?UTF-8?="}, 179 {"=?UTF-8?Q", "=?UTF-8?Q"}, 180 {"=?UTF-8?Q?", "=?UTF-8?Q?"}, 181 {"=?UTF-8?Q?=", "=?UTF-8?Q?="}, 182 {"=?UTF-8?Q?A", "=?UTF-8?Q?A"}, 183 {"=?UTF-8?Q?A?", "=?UTF-8?Q?A?"}, 184 // Tests from RFC 2047 185 {"=?ISO-8859-1?Q?a?=", "a"}, 186 {"=?ISO-8859-1?Q?a?= b", "a b"}, 187 {"=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=", "ab"}, 188 {"=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=", "ab"}, 189 {"=?ISO-8859-1?Q?a?= \r\n\t =?ISO-8859-1?Q?b?=", "ab"}, 190 {"=?ISO-8859-1?Q?a_b?=", "a b"}, 191 } 192 193 for _, test := range tests { 194 dec := new(WordDecoder) 195 s, err := dec.DecodeHeader(test.src) 196 if err != nil { 197 t.Errorf("DecodeHeader(%q): %v", test.src, err) 198 } 199 if s != test.exp { 200 t.Errorf("DecodeHeader(%q) = %q, want %q", test.src, s, test.exp) 201 } 202 } 203 } 204 205 func TestCharsetDecoder(t *testing.T) { 206 tests := []struct { 207 src string 208 want string 209 charsets []string 210 content []string 211 }{ 212 {"=?utf-8?b?Q2Fmw6k=?=", "Café", nil, nil}, 213 {"=?ISO-8859-1?Q?caf=E9?=", "café", nil, nil}, 214 {"=?US-ASCII?Q?foo_bar?=", "foo bar", nil, nil}, 215 {"=?utf-8?Q?=?=", "=?utf-8?Q?=?=", nil, nil}, 216 {"=?utf-8?Q?=A?=", "=?utf-8?Q?=A?=", nil, nil}, 217 { 218 "=?ISO-8859-15?Q?f=F5=F6?= =?windows-1252?Q?b=E0r?=", 219 "f\xf5\xf6b\xe0r", 220 []string{"iso-8859-15", "windows-1252"}, 221 []string{"f\xf5\xf6", "b\xe0r"}, 222 }, 223 } 224 225 for _, test := range tests { 226 i := 0 227 dec := &WordDecoder{ 228 CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { 229 if charset != test.charsets[i] { 230 t.Errorf("DecodeHeader(%q), got charset %q, want %q", test.src, charset, test.charsets[i]) 231 } 232 content, err := ioutil.ReadAll(input) 233 if err != nil { 234 t.Errorf("DecodeHeader(%q), error in reader: %v", test.src, err) 235 } 236 got := string(content) 237 if got != test.content[i] { 238 t.Errorf("DecodeHeader(%q), got content %q, want %q", test.src, got, test.content[i]) 239 } 240 i++ 241 242 return strings.NewReader(got), nil 243 }, 244 } 245 got, err := dec.DecodeHeader(test.src) 246 if err != nil { 247 t.Errorf("DecodeHeader(%q): %v", test.src, err) 248 } 249 if got != test.want { 250 t.Errorf("DecodeHeader(%q) = %q, want %q", test.src, got, test.want) 251 } 252 } 253 } 254 255 func TestCharsetDecoderError(t *testing.T) { 256 dec := &WordDecoder{ 257 CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { 258 return nil, errors.New("Test error") 259 }, 260 } 261 262 if _, err := dec.DecodeHeader("=?charset?Q?foo?="); err == nil { 263 t.Error("DecodeHeader should return an error") 264 } 265 } 266 267 func BenchmarkQEncodeWord(b *testing.B) { 268 for i := 0; i < b.N; i++ { 269 QEncoding.Encode("UTF-8", "¡Hola, señor!") 270 } 271 } 272 273 func BenchmarkQDecodeWord(b *testing.B) { 274 dec := new(WordDecoder) 275 276 for i := 0; i < b.N; i++ { 277 dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=") 278 } 279 } 280 281 func BenchmarkQDecodeHeader(b *testing.B) { 282 dec := new(WordDecoder) 283 284 for i := 0; i < b.N; i++ { 285 dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=") 286 } 287 }