]> git.proxmox.com Git - rustc.git/blame - src/libcollectionstest/str.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / libcollectionstest / 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
165#[test]
166fn 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();
b039eaaf
SL
189 assert_eq!(half_a_million_letter_a(),
190 unsafe { letters.slice_unchecked(0, 500000)});
c34b1796
AL
191}
192
193#[test]
194fn test_starts_with() {
3157f602
XL
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"));
c34b1796
AL
202}
203
204#[test]
205fn test_ends_with() {
3157f602
XL
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ö"));
c34b1796
AL
213}
214
215#[test]
216fn test_is_empty() {
217 assert!("".is_empty());
218 assert!(!"a".is_empty());
219}
220
9e0c209e
SL
221#[test]
222fn 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
c34b1796
AL
235#[test]
236fn test_replace() {
237 let a = "a";
b039eaaf
SL
238 assert_eq!("".replace(a, "b"), "");
239 assert_eq!("a".replace(a, "b"), "b");
240 assert_eq!("ab".replace(a, "b"), "bb");
c34b1796 241 let test = "test";
b039eaaf
SL
242 assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
243 assert_eq!(" test test ".replace(test, ""), " ");
c34b1796
AL
244}
245
246#[test]
247fn 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]
257fn 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]
267fn 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]
277fn test_replace_2d() {
278 let data = "ประเทศไทย中华";
279 let repl = "دولة الكويت";
280
281 let d = "ไท华";
282 assert_eq!(data.replace(d, repl), data);
283}
284
9cc50fc6
SL
285#[test]
286fn 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
c34b1796
AL
294#[test]
295fn 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();
b039eaaf 326 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
c34b1796
AL
327}
328
329#[test]
330fn 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]
357fn test_slice_fail() {
358 &"中华Việt Nam"[0..2];
359}
360
a7813a04
XL
361
362#[test]
363fn 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}
54a0048b
SL
377const LOREM_PARAGRAPH: &'static str = "\
378Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
379ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
380eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
381sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
382tempus vel, gravida nec quam.";
383
384// check the panic includes the prefix of the sliced string
385#[test]
32a655c1 386#[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
54a0048b
SL
387fn test_slice_fail_truncated_1() {
388 &LOREM_PARAGRAPH[..1024];
389}
390// check the truncation in the panic message
391#[test]
32a655c1 392#[should_panic(expected="luctus, im`[...]")]
54a0048b
SL
393fn test_slice_fail_truncated_2() {
394 &LOREM_PARAGRAPH[..1024];
395}
396
32a655c1
SL
397#[test]
398#[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
399fn 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")]
405fn test_slice_fail_boundary_2() {
406 &"abcαβγ"[2..6];
407}
408
c34b1796
AL
409#[test]
410fn test_slice_from() {
411 assert_eq!(&"abcd"[0..], "abcd");
412 assert_eq!(&"abcd"[2..], "cd");
413 assert_eq!(&"abcd"[4..], "");
414}
415#[test]
416fn test_slice_to() {
417 assert_eq!(&"abcd"[..0], "");
418 assert_eq!(&"abcd"[..2], "ab");
419 assert_eq!(&"abcd"[..4], "abcd");
420}
421
422#[test]
423fn 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]
438fn 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]
453fn 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]
468fn 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]
478fn 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]
488fn 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]
498fn 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
c34b1796
AL
506#[test]
507fn 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
9cc50fc6
SL
531#[test]
532fn 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
c34b1796
AL
543#[test]
544fn 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]
559fn test_as_bytes_fail() {
560 // Don't double free. (I'm not sure if this exercises the
561 // original problem code path anymore.)
62682a34 562 let s = String::from("");
c34b1796
AL
563 let _bytes = s.as_bytes();
564 panic!();
565}
566
567#[test]
568fn 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
c34b1796
AL
579#[test]
580fn vec_str_conversions() {
62682a34 581 let s1: String = String::from("All mimsy were the borogoves");
c34b1796
AL
582
583 let v: Vec<u8> = s1.as_bytes().to_vec();
62682a34 584 let s2: String = String::from(from_utf8(&v).unwrap());
c34b1796
AL
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];
c34b1796
AL
592 assert_eq!(a, b);
593 i += 1;
594 }
595}
596
597#[test]
598fn 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]
615fn test_contains_char() {
616 assert!("abc".contains('b'));
617 assert!("a".contains('a'));
618 assert!(!"abc".contains('d'));
619 assert!(!"".contains('a'));
620}
621
62682a34
SL
622#[test]
623fn 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
c1a9b12d
SL
635#[test]
636fn 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
62682a34
SL
647#[test]
648#[should_panic]
649fn test_split_at_boundscheck() {
650 let s = "ศไทย中华Việt Nam";
c1a9b12d 651 s.split_at(1);
62682a34
SL
652}
653
c34b1796
AL
654#[test]
655fn test_escape_unicode() {
b039eaaf
SL
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}");
c34b1796
AL
665}
666
5bcae85e
SL
667#[test]
668fn 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
c34b1796
AL
681#[test]
682fn test_escape_default() {
b039eaaf
SL
683 assert_eq!("abc".escape_default(), "abc");
684 assert_eq!("a c".escape_default(), "a c");
5bcae85e 685 assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
b039eaaf
SL
686 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
687 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
5bcae85e 688 assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
b039eaaf
SL
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}");
5bcae85e
SL
691 assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
692 assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
c34b1796
AL
693}
694
695#[test]
696fn test_total_ord() {
b039eaaf
SL
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);
c34b1796
AL
702}
703
c34b1796
AL
704#[test]
705fn 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());
476ff2be 717 assert_eq!(s.chars().count(), v.len());
c34b1796
AL
718}
719
720#[test]
721fn 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]
736fn test_chars_decoding() {
c30ab7b3 737 let mut bytes = [0; 4];
c34b1796 738 for c in (0..0x110000).filter_map(::std::char::from_u32) {
c30ab7b3 739 let s = c.encode_utf8(&mut bytes);
c34b1796
AL
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]
747fn test_chars_rev_decoding() {
c30ab7b3 748 let mut bytes = [0; 4];
c34b1796 749 for c in (0..0x110000).filter_map(::std::char::from_u32) {
c30ab7b3 750 let s = c.encode_utf8(&mut bytes);
c34b1796
AL
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]
758fn 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
476ff2be
SL
765#[test]
766fn 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
c34b1796
AL
773#[test]
774fn 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]
790fn 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
e9174d1e
SL
805#[test]
806fn 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]
821fn 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]
829fn test_bytesator_last() {
830 let s = "ศไทย中华Việt Nam";
831
832 let b = s.bytes();
833 assert_eq!(b.last().unwrap(), 109)
834}
835
c34b1796
AL
836#[test]
837fn 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]
854fn 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
476ff2be
SL
870#[test]
871fn 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
c34b1796
AL
878#[test]
879fn 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]
897fn 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]
908fn 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]
922fn 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]
d9579d0f 936fn test_split_whitespace() {
c34b1796 937 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
d9579d0f 938 let words: Vec<&str> = data.split_whitespace().collect();
c34b1796
AL
939 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
940}
941
c34b1796
AL
942#[test]
943fn test_lines() {
e9174d1e 944 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
c34b1796
AL
945 let lines: Vec<&str> = data.lines().collect();
946 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
947
e9174d1e 948 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
c34b1796
AL
949 let lines: Vec<&str> = data.lines().collect();
950 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
951}
952
c34b1796
AL
953#[test]
954fn 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]
976fn 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]
989fn test_str_container() {
990 fn sum_len(v: &[&str]) -> usize {
991 v.iter().map(|x| x.len()).sum()
992 }
993
b039eaaf 994 let s = "01234";
c34b1796 995 assert_eq!(5, sum_len(&["012", "", "34"]));
b039eaaf
SL
996 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
997 assert_eq!(5, sum_len(&[s]));
c34b1796
AL
998}
999
1000#[test]
1001fn 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";
9346a6ac
AL
1009 assert!(from_utf8(xs).is_err());
1010}
1011
1012#[test]
1013fn 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]
1021fn test_empty_match_indices() {
1022 let data = "aä中!";
1023 let vec: Vec<_> = data.match_indices("").collect();
b039eaaf 1024 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
9346a6ac
AL
1025}
1026
1027#[test]
1028fn 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
1034fn 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]
1044fn 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]
1053fn strslice_issue_16878() {
1054 assert!(!"1234567ah012345678901ah".contains("hah"));
1055 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1056}
1057
1058
1059#[test]
1060fn 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]
1066fn 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]
1088fn 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]
1122fn 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]
1135fn test_utf16_code_units() {
476ff2be 1136 use std_unicode::str::Utf16Encoder;
9346a6ac
AL
1137 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1138 [0xE9, 0xD83D, 0xDCA9])
1139}
1140
1141#[test]
1142fn starts_with_in_unicode() {
1143 assert!(!"├── Cargo.toml".starts_with("# "));
1144}
1145
1146#[test]
1147fn 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]
1166fn contains_weird_cases() {
1167 assert!("* \t".contains(' '));
1168 assert!(!"* \t".contains('?'));
1169 assert!(!"* \t".contains('\u{1F4A9}'));
1170}
1171
1172#[test]
1173fn 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
62682a34
SL
1188#[test]
1189fn 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]
1222fn to_uppercase() {
1223 assert_eq!("".to_uppercase(), "");
1224 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1225}
1226
c1a9b12d
SL
1227#[test]
1228fn 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");
e9174d1e 1232 assert_eq!(string.clone().into_boxed_str().into_string(), string);
c1a9b12d
SL
1233}
1234
1235#[test]
1236fn test_box_slice_clone() {
1237 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
e9174d1e 1238 let data2 = data.clone().into_boxed_str().clone().into_string();
c1a9b12d
SL
1239
1240 assert_eq!(data, data2);
1241}
1242
7453a54e
SL
1243#[test]
1244fn 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
c30ab7b3
SL
1253#[test]
1254fn test_repeat() {
1255 assert_eq!("".repeat(3), "");
1256 assert_eq!("abc".repeat(0), "");
1257 assert_eq!("α".repeat(3), "ααα");
1258}
1259
9346a6ac
AL
1260mod 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,)*]) => {
62682a34 1267 #[allow(unused_imports)]
9346a6ac
AL
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 ]);
c1a9b12d
SL
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 ]);
9346a6ac
AL
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
1400macro_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
1447generate_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
1455generate_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
1462generate_iterator_test! {
1463 double_ended_matches {
1464 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1465 }
1466 with str::matches, str::rmatches;
1467}
1468
1469generate_iterator_test! {
1470 double_ended_match_indices {
b039eaaf 1471 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
9346a6ac
AL
1472 }
1473 with str::match_indices, str::rmatch_indices;
1474}
1475
1476generate_iterator_test! {
1477 not_double_ended_splitn {
1478 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1479 }
1480 with str::splitn;
1481}
1482
1483generate_iterator_test! {
1484 not_double_ended_rsplitn {
1485 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1486 }
1487 with str::rsplitn;
c34b1796
AL
1488}
1489
54a0048b
SL
1490#[test]
1491fn 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}