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