]> git.lizzy.rs Git - rust.git/blob - src/libcollectionstest/string.rs
doc: make String::as_bytes example more simple
[rust.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 }