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