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