]> git.lizzy.rs Git - rust.git/blob - src/libcollectionstest/str.rs
Rollup merge of #39604 - est31:i128_tests, r=alexcrichton
[rust.git] / src / libcollectionstest / str.rs
1 // Copyright 2012-2015 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::cmp::Ordering::{Equal, Greater, Less};
13 use std::str::from_utf8;
14
15 #[test]
16 fn test_le() {
17     assert!("" <= "");
18     assert!("" <= "foo");
19     assert!("foo" <= "foo");
20     assert!("foo" != "bar");
21 }
22
23 #[test]
24 fn test_find() {
25     assert_eq!("hello".find('l'), Some(2));
26     assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
27     assert!("hello".find('x').is_none());
28     assert!("hello".find(|c:char| c == 'x').is_none());
29     assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
30     assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
31 }
32
33 #[test]
34 fn test_rfind() {
35     assert_eq!("hello".rfind('l'), Some(3));
36     assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
37     assert!("hello".rfind('x').is_none());
38     assert!("hello".rfind(|c:char| c == 'x').is_none());
39     assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
40     assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
41 }
42
43 #[test]
44 fn test_collect() {
45     let empty = "";
46     let s: String = empty.chars().collect();
47     assert_eq!(empty, s);
48     let data = "ประเทศไทย中";
49     let s: String = data.chars().collect();
50     assert_eq!(data, s);
51 }
52
53 #[test]
54 fn test_into_bytes() {
55     let data = String::from("asdf");
56     let buf = data.into_bytes();
57     assert_eq!(buf, b"asdf");
58 }
59
60 #[test]
61 fn test_find_str() {
62     // byte positions
63     assert_eq!("".find(""), Some(0));
64     assert!("banana".find("apple pie").is_none());
65
66     let data = "abcabc";
67     assert_eq!(data[0..6].find("ab"), Some(0));
68     assert_eq!(data[2..6].find("ab"), Some(3 - 2));
69     assert!(data[2..4].find("ab").is_none());
70
71     let string = "ประเทศไทย中华Việt Nam";
72     let mut data = String::from(string);
73     data.push_str(string);
74     assert!(data.find("ไท华").is_none());
75     assert_eq!(data[0..43].find(""), Some(0));
76     assert_eq!(data[6..43].find(""), Some(6 - 6));
77
78     assert_eq!(data[0..43].find("ประ"), Some( 0));
79     assert_eq!(data[0..43].find("ทศไ"), Some(12));
80     assert_eq!(data[0..43].find("ย中"), Some(24));
81     assert_eq!(data[0..43].find("iệt"), Some(34));
82     assert_eq!(data[0..43].find("Nam"), Some(40));
83
84     assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
85     assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
86     assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
87     assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
88     assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
89
90     // find every substring -- assert that it finds it, or an earlier occurrence.
91     let string = "Việt Namacbaabcaabaaba";
92     for (i, ci) in string.char_indices() {
93         let ip = i + ci.len_utf8();
94         for j in string[ip..].char_indices()
95                              .map(|(i, _)| i)
96                              .chain(Some(string.len() - ip))
97         {
98             let pat = &string[i..ip + j];
99             assert!(match string.find(pat) {
100                 None => false,
101                 Some(x) => x <= i,
102             });
103             assert!(match string.rfind(pat) {
104                 None => false,
105                 Some(x) => x >= i,
106             });
107         }
108     }
109 }
110
111 fn s(x: &str) -> String { x.to_string() }
112
113 macro_rules! test_concat {
114     ($expected: expr, $string: expr) => {
115         {
116             let s: String = $string.concat();
117             assert_eq!($expected, s);
118         }
119     }
120 }
121
122 #[test]
123 fn test_concat_for_different_types() {
124     test_concat!("ab", vec![s("a"), s("b")]);
125     test_concat!("ab", vec!["a", "b"]);
126 }
127
128 #[test]
129 fn test_concat_for_different_lengths() {
130     let empty: &[&str] = &[];
131     test_concat!("", empty);
132     test_concat!("a", ["a"]);
133     test_concat!("ab", ["a", "b"]);
134     test_concat!("abc", ["", "a", "bc"]);
135 }
136
137 macro_rules! test_join {
138     ($expected: expr, $string: expr, $delim: expr) => {
139         {
140             let s = $string.join($delim);
141             assert_eq!($expected, s);
142         }
143     }
144 }
145
146 #[test]
147 fn test_join_for_different_types() {
148     test_join!("a-b", ["a", "b"], "-");
149     let hyphen = "-".to_string();
150     test_join!("a-b", [s("a"), s("b")], &*hyphen);
151     test_join!("a-b", vec!["a", "b"], &*hyphen);
152     test_join!("a-b", &*vec!["a", "b"], "-");
153     test_join!("a-b", vec![s("a"), s("b")], "-");
154 }
155
156 #[test]
157 fn test_join_for_different_lengths() {
158     let empty: &[&str] = &[];
159     test_join!("", empty, "-");
160     test_join!("a", ["a"], "-");
161     test_join!("a-b", ["a", "b"], "-");
162     test_join!("-a-bc", ["", "a", "bc"], "-");
163 }
164
165 #[test]
166 fn test_unsafe_slice() {
167     assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
168     assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
169     assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
170     fn a_million_letter_a() -> String {
171         let mut i = 0;
172         let mut rs = String::new();
173         while i < 100000 {
174             rs.push_str("aaaaaaaaaa");
175             i += 1;
176         }
177         rs
178     }
179     fn half_a_million_letter_a() -> String {
180         let mut i = 0;
181         let mut rs = String::new();
182         while i < 100000 {
183             rs.push_str("aaaaa");
184             i += 1;
185         }
186         rs
187     }
188     let letters = a_million_letter_a();
189     assert_eq!(half_a_million_letter_a(),
190         unsafe { letters.slice_unchecked(0, 500000)});
191 }
192
193 #[test]
194 fn test_starts_with() {
195     assert!("".starts_with(""));
196     assert!("abc".starts_with(""));
197     assert!("abc".starts_with("a"));
198     assert!(!"a".starts_with("abc"));
199     assert!(!"".starts_with("abc"));
200     assert!(!"ödd".starts_with("-"));
201     assert!("ödd".starts_with("öd"));
202 }
203
204 #[test]
205 fn test_ends_with() {
206     assert!("".ends_with(""));
207     assert!("abc".ends_with(""));
208     assert!("abc".ends_with("c"));
209     assert!(!"a".ends_with("abc"));
210     assert!(!"".ends_with("abc"));
211     assert!(!"ddö".ends_with("-"));
212     assert!("ddö".ends_with("dö"));
213 }
214
215 #[test]
216 fn test_is_empty() {
217     assert!("".is_empty());
218     assert!(!"a".is_empty());
219 }
220
221 #[test]
222 fn test_replacen() {
223     assert_eq!("".replacen('a', "b", 5), "");
224     assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
225     assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
226
227     let test = "test";
228     assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
229     assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
230     assert_eq!(" test test ".replacen(test, "", 5), "   ");
231
232     assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
233 }
234
235 #[test]
236 fn test_replace() {
237     let a = "a";
238     assert_eq!("".replace(a, "b"), "");
239     assert_eq!("a".replace(a, "b"), "b");
240     assert_eq!("ab".replace(a, "b"), "bb");
241     let test = "test";
242     assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
243     assert_eq!(" test test ".replace(test, ""), "   ");
244 }
245
246 #[test]
247 fn test_replace_2a() {
248     let data = "ประเทศไทย中华";
249     let repl = "دولة الكويت";
250
251     let a = "ประเ";
252     let a2 = "دولة الكويتทศไทย中华";
253     assert_eq!(data.replace(a, repl), a2);
254 }
255
256 #[test]
257 fn test_replace_2b() {
258     let data = "ประเทศไทย中华";
259     let repl = "دولة الكويت";
260
261     let b = "ะเ";
262     let b2 = "ปรدولة الكويتทศไทย中华";
263     assert_eq!(data.replace(b, repl), b2);
264 }
265
266 #[test]
267 fn test_replace_2c() {
268     let data = "ประเทศไทย中华";
269     let repl = "دولة الكويت";
270
271     let c = "中华";
272     let c2 = "ประเทศไทยدولة الكويت";
273     assert_eq!(data.replace(c, repl), c2);
274 }
275
276 #[test]
277 fn test_replace_2d() {
278     let data = "ประเทศไทย中华";
279     let repl = "دولة الكويت";
280
281     let d = "ไท华";
282     assert_eq!(data.replace(d, repl), data);
283 }
284
285 #[test]
286 fn test_replace_pattern() {
287     let data = "abcdαβγδabcdαβγδ";
288     assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
289     assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
290     assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
291     assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
292 }
293
294 #[test]
295 fn test_slice() {
296     assert_eq!("ab", &"abc"[0..2]);
297     assert_eq!("bc", &"abc"[1..3]);
298     assert_eq!("", &"abc"[1..1]);
299     assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
300
301     let data = "ประเทศไทย中华";
302     assert_eq!("ป", &data[0..3]);
303     assert_eq!("ร", &data[3..6]);
304     assert_eq!("", &data[3..3]);
305     assert_eq!("华", &data[30..33]);
306
307     fn a_million_letter_x() -> String {
308         let mut i = 0;
309         let mut rs = String::new();
310         while i < 100000 {
311             rs.push_str("华华华华华华华华华华");
312             i += 1;
313         }
314         rs
315     }
316     fn half_a_million_letter_x() -> String {
317         let mut i = 0;
318         let mut rs = String::new();
319         while i < 100000 {
320             rs.push_str("华华华华华");
321             i += 1;
322         }
323         rs
324     }
325     let letters = a_million_letter_x();
326     assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
327 }
328
329 #[test]
330 fn test_slice_2() {
331     let ss = "中华Việt Nam";
332
333     assert_eq!("华", &ss[3..6]);
334     assert_eq!("Việt Nam", &ss[6..16]);
335
336     assert_eq!("ab", &"abc"[0..2]);
337     assert_eq!("bc", &"abc"[1..3]);
338     assert_eq!("", &"abc"[1..1]);
339
340     assert_eq!("中", &ss[0..3]);
341     assert_eq!("华V", &ss[3..7]);
342     assert_eq!("", &ss[3..3]);
343     /*0: 中
344       3: 华
345       6: V
346       7: i
347       8: ệ
348      11: t
349      12:
350      13: N
351      14: a
352      15: m */
353 }
354
355 #[test]
356 #[should_panic]
357 fn test_slice_fail() {
358     &"中华Việt Nam"[0..2];
359 }
360
361
362 #[test]
363 fn test_is_char_boundary() {
364     let s = "ศไทย中华Việt Nam β-release 🐱123";
365     assert!(s.is_char_boundary(0));
366     assert!(s.is_char_boundary(s.len()));
367     assert!(!s.is_char_boundary(s.len() + 1));
368     for (i, ch) in s.char_indices() {
369         // ensure character locations are boundaries and continuation bytes are not
370         assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
371         for j in 1..ch.len_utf8() {
372             assert!(!s.is_char_boundary(i + j),
373                     "{} should not be a char boundary in {:?}", i + j, s);
374         }
375     }
376 }
377 const LOREM_PARAGRAPH: &'static str = "\
378 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
379 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
380 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
381 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
382 tempus vel, gravida nec quam.";
383
384 // check the panic includes the prefix of the sliced string
385 #[test]
386 #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
387 fn test_slice_fail_truncated_1() {
388     &LOREM_PARAGRAPH[..1024];
389 }
390 // check the truncation in the panic message
391 #[test]
392 #[should_panic(expected="luctus, im`[...]")]
393 fn test_slice_fail_truncated_2() {
394     &LOREM_PARAGRAPH[..1024];
395 }
396
397 #[test]
398 #[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
399 fn test_slice_fail_boundary_1() {
400     &"abcαβγ"[4..];
401 }
402
403 #[test]
404 #[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
405 fn test_slice_fail_boundary_2() {
406     &"abcαβγ"[2..6];
407 }
408
409 #[test]
410 fn test_slice_from() {
411     assert_eq!(&"abcd"[0..], "abcd");
412     assert_eq!(&"abcd"[2..], "cd");
413     assert_eq!(&"abcd"[4..], "");
414 }
415 #[test]
416 fn test_slice_to() {
417     assert_eq!(&"abcd"[..0], "");
418     assert_eq!(&"abcd"[..2], "ab");
419     assert_eq!(&"abcd"[..4], "abcd");
420 }
421
422 #[test]
423 fn test_trim_left_matches() {
424     let v: &[char] = &[];
425     assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
426     let chars: &[char] = &['*', ' '];
427     assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
428     assert_eq!(" ***  *** ".trim_left_matches(chars), "");
429     assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
430
431     assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
432     let chars: &[char] = &['1', '2'];
433     assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
434     assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
435 }
436
437 #[test]
438 fn test_trim_right_matches() {
439     let v: &[char] = &[];
440     assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
441     let chars: &[char] = &['*', ' '];
442     assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
443     assert_eq!(" ***  *** ".trim_right_matches(chars), "");
444     assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
445
446     assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
447     let chars: &[char] = &['1', '2'];
448     assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
449     assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
450 }
451
452 #[test]
453 fn test_trim_matches() {
454     let v: &[char] = &[];
455     assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
456     let chars: &[char] = &['*', ' '];
457     assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
458     assert_eq!(" ***  *** ".trim_matches(chars), "");
459     assert_eq!("foo".trim_matches(chars), "foo");
460
461     assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
462     let chars: &[char] = &['1', '2'];
463     assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
464     assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
465 }
466
467 #[test]
468 fn test_trim_left() {
469     assert_eq!("".trim_left(), "");
470     assert_eq!("a".trim_left(), "a");
471     assert_eq!("    ".trim_left(), "");
472     assert_eq!("     blah".trim_left(), "blah");
473     assert_eq!("   \u{3000}  wut".trim_left(), "wut");
474     assert_eq!("hey ".trim_left(), "hey ");
475 }
476
477 #[test]
478 fn test_trim_right() {
479     assert_eq!("".trim_right(), "");
480     assert_eq!("a".trim_right(), "a");
481     assert_eq!("    ".trim_right(), "");
482     assert_eq!("blah     ".trim_right(), "blah");
483     assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
484     assert_eq!(" hey".trim_right(), " hey");
485 }
486
487 #[test]
488 fn test_trim() {
489     assert_eq!("".trim(), "");
490     assert_eq!("a".trim(), "a");
491     assert_eq!("    ".trim(), "");
492     assert_eq!("    blah     ".trim(), "blah");
493     assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
494     assert_eq!(" hey dude ".trim(), "hey dude");
495 }
496
497 #[test]
498 fn test_is_whitespace() {
499     assert!("".chars().all(|c| c.is_whitespace()));
500     assert!(" ".chars().all(|c| c.is_whitespace()));
501     assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
502     assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
503     assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
504 }
505
506 #[test]
507 fn test_is_utf8() {
508     // deny overlong encodings
509     assert!(from_utf8(&[0xc0, 0x80]).is_err());
510     assert!(from_utf8(&[0xc0, 0xae]).is_err());
511     assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
512     assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
513     assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
514     assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
515     assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
516
517     // deny surrogates
518     assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
519     assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
520
521     assert!(from_utf8(&[0xC2, 0x80]).is_ok());
522     assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
523     assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
524     assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
525     assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
526     assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
527     assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
528     assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
529 }
530
531 #[test]
532 fn from_utf8_mostly_ascii() {
533     // deny invalid bytes embedded in long stretches of ascii
534     for i in 32..64 {
535         let mut data = [0; 128];
536         data[i] = 0xC0;
537         assert!(from_utf8(&data).is_err());
538         data[i] = 0xC2;
539         assert!(from_utf8(&data).is_err());
540     }
541 }
542
543 #[test]
544 fn test_is_utf16() {
545     use std_unicode::str::is_utf16;
546
547     macro_rules! pos {
548         ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
549     }
550
551     // non-surrogates
552     pos!(&[0x0000],
553          &[0x0001, 0x0002],
554          &[0xD7FF],
555          &[0xE000]);
556
557     // surrogate pairs (randomly generated with Python 3's
558     // .encode('utf-16be'))
559     pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
560          &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
561          &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
562
563     // mixtures (also random)
564     pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
565          &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
566          &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
567
568     // negative tests
569     macro_rules! neg {
570         ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
571     }
572
573     neg!(
574         // surrogate + regular unit
575         &[0xdb45, 0x0000],
576         // surrogate + lead surrogate
577         &[0xd900, 0xd900],
578         // unterminated surrogate
579         &[0xd8ff],
580         // trail surrogate without a lead
581         &[0xddb7]);
582
583     // random byte sequences that Python 3's .decode('utf-16be')
584     // failed on
585     neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
586          &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
587          &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
588          &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
589          &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
590          &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
591          &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
592          &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
593          &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
594          &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
595          &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
596          &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
597          &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
598          &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
599          &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
600          &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
601          &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
602          &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
603          &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
604          &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
605          &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
606 }
607
608 #[test]
609 fn test_as_bytes() {
610     // no null
611     let v = [
612         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
613         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
614         109
615     ];
616     let b: &[u8] = &[];
617     assert_eq!("".as_bytes(), b);
618     assert_eq!("abc".as_bytes(), b"abc");
619     assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
620 }
621
622 #[test]
623 #[should_panic]
624 fn test_as_bytes_fail() {
625     // Don't double free. (I'm not sure if this exercises the
626     // original problem code path anymore.)
627     let s = String::from("");
628     let _bytes = s.as_bytes();
629     panic!();
630 }
631
632 #[test]
633 fn test_as_ptr() {
634     let buf = "hello".as_ptr();
635     unsafe {
636         assert_eq!(*buf.offset(0), b'h');
637         assert_eq!(*buf.offset(1), b'e');
638         assert_eq!(*buf.offset(2), b'l');
639         assert_eq!(*buf.offset(3), b'l');
640         assert_eq!(*buf.offset(4), b'o');
641     }
642 }
643
644 #[test]
645 fn vec_str_conversions() {
646     let s1: String = String::from("All mimsy were the borogoves");
647
648     let v: Vec<u8> = s1.as_bytes().to_vec();
649     let s2: String = String::from(from_utf8(&v).unwrap());
650     let mut i = 0;
651     let n1 = s1.len();
652     let n2 = v.len();
653     assert_eq!(n1, n2);
654     while i < n1 {
655         let a: u8 = s1.as_bytes()[i];
656         let b: u8 = s2.as_bytes()[i];
657         assert_eq!(a, b);
658         i += 1;
659     }
660 }
661
662 #[test]
663 fn test_contains() {
664     assert!("abcde".contains("bcd"));
665     assert!("abcde".contains("abcd"));
666     assert!("abcde".contains("bcde"));
667     assert!("abcde".contains(""));
668     assert!("".contains(""));
669     assert!(!"abcde".contains("def"));
670     assert!(!"".contains("a"));
671
672     let data = "ประเทศไทย中华Việt Nam";
673     assert!(data.contains("ประเ"));
674     assert!(data.contains("ะเ"));
675     assert!(data.contains("中华"));
676     assert!(!data.contains("ไท华"));
677 }
678
679 #[test]
680 fn test_contains_char() {
681     assert!("abc".contains('b'));
682     assert!("a".contains('a'));
683     assert!(!"abc".contains('d'));
684     assert!(!"".contains('a'));
685 }
686
687 #[test]
688 fn test_split_at() {
689     let s = "ศไทย中华Việt Nam";
690     for (index, _) in s.char_indices() {
691         let (a, b) = s.split_at(index);
692         assert_eq!(&s[..a.len()], a);
693         assert_eq!(&s[a.len()..], b);
694     }
695     let (a, b) = s.split_at(s.len());
696     assert_eq!(a, s);
697     assert_eq!(b, "");
698 }
699
700 #[test]
701 fn test_split_at_mut() {
702     use std::ascii::AsciiExt;
703     let mut s = "Hello World".to_string();
704     {
705         let (a, b) = s.split_at_mut(5);
706         a.make_ascii_uppercase();
707         b.make_ascii_lowercase();
708     }
709     assert_eq!(s, "HELLO world");
710 }
711
712 #[test]
713 #[should_panic]
714 fn test_split_at_boundscheck() {
715     let s = "ศไทย中华Việt Nam";
716     s.split_at(1);
717 }
718
719 #[test]
720 fn test_escape_unicode() {
721     assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
722     assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
723     assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
724     assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
725     assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
726     assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
727     assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
728     assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
729     assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
730 }
731
732 #[test]
733 fn test_escape_debug() {
734     assert_eq!("abc".escape_debug(), "abc");
735     assert_eq!("a c".escape_debug(), "a c");
736     assert_eq!("éèê".escape_debug(), "éèê");
737     assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
738     assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
739     assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
740     assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
741     assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
742     assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
743     assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
744 }
745
746 #[test]
747 fn test_escape_default() {
748     assert_eq!("abc".escape_default(), "abc");
749     assert_eq!("a c".escape_default(), "a c");
750     assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
751     assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
752     assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
753     assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
754     assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
755     assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
756     assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
757     assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
758 }
759
760 #[test]
761 fn test_total_ord() {
762     assert_eq!("1234".cmp("123"), Greater);
763     assert_eq!("123".cmp("1234"), Less);
764     assert_eq!("1234".cmp("1234"), Equal);
765     assert_eq!("12345555".cmp("123456"), Less);
766     assert_eq!("22".cmp("1234"), Greater);
767 }
768
769 #[test]
770 fn test_iterator() {
771     let s = "ศไทย中华Việt Nam";
772     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
773
774     let mut pos = 0;
775     let it = s.chars();
776
777     for c in it {
778         assert_eq!(c, v[pos]);
779         pos += 1;
780     }
781     assert_eq!(pos, v.len());
782     assert_eq!(s.chars().count(), v.len());
783 }
784
785 #[test]
786 fn test_rev_iterator() {
787     let s = "ศไทย中华Việt Nam";
788     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
789
790     let mut pos = 0;
791     let it = s.chars().rev();
792
793     for c in it {
794         assert_eq!(c, v[pos]);
795         pos += 1;
796     }
797     assert_eq!(pos, v.len());
798 }
799
800 #[test]
801 fn test_chars_decoding() {
802     let mut bytes = [0; 4];
803     for c in (0..0x110000).filter_map(::std::char::from_u32) {
804         let s = c.encode_utf8(&mut bytes);
805         if Some(c) != s.chars().next() {
806             panic!("character {:x}={} does not decode correctly", c as u32, c);
807         }
808     }
809 }
810
811 #[test]
812 fn test_chars_rev_decoding() {
813     let mut bytes = [0; 4];
814     for c in (0..0x110000).filter_map(::std::char::from_u32) {
815         let s = c.encode_utf8(&mut bytes);
816         if Some(c) != s.chars().rev().next() {
817             panic!("character {:x}={} does not decode correctly", c as u32, c);
818         }
819     }
820 }
821
822 #[test]
823 fn test_iterator_clone() {
824     let s = "ศไทย中华Việt Nam";
825     let mut it = s.chars();
826     it.next();
827     assert!(it.clone().zip(it).all(|(x,y)| x == y));
828 }
829
830 #[test]
831 fn test_iterator_last() {
832     let s = "ศไทย中华Việt Nam";
833     let mut it = s.chars();
834     it.next();
835     assert_eq!(it.last(), Some('m'));
836 }
837
838 #[test]
839 fn test_bytesator() {
840     let s = "ศไทย中华Việt Nam";
841     let v = [
842         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
843         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
844         109
845     ];
846     let mut pos = 0;
847
848     for b in s.bytes() {
849         assert_eq!(b, v[pos]);
850         pos += 1;
851     }
852 }
853
854 #[test]
855 fn test_bytes_revator() {
856     let s = "ศไทย中华Việt Nam";
857     let v = [
858         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
859         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
860         109
861     ];
862     let mut pos = v.len();
863
864     for b in s.bytes().rev() {
865         pos -= 1;
866         assert_eq!(b, v[pos]);
867     }
868 }
869
870 #[test]
871 fn test_bytesator_nth() {
872     let s = "ศไทย中华Việt Nam";
873     let v = [
874         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
875         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
876         109
877     ];
878
879     let mut b = s.bytes();
880     assert_eq!(b.nth(2).unwrap(), v[2]);
881     assert_eq!(b.nth(10).unwrap(), v[10]);
882     assert_eq!(b.nth(200), None);
883 }
884
885 #[test]
886 fn test_bytesator_count() {
887     let s = "ศไทย中华Việt Nam";
888
889     let b = s.bytes();
890     assert_eq!(b.count(), 28)
891 }
892
893 #[test]
894 fn test_bytesator_last() {
895     let s = "ศไทย中华Việt Nam";
896
897     let b = s.bytes();
898     assert_eq!(b.last().unwrap(), 109)
899 }
900
901 #[test]
902 fn test_char_indicesator() {
903     let s = "ศไทย中华Việt Nam";
904     let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
905     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
906
907     let mut pos = 0;
908     let it = s.char_indices();
909
910     for c in it {
911         assert_eq!(c, (p[pos], v[pos]));
912         pos += 1;
913     }
914     assert_eq!(pos, v.len());
915     assert_eq!(pos, p.len());
916 }
917
918 #[test]
919 fn test_char_indices_revator() {
920     let s = "ศไทย中华Việt Nam";
921     let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
922     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
923
924     let mut pos = 0;
925     let it = s.char_indices().rev();
926
927     for c in it {
928         assert_eq!(c, (p[pos], v[pos]));
929         pos += 1;
930     }
931     assert_eq!(pos, v.len());
932     assert_eq!(pos, p.len());
933 }
934
935 #[test]
936 fn test_char_indices_last() {
937     let s = "ศไทย中华Việt Nam";
938     let mut it = s.char_indices();
939     it.next();
940     assert_eq!(it.last(), Some((27, 'm')));
941 }
942
943 #[test]
944 fn test_splitn_char_iterator() {
945     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
946
947     let split: Vec<&str> = data.splitn(4, ' ').collect();
948     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
949
950     let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
951     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
952
953     // Unicode
954     let split: Vec<&str> = data.splitn(4, 'ä').collect();
955     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
956
957     let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
958     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
959 }
960
961 #[test]
962 fn test_split_char_iterator_no_trailing() {
963     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
964
965     let split: Vec<&str> = data.split('\n').collect();
966     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
967
968     let split: Vec<&str> = data.split_terminator('\n').collect();
969     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
970 }
971
972 #[test]
973 fn test_rsplit() {
974     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
975
976     let split: Vec<&str> = data.rsplit(' ').collect();
977     assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
978
979     let split: Vec<&str> = data.rsplit("lämb").collect();
980     assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
981
982     let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
983     assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
984 }
985
986 #[test]
987 fn test_rsplitn() {
988     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
989
990     let split: Vec<&str> = data.rsplitn(2, ' ').collect();
991     assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
992
993     let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
994     assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
995
996     let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
997     assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
998 }
999
1000 #[test]
1001 fn test_split_whitespace() {
1002     let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
1003     let words: Vec<&str> = data.split_whitespace().collect();
1004     assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
1005 }
1006
1007 #[test]
1008 fn test_lines() {
1009     let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
1010     let lines: Vec<&str> = data.lines().collect();
1011     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1012
1013     let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
1014     let lines: Vec<&str> = data.lines().collect();
1015     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1016 }
1017
1018 #[test]
1019 fn test_splitator() {
1020     fn t(s: &str, sep: &str, u: &[&str]) {
1021         let v: Vec<&str> = s.split(sep).collect();
1022         assert_eq!(v, u);
1023     }
1024     t("--1233345--", "12345", &["--1233345--"]);
1025     t("abc::hello::there", "::", &["abc", "hello", "there"]);
1026     t("::hello::there", "::", &["", "hello", "there"]);
1027     t("hello::there::", "::", &["hello", "there", ""]);
1028     t("::hello::there::", "::", &["", "hello", "there", ""]);
1029     t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
1030     t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
1031     t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
1032     t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
1033     t("", ".", &[""]);
1034     t("zz", "zz", &["",""]);
1035     t("ok", "z", &["ok"]);
1036     t("zzz", "zz", &["","z"]);
1037     t("zzzzz", "zz", &["","","z"]);
1038 }
1039
1040 #[test]
1041 fn test_str_default() {
1042     use std::default::Default;
1043
1044     fn t<S: Default + AsRef<str>>() {
1045         let s: S = Default::default();
1046         assert_eq!(s.as_ref(), "");
1047     }
1048
1049     t::<&str>();
1050     t::<String>();
1051 }
1052
1053 #[test]
1054 fn test_str_container() {
1055     fn sum_len(v: &[&str]) -> usize {
1056         v.iter().map(|x| x.len()).sum()
1057     }
1058
1059     let s = "01234";
1060     assert_eq!(5, sum_len(&["012", "", "34"]));
1061     assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1062     assert_eq!(5, sum_len(&[s]));
1063 }
1064
1065 #[test]
1066 fn test_str_from_utf8() {
1067     let xs = b"hello";
1068     assert_eq!(from_utf8(xs), Ok("hello"));
1069
1070     let xs = "ศไทย中华Việt Nam".as_bytes();
1071     assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1072
1073     let xs = b"hello\xFF";
1074     assert!(from_utf8(xs).is_err());
1075 }
1076
1077 #[test]
1078 fn test_pattern_deref_forward() {
1079     let data = "aabcdaa";
1080     assert!(data.contains("bcd"));
1081     assert!(data.contains(&"bcd"));
1082     assert!(data.contains(&"bcd".to_string()));
1083 }
1084
1085 #[test]
1086 fn test_empty_match_indices() {
1087     let data = "aä中!";
1088     let vec: Vec<_> = data.match_indices("").collect();
1089     assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1090 }
1091
1092 #[test]
1093 fn test_bool_from_str() {
1094     assert_eq!("true".parse().ok(), Some(true));
1095     assert_eq!("false".parse().ok(), Some(false));
1096     assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1097 }
1098
1099 fn check_contains_all_substrings(s: &str) {
1100     assert!(s.contains(""));
1101     for i in 0..s.len() {
1102         for j in i+1..s.len() + 1 {
1103             assert!(s.contains(&s[i..j]));
1104         }
1105     }
1106 }
1107
1108 #[test]
1109 fn strslice_issue_16589() {
1110     assert!("bananas".contains("nana"));
1111
1112     // prior to the fix for #16589, x.contains("abcdabcd") returned false
1113     // test all substrings for good measure
1114     check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1115 }
1116
1117 #[test]
1118 fn strslice_issue_16878() {
1119     assert!(!"1234567ah012345678901ah".contains("hah"));
1120     assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1121 }
1122
1123
1124 #[test]
1125 fn test_strslice_contains() {
1126     let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1127     check_contains_all_substrings(x);
1128 }
1129
1130 #[test]
1131 fn test_rsplitn_char_iterator() {
1132     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1133
1134     let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1135     split.reverse();
1136     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1137
1138     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1139     split.reverse();
1140     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1141
1142     // Unicode
1143     let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1144     split.reverse();
1145     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1146
1147     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1148     split.reverse();
1149     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1150 }
1151
1152 #[test]
1153 fn test_split_char_iterator() {
1154     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1155
1156     let split: Vec<&str> = data.split(' ').collect();
1157     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1158
1159     let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1160     rsplit.reverse();
1161     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1162
1163     let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1164     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1165
1166     let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1167     rsplit.reverse();
1168     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1169
1170     // Unicode
1171     let split: Vec<&str> = data.split('ä').collect();
1172     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1173
1174     let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1175     rsplit.reverse();
1176     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1177
1178     let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1179     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1180
1181     let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1182     rsplit.reverse();
1183     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1184 }
1185
1186 #[test]
1187 fn test_rev_split_char_iterator_no_trailing() {
1188     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1189
1190     let mut split: Vec<&str> = data.split('\n').rev().collect();
1191     split.reverse();
1192     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1193
1194     let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1195     split.reverse();
1196     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1197 }
1198
1199 #[test]
1200 fn test_utf16_code_units() {
1201     use std_unicode::str::Utf16Encoder;
1202     assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1203                [0xE9, 0xD83D, 0xDCA9])
1204 }
1205
1206 #[test]
1207 fn starts_with_in_unicode() {
1208     assert!(!"├── Cargo.toml".starts_with("# "));
1209 }
1210
1211 #[test]
1212 fn starts_short_long() {
1213     assert!(!"".starts_with("##"));
1214     assert!(!"##".starts_with("####"));
1215     assert!("####".starts_with("##"));
1216     assert!(!"##ä".starts_with("####"));
1217     assert!("####ä".starts_with("##"));
1218     assert!(!"##".starts_with("####ä"));
1219     assert!("##ä##".starts_with("##ä"));
1220
1221     assert!("".starts_with(""));
1222     assert!("ä".starts_with(""));
1223     assert!("#ä".starts_with(""));
1224     assert!("##ä".starts_with(""));
1225     assert!("ä###".starts_with(""));
1226     assert!("#ä##".starts_with(""));
1227     assert!("##ä#".starts_with(""));
1228 }
1229
1230 #[test]
1231 fn contains_weird_cases() {
1232     assert!("* \t".contains(' '));
1233     assert!(!"* \t".contains('?'));
1234     assert!(!"* \t".contains('\u{1F4A9}'));
1235 }
1236
1237 #[test]
1238 fn trim_ws() {
1239     assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
1240                     "a \t  ");
1241     assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
1242                " \t  a");
1243     assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
1244                     "a");
1245     assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
1246                          "");
1247     assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
1248                "");
1249     assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
1250                "");
1251 }
1252
1253 #[test]
1254 fn to_lowercase() {
1255     assert_eq!("".to_lowercase(), "");
1256     assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1257
1258     // https://github.com/rust-lang/rust/issues/26035
1259     assert_eq!("ΑΣ".to_lowercase(), "ας");
1260     assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1261     assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1262
1263     assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1264     assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1265     assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1266
1267     assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1268     assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1269
1270     assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1271     assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1272
1273     assert_eq!("Α Σ".to_lowercase(), "α σ");
1274     assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1275     assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1276
1277     assert_eq!("Σ".to_lowercase(), "σ");
1278     assert_eq!("'Σ".to_lowercase(), "'σ");
1279     assert_eq!("''Σ".to_lowercase(), "''σ");
1280
1281     assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1282     assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1283     assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1284 }
1285
1286 #[test]
1287 fn to_uppercase() {
1288     assert_eq!("".to_uppercase(), "");
1289     assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1290 }
1291
1292 #[test]
1293 fn test_into_string() {
1294     // The only way to acquire a Box<str> in the first place is through a String, so just
1295     // test that we can round-trip between Box<str> and String.
1296     let string = String::from("Some text goes here");
1297     assert_eq!(string.clone().into_boxed_str().into_string(), string);
1298 }
1299
1300 #[test]
1301 fn test_box_slice_clone() {
1302     let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1303     let data2 = data.clone().into_boxed_str().clone().into_string();
1304
1305     assert_eq!(data, data2);
1306 }
1307
1308 #[test]
1309 fn test_cow_from() {
1310     let borrowed = "borrowed";
1311     let owned = String::from("owned");
1312     match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1313         (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1314         _ => panic!("invalid `Cow::from`"),
1315     }
1316 }
1317
1318 #[test]
1319 fn test_repeat() {
1320     assert_eq!("".repeat(3), "");
1321     assert_eq!("abc".repeat(0), "");
1322     assert_eq!("α".repeat(3), "ααα");
1323 }
1324
1325 mod pattern {
1326     use std::str::pattern::Pattern;
1327     use std::str::pattern::{Searcher, ReverseSearcher};
1328     use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1329
1330     macro_rules! make_test {
1331         ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1332             #[allow(unused_imports)]
1333             mod $name {
1334                 use std::str::pattern::SearchStep::{Match, Reject};
1335                 use super::{cmp_search_to_vec};
1336                 #[test]
1337                 fn fwd() {
1338                     cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1339                 }
1340                 #[test]
1341                 fn bwd() {
1342                     cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1343                 }
1344             }
1345         }
1346     }
1347
1348     fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1349                                              right: Vec<SearchStep>)
1350     where P::Searcher: ReverseSearcher<'a>
1351     {
1352         let mut searcher = pat.into_searcher(haystack);
1353         let mut v = vec![];
1354         loop {
1355             match if !rev {searcher.next()} else {searcher.next_back()} {
1356                 Match(a, b) => v.push(Match(a, b)),
1357                 Reject(a, b) => v.push(Reject(a, b)),
1358                 Done => break,
1359             }
1360         }
1361         if rev {
1362             v.reverse();
1363         }
1364
1365         let mut first_index = 0;
1366         let mut err = None;
1367
1368         for (i, e) in right.iter().enumerate() {
1369             match *e {
1370                 Match(a, b) | Reject(a, b)
1371                 if a <= b && a == first_index => {
1372                     first_index = b;
1373                 }
1374                 _ => {
1375                     err = Some(i);
1376                     break;
1377                 }
1378             }
1379         }
1380
1381         if let Some(err) = err {
1382             panic!("Input skipped range at {}", err);
1383         }
1384
1385         if first_index != haystack.len() {
1386             panic!("Did not cover whole input");
1387         }
1388
1389         assert_eq!(v, right);
1390     }
1391
1392     make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1393         Reject(0, 1),
1394         Match (1, 3),
1395         Reject(3, 4),
1396         Match (4, 6),
1397         Reject(6, 7),
1398     ]);
1399     make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1400         Reject(0, 1),
1401         Match (1, 3),
1402         Reject(3, 4),
1403         Match (4, 6),
1404         Match (6, 8),
1405         Reject(8, 9),
1406     ]);
1407     make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1408         Match (0, 0),
1409         Reject(0, 1),
1410         Match (1, 1),
1411         Reject(1, 2),
1412         Match (2, 2),
1413         Reject(2, 3),
1414         Match (3, 3),
1415         Reject(3, 4),
1416         Match (4, 4),
1417         Reject(4, 5),
1418         Match (5, 5),
1419         Reject(5, 6),
1420         Match (6, 6),
1421         Reject(6, 7),
1422         Match (7, 7),
1423     ]);
1424     make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1425         Reject(0, 3),
1426         Reject(3, 6),
1427         Reject(6, 9),
1428     ]);
1429     make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1430         Match (0, 0),
1431         Reject(0, 3),
1432         Match (3, 3),
1433         Reject(3, 6),
1434         Match (6, 6),
1435         Reject(6, 9),
1436         Match (9, 9),
1437     ]);
1438     make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1439         Match(0, 0),
1440     ]);
1441     make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1442     ]);
1443     make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1444         Reject(0, 1),
1445         Match (1, 2),
1446         Match (2, 3),
1447         Reject(3, 4),
1448         Match (4, 5),
1449         Match (5, 6),
1450         Reject(6, 7),
1451     ]);
1452     make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1453         Reject(0, 3),
1454         Reject(3, 6),
1455         Reject(6, 9),
1456     ]);
1457     make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1458         Reject(0, 1),
1459         Reject(1, 2),
1460         Reject(2, 3),
1461     ]);
1462
1463 }
1464
1465 macro_rules! generate_iterator_test {
1466     {
1467         $name:ident {
1468             $(
1469                 ($($arg:expr),*) -> [$($t:tt)*];
1470             )*
1471         }
1472         with $fwd:expr, $bwd:expr;
1473     } => {
1474         #[test]
1475         fn $name() {
1476             $(
1477                 {
1478                     let res = vec![$($t)*];
1479
1480                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1481                     assert_eq!(fwd_vec, res);
1482
1483                     let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1484                     bwd_vec.reverse();
1485                     assert_eq!(bwd_vec, res);
1486                 }
1487             )*
1488         }
1489     };
1490     {
1491         $name:ident {
1492             $(
1493                 ($($arg:expr),*) -> [$($t:tt)*];
1494             )*
1495         }
1496         with $fwd:expr;
1497     } => {
1498         #[test]
1499         fn $name() {
1500             $(
1501                 {
1502                     let res = vec![$($t)*];
1503
1504                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1505                     assert_eq!(fwd_vec, res);
1506                 }
1507             )*
1508         }
1509     }
1510 }
1511
1512 generate_iterator_test! {
1513     double_ended_split {
1514         ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1515         ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1516     }
1517     with str::split, str::rsplit;
1518 }
1519
1520 generate_iterator_test! {
1521     double_ended_split_terminator {
1522         ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1523     }
1524     with str::split_terminator, str::rsplit_terminator;
1525 }
1526
1527 generate_iterator_test! {
1528     double_ended_matches {
1529         ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1530     }
1531     with str::matches, str::rmatches;
1532 }
1533
1534 generate_iterator_test! {
1535     double_ended_match_indices {
1536         ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1537     }
1538     with str::match_indices, str::rmatch_indices;
1539 }
1540
1541 generate_iterator_test! {
1542     not_double_ended_splitn {
1543         ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1544     }
1545     with str::splitn;
1546 }
1547
1548 generate_iterator_test! {
1549     not_double_ended_rsplitn {
1550         ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1551     }
1552     with str::rsplitn;
1553 }
1554
1555 #[test]
1556 fn different_str_pattern_forwarding_lifetimes() {
1557     use std::str::pattern::Pattern;
1558
1559     fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
1560         for _ in 0..3 {
1561             "asdf".find(&p);
1562         }
1563     }
1564
1565     foo::<&str>("x");
1566 }