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_str_slice_rangetoinclusive_max_panics() {
364 &"hello"[..=usize::max_value()];
369 fn test_str_slice_rangeinclusive_max_panics() {
370 &"hello"[1..=usize::max_value()];
375 fn test_str_slicemut_rangetoinclusive_max_panics() {
376 let mut s
= "hello".to_owned();
377 let s
: &mut str = &mut s
;
378 &mut s
[..=usize::max_value()];
383 fn test_str_slicemut_rangeinclusive_max_panics() {
384 let mut s
= "hello".to_owned();
385 let s
: &mut str = &mut s
;
386 &mut s
[1..=usize::max_value()];
390 fn test_str_get_maxinclusive() {
391 let mut s
= "hello".to_owned();
394 assert_eq
!(s
.get(..=usize::max_value()), None
);
395 assert_eq
!(s
.get(1..=usize::max_value()), None
);
398 let s
: &mut str = &mut s
;
399 assert_eq
!(s
.get(..=usize::max_value()), None
);
400 assert_eq
!(s
.get(1..=usize::max_value()), None
);
405 fn test_is_char_boundary() {
406 let s
= "ศไทย中华Việt Nam β-release 🐱123";
407 assert
!(s
.is_char_boundary(0));
408 assert
!(s
.is_char_boundary(s
.len()));
409 assert
!(!s
.is_char_boundary(s
.len() + 1));
410 for (i
, ch
) in s
.char_indices() {
411 // ensure character locations are boundaries and continuation bytes are not
412 assert
!(s
.is_char_boundary(i
), "{} is a char boundary in {:?}", i
, s
);
413 for j
in 1..ch
.len_utf8() {
414 assert
!(!s
.is_char_boundary(i
+ j
),
415 "{} should not be a char boundary in {:?}", i
+ j
, s
);
419 const LOREM_PARAGRAPH
: &'
static str = "\
420 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
421 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
422 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
423 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
424 tempus vel, gravida nec quam.";
426 // check the panic includes the prefix of the sliced string
428 #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
429 fn test_slice_fail_truncated_1() {
430 &LOREM_PARAGRAPH
[..1024];
432 // check the truncation in the panic message
434 #[should_panic(expected="luctus, im`[...]")]
435 fn test_slice_fail_truncated_2() {
436 &LOREM_PARAGRAPH
[..1024];
440 #[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
441 fn test_slice_fail_boundary_1() {
446 #[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
447 fn test_slice_fail_boundary_2() {
452 fn test_slice_from() {
453 assert_eq
!(&"abcd"[0..], "abcd");
454 assert_eq
!(&"abcd"[2..], "cd");
455 assert_eq
!(&"abcd"[4..], "");
459 assert_eq
!(&"abcd"[..0], "");
460 assert_eq
!(&"abcd"[..2], "ab");
461 assert_eq
!(&"abcd"[..4], "abcd");
465 fn test_trim_left_matches() {
466 let v
: &[char] = &[];
467 assert_eq
!(" *** foo *** ".trim_left_matches(v
), " *** foo *** ");
468 let chars
: &[char] = &['
*'
, ' '
];
469 assert_eq
!(" *** foo *** ".trim_left_matches(chars
), "foo *** ");
470 assert_eq
!(" *** *** ".trim_left_matches(chars
), "");
471 assert_eq
!("foo *** ".trim_left_matches(chars
), "foo *** ");
473 assert_eq
!("11foo1bar11".trim_left_matches('
1'
), "foo1bar11");
474 let chars
: &[char] = &['
1'
, '
2'
];
475 assert_eq
!("12foo1bar12".trim_left_matches(chars
), "foo1bar12");
476 assert_eq
!("123foo1bar123".trim_left_matches(|c
: char| c
.is_numeric()), "foo1bar123");
480 fn test_trim_right_matches() {
481 let v
: &[char] = &[];
482 assert_eq
!(" *** foo *** ".trim_right_matches(v
), " *** foo *** ");
483 let chars
: &[char] = &['
*'
, ' '
];
484 assert_eq
!(" *** foo *** ".trim_right_matches(chars
), " *** foo");
485 assert_eq
!(" *** *** ".trim_right_matches(chars
), "");
486 assert_eq
!(" *** foo".trim_right_matches(chars
), " *** foo");
488 assert_eq
!("11foo1bar11".trim_right_matches('
1'
), "11foo1bar");
489 let chars
: &[char] = &['
1'
, '
2'
];
490 assert_eq
!("12foo1bar12".trim_right_matches(chars
), "12foo1bar");
491 assert_eq
!("123foo1bar123".trim_right_matches(|c
: char| c
.is_numeric()), "123foo1bar");
495 fn test_trim_matches() {
496 let v
: &[char] = &[];
497 assert_eq
!(" *** foo *** ".trim_matches(v
), " *** foo *** ");
498 let chars
: &[char] = &['
*'
, ' '
];
499 assert_eq
!(" *** foo *** ".trim_matches(chars
), "foo");
500 assert_eq
!(" *** *** ".trim_matches(chars
), "");
501 assert_eq
!("foo".trim_matches(chars
), "foo");
503 assert_eq
!("11foo1bar11".trim_matches('
1'
), "foo1bar");
504 let chars
: &[char] = &['
1'
, '
2'
];
505 assert_eq
!("12foo1bar12".trim_matches(chars
), "foo1bar");
506 assert_eq
!("123foo1bar123".trim_matches(|c
: char| c
.is_numeric()), "foo1bar");
510 fn test_trim_left() {
511 assert_eq
!("".trim_left(), "");
512 assert_eq
!("a".trim_left(), "a");
513 assert_eq
!(" ".trim_left(), "");
514 assert_eq
!(" blah".trim_left(), "blah");
515 assert_eq
!(" \u{3000} wut".trim_left(), "wut");
516 assert_eq
!("hey ".trim_left(), "hey ");
520 fn test_trim_right() {
521 assert_eq
!("".trim_right(), "");
522 assert_eq
!("a".trim_right(), "a");
523 assert_eq
!(" ".trim_right(), "");
524 assert_eq
!("blah ".trim_right(), "blah");
525 assert_eq
!("wut \u{3000} ".trim_right(), "wut");
526 assert_eq
!(" hey".trim_right(), " hey");
531 assert_eq
!("".trim(), "");
532 assert_eq
!("a".trim(), "a");
533 assert_eq
!(" ".trim(), "");
534 assert_eq
!(" blah ".trim(), "blah");
535 assert_eq
!("\nwut \u{3000} ".trim(), "wut");
536 assert_eq
!(" hey dude ".trim(), "hey dude");
540 fn test_is_whitespace() {
541 assert
!("".chars().all(|c
| c
.is_whitespace()));
542 assert
!(" ".chars().all(|c
| c
.is_whitespace()));
543 assert
!("\u{2009}".chars().all(|c
| c
.is_whitespace())); // Thin space
544 assert
!(" \n\t ".chars().all(|c
| c
.is_whitespace()));
545 assert
!(!" _ ".chars().all(|c
| c
.is_whitespace()));
550 // deny overlong encodings
551 assert
!(from_utf8(&[0xc0, 0x80]).is_err());
552 assert
!(from_utf8(&[0xc0, 0xae]).is_err());
553 assert
!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
554 assert
!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
555 assert
!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
556 assert
!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
557 assert
!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
560 assert
!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
561 assert
!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
563 assert
!(from_utf8(&[0xC2, 0x80]).is_ok());
564 assert
!(from_utf8(&[0xDF, 0xBF]).is_ok());
565 assert
!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
566 assert
!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
567 assert
!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
568 assert
!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
569 assert
!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
570 assert
!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
574 fn from_utf8_mostly_ascii() {
575 // deny invalid bytes embedded in long stretches of ascii
577 let mut data
= [0; 128];
579 assert
!(from_utf8(&data
).is_err());
581 assert
!(from_utf8(&data
).is_err());
586 fn from_utf8_error() {
588 ($input
: expr
, $expected_valid_up_to
: expr
, $expected_error_len
: expr
) => {
589 let error
= from_utf8($input
).unwrap_err();
590 assert_eq
!(error
.valid_up_to(), $expected_valid_up_to
);
591 assert_eq
!(error
.error_len(), $expected_error_len
);
594 test
!(b
"A\xC3\xA9 \xFF ", 4, Some(1));
595 test
!(b
"A\xC3\xA9 \x80 ", 4, Some(1));
596 test
!(b
"A\xC3\xA9 \xC1 ", 4, Some(1));
597 test
!(b
"A\xC3\xA9 \xC1", 4, Some(1));
598 test
!(b
"A\xC3\xA9 \xC2", 4, None
);
599 test
!(b
"A\xC3\xA9 \xC2 ", 4, Some(1));
600 test
!(b
"A\xC3\xA9 \xC2\xC0", 4, Some(1));
601 test
!(b
"A\xC3\xA9 \xE0", 4, None
);
602 test
!(b
"A\xC3\xA9 \xE0\x9F", 4, Some(1));
603 test
!(b
"A\xC3\xA9 \xE0\xA0", 4, None
);
604 test
!(b
"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
605 test
!(b
"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
606 test
!(b
"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
607 test
!(b
"A\xC3\xA9 \xF1", 4, None
);
608 test
!(b
"A\xC3\xA9 \xF1\x80", 4, None
);
609 test
!(b
"A\xC3\xA9 \xF1\x80\x80", 4, None
);
610 test
!(b
"A\xC3\xA9 \xF1 ", 4, Some(1));
611 test
!(b
"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
612 test
!(b
"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
619 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
620 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
624 assert_eq
!("".as_bytes(), b
);
625 assert_eq
!("abc".as_bytes(), b
"abc");
626 assert_eq
!("ศไทย中华Việt Nam".as_bytes(), v
);
631 fn test_as_bytes_fail() {
632 // Don't double free. (I'm not sure if this exercises the
633 // original problem code path anymore.)
634 let s
= String
::from("");
635 let _bytes
= s
.as_bytes();
641 let buf
= "hello".as_ptr();
643 assert_eq
!(*buf
.offset(0), b'h'
);
644 assert_eq
!(*buf
.offset(1), b'e'
);
645 assert_eq
!(*buf
.offset(2), b'l'
);
646 assert_eq
!(*buf
.offset(3), b'l'
);
647 assert_eq
!(*buf
.offset(4), b'o'
);
652 fn vec_str_conversions() {
653 let s1
: String
= String
::from("All mimsy were the borogoves");
655 let v
: Vec
<u8> = s1
.as_bytes().to_vec();
656 let s2
: String
= String
::from(from_utf8(&v
).unwrap());
662 let a
: u8 = s1
.as_bytes()[i
];
663 let b
: u8 = s2
.as_bytes()[i
];
671 assert
!("abcde".contains("bcd"));
672 assert
!("abcde".contains("abcd"));
673 assert
!("abcde".contains("bcde"));
674 assert
!("abcde".contains(""));
675 assert
!("".contains(""));
676 assert
!(!"abcde".contains("def"));
677 assert
!(!"".contains("a"));
679 let data
= "ประเทศไทย中华Việt Nam";
680 assert
!(data
.contains("ประเ"));
681 assert
!(data
.contains("ะเ"));
682 assert
!(data
.contains("中华"));
683 assert
!(!data
.contains("ไท华"));
687 fn test_contains_char() {
688 assert
!("abc".contains('b'
));
689 assert
!("a".contains('a'
));
690 assert
!(!"abc".contains('d'
));
691 assert
!(!"".contains('a'
));
696 let s
= "ศไทย中华Việt Nam";
697 for (index
, _
) in s
.char_indices() {
698 let (a
, b
) = s
.split_at(index
);
699 assert_eq
!(&s
[..a
.len()], a
);
700 assert_eq
!(&s
[a
.len()..], b
);
702 let (a
, b
) = s
.split_at(s
.len());
708 fn test_split_at_mut() {
709 let mut s
= "Hello World".to_string();
711 let (a
, b
) = s
.split_at_mut(5);
712 a
.make_ascii_uppercase();
713 b
.make_ascii_lowercase();
715 assert_eq
!(s
, "HELLO world");
720 fn test_split_at_boundscheck() {
721 let s
= "ศไทย中华Việt Nam";
726 fn test_escape_unicode() {
727 assert_eq
!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
728 assert_eq
!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
729 assert_eq
!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
730 assert_eq
!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
731 assert_eq
!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
732 assert_eq
!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
733 assert_eq
!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
734 assert_eq
!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
735 assert_eq
!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
739 fn test_escape_debug() {
740 assert_eq
!("abc".escape_debug(), "abc");
741 assert_eq
!("a c".escape_debug(), "a c");
742 assert_eq
!("éèê".escape_debug(), "éèê");
743 assert_eq
!("\r\n\t".escape_debug(), "\\r\\n\\t");
744 assert_eq
!("'\"\\".escape_debug(), "\\'\\\"\\\\");
745 assert_eq
!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
746 assert_eq
!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
747 assert_eq
!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
748 assert_eq
!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
749 assert_eq
!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
753 fn test_escape_default() {
754 assert_eq
!("abc".escape_default(), "abc");
755 assert_eq
!("a c".escape_default(), "a c");
756 assert_eq
!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
757 assert_eq
!("\r\n\t".escape_default(), "\\r\\n\\t");
758 assert_eq
!("'\"\\".escape_default(), "\\'\\\"\\\\");
759 assert_eq
!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
760 assert_eq
!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
761 assert_eq
!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
762 assert_eq
!("ab\u{200b}".escape_default(), "ab\\u{200b}");
763 assert_eq
!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
767 fn test_total_ord() {
768 assert_eq
!("1234".cmp("123"), Greater
);
769 assert_eq
!("123".cmp("1234"), Less
);
770 assert_eq
!("1234".cmp("1234"), Equal
);
771 assert_eq
!("12345555".cmp("123456"), Less
);
772 assert_eq
!("22".cmp("1234"), Greater
);
777 let s
= "ศไทย中华Việt Nam";
778 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
784 assert_eq
!(c
, v
[pos
]);
787 assert_eq
!(pos
, v
.len());
788 assert_eq
!(s
.chars().count(), v
.len());
792 fn test_rev_iterator() {
793 let s
= "ศไทย中华Việt Nam";
794 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
797 let it
= s
.chars().rev();
800 assert_eq
!(c
, v
[pos
]);
803 assert_eq
!(pos
, v
.len());
807 fn test_chars_decoding() {
808 let mut bytes
= [0; 4];
809 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
810 let s
= c
.encode_utf8(&mut bytes
);
811 if Some(c
) != s
.chars().next() {
812 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
818 fn test_chars_rev_decoding() {
819 let mut bytes
= [0; 4];
820 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
821 let s
= c
.encode_utf8(&mut bytes
);
822 if Some(c
) != s
.chars().rev().next() {
823 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
829 fn test_iterator_clone() {
830 let s
= "ศไทย中华Việt Nam";
831 let mut it
= s
.chars();
833 assert
!(it
.clone().zip(it
).all(|(x
,y
)| x
== y
));
837 fn test_iterator_last() {
838 let s
= "ศไทย中华Việt Nam";
839 let mut it
= s
.chars();
841 assert_eq
!(it
.last(), Some('m'
));
845 fn test_bytesator() {
846 let s
= "ศไทย中华Việt Nam";
848 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
849 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
855 assert_eq
!(b
, v
[pos
]);
861 fn test_bytes_revator() {
862 let s
= "ศไทย中华Việt Nam";
864 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
865 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
868 let mut pos
= v
.len();
870 for b
in s
.bytes().rev() {
872 assert_eq
!(b
, v
[pos
]);
877 fn test_bytesator_nth() {
878 let s
= "ศไทย中华Việt Nam";
880 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
881 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
885 let mut b
= s
.bytes();
886 assert_eq
!(b
.nth(2).unwrap(), v
[2]);
887 assert_eq
!(b
.nth(10).unwrap(), v
[10]);
888 assert_eq
!(b
.nth(200), None
);
892 fn test_bytesator_count() {
893 let s
= "ศไทย中华Việt Nam";
896 assert_eq
!(b
.count(), 28)
900 fn test_bytesator_last() {
901 let s
= "ศไทย中华Việt Nam";
904 assert_eq
!(b
.last().unwrap(), 109)
908 fn test_char_indicesator() {
909 let s
= "ศไทย中华Việt Nam";
910 let p
= [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
911 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
914 let it
= s
.char_indices();
917 assert_eq
!(c
, (p
[pos
], v
[pos
]));
920 assert_eq
!(pos
, v
.len());
921 assert_eq
!(pos
, p
.len());
925 fn test_char_indices_revator() {
926 let s
= "ศไทย中华Việt Nam";
927 let p
= [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
928 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
931 let it
= s
.char_indices().rev();
934 assert_eq
!(c
, (p
[pos
], v
[pos
]));
937 assert_eq
!(pos
, v
.len());
938 assert_eq
!(pos
, p
.len());
942 fn test_char_indices_last() {
943 let s
= "ศไทย中华Việt Nam";
944 let mut it
= s
.char_indices();
946 assert_eq
!(it
.last(), Some((27, 'm'
)));
950 fn test_splitn_char_iterator() {
951 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
953 let split
: Vec
<&str> = data
.splitn(4, ' '
).collect();
954 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
956 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== ' '
).collect();
957 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
960 let split
: Vec
<&str> = data
.splitn(4, 'ä'
).collect();
961 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
963 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== 'ä'
).collect();
964 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
968 fn test_split_char_iterator_no_trailing() {
969 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
971 let split
: Vec
<&str> = data
.split('
\n'
).collect();
972 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
974 let split
: Vec
<&str> = data
.split_terminator('
\n'
).collect();
975 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
980 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
982 let split
: Vec
<&str> = data
.rsplit(' '
).collect();
983 assert_eq
!(split
, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
985 let split
: Vec
<&str> = data
.rsplit("lämb").collect();
986 assert_eq
!(split
, ["\n", "\nLittle ", "\nMäry häd ä little "]);
988 let split
: Vec
<&str> = data
.rsplit(|c
: char| c
== 'ä'
).collect();
989 assert_eq
!(split
, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
994 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
996 let split
: Vec
<&str> = data
.rsplitn(2, ' '
).collect();
997 assert_eq
!(split
, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
999 let split
: Vec
<&str> = data
.rsplitn(2, "lämb").collect();
1000 assert_eq
!(split
, ["\n", "\nMäry häd ä little lämb\nLittle "]);
1002 let split
: Vec
<&str> = data
.rsplitn(2, |c
: char| c
== 'ä'
).collect();
1003 assert_eq
!(split
, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
1007 fn test_split_whitespace() {
1008 let data
= "\n \tMäry häd\tä little lämb\nLittle lämb\n";
1009 let words
: Vec
<&str> = data
.split_whitespace().collect();
1010 assert_eq
!(words
, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
1015 let data
= "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
1016 let lines
: Vec
<&str> = data
.lines().collect();
1017 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1019 let data
= "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
1020 let lines
: Vec
<&str> = data
.lines().collect();
1021 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1025 fn test_splitator() {
1026 fn t(s
: &str, sep
: &str, u
: &[&str]) {
1027 let v
: Vec
<&str> = s
.split(sep
).collect();
1030 t("--1233345--", "12345", &["--1233345--"]);
1031 t("abc::hello::there", "::", &["abc", "hello", "there"]);
1032 t("::hello::there", "::", &["", "hello", "there"]);
1033 t("hello::there::", "::", &["hello", "there", ""]);
1034 t("::hello::there::", "::", &["", "hello", "there", ""]);
1035 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
1036 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
1037 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
1038 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
1040 t("zz", "zz", &["",""]);
1041 t("ok", "z", &["ok"]);
1042 t("zzz", "zz", &["","z"]);
1043 t("zzzzz", "zz", &["","","z"]);
1047 fn test_str_default() {
1048 use std
::default::Default
;
1050 fn t
<S
: Default
+ AsRef
<str>>() {
1051 let s
: S
= Default
::default();
1052 assert_eq
!(s
.as_ref(), "");
1060 fn test_str_container() {
1061 fn sum_len(v
: &[&str]) -> usize {
1062 v
.iter().map(|x
| x
.len()).sum()
1066 assert_eq
!(5, sum_len(&["012", "", "34"]));
1067 assert_eq
!(5, sum_len(&["01", "2", "34", ""]));
1068 assert_eq
!(5, sum_len(&[s
]));
1072 fn test_str_from_utf8() {
1074 assert_eq
!(from_utf8(xs
), Ok("hello"));
1076 let xs
= "ศไทย中华Việt Nam".as_bytes();
1077 assert_eq
!(from_utf8(xs
), Ok("ศไทย中华Việt Nam"));
1079 let xs
= b
"hello\xFF";
1080 assert
!(from_utf8(xs
).is_err());
1084 fn test_pattern_deref_forward() {
1085 let data
= "aabcdaa";
1086 assert
!(data
.contains("bcd"));
1087 assert
!(data
.contains(&"bcd"));
1088 assert
!(data
.contains(&"bcd".to_string()));
1092 fn test_empty_match_indices() {
1094 let vec
: Vec
<_
> = data
.match_indices("").collect();
1095 assert_eq
!(vec
, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1099 fn test_bool_from_str() {
1100 assert_eq
!("true".parse().ok(), Some(true));
1101 assert_eq
!("false".parse().ok(), Some(false));
1102 assert_eq
!("not even a boolean".parse
::<bool
>().ok(), None
);
1105 fn check_contains_all_substrings(s
: &str) {
1106 assert
!(s
.contains(""));
1107 for i
in 0..s
.len() {
1108 for j
in i
+1..s
.len() + 1 {
1109 assert
!(s
.contains(&s
[i
..j
]));
1115 fn strslice_issue_16589() {
1116 assert
!("bananas".contains("nana"));
1118 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1119 // test all substrings for good measure
1120 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1124 fn strslice_issue_16878() {
1125 assert
!(!"1234567ah012345678901ah".contains("hah"));
1126 assert
!(!"00abc01234567890123456789abc".contains("bcabc"));
1131 fn test_strslice_contains() {
1132 let x
= "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1133 check_contains_all_substrings(x
);
1137 fn test_rsplitn_char_iterator() {
1138 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1140 let mut split
: Vec
<&str> = data
.rsplitn(4, ' '
).collect();
1142 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1144 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== ' '
).collect();
1146 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1149 let mut split
: Vec
<&str> = data
.rsplitn(4, 'ä'
).collect();
1151 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1153 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== 'ä'
).collect();
1155 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1159 fn test_split_char_iterator() {
1160 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1162 let split
: Vec
<&str> = data
.split(' '
).collect();
1163 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1165 let mut rsplit
: Vec
<&str> = data
.split(' '
).rev().collect();
1167 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1169 let split
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).collect();
1170 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1172 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).rev().collect();
1174 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1177 let split
: Vec
<&str> = data
.split('ä'
).collect();
1178 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1180 let mut rsplit
: Vec
<&str> = data
.split('ä'
).rev().collect();
1182 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1184 let split
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).collect();
1185 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1187 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).rev().collect();
1189 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1193 fn test_rev_split_char_iterator_no_trailing() {
1194 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1196 let mut split
: Vec
<&str> = data
.split('
\n'
).rev().collect();
1198 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1200 let mut split
: Vec
<&str> = data
.split_terminator('
\n'
).rev().collect();
1202 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
1206 fn test_utf16_code_units() {
1207 use std_unicode
::str::Utf16Encoder
;
1208 assert_eq
!(Utf16Encoder
::new(vec
!['é'
, '
\u{1F4A9}'
].into_iter()).collect
::<Vec
<u16>>(),
1209 [0xE9, 0xD83D, 0xDCA9])
1213 fn starts_with_in_unicode() {
1214 assert
!(!"├── Cargo.toml".starts_with("# "));
1218 fn starts_short_long() {
1219 assert
!(!"".starts_with("##"));
1220 assert
!(!"##".starts_with("####"));
1221 assert
!("####".starts_with("##"));
1222 assert
!(!"##ä".starts_with("####"));
1223 assert
!("####ä".starts_with("##"));
1224 assert
!(!"##".starts_with("####ä"));
1225 assert
!("##ä##".starts_with("##ä"));
1227 assert
!("".starts_with(""));
1228 assert
!("ä".starts_with(""));
1229 assert
!("#ä".starts_with(""));
1230 assert
!("##ä".starts_with(""));
1231 assert
!("ä###".starts_with(""));
1232 assert
!("#ä##".starts_with(""));
1233 assert
!("##ä#".starts_with(""));
1237 fn contains_weird_cases() {
1238 assert
!("* \t".contains(' '
));
1239 assert
!(!"* \t".contains('?'
));
1240 assert
!(!"* \t".contains('
\u{1F4A9}'
));
1245 assert_eq
!(" \t a \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1247 assert_eq
!(" \t a \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1249 assert_eq
!(" \t a \t ".trim_matches(|c
: char| c
.is_whitespace()),
1251 assert_eq
!(" \t \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1253 assert_eq
!(" \t \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1255 assert_eq
!(" \t \t ".trim_matches(|c
: char| c
.is_whitespace()),
1261 assert_eq
!("".to_lowercase(), "");
1262 assert_eq
!("AÉDžaé ".to_lowercase(), "aédžaé ");
1264 // https://github.com/rust-lang/rust/issues/26035
1265 assert_eq
!("ΑΣ".to_lowercase(), "ας");
1266 assert_eq
!("Α'Σ".to_lowercase(), "α'ς");
1267 assert_eq
!("Α''Σ".to_lowercase(), "α''ς");
1269 assert_eq
!("ΑΣ Α".to_lowercase(), "ας α");
1270 assert_eq
!("Α'Σ Α".to_lowercase(), "α'ς α");
1271 assert_eq
!("Α''Σ Α".to_lowercase(), "α''ς α");
1273 assert_eq
!("ΑΣ' Α".to_lowercase(), "ας' α");
1274 assert_eq
!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1276 assert_eq
!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1277 assert_eq
!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1279 assert_eq
!("Α Σ".to_lowercase(), "α σ");
1280 assert_eq
!("Α 'Σ".to_lowercase(), "α 'σ");
1281 assert_eq
!("Α ''Σ".to_lowercase(), "α ''σ");
1283 assert_eq
!("Σ".to_lowercase(), "σ");
1284 assert_eq
!("'Σ".to_lowercase(), "'σ");
1285 assert_eq
!("''Σ".to_lowercase(), "''σ");
1287 assert_eq
!("ΑΣΑ".to_lowercase(), "ασα");
1288 assert_eq
!("ΑΣ'Α".to_lowercase(), "ασ'α");
1289 assert_eq
!("ΑΣ''Α".to_lowercase(), "ασ''α");
1294 assert_eq
!("".to_uppercase(), "");
1295 assert_eq
!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1299 fn test_into_string() {
1300 // The only way to acquire a Box<str> in the first place is through a String, so just
1301 // test that we can round-trip between Box<str> and String.
1302 let string
= String
::from("Some text goes here");
1303 assert_eq
!(string
.clone().into_boxed_str().into_string(), string
);
1307 fn test_box_slice_clone() {
1308 let data
= String
::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1309 let data2
= data
.clone().into_boxed_str().clone().into_string();
1311 assert_eq
!(data
, data2
);
1315 fn test_cow_from() {
1316 let borrowed
= "borrowed";
1317 let owned
= String
::from("owned");
1318 match (Cow
::from(owned
.clone()), Cow
::from(borrowed
)) {
1319 (Cow
::Owned(o
), Cow
::Borrowed(b
)) => assert
!(o
== owned
&& b
== borrowed
),
1320 _
=> panic
!("invalid `Cow::from`"),
1326 assert_eq
!("".repeat(3), "");
1327 assert_eq
!("abc".repeat(0), "");
1328 assert_eq
!("α".repeat(3), "ααα");
1332 use std
::str::pattern
::Pattern
;
1333 use std
::str::pattern
::{Searcher, ReverseSearcher}
;
1334 use std
::str::pattern
::SearchStep
::{self, Match, Reject, Done}
;
1336 macro_rules
! make_test
{
1337 ($name
:ident
, $p
:expr
, $h
:expr
, [$
($e
:expr
,)*]) => {
1338 #[allow(unused_imports)]
1340 use std
::str::pattern
::SearchStep
::{Match, Reject}
;
1341 use super::{cmp_search_to_vec}
;
1344 cmp_search_to_vec(false, $p
, $h
, vec
![$
($e
),*]);
1348 cmp_search_to_vec(true, $p
, $h
, vec
![$
($e
),*]);
1354 fn cmp_search_to_vec
<'a
, P
: Pattern
<'a
>>(rev
: bool
, pat
: P
, haystack
: &'a
str,
1355 right
: Vec
<SearchStep
>)
1356 where P
::Searcher
: ReverseSearcher
<'a
>
1358 let mut searcher
= pat
.into_searcher(haystack
);
1361 match if !rev {searcher.next()}
else {searcher.next_back()}
{
1362 Match(a
, b
) => v
.push(Match(a
, b
)),
1363 Reject(a
, b
) => v
.push(Reject(a
, b
)),
1371 let mut first_index
= 0;
1374 for (i
, e
) in right
.iter().enumerate() {
1376 Match(a
, b
) | Reject(a
, b
)
1377 if a
<= b
&& a
== first_index
=> {
1387 if let Some(err
) = err
{
1388 panic
!("Input skipped range at {}", err
);
1391 if first_index
!= haystack
.len() {
1392 panic
!("Did not cover whole input");
1395 assert_eq
!(v
, right
);
1398 make_test
!(str_searcher_ascii_haystack
, "bb", "abbcbbd", [
1405 make_test
!(str_searcher_ascii_haystack_seq
, "bb", "abbcbbbbd", [
1413 make_test
!(str_searcher_empty_needle_ascii_haystack
, "", "abbcbbd", [
1430 make_test
!(str_searcher_mulibyte_haystack
, " ", "├──", [
1435 make_test
!(str_searcher_empty_needle_mulibyte_haystack
, "", "├──", [
1444 make_test
!(str_searcher_empty_needle_empty_haystack
, "", "", [
1447 make_test
!(str_searcher_nonempty_needle_empty_haystack
, "├", "", [
1449 make_test
!(char_searcher_ascii_haystack
, 'b'
, "abbcbbd", [
1458 make_test
!(char_searcher_mulibyte_haystack
, ' '
, "├──", [
1463 make_test
!(char_searcher_short_haystack
, '
\u{1F4A9}'
, "* \t", [
1471 macro_rules
! generate_iterator_test
{
1475 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1478 with $fwd
:expr
, $bwd
:expr
;
1484 let res
= vec
![$
($t
)*];
1486 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1487 assert_eq
!(fwd_vec
, res
);
1489 let mut bwd_vec
: Vec
<_
> = ($bwd
)($
($arg
),*).collect();
1491 assert_eq
!(bwd_vec
, res
);
1499 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1508 let res
= vec
![$
($t
)*];
1510 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1511 assert_eq
!(fwd_vec
, res
);
1518 generate_iterator_test
! {
1519 double_ended_split
{
1520 ("foo.bar.baz", '
.'
) -> ["foo", "bar", "baz"];
1521 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1523 with
str::split
, str::rsplit
;
1526 generate_iterator_test
! {
1527 double_ended_split_terminator
{
1528 ("foo;bar;baz;", '
;'
) -> ["foo", "bar", "baz"];
1530 with
str::split_terminator
, str::rsplit_terminator
;
1533 generate_iterator_test
! {
1534 double_ended_matches
{
1535 ("a1b2c3", char::is_numeric
) -> ["1", "2", "3"];
1537 with
str::matches
, str::rmatches
;
1540 generate_iterator_test
! {
1541 double_ended_match_indices
{
1542 ("a1b2c3", char::is_numeric
) -> [(1, "1"), (3, "2"), (5, "3")];
1544 with
str::match_indices
, str::rmatch_indices
;
1547 generate_iterator_test
! {
1548 not_double_ended_splitn
{
1549 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1554 generate_iterator_test
! {
1555 not_double_ended_rsplitn
{
1556 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1562 fn different_str_pattern_forwarding_lifetimes() {
1563 use std
::str::pattern
::Pattern
;
1565 fn foo
<'a
, P
>(p
: P
) where for<'b
> &'b P
: Pattern
<'a
> {