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.
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.
12 use std::cmp::Ordering::{Equal, Greater, Less};
13 use std::str::from_utf8;
19 assert!("foo" <= "foo");
20 assert!("foo" != "bar");
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));
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));
46 let s: String = empty.chars().collect();
48 let data = "ประเทศไทย中";
49 let s: String = data.chars().collect();
54 fn test_into_bytes() {
55 let data = String::from("asdf");
56 let buf = data.into_bytes();
57 assert_eq!(buf, b"asdf");
63 assert_eq!("".find(""), Some(0));
64 assert!("banana".find("apple pie").is_none());
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());
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));
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));
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));
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()
96 .chain(Some(string.len() - ip))
98 let pat = &string[i..ip + j];
99 assert!(match string.find(pat) {
103 assert!(match string.rfind(pat) {
111 fn s(x: &str) -> String { x.to_string() }
113 macro_rules! test_concat {
114 ($expected: expr, $string: expr) => {
116 let s: String = $string.concat();
117 assert_eq!($expected, s);
123 fn test_concat_for_different_types() {
124 test_concat!("ab", vec![s("a"), s("b")]);
125 test_concat!("ab", vec!["a", "b"]);
129 fn test_concat_for_different_lengths() {
130 let empty: &[&str] = &[];
131 test_concat!("", empty);
132 test_concat!("a", ["a"]);
133 test_concat!("ab", ["a", "b"]);
134 test_concat!("abc", ["", "a", "bc"]);
137 macro_rules! test_join {
138 ($expected: expr, $string: expr, $delim: expr) => {
140 let s = $string.join($delim);
141 assert_eq!($expected, s);
147 fn test_join_for_different_types() {
148 test_join!("a-b", ["a", "b"], "-");
149 let hyphen = "-".to_string();
150 test_join!("a-b", [s("a"), s("b")], &*hyphen);
151 test_join!("a-b", vec!["a", "b"], &*hyphen);
152 test_join!("a-b", &*vec!["a", "b"], "-");
153 test_join!("a-b", vec![s("a"), s("b")], "-");
157 fn test_join_for_different_lengths() {
158 let empty: &[&str] = &[];
159 test_join!("", empty, "-");
160 test_join!("a", ["a"], "-");
161 test_join!("a-b", ["a", "b"], "-");
162 test_join!("-a-bc", ["", "a", "bc"], "-");
166 fn test_unsafe_slice() {
167 assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
168 assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
169 assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
170 fn a_million_letter_a() -> String {
172 let mut rs = String::new();
174 rs.push_str("aaaaaaaaaa");
179 fn half_a_million_letter_a() -> String {
181 let mut rs = String::new();
183 rs.push_str("aaaaa");
188 let letters = a_million_letter_a();
189 assert_eq!(half_a_million_letter_a(),
190 unsafe { letters.slice_unchecked(0, 500000)});
194 fn test_starts_with() {
195 assert!("".starts_with(""));
196 assert!("abc".starts_with(""));
197 assert!("abc".starts_with("a"));
198 assert!(!"a".starts_with("abc"));
199 assert!(!"".starts_with("abc"));
200 assert!(!"ödd".starts_with("-"));
201 assert!("ödd".starts_with("öd"));
205 fn test_ends_with() {
206 assert!("".ends_with(""));
207 assert!("abc".ends_with(""));
208 assert!("abc".ends_with("c"));
209 assert!(!"a".ends_with("abc"));
210 assert!(!"".ends_with("abc"));
211 assert!(!"ddö".ends_with("-"));
212 assert!("ddö".ends_with("dö"));
217 assert!("".is_empty());
218 assert!(!"a".is_empty());
223 assert_eq!("".replacen('a', "b", 5), "");
224 assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
225 assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
228 assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
229 assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
230 assert_eq!(" test test ".replacen(test, "", 5), " ");
232 assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
238 assert_eq!("".replace(a, "b"), "");
239 assert_eq!("a".replace(a, "b"), "b");
240 assert_eq!("ab".replace(a, "b"), "bb");
242 assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
243 assert_eq!(" test test ".replace(test, ""), " ");
247 fn test_replace_2a() {
248 let data = "ประเทศไทย中华";
249 let repl = "دولة الكويت";
252 let a2 = "دولة الكويتทศไทย中华";
253 assert_eq!(data.replace(a, repl), a2);
257 fn test_replace_2b() {
258 let data = "ประเทศไทย中华";
259 let repl = "دولة الكويت";
262 let b2 = "ปรدولة الكويتทศไทย中华";
263 assert_eq!(data.replace(b, repl), b2);
267 fn test_replace_2c() {
268 let data = "ประเทศไทย中华";
269 let repl = "دولة الكويت";
272 let c2 = "ประเทศไทยدولة الكويت";
273 assert_eq!(data.replace(c, repl), c2);
277 fn test_replace_2d() {
278 let data = "ประเทศไทย中华";
279 let repl = "دولة الكويت";
282 assert_eq!(data.replace(d, repl), data);
286 fn test_replace_pattern() {
287 let data = "abcdαβγδabcdαβγδ";
288 assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
289 assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
290 assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
291 assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
296 assert_eq!("ab", &"abc"[0..2]);
297 assert_eq!("bc", &"abc"[1..3]);
298 assert_eq!("", &"abc"[1..1]);
299 assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
301 let data = "ประเทศไทย中华";
302 assert_eq!("ป", &data[0..3]);
303 assert_eq!("ร", &data[3..6]);
304 assert_eq!("", &data[3..3]);
305 assert_eq!("华", &data[30..33]);
307 fn a_million_letter_x() -> String {
309 let mut rs = String::new();
311 rs.push_str("华华华华华华华华华华");
316 fn half_a_million_letter_x() -> String {
318 let mut rs = String::new();
320 rs.push_str("华华华华华");
325 let letters = a_million_letter_x();
326 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
331 let ss = "中华Việt Nam";
333 assert_eq!("华", &ss[3..6]);
334 assert_eq!("Việt Nam", &ss[6..16]);
336 assert_eq!("ab", &"abc"[0..2]);
337 assert_eq!("bc", &"abc"[1..3]);
338 assert_eq!("", &"abc"[1..1]);
340 assert_eq!("中", &ss[0..3]);
341 assert_eq!("华V", &ss[3..7]);
342 assert_eq!("", &ss[3..3]);
357 fn test_slice_fail() {
363 fn test_is_char_boundary() {
364 let s = "ศไทย中华Việt Nam β-release 🐱123";
365 assert!(s.is_char_boundary(0));
366 assert!(s.is_char_boundary(s.len()));
367 assert!(!s.is_char_boundary(s.len() + 1));
368 for (i, ch) in s.char_indices() {
369 // ensure character locations are boundaries and continuation bytes are not
370 assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
371 for j in 1..ch.len_utf8() {
372 assert!(!s.is_char_boundary(i + j),
373 "{} should not be a char boundary in {:?}", i + j, s);
377 const LOREM_PARAGRAPH: &'static str = "\
378 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
379 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
380 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
381 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
382 tempus vel, gravida nec quam.";
384 // check the panic includes the prefix of the sliced string
386 #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
387 fn test_slice_fail_truncated_1() {
388 &LOREM_PARAGRAPH[..1024];
390 // check the truncation in the panic message
392 #[should_panic(expected="luctus, im`[...]")]
393 fn test_slice_fail_truncated_2() {
394 &LOREM_PARAGRAPH[..1024];
398 #[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
399 fn test_slice_fail_boundary_1() {
404 #[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
405 fn test_slice_fail_boundary_2() {
410 fn test_slice_from() {
411 assert_eq!(&"abcd"[0..], "abcd");
412 assert_eq!(&"abcd"[2..], "cd");
413 assert_eq!(&"abcd"[4..], "");
417 assert_eq!(&"abcd"[..0], "");
418 assert_eq!(&"abcd"[..2], "ab");
419 assert_eq!(&"abcd"[..4], "abcd");
423 fn test_trim_left_matches() {
424 let v: &[char] = &[];
425 assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
426 let chars: &[char] = &['*', ' '];
427 assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
428 assert_eq!(" *** *** ".trim_left_matches(chars), "");
429 assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
431 assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
432 let chars: &[char] = &['1', '2'];
433 assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
434 assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
438 fn test_trim_right_matches() {
439 let v: &[char] = &[];
440 assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
441 let chars: &[char] = &['*', ' '];
442 assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
443 assert_eq!(" *** *** ".trim_right_matches(chars), "");
444 assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
446 assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
447 let chars: &[char] = &['1', '2'];
448 assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
449 assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
453 fn test_trim_matches() {
454 let v: &[char] = &[];
455 assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
456 let chars: &[char] = &['*', ' '];
457 assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
458 assert_eq!(" *** *** ".trim_matches(chars), "");
459 assert_eq!("foo".trim_matches(chars), "foo");
461 assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
462 let chars: &[char] = &['1', '2'];
463 assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
464 assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
468 fn test_trim_left() {
469 assert_eq!("".trim_left(), "");
470 assert_eq!("a".trim_left(), "a");
471 assert_eq!(" ".trim_left(), "");
472 assert_eq!(" blah".trim_left(), "blah");
473 assert_eq!(" \u{3000} wut".trim_left(), "wut");
474 assert_eq!("hey ".trim_left(), "hey ");
478 fn test_trim_right() {
479 assert_eq!("".trim_right(), "");
480 assert_eq!("a".trim_right(), "a");
481 assert_eq!(" ".trim_right(), "");
482 assert_eq!("blah ".trim_right(), "blah");
483 assert_eq!("wut \u{3000} ".trim_right(), "wut");
484 assert_eq!(" hey".trim_right(), " hey");
489 assert_eq!("".trim(), "");
490 assert_eq!("a".trim(), "a");
491 assert_eq!(" ".trim(), "");
492 assert_eq!(" blah ".trim(), "blah");
493 assert_eq!("\nwut \u{3000} ".trim(), "wut");
494 assert_eq!(" hey dude ".trim(), "hey dude");
498 fn test_is_whitespace() {
499 assert!("".chars().all(|c| c.is_whitespace()));
500 assert!(" ".chars().all(|c| c.is_whitespace()));
501 assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
502 assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
503 assert!(!" _ ".chars().all(|c| c.is_whitespace()));
508 // deny overlong encodings
509 assert!(from_utf8(&[0xc0, 0x80]).is_err());
510 assert!(from_utf8(&[0xc0, 0xae]).is_err());
511 assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
512 assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
513 assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
514 assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
515 assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
518 assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
519 assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
521 assert!(from_utf8(&[0xC2, 0x80]).is_ok());
522 assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
523 assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
524 assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
525 assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
526 assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
527 assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
528 assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
532 fn from_utf8_mostly_ascii() {
533 // deny invalid bytes embedded in long stretches of ascii
535 let mut data = [0; 128];
537 assert!(from_utf8(&data).is_err());
539 assert!(from_utf8(&data).is_err());
545 use std_unicode::str::is_utf16;
548 ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
557 // surrogate pairs (randomly generated with Python 3's
558 // .encode('utf-16be'))
559 pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
560 &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
561 &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
563 // mixtures (also random)
564 pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
565 &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
566 &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
570 ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
574 // surrogate + regular unit
576 // surrogate + lead surrogate
578 // unterminated surrogate
580 // trail surrogate without a lead
583 // random byte sequences that Python 3's .decode('utf-16be')
585 neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
586 &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
587 &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
588 &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
589 &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
590 &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
591 &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
592 &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
593 &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
594 &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
595 &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
596 &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
597 &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
598 &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
599 &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
600 &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
601 &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
602 &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
603 &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
604 &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
605 &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
612 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
613 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
617 assert_eq!("".as_bytes(), b);
618 assert_eq!("abc".as_bytes(), b"abc");
619 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
624 fn test_as_bytes_fail() {
625 // Don't double free. (I'm not sure if this exercises the
626 // original problem code path anymore.)
627 let s = String::from("");
628 let _bytes = s.as_bytes();
634 let buf = "hello".as_ptr();
636 assert_eq!(*buf.offset(0), b'h');
637 assert_eq!(*buf.offset(1), b'e');
638 assert_eq!(*buf.offset(2), b'l');
639 assert_eq!(*buf.offset(3), b'l');
640 assert_eq!(*buf.offset(4), b'o');
645 fn vec_str_conversions() {
646 let s1: String = String::from("All mimsy were the borogoves");
648 let v: Vec<u8> = s1.as_bytes().to_vec();
649 let s2: String = String::from(from_utf8(&v).unwrap());
655 let a: u8 = s1.as_bytes()[i];
656 let b: u8 = s2.as_bytes()[i];
664 assert!("abcde".contains("bcd"));
665 assert!("abcde".contains("abcd"));
666 assert!("abcde".contains("bcde"));
667 assert!("abcde".contains(""));
668 assert!("".contains(""));
669 assert!(!"abcde".contains("def"));
670 assert!(!"".contains("a"));
672 let data = "ประเทศไทย中华Việt Nam";
673 assert!(data.contains("ประเ"));
674 assert!(data.contains("ะเ"));
675 assert!(data.contains("中华"));
676 assert!(!data.contains("ไท华"));
680 fn test_contains_char() {
681 assert!("abc".contains('b'));
682 assert!("a".contains('a'));
683 assert!(!"abc".contains('d'));
684 assert!(!"".contains('a'));
689 let s = "ศไทย中华Việt Nam";
690 for (index, _) in s.char_indices() {
691 let (a, b) = s.split_at(index);
692 assert_eq!(&s[..a.len()], a);
693 assert_eq!(&s[a.len()..], b);
695 let (a, b) = s.split_at(s.len());
701 fn test_split_at_mut() {
702 use std::ascii::AsciiExt;
703 let mut s = "Hello World".to_string();
705 let (a, b) = s.split_at_mut(5);
706 a.make_ascii_uppercase();
707 b.make_ascii_lowercase();
709 assert_eq!(s, "HELLO world");
714 fn test_split_at_boundscheck() {
715 let s = "ศไทย中华Việt Nam";
720 fn test_escape_unicode() {
721 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
722 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
723 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
724 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
725 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
726 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
727 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
728 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
729 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
733 fn test_escape_debug() {
734 assert_eq!("abc".escape_debug(), "abc");
735 assert_eq!("a c".escape_debug(), "a c");
736 assert_eq!("éèê".escape_debug(), "éèê");
737 assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
738 assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
739 assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
740 assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
741 assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
742 assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
743 assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
747 fn test_escape_default() {
748 assert_eq!("abc".escape_default(), "abc");
749 assert_eq!("a c".escape_default(), "a c");
750 assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
751 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
752 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
753 assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
754 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
755 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
756 assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
757 assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
761 fn test_total_ord() {
762 assert_eq!("1234".cmp("123"), Greater);
763 assert_eq!("123".cmp("1234"), Less);
764 assert_eq!("1234".cmp("1234"), Equal);
765 assert_eq!("12345555".cmp("123456"), Less);
766 assert_eq!("22".cmp("1234"), Greater);
771 let s = "ศไทย中华Việt Nam";
772 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
778 assert_eq!(c, v[pos]);
781 assert_eq!(pos, v.len());
782 assert_eq!(s.chars().count(), v.len());
786 fn test_rev_iterator() {
787 let s = "ศไทย中华Việt Nam";
788 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
791 let it = s.chars().rev();
794 assert_eq!(c, v[pos]);
797 assert_eq!(pos, v.len());
801 fn test_chars_decoding() {
802 let mut bytes = [0; 4];
803 for c in (0..0x110000).filter_map(::std::char::from_u32) {
804 let s = c.encode_utf8(&mut bytes);
805 if Some(c) != s.chars().next() {
806 panic!("character {:x}={} does not decode correctly", c as u32, c);
812 fn test_chars_rev_decoding() {
813 let mut bytes = [0; 4];
814 for c in (0..0x110000).filter_map(::std::char::from_u32) {
815 let s = c.encode_utf8(&mut bytes);
816 if Some(c) != s.chars().rev().next() {
817 panic!("character {:x}={} does not decode correctly", c as u32, c);
823 fn test_iterator_clone() {
824 let s = "ศไทย中华Việt Nam";
825 let mut it = s.chars();
827 assert!(it.clone().zip(it).all(|(x,y)| x == y));
831 fn test_iterator_last() {
832 let s = "ศไทย中华Việt Nam";
833 let mut it = s.chars();
835 assert_eq!(it.last(), Some('m'));
839 fn test_bytesator() {
840 let s = "ศไทย中华Việt Nam";
842 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
843 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
849 assert_eq!(b, v[pos]);
855 fn test_bytes_revator() {
856 let s = "ศไทย中华Việt Nam";
858 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
859 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
862 let mut pos = v.len();
864 for b in s.bytes().rev() {
866 assert_eq!(b, v[pos]);
871 fn test_bytesator_nth() {
872 let s = "ศไทย中华Việt Nam";
874 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
875 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
879 let mut b = s.bytes();
880 assert_eq!(b.nth(2).unwrap(), v[2]);
881 assert_eq!(b.nth(10).unwrap(), v[10]);
882 assert_eq!(b.nth(200), None);
886 fn test_bytesator_count() {
887 let s = "ศไทย中华Việt Nam";
890 assert_eq!(b.count(), 28)
894 fn test_bytesator_last() {
895 let s = "ศไทย中华Việt Nam";
898 assert_eq!(b.last().unwrap(), 109)
902 fn test_char_indicesator() {
903 let s = "ศไทย中华Việt Nam";
904 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
905 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
908 let it = s.char_indices();
911 assert_eq!(c, (p[pos], v[pos]));
914 assert_eq!(pos, v.len());
915 assert_eq!(pos, p.len());
919 fn test_char_indices_revator() {
920 let s = "ศไทย中华Việt Nam";
921 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
922 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
925 let it = s.char_indices().rev();
928 assert_eq!(c, (p[pos], v[pos]));
931 assert_eq!(pos, v.len());
932 assert_eq!(pos, p.len());
936 fn test_char_indices_last() {
937 let s = "ศไทย中华Việt Nam";
938 let mut it = s.char_indices();
940 assert_eq!(it.last(), Some((27, 'm')));
944 fn test_splitn_char_iterator() {
945 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
947 let split: Vec<&str> = data.splitn(4, ' ').collect();
948 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
950 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
951 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
954 let split: Vec<&str> = data.splitn(4, 'ä').collect();
955 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
957 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
958 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
962 fn test_split_char_iterator_no_trailing() {
963 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
965 let split: Vec<&str> = data.split('\n').collect();
966 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
968 let split: Vec<&str> = data.split_terminator('\n').collect();
969 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
974 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
976 let split: Vec<&str> = data.rsplit(' ').collect();
977 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
979 let split: Vec<&str> = data.rsplit("lämb").collect();
980 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
982 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
983 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
988 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
990 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
991 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
993 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
994 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
996 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
997 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
1001 fn test_split_whitespace() {
1002 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
1003 let words: Vec<&str> = data.split_whitespace().collect();
1004 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
1009 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
1010 let lines: Vec<&str> = data.lines().collect();
1011 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1013 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
1014 let lines: Vec<&str> = data.lines().collect();
1015 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1019 fn test_splitator() {
1020 fn t(s: &str, sep: &str, u: &[&str]) {
1021 let v: Vec<&str> = s.split(sep).collect();
1024 t("--1233345--", "12345", &["--1233345--"]);
1025 t("abc::hello::there", "::", &["abc", "hello", "there"]);
1026 t("::hello::there", "::", &["", "hello", "there"]);
1027 t("hello::there::", "::", &["hello", "there", ""]);
1028 t("::hello::there::", "::", &["", "hello", "there", ""]);
1029 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
1030 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
1031 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
1032 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
1034 t("zz", "zz", &["",""]);
1035 t("ok", "z", &["ok"]);
1036 t("zzz", "zz", &["","z"]);
1037 t("zzzzz", "zz", &["","","z"]);
1041 fn test_str_default() {
1042 use std::default::Default;
1044 fn t<S: Default + AsRef<str>>() {
1045 let s: S = Default::default();
1046 assert_eq!(s.as_ref(), "");
1054 fn test_str_container() {
1055 fn sum_len(v: &[&str]) -> usize {
1056 v.iter().map(|x| x.len()).sum()
1060 assert_eq!(5, sum_len(&["012", "", "34"]));
1061 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1062 assert_eq!(5, sum_len(&[s]));
1066 fn test_str_from_utf8() {
1068 assert_eq!(from_utf8(xs), Ok("hello"));
1070 let xs = "ศไทย中华Việt Nam".as_bytes();
1071 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1073 let xs = b"hello\xFF";
1074 assert!(from_utf8(xs).is_err());
1078 fn test_pattern_deref_forward() {
1079 let data = "aabcdaa";
1080 assert!(data.contains("bcd"));
1081 assert!(data.contains(&"bcd"));
1082 assert!(data.contains(&"bcd".to_string()));
1086 fn test_empty_match_indices() {
1088 let vec: Vec<_> = data.match_indices("").collect();
1089 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1093 fn test_bool_from_str() {
1094 assert_eq!("true".parse().ok(), Some(true));
1095 assert_eq!("false".parse().ok(), Some(false));
1096 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1099 fn check_contains_all_substrings(s: &str) {
1100 assert!(s.contains(""));
1101 for i in 0..s.len() {
1102 for j in i+1..s.len() + 1 {
1103 assert!(s.contains(&s[i..j]));
1109 fn strslice_issue_16589() {
1110 assert!("bananas".contains("nana"));
1112 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1113 // test all substrings for good measure
1114 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1118 fn strslice_issue_16878() {
1119 assert!(!"1234567ah012345678901ah".contains("hah"));
1120 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1125 fn test_strslice_contains() {
1126 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1127 check_contains_all_substrings(x);
1131 fn test_rsplitn_char_iterator() {
1132 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1134 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1136 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1138 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1140 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1143 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1145 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1147 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1149 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1153 fn test_split_char_iterator() {
1154 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1156 let split: Vec<&str> = data.split(' ').collect();
1157 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1159 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1161 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1163 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1164 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1166 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1168 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1171 let split: Vec<&str> = data.split('ä').collect();
1172 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1174 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1176 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1178 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1179 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1181 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1183 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1187 fn test_rev_split_char_iterator_no_trailing() {
1188 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1190 let mut split: Vec<&str> = data.split('\n').rev().collect();
1192 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1194 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1196 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1200 fn test_utf16_code_units() {
1201 use std_unicode::str::Utf16Encoder;
1202 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1203 [0xE9, 0xD83D, 0xDCA9])
1207 fn starts_with_in_unicode() {
1208 assert!(!"├── Cargo.toml".starts_with("# "));
1212 fn starts_short_long() {
1213 assert!(!"".starts_with("##"));
1214 assert!(!"##".starts_with("####"));
1215 assert!("####".starts_with("##"));
1216 assert!(!"##ä".starts_with("####"));
1217 assert!("####ä".starts_with("##"));
1218 assert!(!"##".starts_with("####ä"));
1219 assert!("##ä##".starts_with("##ä"));
1221 assert!("".starts_with(""));
1222 assert!("ä".starts_with(""));
1223 assert!("#ä".starts_with(""));
1224 assert!("##ä".starts_with(""));
1225 assert!("ä###".starts_with(""));
1226 assert!("#ä##".starts_with(""));
1227 assert!("##ä#".starts_with(""));
1231 fn contains_weird_cases() {
1232 assert!("* \t".contains(' '));
1233 assert!(!"* \t".contains('?'));
1234 assert!(!"* \t".contains('\u{1F4A9}'));
1239 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1241 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1243 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1245 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1247 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1249 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1255 assert_eq!("".to_lowercase(), "");
1256 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1258 // https://github.com/rust-lang/rust/issues/26035
1259 assert_eq!("ΑΣ".to_lowercase(), "ας");
1260 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1261 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1263 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1264 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1265 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1267 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1268 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1270 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1271 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1273 assert_eq!("Α Σ".to_lowercase(), "α σ");
1274 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1275 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1277 assert_eq!("Σ".to_lowercase(), "σ");
1278 assert_eq!("'Σ".to_lowercase(), "'σ");
1279 assert_eq!("''Σ".to_lowercase(), "''σ");
1281 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1282 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1283 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1288 assert_eq!("".to_uppercase(), "");
1289 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1293 fn test_into_string() {
1294 // The only way to acquire a Box<str> in the first place is through a String, so just
1295 // test that we can round-trip between Box<str> and String.
1296 let string = String::from("Some text goes here");
1297 assert_eq!(string.clone().into_boxed_str().into_string(), string);
1301 fn test_box_slice_clone() {
1302 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1303 let data2 = data.clone().into_boxed_str().clone().into_string();
1305 assert_eq!(data, data2);
1309 fn test_cow_from() {
1310 let borrowed = "borrowed";
1311 let owned = String::from("owned");
1312 match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1313 (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1314 _ => panic!("invalid `Cow::from`"),
1320 assert_eq!("".repeat(3), "");
1321 assert_eq!("abc".repeat(0), "");
1322 assert_eq!("α".repeat(3), "ααα");
1326 use std::str::pattern::Pattern;
1327 use std::str::pattern::{Searcher, ReverseSearcher};
1328 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1330 macro_rules! make_test {
1331 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1332 #[allow(unused_imports)]
1334 use std::str::pattern::SearchStep::{Match, Reject};
1335 use super::{cmp_search_to_vec};
1338 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1342 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1348 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1349 right: Vec<SearchStep>)
1350 where P::Searcher: ReverseSearcher<'a>
1352 let mut searcher = pat.into_searcher(haystack);
1355 match if !rev {searcher.next()} else {searcher.next_back()} {
1356 Match(a, b) => v.push(Match(a, b)),
1357 Reject(a, b) => v.push(Reject(a, b)),
1365 let mut first_index = 0;
1368 for (i, e) in right.iter().enumerate() {
1370 Match(a, b) | Reject(a, b)
1371 if a <= b && a == first_index => {
1381 if let Some(err) = err {
1382 panic!("Input skipped range at {}", err);
1385 if first_index != haystack.len() {
1386 panic!("Did not cover whole input");
1389 assert_eq!(v, right);
1392 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1399 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1407 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1424 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1429 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1438 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1441 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1443 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1452 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1457 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1465 macro_rules! generate_iterator_test {
1469 ($($arg:expr),*) -> [$($t:tt)*];
1472 with $fwd:expr, $bwd:expr;
1478 let res = vec![$($t)*];
1480 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1481 assert_eq!(fwd_vec, res);
1483 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1485 assert_eq!(bwd_vec, res);
1493 ($($arg:expr),*) -> [$($t:tt)*];
1502 let res = vec![$($t)*];
1504 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1505 assert_eq!(fwd_vec, res);
1512 generate_iterator_test! {
1513 double_ended_split {
1514 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1515 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1517 with str::split, str::rsplit;
1520 generate_iterator_test! {
1521 double_ended_split_terminator {
1522 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1524 with str::split_terminator, str::rsplit_terminator;
1527 generate_iterator_test! {
1528 double_ended_matches {
1529 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1531 with str::matches, str::rmatches;
1534 generate_iterator_test! {
1535 double_ended_match_indices {
1536 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1538 with str::match_indices, str::rmatch_indices;
1541 generate_iterator_test! {
1542 not_double_ended_splitn {
1543 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1548 generate_iterator_test! {
1549 not_double_ended_rsplitn {
1550 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1556 fn different_str_pattern_forwarding_lifetimes() {
1557 use std::str::pattern::Pattern;
1559 fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
1569 use test::{Bencher, black_box};
1572 fn char_iterator(b: &mut Bencher) {
1573 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1575 b.iter(|| s.chars().count());
1579 fn char_iterator_for(b: &mut Bencher) {
1580 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1583 for ch in s.chars() { black_box(ch); }
1588 fn char_iterator_ascii(b: &mut Bencher) {
1589 let s = "Mary had a little lamb, Little lamb
1590 Mary had a little lamb, Little lamb
1591 Mary had a little lamb, Little lamb
1592 Mary had a little lamb, Little lamb
1593 Mary had a little lamb, Little lamb
1594 Mary had a little lamb, Little lamb";
1596 b.iter(|| s.chars().count());
1600 fn char_iterator_rev(b: &mut Bencher) {
1601 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1603 b.iter(|| s.chars().rev().count());
1607 fn char_iterator_rev_for(b: &mut Bencher) {
1608 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1611 for ch in s.chars().rev() { black_box(ch); }
1616 fn char_indicesator(b: &mut Bencher) {
1617 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1618 let len = s.chars().count();
1620 b.iter(|| assert_eq!(s.char_indices().count(), len));
1624 fn char_indicesator_rev(b: &mut Bencher) {
1625 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1626 let len = s.chars().count();
1628 b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
1632 fn split_unicode_ascii(b: &mut Bencher) {
1633 let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1635 b.iter(|| assert_eq!(s.split('V').count(), 3));
1639 fn split_ascii(b: &mut Bencher) {
1640 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1641 let len = s.split(' ').count();
1643 b.iter(|| assert_eq!(s.split(' ').count(), len));
1647 fn split_extern_fn(b: &mut Bencher) {
1648 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1649 let len = s.split(' ').count();
1650 fn pred(c: char) -> bool { c == ' ' }
1652 b.iter(|| assert_eq!(s.split(pred).count(), len));
1656 fn split_closure(b: &mut Bencher) {
1657 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1658 let len = s.split(' ').count();
1660 b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
1664 fn split_slice(b: &mut Bencher) {
1665 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1666 let len = s.split(' ').count();
1668 let c: &[char] = &[' '];
1669 b.iter(|| assert_eq!(s.split(c).count(), len));
1673 fn bench_join(b: &mut Bencher) {
1674 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1676 let v = vec![s, s, s, s, s, s, s, s, s, s];
1678 assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
1683 fn bench_contains_short_short(b: &mut Bencher) {
1684 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1688 assert!(haystack.contains(needle));
1693 fn bench_contains_short_long(b: &mut Bencher) {
1695 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1696 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1697 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1698 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1699 tempus vel, gravida nec quam.
1701 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1702 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1703 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1704 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1705 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1706 interdum. Curabitur ut nisi justo.
1708 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1709 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1710 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1711 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1712 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1713 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1714 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1715 Aliquam sit amet placerat lorem.
1717 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1718 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1719 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1720 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1721 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1724 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1725 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1726 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1727 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1728 malesuada sollicitudin quam eu fermentum.";
1729 let needle = "english";
1732 assert!(!haystack.contains(needle));
1737 fn bench_contains_bad_naive(b: &mut Bencher) {
1738 let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1739 let needle = "aaaaaaaab";
1742 assert!(!haystack.contains(needle));
1747 fn bench_contains_equal(b: &mut Bencher) {
1748 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1749 let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1752 assert!(haystack.contains(needle));
1756 macro_rules! make_test_inner {
1757 ($s:ident, $code:expr, $name:ident, $str:expr) => {
1759 fn $name(bencher: &mut Bencher) {
1762 bencher.iter(|| $code);
1767 macro_rules! make_test {
1768 ($name:ident, $s:ident, $code:expr) => {
1771 use test::black_box;
1773 // Short strings: 65 bytes each
1774 make_test_inner!($s, $code, short_ascii,
1775 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1776 make_test_inner!($s, $code, short_mixed,
1777 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1778 make_test_inner!($s, $code, short_pile_of_poo,
1779 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1780 make_test_inner!($s, $code, long_lorem_ipsum,"\
1781 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1782 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1783 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1784 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1785 tempus vel, gravida nec quam.
1787 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1788 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1789 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1790 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1791 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1792 interdum. Curabitur ut nisi justo.
1794 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1795 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1796 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1797 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1798 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1799 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1800 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1801 Aliquam sit amet placerat lorem.
1803 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1804 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1805 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1806 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1807 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1810 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1811 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1812 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1813 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1814 malesuada sollicitudin quam eu fermentum!");
1819 make_test!(chars_count, s, s.chars().count());
1821 make_test!(contains_bang_str, s, s.contains("!"));
1822 make_test!(contains_bang_char, s, s.contains('!'));
1824 make_test!(match_indices_a_str, s, s.match_indices("a").count());
1826 make_test!(split_a_str, s, s.split("a").count());
1828 make_test!(trim_ascii_char, s, {
1829 use std::ascii::AsciiExt;
1830 s.trim_matches(|c: char| c.is_ascii())
1832 make_test!(trim_left_ascii_char, s, {
1833 use std::ascii::AsciiExt;
1834 s.trim_left_matches(|c: char| c.is_ascii())
1836 make_test!(trim_right_ascii_char, s, {
1837 use std::ascii::AsciiExt;
1838 s.trim_right_matches(|c: char| c.is_ascii())
1841 make_test!(find_underscore_char, s, s.find('_'));
1842 make_test!(rfind_underscore_char, s, s.rfind('_'));
1843 make_test!(find_underscore_str, s, s.find("_"));
1845 make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
1846 make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
1847 make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
1849 make_test!(split_space_char, s, s.split(' ').count());
1850 make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
1852 make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
1853 make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
1855 make_test!(split_space_str, s, s.split(" ").count());
1856 make_test!(split_ad_str, s, s.split("ad").count());