]> git.proxmox.com Git - rustc.git/blame - src/libcollections/tests/str.rs
New upstream version 1.19.0+dfsg3
[rustc.git] / src / libcollections / tests / str.rs
CommitLineData
9346a6ac 1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
c34b1796
AL
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
7453a54e 11use std::borrow::Cow;
c34b1796 12use std::cmp::Ordering::{Equal, Greater, Less};
62682a34 13use std::str::from_utf8;
c34b1796
AL
14
15#[test]
16fn test_le() {
17 assert!("" <= "");
18 assert!("" <= "foo");
19 assert!("foo" <= "foo");
20 assert!("foo" != "bar");
21}
22
c34b1796
AL
23#[test]
24fn test_find() {
25 assert_eq!("hello".find('l'), Some(2));
26 assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
27 assert!("hello".find('x').is_none());
28 assert!("hello".find(|c:char| c == 'x').is_none());
29 assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
30 assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
31}
32
33#[test]
34fn test_rfind() {
35 assert_eq!("hello".rfind('l'), Some(3));
36 assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
37 assert!("hello".rfind('x').is_none());
38 assert!("hello".rfind(|c:char| c == 'x').is_none());
39 assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
40 assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
41}
42
43#[test]
44fn test_collect() {
b039eaaf 45 let empty = "";
c34b1796
AL
46 let s: String = empty.chars().collect();
47 assert_eq!(empty, s);
b039eaaf 48 let data = "ประเทศไทย中";
c34b1796
AL
49 let s: String = data.chars().collect();
50 assert_eq!(data, s);
51}
52
53#[test]
54fn test_into_bytes() {
62682a34 55 let data = String::from("asdf");
c34b1796
AL
56 let buf = data.into_bytes();
57 assert_eq!(buf, b"asdf");
58}
59
60#[test]
61fn test_find_str() {
62 // byte positions
63 assert_eq!("".find(""), Some(0));
64 assert!("banana".find("apple pie").is_none());
65
66 let data = "abcabc";
67 assert_eq!(data[0..6].find("ab"), Some(0));
68 assert_eq!(data[2..6].find("ab"), Some(3 - 2));
69 assert!(data[2..4].find("ab").is_none());
70
71 let string = "ประเทศไทย中华Việt Nam";
62682a34 72 let mut data = String::from(string);
c34b1796
AL
73 data.push_str(string);
74 assert!(data.find("ไท华").is_none());
75 assert_eq!(data[0..43].find(""), Some(0));
76 assert_eq!(data[6..43].find(""), Some(6 - 6));
77
78 assert_eq!(data[0..43].find("ประ"), Some( 0));
79 assert_eq!(data[0..43].find("ทศไ"), Some(12));
80 assert_eq!(data[0..43].find("ย中"), Some(24));
81 assert_eq!(data[0..43].find("iệt"), Some(34));
82 assert_eq!(data[0..43].find("Nam"), Some(40));
83
84 assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
85 assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
86 assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
87 assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
88 assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
c34b1796 89
b039eaaf 90 // find every substring -- assert that it finds it, or an earlier occurrence.
e9174d1e
SL
91 let string = "Việt Namacbaabcaabaaba";
92 for (i, ci) in string.char_indices() {
93 let ip = i + ci.len_utf8();
94 for j in string[ip..].char_indices()
95 .map(|(i, _)| i)
96 .chain(Some(string.len() - ip))
97 {
98 let pat = &string[i..ip + j];
99 assert!(match string.find(pat) {
100 None => false,
101 Some(x) => x <= i,
102 });
103 assert!(match string.rfind(pat) {
104 None => false,
105 Some(x) => x >= i,
106 });
107 }
c34b1796 108 }
c34b1796
AL
109}
110
111fn s(x: &str) -> String { x.to_string() }
112
113macro_rules! test_concat {
114 ($expected: expr, $string: expr) => {
115 {
116 let s: String = $string.concat();
117 assert_eq!($expected, s);
118 }
119 }
120}
121
122#[test]
123fn test_concat_for_different_types() {
124 test_concat!("ab", vec![s("a"), s("b")]);
125 test_concat!("ab", vec!["a", "b"]);
c34b1796
AL
126}
127
128#[test]
129fn test_concat_for_different_lengths() {
130 let empty: &[&str] = &[];
131 test_concat!("", empty);
132 test_concat!("a", ["a"]);
133 test_concat!("ab", ["a", "b"]);
134 test_concat!("abc", ["", "a", "bc"]);
135}
136
c1a9b12d 137macro_rules! test_join {
c34b1796
AL
138 ($expected: expr, $string: expr, $delim: expr) => {
139 {
c1a9b12d 140 let s = $string.join($delim);
c34b1796
AL
141 assert_eq!($expected, s);
142 }
143 }
144}
145
146#[test]
c1a9b12d
SL
147fn test_join_for_different_types() {
148 test_join!("a-b", ["a", "b"], "-");
c34b1796 149 let hyphen = "-".to_string();
c1a9b12d
SL
150 test_join!("a-b", [s("a"), s("b")], &*hyphen);
151 test_join!("a-b", vec!["a", "b"], &*hyphen);
152 test_join!("a-b", &*vec!["a", "b"], "-");
153 test_join!("a-b", vec![s("a"), s("b")], "-");
c34b1796
AL
154}
155
156#[test]
c1a9b12d 157fn test_join_for_different_lengths() {
c34b1796 158 let empty: &[&str] = &[];
c1a9b12d
SL
159 test_join!("", empty, "-");
160 test_join!("a", ["a"], "-");
161 test_join!("a-b", ["a", "b"], "-");
162 test_join!("-a-bc", ["", "a", "bc"], "-");
c34b1796
AL
163}
164
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
cc61c64b
XL
543#[test]
544fn from_utf8_error() {
545 macro_rules! test {
546 ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
547 let error = from_utf8($input).unwrap_err();
548 assert_eq!(error.valid_up_to(), $expected_valid_up_to);
549 assert_eq!(error.error_len(), $expected_error_len);
550 }
551 }
552 test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
553 test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
554 test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
555 test!(b"A\xC3\xA9 \xC1", 4, Some(1));
556 test!(b"A\xC3\xA9 \xC2", 4, None);
557 test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
558 test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
559 test!(b"A\xC3\xA9 \xE0", 4, None);
560 test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
561 test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
562 test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
563 test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
564 test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
565 test!(b"A\xC3\xA9 \xF1", 4, None);
566 test!(b"A\xC3\xA9 \xF1\x80", 4, None);
567 test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
568 test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
569 test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
570 test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
571}
572
c34b1796
AL
573#[test]
574fn test_as_bytes() {
575 // no null
576 let v = [
577 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
578 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
579 109
580 ];
581 let b: &[u8] = &[];
582 assert_eq!("".as_bytes(), b);
583 assert_eq!("abc".as_bytes(), b"abc");
584 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
585}
586
587#[test]
588#[should_panic]
589fn test_as_bytes_fail() {
590 // Don't double free. (I'm not sure if this exercises the
591 // original problem code path anymore.)
62682a34 592 let s = String::from("");
c34b1796
AL
593 let _bytes = s.as_bytes();
594 panic!();
595}
596
597#[test]
598fn test_as_ptr() {
599 let buf = "hello".as_ptr();
600 unsafe {
601 assert_eq!(*buf.offset(0), b'h');
602 assert_eq!(*buf.offset(1), b'e');
603 assert_eq!(*buf.offset(2), b'l');
604 assert_eq!(*buf.offset(3), b'l');
605 assert_eq!(*buf.offset(4), b'o');
606 }
607}
608
c34b1796
AL
609#[test]
610fn vec_str_conversions() {
62682a34 611 let s1: String = String::from("All mimsy were the borogoves");
c34b1796
AL
612
613 let v: Vec<u8> = s1.as_bytes().to_vec();
62682a34 614 let s2: String = String::from(from_utf8(&v).unwrap());
c34b1796
AL
615 let mut i = 0;
616 let n1 = s1.len();
617 let n2 = v.len();
618 assert_eq!(n1, n2);
619 while i < n1 {
620 let a: u8 = s1.as_bytes()[i];
621 let b: u8 = s2.as_bytes()[i];
c34b1796
AL
622 assert_eq!(a, b);
623 i += 1;
624 }
625}
626
627#[test]
628fn test_contains() {
629 assert!("abcde".contains("bcd"));
630 assert!("abcde".contains("abcd"));
631 assert!("abcde".contains("bcde"));
632 assert!("abcde".contains(""));
633 assert!("".contains(""));
634 assert!(!"abcde".contains("def"));
635 assert!(!"".contains("a"));
636
637 let data = "ประเทศไทย中华Việt Nam";
638 assert!(data.contains("ประเ"));
639 assert!(data.contains("ะเ"));
640 assert!(data.contains("中华"));
641 assert!(!data.contains("ไท华"));
642}
643
644#[test]
645fn test_contains_char() {
646 assert!("abc".contains('b'));
647 assert!("a".contains('a'));
648 assert!(!"abc".contains('d'));
649 assert!(!"".contains('a'));
650}
651
62682a34
SL
652#[test]
653fn test_split_at() {
654 let s = "ศไทย中华Việt Nam";
655 for (index, _) in s.char_indices() {
656 let (a, b) = s.split_at(index);
657 assert_eq!(&s[..a.len()], a);
658 assert_eq!(&s[a.len()..], b);
659 }
660 let (a, b) = s.split_at(s.len());
661 assert_eq!(a, s);
662 assert_eq!(b, "");
663}
664
c1a9b12d
SL
665#[test]
666fn test_split_at_mut() {
667 use std::ascii::AsciiExt;
668 let mut s = "Hello World".to_string();
669 {
670 let (a, b) = s.split_at_mut(5);
671 a.make_ascii_uppercase();
672 b.make_ascii_lowercase();
673 }
674 assert_eq!(s, "HELLO world");
675}
676
62682a34
SL
677#[test]
678#[should_panic]
679fn test_split_at_boundscheck() {
680 let s = "ศไทย中华Việt Nam";
c1a9b12d 681 s.split_at(1);
62682a34
SL
682}
683
c34b1796
AL
684#[test]
685fn test_escape_unicode() {
b039eaaf
SL
686 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
687 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
688 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
689 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
690 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
691 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
692 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
693 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
694 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
c34b1796
AL
695}
696
5bcae85e
SL
697#[test]
698fn test_escape_debug() {
699 assert_eq!("abc".escape_debug(), "abc");
700 assert_eq!("a c".escape_debug(), "a c");
701 assert_eq!("éèê".escape_debug(), "éèê");
702 assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
703 assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
704 assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
705 assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
706 assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
707 assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
708 assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
709}
710
c34b1796
AL
711#[test]
712fn test_escape_default() {
b039eaaf
SL
713 assert_eq!("abc".escape_default(), "abc");
714 assert_eq!("a c".escape_default(), "a c");
5bcae85e 715 assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
b039eaaf
SL
716 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
717 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
5bcae85e 718 assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
b039eaaf
SL
719 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
720 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
5bcae85e
SL
721 assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
722 assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
c34b1796
AL
723}
724
725#[test]
726fn test_total_ord() {
b039eaaf
SL
727 assert_eq!("1234".cmp("123"), Greater);
728 assert_eq!("123".cmp("1234"), Less);
729 assert_eq!("1234".cmp("1234"), Equal);
730 assert_eq!("12345555".cmp("123456"), Less);
731 assert_eq!("22".cmp("1234"), Greater);
c34b1796
AL
732}
733
c34b1796
AL
734#[test]
735fn test_iterator() {
736 let s = "ศไทย中华Việt Nam";
737 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
738
739 let mut pos = 0;
740 let it = s.chars();
741
742 for c in it {
743 assert_eq!(c, v[pos]);
744 pos += 1;
745 }
746 assert_eq!(pos, v.len());
476ff2be 747 assert_eq!(s.chars().count(), v.len());
c34b1796
AL
748}
749
750#[test]
751fn test_rev_iterator() {
752 let s = "ศไทย中华Việt Nam";
753 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
754
755 let mut pos = 0;
756 let it = s.chars().rev();
757
758 for c in it {
759 assert_eq!(c, v[pos]);
760 pos += 1;
761 }
762 assert_eq!(pos, v.len());
763}
764
765#[test]
766fn test_chars_decoding() {
c30ab7b3 767 let mut bytes = [0; 4];
c34b1796 768 for c in (0..0x110000).filter_map(::std::char::from_u32) {
c30ab7b3 769 let s = c.encode_utf8(&mut bytes);
c34b1796
AL
770 if Some(c) != s.chars().next() {
771 panic!("character {:x}={} does not decode correctly", c as u32, c);
772 }
773 }
774}
775
776#[test]
777fn test_chars_rev_decoding() {
c30ab7b3 778 let mut bytes = [0; 4];
c34b1796 779 for c in (0..0x110000).filter_map(::std::char::from_u32) {
c30ab7b3 780 let s = c.encode_utf8(&mut bytes);
c34b1796
AL
781 if Some(c) != s.chars().rev().next() {
782 panic!("character {:x}={} does not decode correctly", c as u32, c);
783 }
784 }
785}
786
787#[test]
788fn test_iterator_clone() {
789 let s = "ศไทย中华Việt Nam";
790 let mut it = s.chars();
791 it.next();
792 assert!(it.clone().zip(it).all(|(x,y)| x == y));
793}
794
476ff2be
SL
795#[test]
796fn test_iterator_last() {
797 let s = "ศไทย中华Việt Nam";
798 let mut it = s.chars();
799 it.next();
800 assert_eq!(it.last(), Some('m'));
801}
802
c34b1796
AL
803#[test]
804fn test_bytesator() {
805 let s = "ศไทย中华Việt Nam";
806 let v = [
807 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
808 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
809 109
810 ];
811 let mut pos = 0;
812
813 for b in s.bytes() {
814 assert_eq!(b, v[pos]);
815 pos += 1;
816 }
817}
818
819#[test]
820fn test_bytes_revator() {
821 let s = "ศไทย中华Việt Nam";
822 let v = [
823 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
824 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
825 109
826 ];
827 let mut pos = v.len();
828
829 for b in s.bytes().rev() {
830 pos -= 1;
831 assert_eq!(b, v[pos]);
832 }
833}
834
e9174d1e
SL
835#[test]
836fn test_bytesator_nth() {
837 let s = "ศไทย中华Việt Nam";
838 let v = [
839 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
840 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
841 109
842 ];
843
844 let mut b = s.bytes();
845 assert_eq!(b.nth(2).unwrap(), v[2]);
846 assert_eq!(b.nth(10).unwrap(), v[10]);
847 assert_eq!(b.nth(200), None);
848}
849
850#[test]
851fn test_bytesator_count() {
852 let s = "ศไทย中华Việt Nam";
853
854 let b = s.bytes();
855 assert_eq!(b.count(), 28)
856}
857
858#[test]
859fn test_bytesator_last() {
860 let s = "ศไทย中华Việt Nam";
861
862 let b = s.bytes();
863 assert_eq!(b.last().unwrap(), 109)
864}
865
c34b1796
AL
866#[test]
867fn test_char_indicesator() {
868 let s = "ศไทย中华Việt Nam";
869 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
870 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
871
872 let mut pos = 0;
873 let it = s.char_indices();
874
875 for c in it {
876 assert_eq!(c, (p[pos], v[pos]));
877 pos += 1;
878 }
879 assert_eq!(pos, v.len());
880 assert_eq!(pos, p.len());
881}
882
883#[test]
884fn test_char_indices_revator() {
885 let s = "ศไทย中华Việt Nam";
886 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
887 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
888
889 let mut pos = 0;
890 let it = s.char_indices().rev();
891
892 for c in it {
893 assert_eq!(c, (p[pos], v[pos]));
894 pos += 1;
895 }
896 assert_eq!(pos, v.len());
897 assert_eq!(pos, p.len());
898}
899
476ff2be
SL
900#[test]
901fn test_char_indices_last() {
902 let s = "ศไทย中华Việt Nam";
903 let mut it = s.char_indices();
904 it.next();
905 assert_eq!(it.last(), Some((27, 'm')));
906}
907
c34b1796
AL
908#[test]
909fn test_splitn_char_iterator() {
910 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
911
912 let split: Vec<&str> = data.splitn(4, ' ').collect();
913 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
914
915 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
916 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
917
918 // Unicode
919 let split: Vec<&str> = data.splitn(4, 'ä').collect();
920 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
921
922 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
923 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
924}
925
926#[test]
927fn test_split_char_iterator_no_trailing() {
928 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
929
930 let split: Vec<&str> = data.split('\n').collect();
931 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
932
933 let split: Vec<&str> = data.split_terminator('\n').collect();
934 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
935}
936
937#[test]
938fn test_rsplit() {
939 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
940
941 let split: Vec<&str> = data.rsplit(' ').collect();
942 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
943
944 let split: Vec<&str> = data.rsplit("lämb").collect();
945 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
946
947 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
948 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
949}
950
951#[test]
952fn test_rsplitn() {
953 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
954
955 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
956 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
957
958 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
959 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
960
961 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
962 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
963}
964
965#[test]
d9579d0f 966fn test_split_whitespace() {
c34b1796 967 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
d9579d0f 968 let words: Vec<&str> = data.split_whitespace().collect();
c34b1796
AL
969 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
970}
971
c34b1796
AL
972#[test]
973fn test_lines() {
e9174d1e 974 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
c34b1796
AL
975 let lines: Vec<&str> = data.lines().collect();
976 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
977
e9174d1e 978 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
c34b1796
AL
979 let lines: Vec<&str> = data.lines().collect();
980 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
981}
982
c34b1796
AL
983#[test]
984fn test_splitator() {
985 fn t(s: &str, sep: &str, u: &[&str]) {
986 let v: Vec<&str> = s.split(sep).collect();
987 assert_eq!(v, u);
988 }
989 t("--1233345--", "12345", &["--1233345--"]);
990 t("abc::hello::there", "::", &["abc", "hello", "there"]);
991 t("::hello::there", "::", &["", "hello", "there"]);
992 t("hello::there::", "::", &["hello", "there", ""]);
993 t("::hello::there::", "::", &["", "hello", "there", ""]);
994 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
995 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
996 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
997 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
998 t("", ".", &[""]);
999 t("zz", "zz", &["",""]);
1000 t("ok", "z", &["ok"]);
1001 t("zzz", "zz", &["","z"]);
1002 t("zzzzz", "zz", &["","","z"]);
1003}
1004
1005#[test]
1006fn test_str_default() {
1007 use std::default::Default;
1008
1009 fn t<S: Default + AsRef<str>>() {
1010 let s: S = Default::default();
1011 assert_eq!(s.as_ref(), "");
1012 }
1013
1014 t::<&str>();
1015 t::<String>();
1016}
1017
1018#[test]
1019fn test_str_container() {
1020 fn sum_len(v: &[&str]) -> usize {
1021 v.iter().map(|x| x.len()).sum()
1022 }
1023
b039eaaf 1024 let s = "01234";
c34b1796 1025 assert_eq!(5, sum_len(&["012", "", "34"]));
b039eaaf
SL
1026 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1027 assert_eq!(5, sum_len(&[s]));
c34b1796
AL
1028}
1029
1030#[test]
1031fn test_str_from_utf8() {
1032 let xs = b"hello";
1033 assert_eq!(from_utf8(xs), Ok("hello"));
1034
1035 let xs = "ศไทย中华Việt Nam".as_bytes();
1036 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1037
1038 let xs = b"hello\xFF";
9346a6ac
AL
1039 assert!(from_utf8(xs).is_err());
1040}
1041
1042#[test]
1043fn test_pattern_deref_forward() {
1044 let data = "aabcdaa";
1045 assert!(data.contains("bcd"));
1046 assert!(data.contains(&"bcd"));
1047 assert!(data.contains(&"bcd".to_string()));
1048}
1049
1050#[test]
1051fn test_empty_match_indices() {
1052 let data = "aä中!";
1053 let vec: Vec<_> = data.match_indices("").collect();
b039eaaf 1054 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
9346a6ac
AL
1055}
1056
1057#[test]
1058fn test_bool_from_str() {
1059 assert_eq!("true".parse().ok(), Some(true));
1060 assert_eq!("false".parse().ok(), Some(false));
1061 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1062}
1063
1064fn check_contains_all_substrings(s: &str) {
1065 assert!(s.contains(""));
1066 for i in 0..s.len() {
1067 for j in i+1..s.len() + 1 {
1068 assert!(s.contains(&s[i..j]));
1069 }
1070 }
1071}
1072
1073#[test]
1074fn strslice_issue_16589() {
1075 assert!("bananas".contains("nana"));
1076
1077 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1078 // test all substrings for good measure
1079 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1080}
1081
1082#[test]
1083fn strslice_issue_16878() {
1084 assert!(!"1234567ah012345678901ah".contains("hah"));
1085 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1086}
1087
1088
1089#[test]
1090fn test_strslice_contains() {
1091 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1092 check_contains_all_substrings(x);
1093}
1094
1095#[test]
1096fn test_rsplitn_char_iterator() {
1097 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1098
1099 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1100 split.reverse();
1101 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1102
1103 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1104 split.reverse();
1105 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1106
1107 // Unicode
1108 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1109 split.reverse();
1110 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1111
1112 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1113 split.reverse();
1114 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1115}
1116
1117#[test]
1118fn test_split_char_iterator() {
1119 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1120
1121 let split: Vec<&str> = data.split(' ').collect();
1122 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1123
1124 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1125 rsplit.reverse();
1126 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1127
1128 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1129 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1130
1131 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1132 rsplit.reverse();
1133 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1134
1135 // Unicode
1136 let split: Vec<&str> = data.split('ä').collect();
1137 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1138
1139 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1140 rsplit.reverse();
1141 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1142
1143 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1144 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1145
1146 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1147 rsplit.reverse();
1148 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1149}
1150
1151#[test]
1152fn test_rev_split_char_iterator_no_trailing() {
1153 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1154
1155 let mut split: Vec<&str> = data.split('\n').rev().collect();
1156 split.reverse();
1157 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1158
1159 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1160 split.reverse();
1161 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1162}
1163
1164#[test]
1165fn test_utf16_code_units() {
476ff2be 1166 use std_unicode::str::Utf16Encoder;
9346a6ac
AL
1167 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1168 [0xE9, 0xD83D, 0xDCA9])
1169}
1170
1171#[test]
1172fn starts_with_in_unicode() {
1173 assert!(!"├── Cargo.toml".starts_with("# "));
1174}
1175
1176#[test]
1177fn starts_short_long() {
1178 assert!(!"".starts_with("##"));
1179 assert!(!"##".starts_with("####"));
1180 assert!("####".starts_with("##"));
1181 assert!(!"##ä".starts_with("####"));
1182 assert!("####ä".starts_with("##"));
1183 assert!(!"##".starts_with("####ä"));
1184 assert!("##ä##".starts_with("##ä"));
1185
1186 assert!("".starts_with(""));
1187 assert!("ä".starts_with(""));
1188 assert!("#ä".starts_with(""));
1189 assert!("##ä".starts_with(""));
1190 assert!("ä###".starts_with(""));
1191 assert!("#ä##".starts_with(""));
1192 assert!("##ä#".starts_with(""));
1193}
1194
1195#[test]
1196fn contains_weird_cases() {
1197 assert!("* \t".contains(' '));
1198 assert!(!"* \t".contains('?'));
1199 assert!(!"* \t".contains('\u{1F4A9}'));
1200}
1201
1202#[test]
1203fn trim_ws() {
1204 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1205 "a \t ");
1206 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1207 " \t a");
1208 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1209 "a");
1210 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1211 "");
1212 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1213 "");
1214 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1215 "");
1216}
1217
62682a34
SL
1218#[test]
1219fn to_lowercase() {
1220 assert_eq!("".to_lowercase(), "");
1221 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1222
1223 // https://github.com/rust-lang/rust/issues/26035
1224 assert_eq!("ΑΣ".to_lowercase(), "ας");
1225 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1226 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1227
1228 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1229 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1230 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1231
1232 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1233 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1234
1235 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1236 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1237
1238 assert_eq!("Α Σ".to_lowercase(), "α σ");
1239 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1240 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1241
1242 assert_eq!("Σ".to_lowercase(), "σ");
1243 assert_eq!("'Σ".to_lowercase(), "'σ");
1244 assert_eq!("''Σ".to_lowercase(), "''σ");
1245
1246 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1247 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1248 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1249}
1250
1251#[test]
1252fn to_uppercase() {
1253 assert_eq!("".to_uppercase(), "");
1254 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1255}
1256
c1a9b12d
SL
1257#[test]
1258fn test_into_string() {
1259 // The only way to acquire a Box<str> in the first place is through a String, so just
1260 // test that we can round-trip between Box<str> and String.
1261 let string = String::from("Some text goes here");
e9174d1e 1262 assert_eq!(string.clone().into_boxed_str().into_string(), string);
c1a9b12d
SL
1263}
1264
1265#[test]
1266fn test_box_slice_clone() {
1267 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
e9174d1e 1268 let data2 = data.clone().into_boxed_str().clone().into_string();
c1a9b12d
SL
1269
1270 assert_eq!(data, data2);
1271}
1272
7453a54e
SL
1273#[test]
1274fn test_cow_from() {
1275 let borrowed = "borrowed";
1276 let owned = String::from("owned");
1277 match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1278 (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1279 _ => panic!("invalid `Cow::from`"),
1280 }
1281}
1282
c30ab7b3
SL
1283#[test]
1284fn test_repeat() {
1285 assert_eq!("".repeat(3), "");
1286 assert_eq!("abc".repeat(0), "");
1287 assert_eq!("α".repeat(3), "ααα");
1288}
1289
9346a6ac
AL
1290mod pattern {
1291 use std::str::pattern::Pattern;
1292 use std::str::pattern::{Searcher, ReverseSearcher};
1293 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1294
1295 macro_rules! make_test {
1296 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
62682a34 1297 #[allow(unused_imports)]
9346a6ac
AL
1298 mod $name {
1299 use std::str::pattern::SearchStep::{Match, Reject};
1300 use super::{cmp_search_to_vec};
1301 #[test]
1302 fn fwd() {
1303 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1304 }
1305 #[test]
1306 fn bwd() {
1307 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1308 }
1309 }
1310 }
1311 }
1312
1313 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1314 right: Vec<SearchStep>)
1315 where P::Searcher: ReverseSearcher<'a>
1316 {
1317 let mut searcher = pat.into_searcher(haystack);
1318 let mut v = vec![];
1319 loop {
1320 match if !rev {searcher.next()} else {searcher.next_back()} {
1321 Match(a, b) => v.push(Match(a, b)),
1322 Reject(a, b) => v.push(Reject(a, b)),
1323 Done => break,
1324 }
1325 }
1326 if rev {
1327 v.reverse();
1328 }
1329
1330 let mut first_index = 0;
1331 let mut err = None;
1332
1333 for (i, e) in right.iter().enumerate() {
1334 match *e {
1335 Match(a, b) | Reject(a, b)
1336 if a <= b && a == first_index => {
1337 first_index = b;
1338 }
1339 _ => {
1340 err = Some(i);
1341 break;
1342 }
1343 }
1344 }
1345
1346 if let Some(err) = err {
1347 panic!("Input skipped range at {}", err);
1348 }
1349
1350 if first_index != haystack.len() {
1351 panic!("Did not cover whole input");
1352 }
1353
1354 assert_eq!(v, right);
1355 }
1356
1357 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1358 Reject(0, 1),
1359 Match (1, 3),
1360 Reject(3, 4),
1361 Match (4, 6),
1362 Reject(6, 7),
1363 ]);
c1a9b12d
SL
1364 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1365 Reject(0, 1),
1366 Match (1, 3),
1367 Reject(3, 4),
1368 Match (4, 6),
1369 Match (6, 8),
1370 Reject(8, 9),
1371 ]);
9346a6ac
AL
1372 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1373 Match (0, 0),
1374 Reject(0, 1),
1375 Match (1, 1),
1376 Reject(1, 2),
1377 Match (2, 2),
1378 Reject(2, 3),
1379 Match (3, 3),
1380 Reject(3, 4),
1381 Match (4, 4),
1382 Reject(4, 5),
1383 Match (5, 5),
1384 Reject(5, 6),
1385 Match (6, 6),
1386 Reject(6, 7),
1387 Match (7, 7),
1388 ]);
1389 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1390 Reject(0, 3),
1391 Reject(3, 6),
1392 Reject(6, 9),
1393 ]);
1394 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1395 Match (0, 0),
1396 Reject(0, 3),
1397 Match (3, 3),
1398 Reject(3, 6),
1399 Match (6, 6),
1400 Reject(6, 9),
1401 Match (9, 9),
1402 ]);
1403 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1404 Match(0, 0),
1405 ]);
1406 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1407 ]);
1408 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1409 Reject(0, 1),
1410 Match (1, 2),
1411 Match (2, 3),
1412 Reject(3, 4),
1413 Match (4, 5),
1414 Match (5, 6),
1415 Reject(6, 7),
1416 ]);
1417 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1418 Reject(0, 3),
1419 Reject(3, 6),
1420 Reject(6, 9),
1421 ]);
1422 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1423 Reject(0, 1),
1424 Reject(1, 2),
1425 Reject(2, 3),
1426 ]);
1427
1428}
1429
1430macro_rules! generate_iterator_test {
1431 {
1432 $name:ident {
1433 $(
1434 ($($arg:expr),*) -> [$($t:tt)*];
1435 )*
1436 }
1437 with $fwd:expr, $bwd:expr;
1438 } => {
1439 #[test]
1440 fn $name() {
1441 $(
1442 {
1443 let res = vec![$($t)*];
1444
1445 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1446 assert_eq!(fwd_vec, res);
1447
1448 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1449 bwd_vec.reverse();
1450 assert_eq!(bwd_vec, res);
1451 }
1452 )*
1453 }
1454 };
1455 {
1456 $name:ident {
1457 $(
1458 ($($arg:expr),*) -> [$($t:tt)*];
1459 )*
1460 }
1461 with $fwd:expr;
1462 } => {
1463 #[test]
1464 fn $name() {
1465 $(
1466 {
1467 let res = vec![$($t)*];
1468
1469 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1470 assert_eq!(fwd_vec, res);
1471 }
1472 )*
1473 }
1474 }
1475}
1476
1477generate_iterator_test! {
1478 double_ended_split {
1479 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1480 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1481 }
1482 with str::split, str::rsplit;
1483}
1484
1485generate_iterator_test! {
1486 double_ended_split_terminator {
1487 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1488 }
1489 with str::split_terminator, str::rsplit_terminator;
1490}
1491
1492generate_iterator_test! {
1493 double_ended_matches {
1494 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1495 }
1496 with str::matches, str::rmatches;
1497}
1498
1499generate_iterator_test! {
1500 double_ended_match_indices {
b039eaaf 1501 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
9346a6ac
AL
1502 }
1503 with str::match_indices, str::rmatch_indices;
1504}
1505
1506generate_iterator_test! {
1507 not_double_ended_splitn {
1508 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1509 }
1510 with str::splitn;
1511}
1512
1513generate_iterator_test! {
1514 not_double_ended_rsplitn {
1515 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1516 }
1517 with str::rsplitn;
c34b1796
AL
1518}
1519
54a0048b
SL
1520#[test]
1521fn different_str_pattern_forwarding_lifetimes() {
1522 use std::str::pattern::Pattern;
1523
1524 fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
1525 for _ in 0..3 {
1526 "asdf".find(&p);
1527 }
1528 }
1529
1530 foo::<&str>("x");
1531}