]> git.lizzy.rs Git - rust.git/blob - src/libcollectionstest/str.rs
add inline attributes to stage 0 methods
[rust.git] / src / libcollectionstest / str.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::borrow::Cow;
12 use std::cmp::Ordering::{Equal, Greater, Less};
13 use std::str::from_utf8;
14
15 #[test]
16 fn test_le() {
17     assert!("" <= "");
18     assert!("" <= "foo");
19     assert!("foo" <= "foo");
20     assert!("foo" != "bar");
21 }
22
23 #[test]
24 fn test_find() {
25     assert_eq!("hello".find('l'), Some(2));
26     assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
27     assert!("hello".find('x').is_none());
28     assert!("hello".find(|c:char| c == 'x').is_none());
29     assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
30     assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
31 }
32
33 #[test]
34 fn test_rfind() {
35     assert_eq!("hello".rfind('l'), Some(3));
36     assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
37     assert!("hello".rfind('x').is_none());
38     assert!("hello".rfind(|c:char| c == 'x').is_none());
39     assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
40     assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
41 }
42
43 #[test]
44 fn test_collect() {
45     let empty = "";
46     let s: String = empty.chars().collect();
47     assert_eq!(empty, s);
48     let data = "ประเทศไทย中";
49     let s: String = data.chars().collect();
50     assert_eq!(data, s);
51 }
52
53 #[test]
54 fn test_into_bytes() {
55     let data = String::from("asdf");
56     let buf = data.into_bytes();
57     assert_eq!(buf, b"asdf");
58 }
59
60 #[test]
61 fn test_find_str() {
62     // byte positions
63     assert_eq!("".find(""), Some(0));
64     assert!("banana".find("apple pie").is_none());
65
66     let data = "abcabc";
67     assert_eq!(data[0..6].find("ab"), Some(0));
68     assert_eq!(data[2..6].find("ab"), Some(3 - 2));
69     assert!(data[2..4].find("ab").is_none());
70
71     let string = "ประเทศไทย中华Việt Nam";
72     let mut data = String::from(string);
73     data.push_str(string);
74     assert!(data.find("ไท华").is_none());
75     assert_eq!(data[0..43].find(""), Some(0));
76     assert_eq!(data[6..43].find(""), Some(6 - 6));
77
78     assert_eq!(data[0..43].find("ประ"), Some( 0));
79     assert_eq!(data[0..43].find("ทศไ"), Some(12));
80     assert_eq!(data[0..43].find("ย中"), Some(24));
81     assert_eq!(data[0..43].find("iệt"), Some(34));
82     assert_eq!(data[0..43].find("Nam"), Some(40));
83
84     assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
85     assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
86     assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
87     assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
88     assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
89
90     // find every substring -- assert that it finds it, or an earlier occurrence.
91     let string = "Việt Namacbaabcaabaaba";
92     for (i, ci) in string.char_indices() {
93         let ip = i + ci.len_utf8();
94         for j in string[ip..].char_indices()
95                              .map(|(i, _)| i)
96                              .chain(Some(string.len() - ip))
97         {
98             let pat = &string[i..ip + j];
99             assert!(match string.find(pat) {
100                 None => false,
101                 Some(x) => x <= i,
102             });
103             assert!(match string.rfind(pat) {
104                 None => false,
105                 Some(x) => x >= i,
106             });
107         }
108     }
109 }
110
111 fn s(x: &str) -> String { x.to_string() }
112
113 macro_rules! test_concat {
114     ($expected: expr, $string: expr) => {
115         {
116             let s: String = $string.concat();
117             assert_eq!($expected, s);
118         }
119     }
120 }
121
122 #[test]
123 fn test_concat_for_different_types() {
124     test_concat!("ab", vec![s("a"), s("b")]);
125     test_concat!("ab", vec!["a", "b"]);
126 }
127
128 #[test]
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"]);
135 }
136
137 macro_rules! test_join {
138     ($expected: expr, $string: expr, $delim: expr) => {
139         {
140             let s = $string.join($delim);
141             assert_eq!($expected, s);
142         }
143     }
144 }
145
146 #[test]
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")], "-");
154 }
155
156 #[test]
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"], "-");
163 }
164
165 #[test]
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 {
171         let mut i = 0;
172         let mut rs = String::new();
173         while i < 100000 {
174             rs.push_str("aaaaaaaaaa");
175             i += 1;
176         }
177         rs
178     }
179     fn half_a_million_letter_a() -> String {
180         let mut i = 0;
181         let mut rs = String::new();
182         while i < 100000 {
183             rs.push_str("aaaaa");
184             i += 1;
185         }
186         rs
187     }
188     let letters = a_million_letter_a();
189     assert_eq!(half_a_million_letter_a(),
190         unsafe { letters.slice_unchecked(0, 500000)});
191 }
192
193 #[test]
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"));
202 }
203
204 #[test]
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ö"));
213 }
214
215 #[test]
216 fn test_is_empty() {
217     assert!("".is_empty());
218     assert!(!"a".is_empty());
219 }
220
221 #[test]
222 fn test_replacen() {
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");
226
227     let test = "test";
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), "   ");
231
232     assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
233 }
234
235 #[test]
236 fn test_replace() {
237     let a = "a";
238     assert_eq!("".replace(a, "b"), "");
239     assert_eq!("a".replace(a, "b"), "b");
240     assert_eq!("ab".replace(a, "b"), "bb");
241     let test = "test";
242     assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
243     assert_eq!(" test test ".replace(test, ""), "   ");
244 }
245
246 #[test]
247 fn test_replace_2a() {
248     let data = "ประเทศไทย中华";
249     let repl = "دولة الكويت";
250
251     let a = "ประเ";
252     let a2 = "دولة الكويتทศไทย中华";
253     assert_eq!(data.replace(a, repl), a2);
254 }
255
256 #[test]
257 fn test_replace_2b() {
258     let data = "ประเทศไทย中华";
259     let repl = "دولة الكويت";
260
261     let b = "ะเ";
262     let b2 = "ปรدولة الكويتทศไทย中华";
263     assert_eq!(data.replace(b, repl), b2);
264 }
265
266 #[test]
267 fn test_replace_2c() {
268     let data = "ประเทศไทย中华";
269     let repl = "دولة الكويت";
270
271     let c = "中华";
272     let c2 = "ประเทศไทยدولة الكويت";
273     assert_eq!(data.replace(c, repl), c2);
274 }
275
276 #[test]
277 fn test_replace_2d() {
278     let data = "ประเทศไทย中华";
279     let repl = "دولة الكويت";
280
281     let d = "ไท华";
282     assert_eq!(data.replace(d, repl), data);
283 }
284
285 #[test]
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αβ😺😺😺δ");
292 }
293
294 #[test]
295 fn test_slice() {
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]);
300
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]);
306
307     fn a_million_letter_x() -> String {
308         let mut i = 0;
309         let mut rs = String::new();
310         while i < 100000 {
311             rs.push_str("华华华华华华华华华华");
312             i += 1;
313         }
314         rs
315     }
316     fn half_a_million_letter_x() -> String {
317         let mut i = 0;
318         let mut rs = String::new();
319         while i < 100000 {
320             rs.push_str("华华华华华");
321             i += 1;
322         }
323         rs
324     }
325     let letters = a_million_letter_x();
326     assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
327 }
328
329 #[test]
330 fn test_slice_2() {
331     let ss = "中华Việt Nam";
332
333     assert_eq!("华", &ss[3..6]);
334     assert_eq!("Việt Nam", &ss[6..16]);
335
336     assert_eq!("ab", &"abc"[0..2]);
337     assert_eq!("bc", &"abc"[1..3]);
338     assert_eq!("", &"abc"[1..1]);
339
340     assert_eq!("中", &ss[0..3]);
341     assert_eq!("华V", &ss[3..7]);
342     assert_eq!("", &ss[3..3]);
343     /*0: 中
344       3: 华
345       6: V
346       7: i
347       8: ệ
348      11: t
349      12:
350      13: N
351      14: a
352      15: m */
353 }
354
355 #[test]
356 #[should_panic]
357 fn test_slice_fail() {
358     &"中华Việt Nam"[0..2];
359 }
360
361
362 #[test]
363 fn test_is_char_boundary() {
364     let s = "ศไทย中华Việt Nam β-release 🐱123";
365     assert!(s.is_char_boundary(0));
366     assert!(s.is_char_boundary(s.len()));
367     assert!(!s.is_char_boundary(s.len() + 1));
368     for (i, ch) in s.char_indices() {
369         // ensure character locations are boundaries and continuation bytes are not
370         assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
371         for j in 1..ch.len_utf8() {
372             assert!(!s.is_char_boundary(i + j),
373                     "{} should not be a char boundary in {:?}", i + j, s);
374         }
375     }
376 }
377 const LOREM_PARAGRAPH: &'static str = "\
378 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
379 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
380 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
381 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
382 tempus vel, gravida nec quam.";
383
384 // check the panic includes the prefix of the sliced string
385 #[test]
386 #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
387 fn test_slice_fail_truncated_1() {
388     &LOREM_PARAGRAPH[..1024];
389 }
390 // check the truncation in the panic message
391 #[test]
392 #[should_panic(expected="luctus, im`[...]")]
393 fn test_slice_fail_truncated_2() {
394     &LOREM_PARAGRAPH[..1024];
395 }
396
397 #[test]
398 #[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
399 fn test_slice_fail_boundary_1() {
400     &"abcαβγ"[4..];
401 }
402
403 #[test]
404 #[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
405 fn test_slice_fail_boundary_2() {
406     &"abcαβγ"[2..6];
407 }
408
409 #[test]
410 fn test_slice_from() {
411     assert_eq!(&"abcd"[0..], "abcd");
412     assert_eq!(&"abcd"[2..], "cd");
413     assert_eq!(&"abcd"[4..], "");
414 }
415 #[test]
416 fn test_slice_to() {
417     assert_eq!(&"abcd"[..0], "");
418     assert_eq!(&"abcd"[..2], "ab");
419     assert_eq!(&"abcd"[..4], "abcd");
420 }
421
422 #[test]
423 fn test_trim_left_matches() {
424     let v: &[char] = &[];
425     assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
426     let chars: &[char] = &['*', ' '];
427     assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
428     assert_eq!(" ***  *** ".trim_left_matches(chars), "");
429     assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
430
431     assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
432     let chars: &[char] = &['1', '2'];
433     assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
434     assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
435 }
436
437 #[test]
438 fn test_trim_right_matches() {
439     let v: &[char] = &[];
440     assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
441     let chars: &[char] = &['*', ' '];
442     assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
443     assert_eq!(" ***  *** ".trim_right_matches(chars), "");
444     assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
445
446     assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
447     let chars: &[char] = &['1', '2'];
448     assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
449     assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
450 }
451
452 #[test]
453 fn test_trim_matches() {
454     let v: &[char] = &[];
455     assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
456     let chars: &[char] = &['*', ' '];
457     assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
458     assert_eq!(" ***  *** ".trim_matches(chars), "");
459     assert_eq!("foo".trim_matches(chars), "foo");
460
461     assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
462     let chars: &[char] = &['1', '2'];
463     assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
464     assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
465 }
466
467 #[test]
468 fn test_trim_left() {
469     assert_eq!("".trim_left(), "");
470     assert_eq!("a".trim_left(), "a");
471     assert_eq!("    ".trim_left(), "");
472     assert_eq!("     blah".trim_left(), "blah");
473     assert_eq!("   \u{3000}  wut".trim_left(), "wut");
474     assert_eq!("hey ".trim_left(), "hey ");
475 }
476
477 #[test]
478 fn test_trim_right() {
479     assert_eq!("".trim_right(), "");
480     assert_eq!("a".trim_right(), "a");
481     assert_eq!("    ".trim_right(), "");
482     assert_eq!("blah     ".trim_right(), "blah");
483     assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
484     assert_eq!(" hey".trim_right(), " hey");
485 }
486
487 #[test]
488 fn test_trim() {
489     assert_eq!("".trim(), "");
490     assert_eq!("a".trim(), "a");
491     assert_eq!("    ".trim(), "");
492     assert_eq!("    blah     ".trim(), "blah");
493     assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
494     assert_eq!(" hey dude ".trim(), "hey dude");
495 }
496
497 #[test]
498 fn test_is_whitespace() {
499     assert!("".chars().all(|c| c.is_whitespace()));
500     assert!(" ".chars().all(|c| c.is_whitespace()));
501     assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
502     assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
503     assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
504 }
505
506 #[test]
507 fn test_is_utf8() {
508     // deny overlong encodings
509     assert!(from_utf8(&[0xc0, 0x80]).is_err());
510     assert!(from_utf8(&[0xc0, 0xae]).is_err());
511     assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
512     assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
513     assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
514     assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
515     assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
516
517     // deny surrogates
518     assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
519     assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
520
521     assert!(from_utf8(&[0xC2, 0x80]).is_ok());
522     assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
523     assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
524     assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
525     assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
526     assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
527     assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
528     assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
529 }
530
531 #[test]
532 fn from_utf8_mostly_ascii() {
533     // deny invalid bytes embedded in long stretches of ascii
534     for i in 32..64 {
535         let mut data = [0; 128];
536         data[i] = 0xC0;
537         assert!(from_utf8(&data).is_err());
538         data[i] = 0xC2;
539         assert!(from_utf8(&data).is_err());
540     }
541 }
542
543 #[test]
544 fn test_as_bytes() {
545     // no null
546     let v = [
547         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
548         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
549         109
550     ];
551     let b: &[u8] = &[];
552     assert_eq!("".as_bytes(), b);
553     assert_eq!("abc".as_bytes(), b"abc");
554     assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
555 }
556
557 #[test]
558 #[should_panic]
559 fn test_as_bytes_fail() {
560     // Don't double free. (I'm not sure if this exercises the
561     // original problem code path anymore.)
562     let s = String::from("");
563     let _bytes = s.as_bytes();
564     panic!();
565 }
566
567 #[test]
568 fn test_as_ptr() {
569     let buf = "hello".as_ptr();
570     unsafe {
571         assert_eq!(*buf.offset(0), b'h');
572         assert_eq!(*buf.offset(1), b'e');
573         assert_eq!(*buf.offset(2), b'l');
574         assert_eq!(*buf.offset(3), b'l');
575         assert_eq!(*buf.offset(4), b'o');
576     }
577 }
578
579 #[test]
580 fn vec_str_conversions() {
581     let s1: String = String::from("All mimsy were the borogoves");
582
583     let v: Vec<u8> = s1.as_bytes().to_vec();
584     let s2: String = String::from(from_utf8(&v).unwrap());
585     let mut i = 0;
586     let n1 = s1.len();
587     let n2 = v.len();
588     assert_eq!(n1, n2);
589     while i < n1 {
590         let a: u8 = s1.as_bytes()[i];
591         let b: u8 = s2.as_bytes()[i];
592         assert_eq!(a, b);
593         i += 1;
594     }
595 }
596
597 #[test]
598 fn test_contains() {
599     assert!("abcde".contains("bcd"));
600     assert!("abcde".contains("abcd"));
601     assert!("abcde".contains("bcde"));
602     assert!("abcde".contains(""));
603     assert!("".contains(""));
604     assert!(!"abcde".contains("def"));
605     assert!(!"".contains("a"));
606
607     let data = "ประเทศไทย中华Việt Nam";
608     assert!(data.contains("ประเ"));
609     assert!(data.contains("ะเ"));
610     assert!(data.contains("中华"));
611     assert!(!data.contains("ไท华"));
612 }
613
614 #[test]
615 fn test_contains_char() {
616     assert!("abc".contains('b'));
617     assert!("a".contains('a'));
618     assert!(!"abc".contains('d'));
619     assert!(!"".contains('a'));
620 }
621
622 #[test]
623 fn test_split_at() {
624     let s = "ศไทย中华Việt Nam";
625     for (index, _) in s.char_indices() {
626         let (a, b) = s.split_at(index);
627         assert_eq!(&s[..a.len()], a);
628         assert_eq!(&s[a.len()..], b);
629     }
630     let (a, b) = s.split_at(s.len());
631     assert_eq!(a, s);
632     assert_eq!(b, "");
633 }
634
635 #[test]
636 fn test_split_at_mut() {
637     use std::ascii::AsciiExt;
638     let mut s = "Hello World".to_string();
639     {
640         let (a, b) = s.split_at_mut(5);
641         a.make_ascii_uppercase();
642         b.make_ascii_lowercase();
643     }
644     assert_eq!(s, "HELLO world");
645 }
646
647 #[test]
648 #[should_panic]
649 fn test_split_at_boundscheck() {
650     let s = "ศไทย中华Việt Nam";
651     s.split_at(1);
652 }
653
654 #[test]
655 fn test_escape_unicode() {
656     assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
657     assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
658     assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
659     assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
660     assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
661     assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
662     assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
663     assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
664     assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
665 }
666
667 #[test]
668 fn test_escape_debug() {
669     assert_eq!("abc".escape_debug(), "abc");
670     assert_eq!("a c".escape_debug(), "a c");
671     assert_eq!("éèê".escape_debug(), "éèê");
672     assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
673     assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
674     assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
675     assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
676     assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
677     assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
678     assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
679 }
680
681 #[test]
682 fn test_escape_default() {
683     assert_eq!("abc".escape_default(), "abc");
684     assert_eq!("a c".escape_default(), "a c");
685     assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
686     assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
687     assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
688     assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
689     assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
690     assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
691     assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
692     assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
693 }
694
695 #[test]
696 fn test_total_ord() {
697     assert_eq!("1234".cmp("123"), Greater);
698     assert_eq!("123".cmp("1234"), Less);
699     assert_eq!("1234".cmp("1234"), Equal);
700     assert_eq!("12345555".cmp("123456"), Less);
701     assert_eq!("22".cmp("1234"), Greater);
702 }
703
704 #[test]
705 fn test_iterator() {
706     let s = "ศไทย中华Việt Nam";
707     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
708
709     let mut pos = 0;
710     let it = s.chars();
711
712     for c in it {
713         assert_eq!(c, v[pos]);
714         pos += 1;
715     }
716     assert_eq!(pos, v.len());
717     assert_eq!(s.chars().count(), v.len());
718 }
719
720 #[test]
721 fn test_rev_iterator() {
722     let s = "ศไทย中华Việt Nam";
723     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
724
725     let mut pos = 0;
726     let it = s.chars().rev();
727
728     for c in it {
729         assert_eq!(c, v[pos]);
730         pos += 1;
731     }
732     assert_eq!(pos, v.len());
733 }
734
735 #[test]
736 fn test_chars_decoding() {
737     let mut bytes = [0; 4];
738     for c in (0..0x110000).filter_map(::std::char::from_u32) {
739         let s = c.encode_utf8(&mut bytes);
740         if Some(c) != s.chars().next() {
741             panic!("character {:x}={} does not decode correctly", c as u32, c);
742         }
743     }
744 }
745
746 #[test]
747 fn test_chars_rev_decoding() {
748     let mut bytes = [0; 4];
749     for c in (0..0x110000).filter_map(::std::char::from_u32) {
750         let s = c.encode_utf8(&mut bytes);
751         if Some(c) != s.chars().rev().next() {
752             panic!("character {:x}={} does not decode correctly", c as u32, c);
753         }
754     }
755 }
756
757 #[test]
758 fn test_iterator_clone() {
759     let s = "ศไทย中华Việt Nam";
760     let mut it = s.chars();
761     it.next();
762     assert!(it.clone().zip(it).all(|(x,y)| x == y));
763 }
764
765 #[test]
766 fn test_iterator_last() {
767     let s = "ศไทย中华Việt Nam";
768     let mut it = s.chars();
769     it.next();
770     assert_eq!(it.last(), Some('m'));
771 }
772
773 #[test]
774 fn test_bytesator() {
775     let s = "ศไทย中华Việt Nam";
776     let v = [
777         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
778         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
779         109
780     ];
781     let mut pos = 0;
782
783     for b in s.bytes() {
784         assert_eq!(b, v[pos]);
785         pos += 1;
786     }
787 }
788
789 #[test]
790 fn test_bytes_revator() {
791     let s = "ศไทย中华Việt Nam";
792     let v = [
793         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
794         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
795         109
796     ];
797     let mut pos = v.len();
798
799     for b in s.bytes().rev() {
800         pos -= 1;
801         assert_eq!(b, v[pos]);
802     }
803 }
804
805 #[test]
806 fn test_bytesator_nth() {
807     let s = "ศไทย中华Việt Nam";
808     let v = [
809         224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
810         184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
811         109
812     ];
813
814     let mut b = s.bytes();
815     assert_eq!(b.nth(2).unwrap(), v[2]);
816     assert_eq!(b.nth(10).unwrap(), v[10]);
817     assert_eq!(b.nth(200), None);
818 }
819
820 #[test]
821 fn test_bytesator_count() {
822     let s = "ศไทย中华Việt Nam";
823
824     let b = s.bytes();
825     assert_eq!(b.count(), 28)
826 }
827
828 #[test]
829 fn test_bytesator_last() {
830     let s = "ศไทย中华Việt Nam";
831
832     let b = s.bytes();
833     assert_eq!(b.last().unwrap(), 109)
834 }
835
836 #[test]
837 fn test_char_indicesator() {
838     let s = "ศไทย中华Việt Nam";
839     let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
840     let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
841
842     let mut pos = 0;
843     let it = s.char_indices();
844
845     for c in it {
846         assert_eq!(c, (p[pos], v[pos]));
847         pos += 1;
848     }
849     assert_eq!(pos, v.len());
850     assert_eq!(pos, p.len());
851 }
852
853 #[test]
854 fn test_char_indices_revator() {
855     let s = "ศไทย中华Việt Nam";
856     let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
857     let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
858
859     let mut pos = 0;
860     let it = s.char_indices().rev();
861
862     for c in it {
863         assert_eq!(c, (p[pos], v[pos]));
864         pos += 1;
865     }
866     assert_eq!(pos, v.len());
867     assert_eq!(pos, p.len());
868 }
869
870 #[test]
871 fn test_char_indices_last() {
872     let s = "ศไทย中华Việt Nam";
873     let mut it = s.char_indices();
874     it.next();
875     assert_eq!(it.last(), Some((27, 'm')));
876 }
877
878 #[test]
879 fn test_splitn_char_iterator() {
880     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
881
882     let split: Vec<&str> = data.splitn(4, ' ').collect();
883     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
884
885     let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
886     assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
887
888     // Unicode
889     let split: Vec<&str> = data.splitn(4, 'ä').collect();
890     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
891
892     let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
893     assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
894 }
895
896 #[test]
897 fn test_split_char_iterator_no_trailing() {
898     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
899
900     let split: Vec<&str> = data.split('\n').collect();
901     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
902
903     let split: Vec<&str> = data.split_terminator('\n').collect();
904     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
905 }
906
907 #[test]
908 fn test_rsplit() {
909     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
910
911     let split: Vec<&str> = data.rsplit(' ').collect();
912     assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
913
914     let split: Vec<&str> = data.rsplit("lämb").collect();
915     assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
916
917     let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
918     assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
919 }
920
921 #[test]
922 fn test_rsplitn() {
923     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
924
925     let split: Vec<&str> = data.rsplitn(2, ' ').collect();
926     assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
927
928     let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
929     assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
930
931     let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
932     assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
933 }
934
935 #[test]
936 fn test_split_whitespace() {
937     let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
938     let words: Vec<&str> = data.split_whitespace().collect();
939     assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
940 }
941
942 #[test]
943 fn test_lines() {
944     let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
945     let lines: Vec<&str> = data.lines().collect();
946     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
947
948     let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
949     let lines: Vec<&str> = data.lines().collect();
950     assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
951 }
952
953 #[test]
954 fn test_splitator() {
955     fn t(s: &str, sep: &str, u: &[&str]) {
956         let v: Vec<&str> = s.split(sep).collect();
957         assert_eq!(v, u);
958     }
959     t("--1233345--", "12345", &["--1233345--"]);
960     t("abc::hello::there", "::", &["abc", "hello", "there"]);
961     t("::hello::there", "::", &["", "hello", "there"]);
962     t("hello::there::", "::", &["hello", "there", ""]);
963     t("::hello::there::", "::", &["", "hello", "there", ""]);
964     t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
965     t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
966     t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
967     t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
968     t("", ".", &[""]);
969     t("zz", "zz", &["",""]);
970     t("ok", "z", &["ok"]);
971     t("zzz", "zz", &["","z"]);
972     t("zzzzz", "zz", &["","","z"]);
973 }
974
975 #[test]
976 fn test_str_default() {
977     use std::default::Default;
978
979     fn t<S: Default + AsRef<str>>() {
980         let s: S = Default::default();
981         assert_eq!(s.as_ref(), "");
982     }
983
984     t::<&str>();
985     t::<String>();
986 }
987
988 #[test]
989 fn test_str_container() {
990     fn sum_len(v: &[&str]) -> usize {
991         v.iter().map(|x| x.len()).sum()
992     }
993
994     let s = "01234";
995     assert_eq!(5, sum_len(&["012", "", "34"]));
996     assert_eq!(5, sum_len(&["01", "2", "34", ""]));
997     assert_eq!(5, sum_len(&[s]));
998 }
999
1000 #[test]
1001 fn test_str_from_utf8() {
1002     let xs = b"hello";
1003     assert_eq!(from_utf8(xs), Ok("hello"));
1004
1005     let xs = "ศไทย中华Việt Nam".as_bytes();
1006     assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1007
1008     let xs = b"hello\xFF";
1009     assert!(from_utf8(xs).is_err());
1010 }
1011
1012 #[test]
1013 fn test_pattern_deref_forward() {
1014     let data = "aabcdaa";
1015     assert!(data.contains("bcd"));
1016     assert!(data.contains(&"bcd"));
1017     assert!(data.contains(&"bcd".to_string()));
1018 }
1019
1020 #[test]
1021 fn test_empty_match_indices() {
1022     let data = "aä中!";
1023     let vec: Vec<_> = data.match_indices("").collect();
1024     assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1025 }
1026
1027 #[test]
1028 fn test_bool_from_str() {
1029     assert_eq!("true".parse().ok(), Some(true));
1030     assert_eq!("false".parse().ok(), Some(false));
1031     assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1032 }
1033
1034 fn check_contains_all_substrings(s: &str) {
1035     assert!(s.contains(""));
1036     for i in 0..s.len() {
1037         for j in i+1..s.len() + 1 {
1038             assert!(s.contains(&s[i..j]));
1039         }
1040     }
1041 }
1042
1043 #[test]
1044 fn strslice_issue_16589() {
1045     assert!("bananas".contains("nana"));
1046
1047     // prior to the fix for #16589, x.contains("abcdabcd") returned false
1048     // test all substrings for good measure
1049     check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1050 }
1051
1052 #[test]
1053 fn strslice_issue_16878() {
1054     assert!(!"1234567ah012345678901ah".contains("hah"));
1055     assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1056 }
1057
1058
1059 #[test]
1060 fn test_strslice_contains() {
1061     let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1062     check_contains_all_substrings(x);
1063 }
1064
1065 #[test]
1066 fn test_rsplitn_char_iterator() {
1067     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1068
1069     let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1070     split.reverse();
1071     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1072
1073     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1074     split.reverse();
1075     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1076
1077     // Unicode
1078     let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1079     split.reverse();
1080     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1081
1082     let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1083     split.reverse();
1084     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1085 }
1086
1087 #[test]
1088 fn test_split_char_iterator() {
1089     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1090
1091     let split: Vec<&str> = data.split(' ').collect();
1092     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1093
1094     let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1095     rsplit.reverse();
1096     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1097
1098     let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1099     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1100
1101     let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1102     rsplit.reverse();
1103     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1104
1105     // Unicode
1106     let split: Vec<&str> = data.split('ä').collect();
1107     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1108
1109     let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1110     rsplit.reverse();
1111     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1112
1113     let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1114     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1115
1116     let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1117     rsplit.reverse();
1118     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1119 }
1120
1121 #[test]
1122 fn test_rev_split_char_iterator_no_trailing() {
1123     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1124
1125     let mut split: Vec<&str> = data.split('\n').rev().collect();
1126     split.reverse();
1127     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1128
1129     let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1130     split.reverse();
1131     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1132 }
1133
1134 #[test]
1135 fn test_utf16_code_units() {
1136     use std_unicode::str::Utf16Encoder;
1137     assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1138                [0xE9, 0xD83D, 0xDCA9])
1139 }
1140
1141 #[test]
1142 fn starts_with_in_unicode() {
1143     assert!(!"├── Cargo.toml".starts_with("# "));
1144 }
1145
1146 #[test]
1147 fn starts_short_long() {
1148     assert!(!"".starts_with("##"));
1149     assert!(!"##".starts_with("####"));
1150     assert!("####".starts_with("##"));
1151     assert!(!"##ä".starts_with("####"));
1152     assert!("####ä".starts_with("##"));
1153     assert!(!"##".starts_with("####ä"));
1154     assert!("##ä##".starts_with("##ä"));
1155
1156     assert!("".starts_with(""));
1157     assert!("ä".starts_with(""));
1158     assert!("#ä".starts_with(""));
1159     assert!("##ä".starts_with(""));
1160     assert!("ä###".starts_with(""));
1161     assert!("#ä##".starts_with(""));
1162     assert!("##ä#".starts_with(""));
1163 }
1164
1165 #[test]
1166 fn contains_weird_cases() {
1167     assert!("* \t".contains(' '));
1168     assert!(!"* \t".contains('?'));
1169     assert!(!"* \t".contains('\u{1F4A9}'));
1170 }
1171
1172 #[test]
1173 fn trim_ws() {
1174     assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
1175                     "a \t  ");
1176     assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
1177                " \t  a");
1178     assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
1179                     "a");
1180     assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
1181                          "");
1182     assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
1183                "");
1184     assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
1185                "");
1186 }
1187
1188 #[test]
1189 fn to_lowercase() {
1190     assert_eq!("".to_lowercase(), "");
1191     assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1192
1193     // https://github.com/rust-lang/rust/issues/26035
1194     assert_eq!("ΑΣ".to_lowercase(), "ας");
1195     assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1196     assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1197
1198     assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1199     assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1200     assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1201
1202     assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1203     assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1204
1205     assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1206     assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1207
1208     assert_eq!("Α Σ".to_lowercase(), "α σ");
1209     assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1210     assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1211
1212     assert_eq!("Σ".to_lowercase(), "σ");
1213     assert_eq!("'Σ".to_lowercase(), "'σ");
1214     assert_eq!("''Σ".to_lowercase(), "''σ");
1215
1216     assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1217     assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1218     assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1219 }
1220
1221 #[test]
1222 fn to_uppercase() {
1223     assert_eq!("".to_uppercase(), "");
1224     assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1225 }
1226
1227 #[test]
1228 fn test_into_string() {
1229     // The only way to acquire a Box<str> in the first place is through a String, so just
1230     // test that we can round-trip between Box<str> and String.
1231     let string = String::from("Some text goes here");
1232     assert_eq!(string.clone().into_boxed_str().into_string(), string);
1233 }
1234
1235 #[test]
1236 fn test_box_slice_clone() {
1237     let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1238     let data2 = data.clone().into_boxed_str().clone().into_string();
1239
1240     assert_eq!(data, data2);
1241 }
1242
1243 #[test]
1244 fn test_cow_from() {
1245     let borrowed = "borrowed";
1246     let owned = String::from("owned");
1247     match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1248         (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1249         _ => panic!("invalid `Cow::from`"),
1250     }
1251 }
1252
1253 #[test]
1254 fn test_repeat() {
1255     assert_eq!("".repeat(3), "");
1256     assert_eq!("abc".repeat(0), "");
1257     assert_eq!("α".repeat(3), "ααα");
1258 }
1259
1260 mod pattern {
1261     use std::str::pattern::Pattern;
1262     use std::str::pattern::{Searcher, ReverseSearcher};
1263     use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1264
1265     macro_rules! make_test {
1266         ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1267             #[allow(unused_imports)]
1268             mod $name {
1269                 use std::str::pattern::SearchStep::{Match, Reject};
1270                 use super::{cmp_search_to_vec};
1271                 #[test]
1272                 fn fwd() {
1273                     cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1274                 }
1275                 #[test]
1276                 fn bwd() {
1277                     cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1278                 }
1279             }
1280         }
1281     }
1282
1283     fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1284                                              right: Vec<SearchStep>)
1285     where P::Searcher: ReverseSearcher<'a>
1286     {
1287         let mut searcher = pat.into_searcher(haystack);
1288         let mut v = vec![];
1289         loop {
1290             match if !rev {searcher.next()} else {searcher.next_back()} {
1291                 Match(a, b) => v.push(Match(a, b)),
1292                 Reject(a, b) => v.push(Reject(a, b)),
1293                 Done => break,
1294             }
1295         }
1296         if rev {
1297             v.reverse();
1298         }
1299
1300         let mut first_index = 0;
1301         let mut err = None;
1302
1303         for (i, e) in right.iter().enumerate() {
1304             match *e {
1305                 Match(a, b) | Reject(a, b)
1306                 if a <= b && a == first_index => {
1307                     first_index = b;
1308                 }
1309                 _ => {
1310                     err = Some(i);
1311                     break;
1312                 }
1313             }
1314         }
1315
1316         if let Some(err) = err {
1317             panic!("Input skipped range at {}", err);
1318         }
1319
1320         if first_index != haystack.len() {
1321             panic!("Did not cover whole input");
1322         }
1323
1324         assert_eq!(v, right);
1325     }
1326
1327     make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1328         Reject(0, 1),
1329         Match (1, 3),
1330         Reject(3, 4),
1331         Match (4, 6),
1332         Reject(6, 7),
1333     ]);
1334     make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1335         Reject(0, 1),
1336         Match (1, 3),
1337         Reject(3, 4),
1338         Match (4, 6),
1339         Match (6, 8),
1340         Reject(8, 9),
1341     ]);
1342     make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1343         Match (0, 0),
1344         Reject(0, 1),
1345         Match (1, 1),
1346         Reject(1, 2),
1347         Match (2, 2),
1348         Reject(2, 3),
1349         Match (3, 3),
1350         Reject(3, 4),
1351         Match (4, 4),
1352         Reject(4, 5),
1353         Match (5, 5),
1354         Reject(5, 6),
1355         Match (6, 6),
1356         Reject(6, 7),
1357         Match (7, 7),
1358     ]);
1359     make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1360         Reject(0, 3),
1361         Reject(3, 6),
1362         Reject(6, 9),
1363     ]);
1364     make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1365         Match (0, 0),
1366         Reject(0, 3),
1367         Match (3, 3),
1368         Reject(3, 6),
1369         Match (6, 6),
1370         Reject(6, 9),
1371         Match (9, 9),
1372     ]);
1373     make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1374         Match(0, 0),
1375     ]);
1376     make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1377     ]);
1378     make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1379         Reject(0, 1),
1380         Match (1, 2),
1381         Match (2, 3),
1382         Reject(3, 4),
1383         Match (4, 5),
1384         Match (5, 6),
1385         Reject(6, 7),
1386     ]);
1387     make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1388         Reject(0, 3),
1389         Reject(3, 6),
1390         Reject(6, 9),
1391     ]);
1392     make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1393         Reject(0, 1),
1394         Reject(1, 2),
1395         Reject(2, 3),
1396     ]);
1397
1398 }
1399
1400 macro_rules! generate_iterator_test {
1401     {
1402         $name:ident {
1403             $(
1404                 ($($arg:expr),*) -> [$($t:tt)*];
1405             )*
1406         }
1407         with $fwd:expr, $bwd:expr;
1408     } => {
1409         #[test]
1410         fn $name() {
1411             $(
1412                 {
1413                     let res = vec![$($t)*];
1414
1415                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1416                     assert_eq!(fwd_vec, res);
1417
1418                     let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1419                     bwd_vec.reverse();
1420                     assert_eq!(bwd_vec, res);
1421                 }
1422             )*
1423         }
1424     };
1425     {
1426         $name:ident {
1427             $(
1428                 ($($arg:expr),*) -> [$($t:tt)*];
1429             )*
1430         }
1431         with $fwd:expr;
1432     } => {
1433         #[test]
1434         fn $name() {
1435             $(
1436                 {
1437                     let res = vec![$($t)*];
1438
1439                     let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1440                     assert_eq!(fwd_vec, res);
1441                 }
1442             )*
1443         }
1444     }
1445 }
1446
1447 generate_iterator_test! {
1448     double_ended_split {
1449         ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1450         ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1451     }
1452     with str::split, str::rsplit;
1453 }
1454
1455 generate_iterator_test! {
1456     double_ended_split_terminator {
1457         ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1458     }
1459     with str::split_terminator, str::rsplit_terminator;
1460 }
1461
1462 generate_iterator_test! {
1463     double_ended_matches {
1464         ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1465     }
1466     with str::matches, str::rmatches;
1467 }
1468
1469 generate_iterator_test! {
1470     double_ended_match_indices {
1471         ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1472     }
1473     with str::match_indices, str::rmatch_indices;
1474 }
1475
1476 generate_iterator_test! {
1477     not_double_ended_splitn {
1478         ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1479     }
1480     with str::splitn;
1481 }
1482
1483 generate_iterator_test! {
1484     not_double_ended_rsplitn {
1485         ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1486     }
1487     with str::rsplitn;
1488 }
1489
1490 #[test]
1491 fn different_str_pattern_forwarding_lifetimes() {
1492     use std::str::pattern::Pattern;
1493
1494     fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
1495         for _ in 0..3 {
1496             "asdf".find(&p);
1497         }
1498     }
1499
1500     foo::<&str>("x");
1501 }