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