]> git.proxmox.com Git - rustc.git/blob - src/libcollectionstest/string.rs
257caca4016df28e8cef0f826544a4d16649bceb
[rustc.git] / src / libcollectionstest / string.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::borrow::{IntoCow, Cow};
12 use std::iter::repeat;
13 #[allow(deprecated)]
14 use std::string::as_string;
15
16 use test::Bencher;
17
18 #[test]
19 #[allow(deprecated)]
20 fn test_as_string() {
21 let x = "foo";
22 assert_eq!(x, &**as_string(x));
23 }
24
25 #[test]
26 fn test_from_str() {
27 let owned: Option<::std::string::String> = "string".parse().ok();
28 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
29 }
30
31 #[test]
32 fn test_unsized_to_string() {
33 let s: &str = "abc";
34 let _: String = (*s).to_string();
35 }
36
37 #[test]
38 fn test_from_utf8() {
39 let xs = b"hello".to_vec();
40 assert_eq!(String::from_utf8(xs).unwrap(),
41 String::from("hello"));
42
43 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
44 assert_eq!(String::from_utf8(xs).unwrap(),
45 String::from("ศไทย中华Việt Nam"));
46
47 let xs = b"hello\xFF".to_vec();
48 let err = String::from_utf8(xs).err().unwrap();
49 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
50 }
51
52 #[test]
53 fn test_from_utf8_lossy() {
54 let xs = b"hello";
55 let ys: Cow<str> = "hello".into_cow();
56 assert_eq!(String::from_utf8_lossy(xs), ys);
57
58 let xs = "ศไทย中华Việt Nam".as_bytes();
59 let ys: Cow<str> = "ศไทย中华Việt Nam".into_cow();
60 assert_eq!(String::from_utf8_lossy(xs), ys);
61
62 let xs = b"Hello\xC2 There\xFF Goodbye";
63 assert_eq!(String::from_utf8_lossy(xs),
64 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
65
66 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
67 assert_eq!(String::from_utf8_lossy(xs),
68 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
69
70 let xs = b"\xF5foo\xF5\x80bar";
71 assert_eq!(String::from_utf8_lossy(xs),
72 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
73
74 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
75 assert_eq!(String::from_utf8_lossy(xs),
76 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
77
78 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
79 assert_eq!(String::from_utf8_lossy(xs),
80 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
81
82 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
83 assert_eq!(String::from_utf8_lossy(xs), String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
84 foo\u{10000}bar").into_cow());
85
86 // surrogates
87 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
88 assert_eq!(String::from_utf8_lossy(xs), String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\
89 \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
90 }
91
92 #[test]
93 fn test_from_utf16() {
94 let pairs =
95 [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
96 vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
97 0xd800, 0xdf3b, 0xd800, 0xdf46,
98 0xd800, 0xdf39, 0xd800, 0xdf3b,
99 0xd800, 0xdf30, 0x000a]),
100
101 (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
102 vec![0xd801, 0xdc12, 0xd801,
103 0xdc49, 0xd801, 0xdc2e, 0xd801,
104 0xdc40, 0xd801, 0xdc32, 0xd801,
105 0xdc4b, 0x0020, 0xd801, 0xdc0f,
106 0xd801, 0xdc32, 0xd801, 0xdc4d,
107 0x000a]),
108
109 (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
110 vec![0xd800, 0xdf00, 0xd800, 0xdf16,
111 0xd800, 0xdf0b, 0xd800, 0xdf04,
112 0xd800, 0xdf11, 0xd800, 0xdf09,
113 0x00b7, 0xd800, 0xdf0c, 0xd800,
114 0xdf04, 0xd800, 0xdf15, 0xd800,
115 0xdf04, 0xd800, 0xdf0b, 0xd800,
116 0xdf09, 0xd800, 0xdf11, 0x000a ]),
117
118 (String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
119 vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
120 0xd801, 0xdc88, 0xd801, 0xdc91,
121 0xd801, 0xdc9b, 0xd801, 0xdc92,
122 0x0020, 0xd801, 0xdc95, 0xd801,
123 0xdc93, 0x0020, 0xd801, 0xdc88,
124 0xd801, 0xdc9a, 0xd801, 0xdc8d,
125 0x0020, 0xd801, 0xdc8f, 0xd801,
126 0xdc9c, 0xd801, 0xdc92, 0xd801,
127 0xdc96, 0xd801, 0xdc86, 0x0020,
128 0xd801, 0xdc95, 0xd801, 0xdc86,
129 0x000a ]),
130 // Issue #12318, even-numbered non-BMP planes
131 (String::from("\u{20000}"),
132 vec![0xD840, 0xDC00])];
133
134 for p in &pairs {
135 let (s, u) = (*p).clone();
136 let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
137 let u_as_string = String::from_utf16(&u).unwrap();
138
139 assert!(::rustc_unicode::str::is_utf16(&u));
140 assert_eq!(s_as_utf16, u);
141
142 assert_eq!(u_as_string, s);
143 assert_eq!(String::from_utf16_lossy(&u), s);
144
145 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
146 assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
147 }
148 }
149
150 #[test]
151 fn test_utf16_invalid() {
152 // completely positive cases tested above.
153 // lead + eof
154 assert!(String::from_utf16(&[0xD800]).is_err());
155 // lead + lead
156 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
157
158 // isolated trail
159 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
160
161 // general
162 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
163 }
164
165 #[test]
166 fn test_from_utf16_lossy() {
167 // completely positive cases tested above.
168 // lead + eof
169 assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
170 // lead + lead
171 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
172 String::from("\u{FFFD}\u{FFFD}"));
173
174 // isolated trail
175 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
176
177 // general
178 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
179 String::from("\u{FFFD}𐒋\u{FFFD}"));
180 }
181
182 #[test]
183 fn test_push_bytes() {
184 let mut s = String::from("ABC");
185 unsafe {
186 let mv = s.as_mut_vec();
187 mv.push_all(&[b'D']);
188 }
189 assert_eq!(s, "ABCD");
190 }
191
192 #[test]
193 fn test_push_str() {
194 let mut s = String::new();
195 s.push_str("");
196 assert_eq!(&s[0..], "");
197 s.push_str("abc");
198 assert_eq!(&s[0..], "abc");
199 s.push_str("ประเทศไทย中华Việt Nam");
200 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
201 }
202
203 #[test]
204 fn test_push() {
205 let mut data = String::from("ประเทศไทย中");
206 data.push('华');
207 data.push('b'); // 1 byte
208 data.push('¢'); // 2 byte
209 data.push('€'); // 3 byte
210 data.push('𤭢'); // 4 byte
211 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
212 }
213
214 #[test]
215 fn test_pop() {
216 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
217 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
218 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
219 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
220 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
221 assert_eq!(data.pop().unwrap(), '华');
222 assert_eq!(data, "ประเทศไทย中");
223 }
224
225 #[test]
226 fn test_str_truncate() {
227 let mut s = String::from("12345");
228 s.truncate(5);
229 assert_eq!(s, "12345");
230 s.truncate(3);
231 assert_eq!(s, "123");
232 s.truncate(0);
233 assert_eq!(s, "");
234
235 let mut s = String::from("12345");
236 let p = s.as_ptr();
237 s.truncate(3);
238 s.push_str("6");
239 let p_ = s.as_ptr();
240 assert_eq!(p_, p);
241 }
242
243 #[test]
244 #[should_panic]
245 fn test_str_truncate_invalid_len() {
246 let mut s = String::from("12345");
247 s.truncate(6);
248 }
249
250 #[test]
251 #[should_panic]
252 fn test_str_truncate_split_codepoint() {
253 let mut s = String::from("\u{FC}"); // ü
254 s.truncate(1);
255 }
256
257 #[test]
258 fn test_str_clear() {
259 let mut s = String::from("12345");
260 s.clear();
261 assert_eq!(s.len(), 0);
262 assert_eq!(s, "");
263 }
264
265 #[test]
266 fn test_str_add() {
267 let a = String::from("12345");
268 let b = a + "2";
269 let b = b + "2";
270 assert_eq!(b.len(), 7);
271 assert_eq!(b, "1234522");
272 }
273
274 #[test]
275 fn remove() {
276 let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
277 assert_eq!(s.remove(0), 'ศ');
278 assert_eq!(s.len(), 33);
279 assert_eq!(s, "ไทย中华Việt Nam; foobar");
280 assert_eq!(s.remove(17), 'ệ');
281 assert_eq!(s, "ไทย中华Vit Nam; foobar");
282 }
283
284 #[test] #[should_panic]
285 fn remove_bad() {
286 "ศ".to_string().remove(1);
287 }
288
289 #[test]
290 fn insert() {
291 let mut s = "foobar".to_string();
292 s.insert(0, 'ệ');
293 assert_eq!(s, "ệfoobar");
294 s.insert(6, 'ย');
295 assert_eq!(s, "ệfooยbar");
296 }
297
298 #[test] #[should_panic] fn insert_bad1() { "".to_string().insert(1, 't'); }
299 #[test] #[should_panic] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
300
301 #[test]
302 fn test_slicing() {
303 let s = "foobar".to_string();
304 assert_eq!("foobar", &s[..]);
305 assert_eq!("foo", &s[..3]);
306 assert_eq!("bar", &s[3..]);
307 assert_eq!("oob", &s[1..4]);
308 }
309
310 #[test]
311 fn test_simple_types() {
312 assert_eq!(1.to_string(), "1");
313 assert_eq!((-1).to_string(), "-1");
314 assert_eq!(200.to_string(), "200");
315 assert_eq!(2.to_string(), "2");
316 assert_eq!(true.to_string(), "true");
317 assert_eq!(false.to_string(), "false");
318 assert_eq!(("hi".to_string()).to_string(), "hi");
319 }
320
321 #[test]
322 fn test_vectors() {
323 let x: Vec<i32> = vec![];
324 assert_eq!(format!("{:?}", x), "[]");
325 assert_eq!(format!("{:?}", vec![1]), "[1]");
326 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
327 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
328 "[[], [1], [1, 1]]");
329 }
330
331 #[test]
332 fn test_from_iterator() {
333 let s = "ศไทย中华Việt Nam".to_string();
334 let t = "ศไทย中华";
335 let u = "Việt Nam";
336
337 let a: String = s.chars().collect();
338 assert_eq!(s, a);
339
340 let mut b = t.to_string();
341 b.extend(u.chars());
342 assert_eq!(s, b);
343
344 let c: String = vec![t, u].into_iter().collect();
345 assert_eq!(s, c);
346
347 let mut d = t.to_string();
348 d.extend(vec![u]);
349 assert_eq!(s, d);
350 }
351
352 #[test]
353 fn test_drain() {
354 let mut s = String::from("αβγ");
355 assert_eq!(s.drain(2..4).collect::<String>(), "β");
356 assert_eq!(s, "αγ");
357
358 let mut t = String::from("abcd");
359 t.drain(..0);
360 assert_eq!(t, "abcd");
361 t.drain(..1);
362 assert_eq!(t, "bcd");
363 t.drain(3..);
364 assert_eq!(t, "bcd");
365 t.drain(..);
366 assert_eq!(t, "");
367 }
368
369 #[test]
370 fn test_extend_ref() {
371 let mut a = "foo".to_string();
372 a.extend(&['b', 'a', 'r']);
373
374 assert_eq!(&a, "foobar");
375 }
376
377 #[bench]
378 fn bench_with_capacity(b: &mut Bencher) {
379 b.iter(|| {
380 String::with_capacity(100)
381 });
382 }
383
384 #[bench]
385 fn bench_push_str(b: &mut Bencher) {
386 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
387 b.iter(|| {
388 let mut r = String::new();
389 r.push_str(s);
390 });
391 }
392
393 const REPETITIONS: u64 = 10_000;
394
395 #[bench]
396 fn bench_push_str_one_byte(b: &mut Bencher) {
397 b.bytes = REPETITIONS;
398 b.iter(|| {
399 let mut r = String::new();
400 for _ in 0..REPETITIONS {
401 r.push_str("a")
402 }
403 });
404 }
405
406 #[bench]
407 fn bench_push_char_one_byte(b: &mut Bencher) {
408 b.bytes = REPETITIONS;
409 b.iter(|| {
410 let mut r = String::new();
411 for _ in 0..REPETITIONS {
412 r.push('a')
413 }
414 });
415 }
416
417 #[bench]
418 fn bench_push_char_two_bytes(b: &mut Bencher) {
419 b.bytes = REPETITIONS * 2;
420 b.iter(|| {
421 let mut r = String::new();
422 for _ in 0..REPETITIONS {
423 r.push('â')
424 }
425 });
426 }
427
428 #[bench]
429 fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
430 let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
431 Lorem ipsum dolor sit amet, consectetur. ";
432
433 assert_eq!(100, s.len());
434 b.iter(|| {
435 let _ = String::from_utf8_lossy(s);
436 });
437 }
438
439 #[bench]
440 fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
441 let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
442 assert_eq!(100, s.len());
443 b.iter(|| {
444 let _ = String::from_utf8_lossy(s);
445 });
446 }
447
448 #[bench]
449 fn from_utf8_lossy_invalid(b: &mut Bencher) {
450 let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
451 b.iter(|| {
452 let _ = String::from_utf8_lossy(s);
453 });
454 }
455
456 #[bench]
457 fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
458 let s = repeat(0xf5).take(100).collect::<Vec<_>>();
459 b.iter(|| {
460 let _ = String::from_utf8_lossy(&s);
461 });
462 }
463
464 #[bench]
465 fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
466 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
467 Lorem ipsum dolor sit amet, consectetur. ";
468 // ensure our operation produces an exact-size string before we benchmark it
469 let mut r = String::with_capacity(s.len());
470 r.push_str(s);
471 assert_eq!(r.len(), r.capacity());
472 b.iter(|| {
473 let mut r = String::with_capacity(s.len());
474 r.push_str(s);
475 r.shrink_to_fit();
476 r
477 });
478 }
479
480 #[bench]
481 fn bench_from_str(b: &mut Bencher) {
482 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
483 Lorem ipsum dolor sit amet, consectetur. ";
484 b.iter(|| {
485 String::from(s)
486 })
487 }
488
489 #[bench]
490 fn bench_from(b: &mut Bencher) {
491 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
492 Lorem ipsum dolor sit amet, consectetur. ";
493 b.iter(|| {
494 String::from(s)
495 })
496 }
497
498 #[bench]
499 fn bench_to_string(b: &mut Bencher) {
500 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
501 Lorem ipsum dolor sit amet, consectetur. ";
502 b.iter(|| {
503 s.to_string()
504 })
505 }