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