]> git.lizzy.rs Git - rust.git/blob - src/liballoc/tests/str.rs
Fix rebase fail
[rust.git] / src / liballoc / tests / str.rs
1 use std::borrow::Cow;
2 use std::cmp::Ordering::{Equal, Greater, Less};
3 use std::str::from_utf8;
4
5 #[test]
6 fn test_le() {
7     assert!("" <= "");
8     assert!("" <= "foo");
9     assert!("foo" <= "foo");
10     assert!("foo" != "bar");
11 }
12
13 #[test]
14 fn test_find() {
15     assert_eq!("hello".find('l'), Some(2));
16     assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
17     assert!("hello".find('x').is_none());
18     assert!("hello".find(|c:char| c == 'x').is_none());
19     assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
20     assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
21 }
22
23 #[test]
24 fn test_rfind() {
25     assert_eq!("hello".rfind('l'), Some(3));
26     assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
27     assert!("hello".rfind('x').is_none());
28     assert!("hello".rfind(|c:char| c == 'x').is_none());
29     assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
30     assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
31 }
32
33 #[test]
34 #[cfg(not(miri))]
35 fn test_collect() {
36     let empty = "";
37     let s: String = empty.chars().collect();
38     assert_eq!(empty, s);
39     let data = "ประเทศไทย中";
40     let s: String = data.chars().collect();
41     assert_eq!(data, s);
42 }
43
44 #[test]
45 fn test_into_bytes() {
46     let data = String::from("asdf");
47     let buf = data.into_bytes();
48     assert_eq!(buf, b"asdf");
49 }
50
51 #[test]
52 fn test_find_str() {
53     // byte positions
54     assert_eq!("".find(""), Some(0));
55     assert!("banana".find("apple pie").is_none());
56
57     let data = "abcabc";
58     assert_eq!(data[0..6].find("ab"), Some(0));
59     assert_eq!(data[2..6].find("ab"), Some(3 - 2));
60     assert!(data[2..4].find("ab").is_none());
61
62     let string = "ประเทศไทย中华Việt Nam";
63     let mut data = String::from(string);
64     data.push_str(string);
65     assert!(data.find("ไท华").is_none());
66     assert_eq!(data[0..43].find(""), Some(0));
67     assert_eq!(data[6..43].find(""), Some(6 - 6));
68
69     assert_eq!(data[0..43].find("ประ"), Some( 0));
70     assert_eq!(data[0..43].find("ทศไ"), Some(12));
71     assert_eq!(data[0..43].find("ย中"), Some(24));
72     assert_eq!(data[0..43].find("iệt"), Some(34));
73     assert_eq!(data[0..43].find("Nam"), Some(40));
74
75     assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
76     assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
77     assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
78     assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
79     assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
80
81     // find every substring -- assert that it finds it, or an earlier occurrence.
82     let string = "Việt Namacbaabcaabaaba";
83     for (i, ci) in string.char_indices() {
84         let ip = i + ci.len_utf8();
85         for j in string[ip..].char_indices()
86                              .map(|(i, _)| i)
87                              .chain(Some(string.len() - ip))
88         {
89             let pat = &string[i..ip + j];
90             assert!(match string.find(pat) {
91                 None => false,
92                 Some(x) => x <= i,
93             });
94             assert!(match string.rfind(pat) {
95                 None => false,
96                 Some(x) => x >= i,
97             });
98         }
99     }
100 }
101
102 fn s(x: &str) -> String { x.to_string() }
103
104 macro_rules! test_concat {
105     ($expected: expr, $string: expr) => {
106         {
107             let s: String = $string.concat();
108             assert_eq!($expected, s);
109         }
110     }
111 }
112
113 #[test]
114 fn test_concat_for_different_types() {
115     test_concat!("ab", vec![s("a"), s("b")]);
116     test_concat!("ab", vec!["a", "b"]);
117 }
118
119 #[test]
120 fn test_concat_for_different_lengths() {
121     let empty: &[&str] = &[];
122     #[cfg(not(miri))]
123     test_concat!("", empty);
124     test_concat!("a", ["a"]);
125     test_concat!("ab", ["a", "b"]);
126     test_concat!("abc", ["", "a", "bc"]);
127 }
128
129 macro_rules! test_join {
130     ($expected: expr, $string: expr, $delim: expr) => {
131         {
132             let s = $string.join($delim);
133             assert_eq!($expected, s);
134         }
135     }
136 }
137
138 #[test]
139 fn test_join_for_different_types() {
140     test_join!("a-b", ["a", "b"], "-");
141     let hyphen = "-".to_string();
142     test_join!("a-b", [s("a"), s("b")], &*hyphen);
143     test_join!("a-b", vec!["a", "b"], &*hyphen);
144     test_join!("a-b", &*vec!["a", "b"], "-");
145     test_join!("a-b", vec![s("a"), s("b")], "-");
146 }
147
148 #[test]
149 fn test_join_for_different_lengths() {
150     let empty: &[&str] = &[];
151     #[cfg(not(miri))]
152     test_join!("", empty, "-");
153     test_join!("a", ["a"], "-");
154     test_join!("a-b", ["a", "b"], "-");
155     test_join!("-a-bc", ["", "a", "bc"], "-");
156 }
157
158 // join has fast paths for small separators up to 4 bytes
159 // this tests the slow paths.
160 #[test]
161 fn test_join_for_different_lengths_with_long_separator() {
162     assert_eq!("~~~~~".len(), 15);
163
164     let empty: &[&str] = &[];
165     #[cfg(not(miri))]
166     test_join!("", empty, "~~~~~");
167     test_join!("a", ["a"], "~~~~~");
168     test_join!("a~~~~~b", ["a", "b"], "~~~~~");
169     test_join!("~~~~~a~~~~~bc", ["", "a", "bc"], "~~~~~");
170 }
171
172 #[test]
173 #[cfg(not(miri))]
174 fn test_unsafe_slice() {
175     assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)});
176     assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)});
177     assert_eq!("", unsafe {"abc".get_unchecked(1..1)});
178     fn a_million_letter_a() -> String {
179         let mut i = 0;
180         let mut rs = String::new();
181         while i < 100000 {
182             rs.push_str("aaaaaaaaaa");
183             i += 1;
184         }
185         rs
186     }
187     fn half_a_million_letter_a() -> String {
188         let mut i = 0;
189         let mut rs = String::new();
190         while i < 100000 {
191             rs.push_str("aaaaa");
192             i += 1;
193         }
194         rs
195     }
196     let letters = a_million_letter_a();
197     assert_eq!(half_a_million_letter_a(),
198         unsafe { letters.get_unchecked(0..500000)});
199 }
200
201 #[test]
202 fn test_starts_with() {
203     assert!("".starts_with(""));
204     assert!("abc".starts_with(""));
205     assert!("abc".starts_with("a"));
206     assert!(!"a".starts_with("abc"));
207     assert!(!"".starts_with("abc"));
208     assert!(!"ödd".starts_with("-"));
209     assert!("ödd".starts_with("öd"));
210 }
211
212 #[test]
213 fn test_ends_with() {
214     assert!("".ends_with(""));
215     assert!("abc".ends_with(""));
216     assert!("abc".ends_with("c"));
217     assert!(!"a".ends_with("abc"));
218     assert!(!"".ends_with("abc"));
219     assert!(!"ddö".ends_with("-"));
220     assert!("ddö".ends_with("dö"));
221 }
222
223 #[test]
224 fn test_is_empty() {
225     assert!("".is_empty());
226     assert!(!"a".is_empty());
227 }
228
229 #[test]
230 fn test_replacen() {
231     assert_eq!("".replacen('a', "b", 5), "");
232     assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
233     assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
234
235     let test = "test";
236     assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
237     assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
238     assert_eq!(" test test ".replacen(test, "", 5), "   ");
239
240     assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
241 }
242
243 #[test]
244 fn test_replace() {
245     let a = "a";
246     #[cfg(not(miri))]
247     assert_eq!("".replace(a, "b"), "");
248     assert_eq!("a".replace(a, "b"), "b");
249     assert_eq!("ab".replace(a, "b"), "bb");
250     let test = "test";
251     assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
252     assert_eq!(" test test ".replace(test, ""), "   ");
253 }
254
255 #[test]
256 fn test_replace_2a() {
257     let data = "ประเทศไทย中华";
258     let repl = "دولة الكويت";
259
260     let a = "ประเ";
261     let a2 = "دولة الكويتทศไทย中华";
262     assert_eq!(data.replace(a, repl), a2);
263 }
264
265 #[test]
266 fn test_replace_2b() {
267     let data = "ประเทศไทย中华";
268     let repl = "دولة الكويت";
269
270     let b = "ะเ";
271     let b2 = "ปรدولة الكويتทศไทย中华";
272     assert_eq!(data.replace(b, repl), b2);
273 }
274
275 #[test]
276 fn test_replace_2c() {
277     let data = "ประเทศไทย中华";
278     let repl = "دولة الكويت";
279
280     let c = "中华";
281     let c2 = "ประเทศไทยدولة الكويت";
282     assert_eq!(data.replace(c, repl), c2);
283 }
284
285 #[test]
286 fn test_replace_2d() {
287     let data = "ประเทศไทย中华";
288     let repl = "دولة الكويت";
289
290     let d = "ไท华";
291     assert_eq!(data.replace(d, repl), data);
292 }
293
294 #[test]
295 fn test_replace_pattern() {
296     let data = "abcdαβγδabcdαβγδ";
297     assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
298     assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
299     assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
300     assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
301 }
302
303 // The current implementation of SliceIndex fails to handle methods
304 // orthogonally from range types; therefore, it is worth testing
305 // all of the indexing operations on each input.
306 #[cfg(not(miri))]
307 mod slice_index {
308     // Test a slicing operation **that should succeed,**
309     // testing it on all of the indexing methods.
310     //
311     // This is not suitable for testing failure on invalid inputs.
312     macro_rules! assert_range_eq {
313         ($s:expr, $range:expr, $expected:expr)
314         => {
315             let mut s: String = $s.to_owned();
316             let mut expected: String = $expected.to_owned();
317             {
318                 let s: &str = &s;
319                 let expected: &str = &expected;
320
321                 assert_eq!(&s[$range], expected, "(in assertion for: index)");
322                 assert_eq!(s.get($range), Some(expected), "(in assertion for: get)");
323                 unsafe {
324                     assert_eq!(
325                         s.get_unchecked($range), expected,
326                         "(in assertion for: get_unchecked)",
327                     );
328                 }
329             }
330             {
331                 let s: &mut str = &mut s;
332                 let expected: &mut str = &mut expected;
333
334                 assert_eq!(
335                     &mut s[$range], expected,
336                     "(in assertion for: index_mut)",
337                 );
338                 assert_eq!(
339                     s.get_mut($range), Some(&mut expected[..]),
340                     "(in assertion for: get_mut)",
341                 );
342                 unsafe {
343                     assert_eq!(
344                         s.get_unchecked_mut($range), expected,
345                         "(in assertion for: get_unchecked_mut)",
346                     );
347                 }
348             }
349         }
350     }
351
352     // Make sure the macro can actually detect bugs,
353     // because if it can't, then what are we even doing here?
354     //
355     // (Be aware this only demonstrates the ability to detect bugs
356     //  in the FIRST method that panics, as the macro is not designed
357     //  to be used in `should_panic`)
358     #[test]
359     #[should_panic(expected = "out of bounds")]
360     fn assert_range_eq_can_fail_by_panic() {
361         assert_range_eq!("abc", 0..5, "abc");
362     }
363
364     // (Be aware this only demonstrates the ability to detect bugs
365     //  in the FIRST method it calls, as the macro is not designed
366     //  to be used in `should_panic`)
367     #[test]
368     #[should_panic(expected = "==")]
369     fn assert_range_eq_can_fail_by_inequality() {
370         assert_range_eq!("abc", 0..2, "abc");
371     }
372
373     // Generates test cases for bad index operations.
374     //
375     // This generates `should_panic` test cases for Index/IndexMut
376     // and `None` test cases for get/get_mut.
377     macro_rules! panic_cases {
378         ($(
379             in mod $case_name:ident {
380                 data: $data:expr;
381
382                 // optional:
383                 //
384                 // a similar input for which DATA[input] succeeds, and the corresponding
385                 // output str. This helps validate "critical points" where an input range
386                 // straddles the boundary between valid and invalid.
387                 // (such as the input `len..len`, which is just barely valid)
388                 $(
389                     good: data[$good:expr] == $output:expr;
390                 )*
391
392                 bad: data[$bad:expr];
393                 message: $expect_msg:expr; // must be a literal
394             }
395         )*) => {$(
396             mod $case_name {
397                 #[test]
398                 fn pass() {
399                     let mut v: String = $data.into();
400
401                     $( assert_range_eq!(v, $good, $output); )*
402
403                     {
404                         let v: &str = &v;
405                         assert_eq!(v.get($bad), None, "(in None assertion for get)");
406                     }
407
408                     {
409                         let v: &mut str = &mut v;
410                         assert_eq!(v.get_mut($bad), None, "(in None assertion for get_mut)");
411                     }
412                 }
413
414                 #[test]
415                 #[should_panic(expected = $expect_msg)]
416                 fn index_fail() {
417                     let v: String = $data.into();
418                     let v: &str = &v;
419                     let _v = &v[$bad];
420                 }
421
422                 #[test]
423                 #[should_panic(expected = $expect_msg)]
424                 fn index_mut_fail() {
425                     let mut v: String = $data.into();
426                     let v: &mut str = &mut v;
427                     let _v = &mut v[$bad];
428                 }
429             }
430         )*};
431     }
432
433     #[test]
434     fn simple_ascii() {
435         assert_range_eq!("abc", .., "abc");
436
437         assert_range_eq!("abc", 0..2, "ab");
438         assert_range_eq!("abc", 0..=1, "ab");
439         assert_range_eq!("abc", ..2, "ab");
440         assert_range_eq!("abc", ..=1, "ab");
441
442         assert_range_eq!("abc", 1..3, "bc");
443         assert_range_eq!("abc", 1..=2, "bc");
444         assert_range_eq!("abc", 1..1, "");
445         assert_range_eq!("abc", 1..=0, "");
446     }
447
448     #[test]
449     fn simple_unicode() {
450         // 日本
451         assert_range_eq!("\u{65e5}\u{672c}", .., "\u{65e5}\u{672c}");
452
453         assert_range_eq!("\u{65e5}\u{672c}", 0..3, "\u{65e5}");
454         assert_range_eq!("\u{65e5}\u{672c}", 0..=2, "\u{65e5}");
455         assert_range_eq!("\u{65e5}\u{672c}", ..3, "\u{65e5}");
456         assert_range_eq!("\u{65e5}\u{672c}", ..=2, "\u{65e5}");
457
458         assert_range_eq!("\u{65e5}\u{672c}", 3..6, "\u{672c}");
459         assert_range_eq!("\u{65e5}\u{672c}", 3..=5, "\u{672c}");
460         assert_range_eq!("\u{65e5}\u{672c}", 3.., "\u{672c}");
461
462         let data = "ประเทศไทย中华";
463         assert_range_eq!(data, 0..3, "ป");
464         assert_range_eq!(data, 3..6, "ร");
465         assert_range_eq!(data, 3..3, "");
466         assert_range_eq!(data, 30..33, "华");
467
468         /*0: 中
469           3: 华
470           6: V
471           7: i
472           8: ệ
473          11: t
474          12:
475          13: N
476          14: a
477          15: m */
478         let ss = "中华Việt Nam";
479         assert_range_eq!(ss, 3..6, "华");
480         assert_range_eq!(ss, 6..16, "Việt Nam");
481         assert_range_eq!(ss, 6..=15, "Việt Nam");
482         assert_range_eq!(ss, 6.., "Việt Nam");
483
484         assert_range_eq!(ss, 0..3, "中");
485         assert_range_eq!(ss, 3..7, "华V");
486         assert_range_eq!(ss, 3..=6, "华V");
487         assert_range_eq!(ss, 3..3, "");
488         assert_range_eq!(ss, 3..=2, "");
489     }
490
491     #[test]
492     #[cfg(not(target_arch = "asmjs"))] // hits an OOM
493     fn simple_big() {
494         fn a_million_letter_x() -> String {
495             let mut i = 0;
496             let mut rs = String::new();
497             while i < 100000 {
498                 rs.push_str("华华华华华华华华华华");
499                 i += 1;
500             }
501             rs
502         }
503         fn half_a_million_letter_x() -> String {
504             let mut i = 0;
505             let mut rs = String::new();
506             while i < 100000 {
507                 rs.push_str("华华华华华");
508                 i += 1;
509             }
510             rs
511         }
512         let letters = a_million_letter_x();
513         assert_range_eq!(letters, 0..3 * 500000, half_a_million_letter_x());
514     }
515
516     #[test]
517     #[should_panic]
518     fn test_slice_fail() {
519         &"中华Việt Nam"[0..2];
520     }
521
522     panic_cases! {
523         in mod rangefrom_len {
524             data: "abcdef";
525             good: data[6..] == "";
526             bad: data[7..];
527             message: "out of bounds";
528         }
529
530         in mod rangeto_len {
531             data: "abcdef";
532             good: data[..6] == "abcdef";
533             bad: data[..7];
534             message: "out of bounds";
535         }
536
537         in mod rangetoinclusive_len {
538             data: "abcdef";
539             good: data[..=5] == "abcdef";
540             bad: data[..=6];
541             message: "out of bounds";
542         }
543
544         in mod range_len_len {
545             data: "abcdef";
546             good: data[6..6] == "";
547             bad: data[7..7];
548             message: "out of bounds";
549         }
550
551         in mod rangeinclusive_len_len {
552             data: "abcdef";
553             good: data[6..=5] == "";
554             bad: data[7..=6];
555             message: "out of bounds";
556         }
557     }
558
559     panic_cases! {
560         in mod range_neg_width {
561             data: "abcdef";
562             good: data[4..4] == "";
563             bad: data[4..3];
564             message: "begin <= end (4 <= 3)";
565         }
566
567         in mod rangeinclusive_neg_width {
568             data: "abcdef";
569             good: data[4..=3] == "";
570             bad: data[4..=2];
571             message: "begin <= end (4 <= 3)";
572         }
573     }
574
575     mod overflow {
576         panic_cases! {
577             in mod rangeinclusive {
578                 data: "hello";
579                 // note: using 0 specifically ensures that the result of overflowing is 0..0,
580                 //       so that `get` doesn't simply return None for the wrong reason.
581                 bad: data[0..=usize::max_value()];
582                 message: "maximum usize";
583             }
584
585             in mod rangetoinclusive {
586                 data: "hello";
587                 bad: data[..=usize::max_value()];
588                 message: "maximum usize";
589             }
590         }
591     }
592
593     mod boundary {
594         const DATA: &str = "abcαβγ";
595
596         const BAD_START: usize = 4;
597         const GOOD_START: usize = 3;
598         const BAD_END: usize = 6;
599         const GOOD_END: usize = 7;
600         const BAD_END_INCL: usize = BAD_END - 1;
601         const GOOD_END_INCL: usize = GOOD_END - 1;
602
603         // it is especially important to test all of the different range types here
604         // because some of the logic may be duplicated as part of micro-optimizations
605         // to dodge unicode boundary checks on half-ranges.
606         panic_cases! {
607             in mod range_1 {
608                 data: super::DATA;
609                 bad: data[super::BAD_START..super::GOOD_END];
610                 message:
611                     "byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
612             }
613
614             in mod range_2 {
615                 data: super::DATA;
616                 bad: data[super::GOOD_START..super::BAD_END];
617                 message:
618                     "byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
619             }
620
621             in mod rangefrom {
622                 data: super::DATA;
623                 bad: data[super::BAD_START..];
624                 message:
625                     "byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
626             }
627
628             in mod rangeto {
629                 data: super::DATA;
630                 bad: data[..super::BAD_END];
631                 message:
632                     "byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
633             }
634
635             in mod rangeinclusive_1 {
636                 data: super::DATA;
637                 bad: data[super::BAD_START..=super::GOOD_END_INCL];
638                 message:
639                     "byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
640             }
641
642             in mod rangeinclusive_2 {
643                 data: super::DATA;
644                 bad: data[super::GOOD_START..=super::BAD_END_INCL];
645                 message:
646                     "byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
647             }
648
649             in mod rangetoinclusive {
650                 data: super::DATA;
651                 bad: data[..=super::BAD_END_INCL];
652                 message:
653                     "byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
654             }
655         }
656     }
657
658     const LOREM_PARAGRAPH: &str = "\
659     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem \
660     sit amet dolor ultricies condimentum. Praesent iaculis purus elit, ac malesuada \
661     quam malesuada in. Duis sed orci eros. Suspendisse sit amet magna mollis, mollis \
662     nunc luctus, imperdiet mi. Integer fringilla non sem ut lacinia. Fusce varius \
663     tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec tempus vel, \
664     gravida nec quam.";
665
666     // check the panic includes the prefix of the sliced string
667     #[test]
668     #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
669     fn test_slice_fail_truncated_1() {
670         &LOREM_PARAGRAPH[..1024];
671     }
672     // check the truncation in the panic message
673     #[test]
674     #[should_panic(expected="luctus, im`[...]")]
675     fn test_slice_fail_truncated_2() {
676         &LOREM_PARAGRAPH[..1024];
677     }
678 }
679
680 #[test]
681 fn test_str_slice_rangetoinclusive_ok() {
682     let s = "abcαβγ";
683     assert_eq!(&s[..=2], "abc");
684     assert_eq!(&s[..=4], "abcα");
685 }
686
687 #[test]
688 #[should_panic]
689 #[cfg(not(miri))]
690 fn test_str_slice_rangetoinclusive_notok() {
691     let s = "abcαβγ";
692     &s[..=3];
693 }
694
695 #[test]
696 fn test_str_slicemut_rangetoinclusive_ok() {
697     let mut s = "abcαβγ".to_owned();
698     let s: &mut str = &mut s;
699     assert_eq!(&mut s[..=2], "abc");
700     assert_eq!(&mut s[..=4], "abcα");
701 }
702
703 #[test]
704 #[should_panic]
705 #[cfg(not(miri))]
706 fn test_str_slicemut_rangetoinclusive_notok() {
707     let mut s = "abcαβγ".to_owned();
708     let s: &mut str = &mut s;
709     &mut s[..=3];
710 }
711
712 #[test]
713 fn test_is_char_boundary() {
714     let s = "ศไทย中华Việt Nam β-release 🐱123";
715     assert!(s.is_char_boundary(0));
716     assert!(s.is_char_boundary(s.len()));
717     assert!(!s.is_char_boundary(s.len() + 1));
718     for (i, ch) in s.char_indices() {
719         // ensure character locations are boundaries and continuation bytes are not
720         assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
721         for j in 1..ch.len_utf8() {
722             assert!(!s.is_char_boundary(i + j),
723                     "{} should not be a char boundary in {:?}", i + j, s);
724         }
725     }
726 }
727
728 #[test]
729 fn test_trim_start_matches() {
730     let v: &[char] = &[];
731     assert_eq!(" *** foo *** ".trim_start_matches(v), " *** foo *** ");
732     let chars: &[char] = &['*', ' '];
733     assert_eq!(" *** foo *** ".trim_start_matches(chars), "foo *** ");
734     assert_eq!(" ***  *** ".trim_start_matches(chars), "");
735     assert_eq!("foo *** ".trim_start_matches(chars), "foo *** ");
736
737     assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11");
738     let chars: &[char] = &['1', '2'];
739     assert_eq!("12foo1bar12".trim_start_matches(chars), "foo1bar12");
740     assert_eq!("123foo1bar123".trim_start_matches(|c: char| c.is_numeric()), "foo1bar123");
741 }
742
743 #[test]
744 fn test_trim_end_matches() {
745     let v: &[char] = &[];
746     assert_eq!(" *** foo *** ".trim_end_matches(v), " *** foo *** ");
747     let chars: &[char] = &['*', ' '];
748     assert_eq!(" *** foo *** ".trim_end_matches(chars), " *** foo");
749     assert_eq!(" ***  *** ".trim_end_matches(chars), "");
750     assert_eq!(" *** foo".trim_end_matches(chars), " *** foo");
751
752     assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar");
753     let chars: &[char] = &['1', '2'];
754     assert_eq!("12foo1bar12".trim_end_matches(chars), "12foo1bar");
755     assert_eq!("123foo1bar123".trim_end_matches(|c: char| c.is_numeric()), "123foo1bar");
756 }
757
758 #[test]
759 fn test_trim_matches() {
760     let v: &[char] = &[];
761     assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
762     let chars: &[char] = &['*', ' '];
763     assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
764     assert_eq!(" ***  *** ".trim_matches(chars), "");
765     assert_eq!("foo".trim_matches(chars), "foo");
766
767     assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
768     let chars: &[char] = &['1', '2'];
769     assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
770     assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
771 }
772
773 #[test]
774 fn test_trim_start() {
775     assert_eq!("".trim_start(), "");
776     assert_eq!("a".trim_start(), "a");
777     assert_eq!("    ".trim_start(), "");
778     assert_eq!("     blah".trim_start(), "blah");
779     assert_eq!("   \u{3000}  wut".trim_start(), "wut");
780     assert_eq!("hey ".trim_start(), "hey ");
781 }
782
783 #[test]
784 fn test_trim_end() {
785     assert_eq!("".trim_end(), "");
786     assert_eq!("a".trim_end(), "a");
787     assert_eq!("    ".trim_end(), "");
788     assert_eq!("blah     ".trim_end(), "blah");
789     assert_eq!("wut   \u{3000}  ".trim_end(), "wut");
790     assert_eq!(" hey".trim_end(), " hey");
791 }
792
793 #[test]
794 fn test_trim() {
795     assert_eq!("".trim(), "");
796     assert_eq!("a".trim(), "a");
797     assert_eq!("    ".trim(), "");
798     assert_eq!("    blah     ".trim(), "blah");
799     assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
800     assert_eq!(" hey dude ".trim(), "hey dude");
801 }
802
803 #[test]
804 fn test_is_whitespace() {
805     assert!("".chars().all(|c| c.is_whitespace()));
806     assert!(" ".chars().all(|c| c.is_whitespace()));
807     assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
808     assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
809     assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
810 }
811
812 #[test]
813 fn test_is_utf8() {
814     // deny overlong encodings
815     assert!(from_utf8(&[0xc0, 0x80]).is_err());
816     assert!(from_utf8(&[0xc0, 0xae]).is_err());
817     assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
818     assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
819     assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
820     assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
821     assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
822
823     // deny surrogates
824     assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
825     assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
826
827     assert!(from_utf8(&[0xC2, 0x80]).is_ok());
828     assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
829     assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
830     assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
831     assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
832     assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
833     assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
834     assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
835 }
836
837 #[test]
838 fn from_utf8_mostly_ascii() {
839     // deny invalid bytes embedded in long stretches of ascii
840     for i in 32..64 {
841         let mut data = [0; 128];
842         data[i] = 0xC0;
843         assert!(from_utf8(&data).is_err());
844         data[i] = 0xC2;
845         assert!(from_utf8(&data).is_err());
846     }
847 }
848
849 #[test]
850 fn from_utf8_error() {
851     macro_rules! test {
852         ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
853             let error = from_utf8($input).unwrap_err();
854             assert_eq!(error.valid_up_to(), $expected_valid_up_to);
855             assert_eq!(error.error_len(), $expected_error_len);
856         }
857     }
858     test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
859     test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
860     test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
861     test!(b"A\xC3\xA9 \xC1", 4, Some(1));
862     test!(b"A\xC3\xA9 \xC2", 4, None);
863     test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
864     test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
865     test!(b"A\xC3\xA9 \xE0", 4, None);
866     test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
867     test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
868     test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
869     test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
870     test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
871     test!(b"A\xC3\xA9 \xF1", 4, None);
872     test!(b"A\xC3\xA9 \xF1\x80", 4, None);
873     test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
874     test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
875     test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
876     test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
877 }
878
879 #[test]
880 fn test_as_bytes() {
881     // no null
882     let v = [
883         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
884         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
885         109
886     ];
887     let b: &[u8] = &[];
888     assert_eq!("".as_bytes(), b);
889     assert_eq!("abc".as_bytes(), b"abc");
890     assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
891 }
892
893 #[test]
894 #[should_panic]
895 #[cfg(not(miri))]
896 fn test_as_bytes_fail() {
897     // Don't double free. (I'm not sure if this exercises the
898     // original problem code path anymore.)
899     let s = String::from("");
900     let _bytes = s.as_bytes();
901     panic!();
902 }
903
904 #[test]
905 fn test_as_ptr() {
906     let buf = "hello".as_ptr();
907     unsafe {
908         assert_eq!(*buf.offset(0), b'h');
909         assert_eq!(*buf.offset(1), b'e');
910         assert_eq!(*buf.offset(2), b'l');
911         assert_eq!(*buf.offset(3), b'l');
912         assert_eq!(*buf.offset(4), b'o');
913     }
914 }
915
916 #[test]
917 fn vec_str_conversions() {
918     let s1: String = String::from("All mimsy were the borogoves");
919
920     let v: Vec<u8> = s1.as_bytes().to_vec();
921     let s2: String = String::from(from_utf8(&v).unwrap());
922     let mut i = 0;
923     let n1 = s1.len();
924     let n2 = v.len();
925     assert_eq!(n1, n2);
926     while i < n1 {
927         let a: u8 = s1.as_bytes()[i];
928         let b: u8 = s2.as_bytes()[i];
929         assert_eq!(a, b);
930         i += 1;
931     }
932 }
933
934 #[test]
935 fn test_contains() {
936     assert!("abcde".contains("bcd"));
937     assert!("abcde".contains("abcd"));
938     assert!("abcde".contains("bcde"));
939     assert!("abcde".contains(""));
940     assert!("".contains(""));
941     assert!(!"abcde".contains("def"));
942     assert!(!"".contains("a"));
943
944     let data = "ประเทศไทย中华Việt Nam";
945     assert!(data.contains("ประเ"));
946     assert!(data.contains("ะเ"));
947     assert!(data.contains("中华"));
948     assert!(!data.contains("ไท华"));
949 }
950
951 #[test]
952 fn test_contains_char() {
953     assert!("abc".contains('b'));
954     assert!("a".contains('a'));
955     assert!(!"abc".contains('d'));
956     assert!(!"".contains('a'));
957 }
958
959 #[test]
960 fn test_split_at() {
961     let s = "ศไทย中华Việt Nam";
962     for (index, _) in s.char_indices() {
963         let (a, b) = s.split_at(index);
964         assert_eq!(&s[..a.len()], a);
965         assert_eq!(&s[a.len()..], b);
966     }
967     let (a, b) = s.split_at(s.len());
968     assert_eq!(a, s);
969     assert_eq!(b, "");
970 }
971
972 #[test]
973 fn test_split_at_mut() {
974     let mut s = "Hello World".to_string();
975     {
976         let (a, b) = s.split_at_mut(5);
977         a.make_ascii_uppercase();
978         b.make_ascii_lowercase();
979     }
980     assert_eq!(s, "HELLO world");
981 }
982
983 #[test]
984 #[should_panic]
985 #[cfg(not(miri))]
986 fn test_split_at_boundscheck() {
987     let s = "ศไทย中华Việt Nam";
988     s.split_at(1);
989 }
990
991 #[test]
992 fn test_escape_unicode() {
993     assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
994     assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
995     assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
996     assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
997     assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
998     assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
999     assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
1000     assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
1001     assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
1002 }
1003
1004 #[test]
1005 fn test_escape_debug() {
1006     // Note that there are subtleties with the number of backslashes
1007     // on the left- and right-hand sides. In particular, Unicode code points
1008     // are usually escaped with two backslashes on the right-hand side, as
1009     // they are escaped. However, when the character is unescaped (e.g., for
1010     // printable characters), only a single backslash appears (as the character
1011     // itself appears in the debug string).
1012     assert_eq!("abc".escape_debug(), "abc");
1013     assert_eq!("a c".escape_debug(), "a c");
1014     assert_eq!("éèê".escape_debug(), "éèê");
1015     assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
1016     assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
1017     assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
1018     assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
1019     assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
1020     assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
1021     assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
1022     assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug(), "\\u{301}a\u{301}bé\\u{e000}");
1023 }
1024
1025 #[test]
1026 fn test_escape_default() {
1027     assert_eq!("abc".escape_default(), "abc");
1028     assert_eq!("a c".escape_default(), "a c");
1029     assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
1030     assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
1031     assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
1032     assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
1033     assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
1034     assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
1035     assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
1036     assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
1037 }
1038
1039 #[test]
1040 fn test_total_ord() {
1041     assert_eq!("1234".cmp("123"), Greater);
1042     assert_eq!("123".cmp("1234"), Less);
1043     assert_eq!("1234".cmp("1234"), Equal);
1044     assert_eq!("12345555".cmp("123456"), Less);
1045     assert_eq!("22".cmp("1234"), Greater);
1046 }
1047
1048 #[test]
1049 fn test_iterator() {
1050     let s = "ศไทย中华Việt Nam";
1051     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
1052
1053     let mut pos = 0;
1054     let it = s.chars();
1055
1056     for c in it {
1057         assert_eq!(c, v[pos]);
1058         pos += 1;
1059     }
1060     assert_eq!(pos, v.len());
1061     assert_eq!(s.chars().count(), v.len());
1062 }
1063
1064 #[test]
1065 fn test_rev_iterator() {
1066     let s = "ศไทย中华Việt Nam";
1067     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
1068
1069     let mut pos = 0;
1070     let it = s.chars().rev();
1071
1072     for c in it {
1073         assert_eq!(c, v[pos]);
1074         pos += 1;
1075     }
1076     assert_eq!(pos, v.len());
1077 }
1078
1079 #[test]
1080 #[cfg(not(miri))]
1081 fn test_chars_decoding() {
1082     let mut bytes = [0; 4];
1083     for c in (0..0x110000).filter_map(std::char::from_u32) {
1084         let s = c.encode_utf8(&mut bytes);
1085         if Some(c) != s.chars().next() {
1086             panic!("character {:x}={} does not decode correctly", c as u32, c);
1087         }
1088     }
1089 }
1090
1091 #[test]
1092 #[cfg(not(miri))]
1093 fn test_chars_rev_decoding() {
1094     let mut bytes = [0; 4];
1095     for c in (0..0x110000).filter_map(std::char::from_u32) {
1096         let s = c.encode_utf8(&mut bytes);
1097         if Some(c) != s.chars().rev().next() {
1098             panic!("character {:x}={} does not decode correctly", c as u32, c);
1099         }
1100     }
1101 }
1102
1103 #[test]
1104 fn test_iterator_clone() {
1105     let s = "ศไทย中华Việt Nam";
1106     let mut it = s.chars();
1107     it.next();
1108     assert!(it.clone().zip(it).all(|(x,y)| x == y));
1109 }
1110
1111 #[test]
1112 fn test_iterator_last() {
1113     let s = "ศไทย中华Việt Nam";
1114     let mut it = s.chars();
1115     it.next();
1116     assert_eq!(it.last(), Some('m'));
1117 }
1118
1119 #[test]
1120 fn test_bytesator() {
1121     let s = "ศไทย中华Việt Nam";
1122     let v = [
1123         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
1124         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
1125         109
1126     ];
1127     let mut pos = 0;
1128
1129     for b in s.bytes() {
1130         assert_eq!(b, v[pos]);
1131         pos += 1;
1132     }
1133 }
1134
1135 #[test]
1136 fn test_bytes_revator() {
1137     let s = "ศไทย中华Việt Nam";
1138     let v = [
1139         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
1140         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
1141         109
1142     ];
1143     let mut pos = v.len();
1144
1145     for b in s.bytes().rev() {
1146         pos -= 1;
1147         assert_eq!(b, v[pos]);
1148     }
1149 }
1150
1151 #[test]
1152 fn test_bytesator_nth() {
1153     let s = "ศไทย中华Việt Nam";
1154     let v = [
1155         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
1156         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
1157         109
1158     ];
1159
1160     let mut b = s.bytes();
1161     assert_eq!(b.nth(2).unwrap(), v[2]);
1162     assert_eq!(b.nth(10).unwrap(), v[10]);
1163     assert_eq!(b.nth(200), None);
1164 }
1165
1166 #[test]
1167 fn test_bytesator_count() {
1168     let s = "ศไทย中华Việt Nam";
1169
1170     let b = s.bytes();
1171     assert_eq!(b.count(), 28)
1172 }
1173
1174 #[test]
1175 fn test_bytesator_last() {
1176     let s = "ศไทย中华Việt Nam";
1177
1178     let b = s.bytes();
1179     assert_eq!(b.last().unwrap(), 109)
1180 }
1181
1182 #[test]
1183 fn test_char_indicesator() {
1184     let s = "ศไทย中华Việt Nam";
1185     let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
1186     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
1187
1188     let mut pos = 0;
1189     let it = s.char_indices();
1190
1191     for c in it {
1192         assert_eq!(c, (p[pos], v[pos]));
1193         pos += 1;
1194     }
1195     assert_eq!(pos, v.len());
1196     assert_eq!(pos, p.len());
1197 }
1198
1199 #[test]
1200 fn test_char_indices_revator() {
1201     let s = "ศไทย中华Việt Nam";
1202     let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
1203     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
1204
1205     let mut pos = 0;
1206     let it = s.char_indices().rev();
1207
1208     for c in it {
1209         assert_eq!(c, (p[pos], v[pos]));
1210         pos += 1;
1211     }
1212     assert_eq!(pos, v.len());
1213     assert_eq!(pos, p.len());
1214 }
1215
1216 #[test]
1217 fn test_char_indices_last() {
1218     let s = "ศไทย中华Việt Nam";
1219     let mut it = s.char_indices();
1220     it.next();
1221     assert_eq!(it.last(), Some((27, 'm')));
1222 }
1223
1224 #[test]
1225 fn test_splitn_char_iterator() {
1226     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1227
1228     let split: Vec<&str> = data.splitn(4, ' ').collect();
1229     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
1230
1231     let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
1232     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
1233
1234     // Unicode
1235     let split: Vec<&str> = data.splitn(4, 'ä').collect();
1236     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
1237
1238     let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
1239     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
1240 }
1241
1242 #[test]
1243 fn test_split_char_iterator_no_trailing() {
1244     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1245
1246     let split: Vec<&str> = data.split('\n').collect();
1247     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1248
1249     let split: Vec<&str> = data.split_terminator('\n').collect();
1250     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1251 }
1252
1253 #[test]
1254 fn test_rsplit() {
1255     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1256
1257     let split: Vec<&str> = data.rsplit(' ').collect();
1258     assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
1259
1260     let split: Vec<&str> = data.rsplit("lämb").collect();
1261     assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
1262
1263     let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
1264     assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
1265 }
1266
1267 #[test]
1268 fn test_rsplitn() {
1269     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1270
1271     let split: Vec<&str> = data.rsplitn(2, ' ').collect();
1272     assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
1273
1274     let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
1275     assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
1276
1277     let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
1278     assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
1279 }
1280
1281 #[test]
1282 fn test_split_whitespace() {
1283     let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
1284     let words: Vec<&str> = data.split_whitespace().collect();
1285     assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
1286 }
1287
1288 #[test]
1289 fn test_lines() {
1290     let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
1291     let lines: Vec<&str> = data.lines().collect();
1292     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1293
1294     let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
1295     let lines: Vec<&str> = data.lines().collect();
1296     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1297 }
1298
1299 #[test]
1300 fn test_splitator() {
1301     fn t(s: &str, sep: &str, u: &[&str]) {
1302         let v: Vec<&str> = s.split(sep).collect();
1303         assert_eq!(v, u);
1304     }
1305     t("--1233345--", "12345", &["--1233345--"]);
1306     t("abc::hello::there", "::", &["abc", "hello", "there"]);
1307     t("::hello::there", "::", &["", "hello", "there"]);
1308     t("hello::there::", "::", &["hello", "there", ""]);
1309     t("::hello::there::", "::", &["", "hello", "there", ""]);
1310     t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
1311     t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
1312     t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
1313     t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
1314     t("", ".", &[""]);
1315     t("zz", "zz", &["",""]);
1316     t("ok", "z", &["ok"]);
1317     t("zzz", "zz", &["","z"]);
1318     t("zzzzz", "zz", &["","","z"]);
1319 }
1320
1321 #[test]
1322 #[cfg(not(miri))]
1323 fn test_str_default() {
1324     use std::default::Default;
1325
1326     fn t<S: Default + AsRef<str>>() {
1327         let s: S = Default::default();
1328         assert_eq!(s.as_ref(), "");
1329     }
1330
1331     t::<&str>();
1332     t::<String>();
1333     t::<&mut str>();
1334 }
1335
1336 #[test]
1337 fn test_str_container() {
1338     fn sum_len(v: &[&str]) -> usize {
1339         v.iter().map(|x| x.len()).sum()
1340     }
1341
1342     let s = "01234";
1343     assert_eq!(5, sum_len(&["012", "", "34"]));
1344     assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1345     assert_eq!(5, sum_len(&[s]));
1346 }
1347
1348 #[test]
1349 fn test_str_from_utf8() {
1350     let xs = b"hello";
1351     assert_eq!(from_utf8(xs), Ok("hello"));
1352
1353     let xs = "ศไทย中华Việt Nam".as_bytes();
1354     assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1355
1356     let xs = b"hello\xFF";
1357     assert!(from_utf8(xs).is_err());
1358 }
1359
1360 #[test]
1361 fn test_pattern_deref_forward() {
1362     let data = "aabcdaa";
1363     assert!(data.contains("bcd"));
1364     assert!(data.contains(&"bcd"));
1365     assert!(data.contains(&"bcd".to_string()));
1366 }
1367
1368 #[test]
1369 fn test_empty_match_indices() {
1370     let data = "aä中!";
1371     let vec: Vec<_> = data.match_indices("").collect();
1372     assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1373 }
1374
1375 #[test]
1376 fn test_bool_from_str() {
1377     assert_eq!("true".parse().ok(), Some(true));
1378     assert_eq!("false".parse().ok(), Some(false));
1379     assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1380 }
1381
1382 #[cfg(not(miri))]
1383 fn check_contains_all_substrings(s: &str) {
1384     assert!(s.contains(""));
1385     for i in 0..s.len() {
1386         for j in i+1..=s.len() {
1387             assert!(s.contains(&s[i..j]));
1388         }
1389     }
1390 }
1391
1392 #[test]
1393 #[cfg(not(miri))]
1394 fn strslice_issue_16589() {
1395     assert!("bananas".contains("nana"));
1396
1397     // prior to the fix for #16589, x.contains("abcdabcd") returned false
1398     // test all substrings for good measure
1399     check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1400 }
1401
1402 #[test]
1403 #[cfg(not(miri))]
1404 fn strslice_issue_16878() {
1405     assert!(!"1234567ah012345678901ah".contains("hah"));
1406     assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1407 }
1408
1409
1410 #[test]
1411 #[cfg(not(miri))]
1412 fn test_strslice_contains() {
1413     let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1414     check_contains_all_substrings(x);
1415 }
1416
1417 #[test]
1418 fn test_rsplitn_char_iterator() {
1419     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1420
1421     let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1422     split.reverse();
1423     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1424
1425     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1426     split.reverse();
1427     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1428
1429     // Unicode
1430     let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1431     split.reverse();
1432     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1433
1434     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1435     split.reverse();
1436     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1437 }
1438
1439 #[test]
1440 fn test_split_char_iterator() {
1441     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1442
1443     let split: Vec<&str> = data.split(' ').collect();
1444     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1445
1446     let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1447     rsplit.reverse();
1448     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1449
1450     let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1451     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1452
1453     let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1454     rsplit.reverse();
1455     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1456
1457     // Unicode
1458     let split: Vec<&str> = data.split('ä').collect();
1459     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1460
1461     let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1462     rsplit.reverse();
1463     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1464
1465     let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1466     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1467
1468     let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1469     rsplit.reverse();
1470     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1471 }
1472
1473 #[test]
1474 fn test_rev_split_char_iterator_no_trailing() {
1475     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1476
1477     let mut split: Vec<&str> = data.split('\n').rev().collect();
1478     split.reverse();
1479     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1480
1481     let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1482     split.reverse();
1483     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1484 }
1485
1486 #[test]
1487 fn test_utf16_code_units() {
1488     assert_eq!("é\u{1F4A9}".encode_utf16().collect::<Vec<u16>>(),
1489                [0xE9, 0xD83D, 0xDCA9])
1490 }
1491
1492 #[test]
1493 fn starts_with_in_unicode() {
1494     assert!(!"├── Cargo.toml".starts_with("# "));
1495 }
1496
1497 #[test]
1498 fn starts_short_long() {
1499     assert!(!"".starts_with("##"));
1500     assert!(!"##".starts_with("####"));
1501     assert!("####".starts_with("##"));
1502     assert!(!"##ä".starts_with("####"));
1503     assert!("####ä".starts_with("##"));
1504     assert!(!"##".starts_with("####ä"));
1505     assert!("##ä##".starts_with("##ä"));
1506
1507     assert!("".starts_with(""));
1508     assert!("ä".starts_with(""));
1509     assert!("#ä".starts_with(""));
1510     assert!("##ä".starts_with(""));
1511     assert!("ä###".starts_with(""));
1512     assert!("#ä##".starts_with(""));
1513     assert!("##ä#".starts_with(""));
1514 }
1515
1516 #[test]
1517 fn contains_weird_cases() {
1518     assert!("* \t".contains(' '));
1519     assert!(!"* \t".contains('?'));
1520     assert!(!"* \t".contains('\u{1F4A9}'));
1521 }
1522
1523 #[test]
1524 fn trim_ws() {
1525     assert_eq!(" \t  a \t  ".trim_start_matches(|c: char| c.is_whitespace()),
1526                     "a \t  ");
1527     assert_eq!(" \t  a \t  ".trim_end_matches(|c: char| c.is_whitespace()),
1528                " \t  a");
1529     assert_eq!(" \t  a \t  ".trim_start_matches(|c: char| c.is_whitespace()),
1530                     "a \t  ");
1531     assert_eq!(" \t  a \t  ".trim_end_matches(|c: char| c.is_whitespace()),
1532                " \t  a");
1533     assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
1534                     "a");
1535     assert_eq!(" \t   \t  ".trim_start_matches(|c: char| c.is_whitespace()),
1536                          "");
1537     assert_eq!(" \t   \t  ".trim_end_matches(|c: char| c.is_whitespace()),
1538                "");
1539     assert_eq!(" \t   \t  ".trim_start_matches(|c: char| c.is_whitespace()),
1540                          "");
1541     assert_eq!(" \t   \t  ".trim_end_matches(|c: char| c.is_whitespace()),
1542                "");
1543     assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
1544                "");
1545 }
1546
1547 #[test]
1548 fn to_lowercase() {
1549     #[cfg(not(miri))]
1550     assert_eq!("".to_lowercase(), "");
1551     assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1552
1553     // https://github.com/rust-lang/rust/issues/26035
1554     assert_eq!("ΑΣ".to_lowercase(), "ας");
1555     assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1556     assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1557
1558     assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1559     assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1560     assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1561
1562     assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1563     assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1564
1565     assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1566     assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1567
1568     assert_eq!("Α Σ".to_lowercase(), "α σ");
1569     assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1570     assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1571
1572     assert_eq!("Σ".to_lowercase(), "σ");
1573     assert_eq!("'Σ".to_lowercase(), "'σ");
1574     assert_eq!("''Σ".to_lowercase(), "''σ");
1575
1576     assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1577     assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1578     assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1579 }
1580
1581 #[test]
1582 fn to_uppercase() {
1583     #[cfg(not(miri))]
1584     assert_eq!("".to_uppercase(), "");
1585     assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1586 }
1587
1588 #[test]
1589 fn test_into_string() {
1590     // The only way to acquire a Box<str> in the first place is through a String, so just
1591     // test that we can round-trip between Box<str> and String.
1592     let string = String::from("Some text goes here");
1593     assert_eq!(string.clone().into_boxed_str().into_string(), string);
1594 }
1595
1596 #[test]
1597 fn test_box_slice_clone() {
1598     let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1599     let data2 = data.clone().into_boxed_str().clone().into_string();
1600
1601     assert_eq!(data, data2);
1602 }
1603
1604 #[test]
1605 fn test_cow_from() {
1606     let borrowed = "borrowed";
1607     let owned = String::from("owned");
1608     match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1609         (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1610         _ => panic!("invalid `Cow::from`"),
1611     }
1612 }
1613
1614 #[test]
1615 #[cfg(not(miri))]
1616 fn test_repeat() {
1617     assert_eq!("".repeat(3), "");
1618     assert_eq!("abc".repeat(0), "");
1619     assert_eq!("α".repeat(3), "ααα");
1620 }
1621
1622 mod pattern {
1623     use std::str::pattern::{Pattern, Searcher, ReverseSearcher};
1624     use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1625
1626     macro_rules! make_test {
1627         ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1628             #[allow(unused_imports)]
1629             mod $name {
1630                 use std::str::pattern::SearchStep::{Match, Reject};
1631                 use super::{cmp_search_to_vec};
1632                 #[test]
1633                 fn fwd() {
1634                     cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1635                 }
1636                 #[test]
1637                 fn bwd() {
1638                     cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1639                 }
1640             }
1641         }
1642     }
1643
1644     fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1645                                              right: Vec<SearchStep>)
1646     where P::Searcher: ReverseSearcher<'a>
1647     {
1648         let mut searcher = pat.into_searcher(haystack);
1649         let mut v = vec![];
1650         loop {
1651             match if !rev {searcher.next()} else {searcher.next_back()} {
1652                 Match(a, b) => v.push(Match(a, b)),
1653                 Reject(a, b) => v.push(Reject(a, b)),
1654                 Done => break,
1655             }
1656         }
1657         if rev {
1658             v.reverse();
1659         }
1660
1661         let mut first_index = 0;
1662         let mut err = None;
1663
1664         for (i, e) in right.iter().enumerate() {
1665             match *e {
1666                 Match(a, b) | Reject(a, b)
1667                 if a <= b && a == first_index => {
1668                     first_index = b;
1669                 }
1670                 _ => {
1671                     err = Some(i);
1672                     break;
1673                 }
1674             }
1675         }
1676
1677         if let Some(err) = err {
1678             panic!("Input skipped range at {}", err);
1679         }
1680
1681         if first_index != haystack.len() {
1682             panic!("Did not cover whole input");
1683         }
1684
1685         assert_eq!(v, right);
1686     }
1687
1688     make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1689         Reject(0, 1),
1690         Match (1, 3),
1691         Reject(3, 4),
1692         Match (4, 6),
1693         Reject(6, 7),
1694     ]);
1695     make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1696         Reject(0, 1),
1697         Match (1, 3),
1698         Reject(3, 4),
1699         Match (4, 6),
1700         Match (6, 8),
1701         Reject(8, 9),
1702     ]);
1703     make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1704         Match (0, 0),
1705         Reject(0, 1),
1706         Match (1, 1),
1707         Reject(1, 2),
1708         Match (2, 2),
1709         Reject(2, 3),
1710         Match (3, 3),
1711         Reject(3, 4),
1712         Match (4, 4),
1713         Reject(4, 5),
1714         Match (5, 5),
1715         Reject(5, 6),
1716         Match (6, 6),
1717         Reject(6, 7),
1718         Match (7, 7),
1719     ]);
1720     make_test!(str_searcher_multibyte_haystack, " ", "├──", [
1721         Reject(0, 3),
1722         Reject(3, 6),
1723         Reject(6, 9),
1724     ]);
1725     make_test!(str_searcher_empty_needle_multibyte_haystack, "", "├──", [
1726         Match (0, 0),
1727         Reject(0, 3),
1728         Match (3, 3),
1729         Reject(3, 6),
1730         Match (6, 6),
1731         Reject(6, 9),
1732         Match (9, 9),
1733     ]);
1734     make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1735         Match(0, 0),
1736     ]);
1737     make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1738     ]);
1739     make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1740         Reject(0, 1),
1741         Match (1, 2),
1742         Match (2, 3),
1743         Reject(3, 4),
1744         Match (4, 5),
1745         Match (5, 6),
1746         Reject(6, 7),
1747     ]);
1748     make_test!(char_searcher_multibyte_haystack, ' ', "├──", [
1749         Reject(0, 3),
1750         Reject(3, 6),
1751         Reject(6, 9),
1752     ]);
1753     make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1754         Reject(0, 1),
1755         Reject(1, 2),
1756         Reject(2, 3),
1757     ]);
1758
1759 }
1760
1761 macro_rules! generate_iterator_test {
1762     {
1763         $name:ident {
1764             $(
1765                 ($($arg:expr),*) -> [$($t:tt)*];
1766             )*
1767         }
1768         with $fwd:expr, $bwd:expr;
1769     } => {
1770         #[test]
1771         fn $name() {
1772             $(
1773                 {
1774                     let res = vec![$($t)*];
1775
1776                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1777                     assert_eq!(fwd_vec, res);
1778
1779                     let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1780                     bwd_vec.reverse();
1781                     assert_eq!(bwd_vec, res);
1782                 }
1783             )*
1784         }
1785     };
1786     {
1787         $name:ident {
1788             $(
1789                 ($($arg:expr),*) -> [$($t:tt)*];
1790             )*
1791         }
1792         with $fwd:expr;
1793     } => {
1794         #[test]
1795         fn $name() {
1796             $(
1797                 {
1798                     let res = vec![$($t)*];
1799
1800                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1801                     assert_eq!(fwd_vec, res);
1802                 }
1803             )*
1804         }
1805     }
1806 }
1807
1808 generate_iterator_test! {
1809     double_ended_split {
1810         ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1811         ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1812     }
1813     with str::split, str::rsplit;
1814 }
1815
1816 generate_iterator_test! {
1817     double_ended_split_terminator {
1818         ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1819     }
1820     with str::split_terminator, str::rsplit_terminator;
1821 }
1822
1823 generate_iterator_test! {
1824     double_ended_matches {
1825         ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1826     }
1827     with str::matches, str::rmatches;
1828 }
1829
1830 generate_iterator_test! {
1831     double_ended_match_indices {
1832         ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1833     }
1834     with str::match_indices, str::rmatch_indices;
1835 }
1836
1837 generate_iterator_test! {
1838     not_double_ended_splitn {
1839         ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1840     }
1841     with str::splitn;
1842 }
1843
1844 generate_iterator_test! {
1845     not_double_ended_rsplitn {
1846         ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1847     }
1848     with str::rsplitn;
1849 }
1850
1851 #[test]
1852 fn different_str_pattern_forwarding_lifetimes() {
1853     use std::str::pattern::Pattern;
1854
1855     fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
1856         for _ in 0..3 {
1857             "asdf".find(&p);
1858         }
1859     }
1860
1861     foo::<&str>("x");
1862 }