]>
Commit | Line | Data |
---|---|---|
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 | 11 | use std::borrow::Cow; |
c34b1796 | 12 | use std::cmp::Ordering::{Equal, Greater, Less}; |
62682a34 | 13 | use std::str::from_utf8; |
c34b1796 AL |
14 | |
15 | #[test] | |
16 | fn test_le() { | |
17 | assert!("" <= ""); | |
18 | assert!("" <= "foo"); | |
19 | assert!("foo" <= "foo"); | |
20 | assert!("foo" != "bar"); | |
21 | } | |
22 | ||
c34b1796 AL |
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() { | |
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] | |
54 | fn 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] | |
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"; | |
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 | ||
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 | test_concat!("ab", vec!["a", "b"]); | |
127 | test_concat!("ab", vec![s("a"), s("b")]); | |
128 | } | |
129 | ||
130 | #[test] | |
131 | fn test_concat_for_different_lengths() { | |
132 | let empty: &[&str] = &[]; | |
133 | test_concat!("", empty); | |
134 | test_concat!("a", ["a"]); | |
135 | test_concat!("ab", ["a", "b"]); | |
136 | test_concat!("abc", ["", "a", "bc"]); | |
137 | } | |
138 | ||
c1a9b12d | 139 | macro_rules! test_join { |
c34b1796 AL |
140 | ($expected: expr, $string: expr, $delim: expr) => { |
141 | { | |
c1a9b12d | 142 | let s = $string.join($delim); |
c34b1796 AL |
143 | assert_eq!($expected, s); |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | #[test] | |
c1a9b12d SL |
149 | fn test_join_for_different_types() { |
150 | test_join!("a-b", ["a", "b"], "-"); | |
c34b1796 | 151 | let hyphen = "-".to_string(); |
c1a9b12d SL |
152 | test_join!("a-b", [s("a"), s("b")], &*hyphen); |
153 | test_join!("a-b", vec!["a", "b"], &*hyphen); | |
154 | test_join!("a-b", &*vec!["a", "b"], "-"); | |
155 | test_join!("a-b", vec![s("a"), s("b")], "-"); | |
c34b1796 AL |
156 | } |
157 | ||
158 | #[test] | |
c1a9b12d | 159 | fn test_join_for_different_lengths() { |
c34b1796 | 160 | let empty: &[&str] = &[]; |
c1a9b12d SL |
161 | test_join!("", empty, "-"); |
162 | test_join!("a", ["a"], "-"); | |
163 | test_join!("a-b", ["a", "b"], "-"); | |
164 | test_join!("-a-bc", ["", "a", "bc"], "-"); | |
c34b1796 AL |
165 | } |
166 | ||
167 | #[test] | |
168 | fn test_unsafe_slice() { | |
169 | assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)}); | |
170 | assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)}); | |
171 | assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)}); | |
172 | fn a_million_letter_a() -> String { | |
173 | let mut i = 0; | |
174 | let mut rs = String::new(); | |
175 | while i < 100000 { | |
176 | rs.push_str("aaaaaaaaaa"); | |
177 | i += 1; | |
178 | } | |
179 | rs | |
180 | } | |
181 | fn half_a_million_letter_a() -> String { | |
182 | let mut i = 0; | |
183 | let mut rs = String::new(); | |
184 | while i < 100000 { | |
185 | rs.push_str("aaaaa"); | |
186 | i += 1; | |
187 | } | |
188 | rs | |
189 | } | |
190 | let letters = a_million_letter_a(); | |
b039eaaf SL |
191 | assert_eq!(half_a_million_letter_a(), |
192 | unsafe { letters.slice_unchecked(0, 500000)}); | |
c34b1796 AL |
193 | } |
194 | ||
195 | #[test] | |
196 | fn test_starts_with() { | |
197 | assert!(("".starts_with(""))); | |
198 | assert!(("abc".starts_with(""))); | |
199 | assert!(("abc".starts_with("a"))); | |
200 | assert!((!"a".starts_with("abc"))); | |
201 | assert!((!"".starts_with("abc"))); | |
202 | assert!((!"ödd".starts_with("-"))); | |
203 | assert!(("ödd".starts_with("öd"))); | |
204 | } | |
205 | ||
206 | #[test] | |
207 | fn test_ends_with() { | |
208 | assert!(("".ends_with(""))); | |
209 | assert!(("abc".ends_with(""))); | |
210 | assert!(("abc".ends_with("c"))); | |
211 | assert!((!"a".ends_with("abc"))); | |
212 | assert!((!"".ends_with("abc"))); | |
213 | assert!((!"ddö".ends_with("-"))); | |
214 | assert!(("ddö".ends_with("dö"))); | |
215 | } | |
216 | ||
217 | #[test] | |
218 | fn test_is_empty() { | |
219 | assert!("".is_empty()); | |
220 | assert!(!"a".is_empty()); | |
221 | } | |
222 | ||
223 | #[test] | |
224 | fn test_replace() { | |
225 | let a = "a"; | |
b039eaaf SL |
226 | assert_eq!("".replace(a, "b"), ""); |
227 | assert_eq!("a".replace(a, "b"), "b"); | |
228 | assert_eq!("ab".replace(a, "b"), "bb"); | |
c34b1796 | 229 | let test = "test"; |
b039eaaf SL |
230 | assert_eq!(" test test ".replace(test, "toast"), " toast toast "); |
231 | assert_eq!(" test test ".replace(test, ""), " "); | |
c34b1796 AL |
232 | } |
233 | ||
234 | #[test] | |
235 | fn test_replace_2a() { | |
236 | let data = "ประเทศไทย中华"; | |
237 | let repl = "دولة الكويت"; | |
238 | ||
239 | let a = "ประเ"; | |
240 | let a2 = "دولة الكويتทศไทย中华"; | |
241 | assert_eq!(data.replace(a, repl), a2); | |
242 | } | |
243 | ||
244 | #[test] | |
245 | fn test_replace_2b() { | |
246 | let data = "ประเทศไทย中华"; | |
247 | let repl = "دولة الكويت"; | |
248 | ||
249 | let b = "ะเ"; | |
250 | let b2 = "ปรدولة الكويتทศไทย中华"; | |
251 | assert_eq!(data.replace(b, repl), b2); | |
252 | } | |
253 | ||
254 | #[test] | |
255 | fn test_replace_2c() { | |
256 | let data = "ประเทศไทย中华"; | |
257 | let repl = "دولة الكويت"; | |
258 | ||
259 | let c = "中华"; | |
260 | let c2 = "ประเทศไทยدولة الكويت"; | |
261 | assert_eq!(data.replace(c, repl), c2); | |
262 | } | |
263 | ||
264 | #[test] | |
265 | fn test_replace_2d() { | |
266 | let data = "ประเทศไทย中华"; | |
267 | let repl = "دولة الكويت"; | |
268 | ||
269 | let d = "ไท华"; | |
270 | assert_eq!(data.replace(d, repl), data); | |
271 | } | |
272 | ||
9cc50fc6 SL |
273 | #[test] |
274 | fn test_replace_pattern() { | |
275 | let data = "abcdαβγδabcdαβγδ"; | |
276 | assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ"); | |
277 | assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ"); | |
278 | assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ"); | |
279 | assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ"); | |
280 | } | |
281 | ||
c34b1796 AL |
282 | #[test] |
283 | fn test_slice() { | |
284 | assert_eq!("ab", &"abc"[0..2]); | |
285 | assert_eq!("bc", &"abc"[1..3]); | |
286 | assert_eq!("", &"abc"[1..1]); | |
287 | assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]); | |
288 | ||
289 | let data = "ประเทศไทย中华"; | |
290 | assert_eq!("ป", &data[0..3]); | |
291 | assert_eq!("ร", &data[3..6]); | |
292 | assert_eq!("", &data[3..3]); | |
293 | assert_eq!("华", &data[30..33]); | |
294 | ||
295 | fn a_million_letter_x() -> String { | |
296 | let mut i = 0; | |
297 | let mut rs = String::new(); | |
298 | while i < 100000 { | |
299 | rs.push_str("华华华华华华华华华华"); | |
300 | i += 1; | |
301 | } | |
302 | rs | |
303 | } | |
304 | fn half_a_million_letter_x() -> String { | |
305 | let mut i = 0; | |
306 | let mut rs = String::new(); | |
307 | while i < 100000 { | |
308 | rs.push_str("华华华华华"); | |
309 | i += 1; | |
310 | } | |
311 | rs | |
312 | } | |
313 | let letters = a_million_letter_x(); | |
b039eaaf | 314 | assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]); |
c34b1796 AL |
315 | } |
316 | ||
317 | #[test] | |
318 | fn test_slice_2() { | |
319 | let ss = "中华Việt Nam"; | |
320 | ||
321 | assert_eq!("华", &ss[3..6]); | |
322 | assert_eq!("Việt Nam", &ss[6..16]); | |
323 | ||
324 | assert_eq!("ab", &"abc"[0..2]); | |
325 | assert_eq!("bc", &"abc"[1..3]); | |
326 | assert_eq!("", &"abc"[1..1]); | |
327 | ||
328 | assert_eq!("中", &ss[0..3]); | |
329 | assert_eq!("华V", &ss[3..7]); | |
330 | assert_eq!("", &ss[3..3]); | |
331 | /*0: 中 | |
332 | 3: 华 | |
333 | 6: V | |
334 | 7: i | |
335 | 8: ệ | |
336 | 11: t | |
337 | 12: | |
338 | 13: N | |
339 | 14: a | |
340 | 15: m */ | |
341 | } | |
342 | ||
343 | #[test] | |
344 | #[should_panic] | |
345 | fn test_slice_fail() { | |
346 | &"中华Việt Nam"[0..2]; | |
347 | } | |
348 | ||
54a0048b SL |
349 | const LOREM_PARAGRAPH: &'static str = "\ |
350 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ | |
351 | ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ | |
352 | eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \ | |
353 | sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \ | |
354 | tempus vel, gravida nec quam."; | |
355 | ||
356 | // check the panic includes the prefix of the sliced string | |
357 | #[test] | |
358 | #[should_panic(expected="Lorem ipsum dolor sit amet")] | |
359 | fn test_slice_fail_truncated_1() { | |
360 | &LOREM_PARAGRAPH[..1024]; | |
361 | } | |
362 | // check the truncation in the panic message | |
363 | #[test] | |
364 | #[should_panic(expected="luctus, im`[...] do not lie on character boundary")] | |
365 | fn test_slice_fail_truncated_2() { | |
366 | &LOREM_PARAGRAPH[..1024]; | |
367 | } | |
368 | ||
c34b1796 AL |
369 | #[test] |
370 | fn test_slice_from() { | |
371 | assert_eq!(&"abcd"[0..], "abcd"); | |
372 | assert_eq!(&"abcd"[2..], "cd"); | |
373 | assert_eq!(&"abcd"[4..], ""); | |
374 | } | |
375 | #[test] | |
376 | fn test_slice_to() { | |
377 | assert_eq!(&"abcd"[..0], ""); | |
378 | assert_eq!(&"abcd"[..2], "ab"); | |
379 | assert_eq!(&"abcd"[..4], "abcd"); | |
380 | } | |
381 | ||
382 | #[test] | |
383 | fn test_trim_left_matches() { | |
384 | let v: &[char] = &[]; | |
385 | assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** "); | |
386 | let chars: &[char] = &['*', ' ']; | |
387 | assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** "); | |
388 | assert_eq!(" *** *** ".trim_left_matches(chars), ""); | |
389 | assert_eq!("foo *** ".trim_left_matches(chars), "foo *** "); | |
390 | ||
391 | assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11"); | |
392 | let chars: &[char] = &['1', '2']; | |
393 | assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12"); | |
394 | assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123"); | |
395 | } | |
396 | ||
397 | #[test] | |
398 | fn test_trim_right_matches() { | |
399 | let v: &[char] = &[]; | |
400 | assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** "); | |
401 | let chars: &[char] = &['*', ' ']; | |
402 | assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo"); | |
403 | assert_eq!(" *** *** ".trim_right_matches(chars), ""); | |
404 | assert_eq!(" *** foo".trim_right_matches(chars), " *** foo"); | |
405 | ||
406 | assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar"); | |
407 | let chars: &[char] = &['1', '2']; | |
408 | assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar"); | |
409 | assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar"); | |
410 | } | |
411 | ||
412 | #[test] | |
413 | fn test_trim_matches() { | |
414 | let v: &[char] = &[]; | |
415 | assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** "); | |
416 | let chars: &[char] = &['*', ' ']; | |
417 | assert_eq!(" *** foo *** ".trim_matches(chars), "foo"); | |
418 | assert_eq!(" *** *** ".trim_matches(chars), ""); | |
419 | assert_eq!("foo".trim_matches(chars), "foo"); | |
420 | ||
421 | assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar"); | |
422 | let chars: &[char] = &['1', '2']; | |
423 | assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar"); | |
424 | assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar"); | |
425 | } | |
426 | ||
427 | #[test] | |
428 | fn test_trim_left() { | |
429 | assert_eq!("".trim_left(), ""); | |
430 | assert_eq!("a".trim_left(), "a"); | |
431 | assert_eq!(" ".trim_left(), ""); | |
432 | assert_eq!(" blah".trim_left(), "blah"); | |
433 | assert_eq!(" \u{3000} wut".trim_left(), "wut"); | |
434 | assert_eq!("hey ".trim_left(), "hey "); | |
435 | } | |
436 | ||
437 | #[test] | |
438 | fn test_trim_right() { | |
439 | assert_eq!("".trim_right(), ""); | |
440 | assert_eq!("a".trim_right(), "a"); | |
441 | assert_eq!(" ".trim_right(), ""); | |
442 | assert_eq!("blah ".trim_right(), "blah"); | |
443 | assert_eq!("wut \u{3000} ".trim_right(), "wut"); | |
444 | assert_eq!(" hey".trim_right(), " hey"); | |
445 | } | |
446 | ||
447 | #[test] | |
448 | fn test_trim() { | |
449 | assert_eq!("".trim(), ""); | |
450 | assert_eq!("a".trim(), "a"); | |
451 | assert_eq!(" ".trim(), ""); | |
452 | assert_eq!(" blah ".trim(), "blah"); | |
453 | assert_eq!("\nwut \u{3000} ".trim(), "wut"); | |
454 | assert_eq!(" hey dude ".trim(), "hey dude"); | |
455 | } | |
456 | ||
457 | #[test] | |
458 | fn test_is_whitespace() { | |
459 | assert!("".chars().all(|c| c.is_whitespace())); | |
460 | assert!(" ".chars().all(|c| c.is_whitespace())); | |
461 | assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space | |
462 | assert!(" \n\t ".chars().all(|c| c.is_whitespace())); | |
463 | assert!(!" _ ".chars().all(|c| c.is_whitespace())); | |
464 | } | |
465 | ||
466 | #[test] | |
54a0048b | 467 | #[allow(deprecated)] |
c34b1796 AL |
468 | fn test_slice_shift_char() { |
469 | let data = "ประเทศไทย中"; | |
470 | assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中"))); | |
471 | } | |
472 | ||
473 | #[test] | |
54a0048b | 474 | #[allow(deprecated)] |
c34b1796 AL |
475 | fn test_slice_shift_char_2() { |
476 | let empty = ""; | |
477 | assert_eq!(empty.slice_shift_char(), None); | |
478 | } | |
479 | ||
480 | #[test] | |
481 | fn test_is_utf8() { | |
482 | // deny overlong encodings | |
483 | assert!(from_utf8(&[0xc0, 0x80]).is_err()); | |
484 | assert!(from_utf8(&[0xc0, 0xae]).is_err()); | |
485 | assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err()); | |
486 | assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err()); | |
487 | assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err()); | |
488 | assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err()); | |
489 | assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err()); | |
490 | ||
491 | // deny surrogates | |
492 | assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err()); | |
493 | assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err()); | |
494 | ||
495 | assert!(from_utf8(&[0xC2, 0x80]).is_ok()); | |
496 | assert!(from_utf8(&[0xDF, 0xBF]).is_ok()); | |
497 | assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok()); | |
498 | assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok()); | |
499 | assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok()); | |
500 | assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok()); | |
501 | assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok()); | |
502 | assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok()); | |
503 | } | |
504 | ||
9cc50fc6 SL |
505 | #[test] |
506 | fn from_utf8_mostly_ascii() { | |
507 | // deny invalid bytes embedded in long stretches of ascii | |
508 | for i in 32..64 { | |
509 | let mut data = [0; 128]; | |
510 | data[i] = 0xC0; | |
511 | assert!(from_utf8(&data).is_err()); | |
512 | data[i] = 0xC2; | |
513 | assert!(from_utf8(&data).is_err()); | |
514 | } | |
515 | } | |
516 | ||
c34b1796 AL |
517 | #[test] |
518 | fn test_is_utf16() { | |
d9579d0f | 519 | use rustc_unicode::str::is_utf16; |
c34b1796 AL |
520 | |
521 | macro_rules! pos { | |
522 | ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } } | |
523 | } | |
524 | ||
525 | // non-surrogates | |
526 | pos!(&[0x0000], | |
527 | &[0x0001, 0x0002], | |
528 | &[0xD7FF], | |
529 | &[0xE000]); | |
530 | ||
531 | // surrogate pairs (randomly generated with Python 3's | |
532 | // .encode('utf-16be')) | |
533 | pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45], | |
534 | &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14], | |
535 | &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]); | |
536 | ||
537 | // mixtures (also random) | |
538 | pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65], | |
539 | &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006], | |
540 | &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]); | |
541 | ||
542 | // negative tests | |
543 | macro_rules! neg { | |
544 | ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } } | |
545 | } | |
546 | ||
547 | neg!( | |
548 | // surrogate + regular unit | |
549 | &[0xdb45, 0x0000], | |
550 | // surrogate + lead surrogate | |
551 | &[0xd900, 0xd900], | |
552 | // unterminated surrogate | |
553 | &[0xd8ff], | |
554 | // trail surrogate without a lead | |
555 | &[0xddb7]); | |
556 | ||
557 | // random byte sequences that Python 3's .decode('utf-16be') | |
558 | // failed on | |
559 | neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7], | |
560 | &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3], | |
561 | &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca], | |
562 | &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278], | |
563 | &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e], | |
564 | &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5], | |
565 | &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee], | |
566 | &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7], | |
567 | &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a], | |
568 | &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a], | |
569 | &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe], | |
570 | &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf], | |
571 | &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e], | |
572 | &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5], | |
573 | &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f], | |
574 | &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b], | |
575 | &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7], | |
576 | &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9], | |
577 | &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8], | |
578 | &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282], | |
579 | &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]); | |
580 | } | |
581 | ||
582 | #[test] | |
583 | fn test_as_bytes() { | |
584 | // no null | |
585 | let v = [ | |
586 | 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, | |
587 | 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, | |
588 | 109 | |
589 | ]; | |
590 | let b: &[u8] = &[]; | |
591 | assert_eq!("".as_bytes(), b); | |
592 | assert_eq!("abc".as_bytes(), b"abc"); | |
593 | assert_eq!("ศไทย中华Việt Nam".as_bytes(), v); | |
594 | } | |
595 | ||
596 | #[test] | |
597 | #[should_panic] | |
598 | fn test_as_bytes_fail() { | |
599 | // Don't double free. (I'm not sure if this exercises the | |
600 | // original problem code path anymore.) | |
62682a34 | 601 | let s = String::from(""); |
c34b1796 AL |
602 | let _bytes = s.as_bytes(); |
603 | panic!(); | |
604 | } | |
605 | ||
606 | #[test] | |
607 | fn test_as_ptr() { | |
608 | let buf = "hello".as_ptr(); | |
609 | unsafe { | |
610 | assert_eq!(*buf.offset(0), b'h'); | |
611 | assert_eq!(*buf.offset(1), b'e'); | |
612 | assert_eq!(*buf.offset(2), b'l'); | |
613 | assert_eq!(*buf.offset(3), b'l'); | |
614 | assert_eq!(*buf.offset(4), b'o'); | |
615 | } | |
616 | } | |
617 | ||
c34b1796 AL |
618 | #[test] |
619 | fn vec_str_conversions() { | |
62682a34 | 620 | let s1: String = String::from("All mimsy were the borogoves"); |
c34b1796 AL |
621 | |
622 | let v: Vec<u8> = s1.as_bytes().to_vec(); | |
62682a34 | 623 | let s2: String = String::from(from_utf8(&v).unwrap()); |
c34b1796 AL |
624 | let mut i = 0; |
625 | let n1 = s1.len(); | |
626 | let n2 = v.len(); | |
627 | assert_eq!(n1, n2); | |
628 | while i < n1 { | |
629 | let a: u8 = s1.as_bytes()[i]; | |
630 | let b: u8 = s2.as_bytes()[i]; | |
c34b1796 AL |
631 | assert_eq!(a, b); |
632 | i += 1; | |
633 | } | |
634 | } | |
635 | ||
636 | #[test] | |
637 | fn test_contains() { | |
638 | assert!("abcde".contains("bcd")); | |
639 | assert!("abcde".contains("abcd")); | |
640 | assert!("abcde".contains("bcde")); | |
641 | assert!("abcde".contains("")); | |
642 | assert!("".contains("")); | |
643 | assert!(!"abcde".contains("def")); | |
644 | assert!(!"".contains("a")); | |
645 | ||
646 | let data = "ประเทศไทย中华Việt Nam"; | |
647 | assert!(data.contains("ประเ")); | |
648 | assert!(data.contains("ะเ")); | |
649 | assert!(data.contains("中华")); | |
650 | assert!(!data.contains("ไท华")); | |
651 | } | |
652 | ||
653 | #[test] | |
654 | fn test_contains_char() { | |
655 | assert!("abc".contains('b')); | |
656 | assert!("a".contains('a')); | |
657 | assert!(!"abc".contains('d')); | |
658 | assert!(!"".contains('a')); | |
659 | } | |
660 | ||
661 | #[test] | |
54a0048b | 662 | #[allow(deprecated)] |
c34b1796 AL |
663 | fn test_char_at() { |
664 | let s = "ศไทย中华Việt Nam"; | |
665 | let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; | |
666 | let mut pos = 0; | |
667 | for ch in &v { | |
668 | assert!(s.char_at(pos) == *ch); | |
669 | pos += ch.to_string().len(); | |
670 | } | |
671 | } | |
672 | ||
673 | #[test] | |
54a0048b | 674 | #[allow(deprecated)] |
c34b1796 AL |
675 | fn test_char_at_reverse() { |
676 | let s = "ศไทย中华Việt Nam"; | |
677 | let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; | |
678 | let mut pos = s.len(); | |
679 | for ch in v.iter().rev() { | |
680 | assert!(s.char_at_reverse(pos) == *ch); | |
681 | pos -= ch.to_string().len(); | |
682 | } | |
683 | } | |
684 | ||
62682a34 SL |
685 | #[test] |
686 | fn test_split_at() { | |
687 | let s = "ศไทย中华Việt Nam"; | |
688 | for (index, _) in s.char_indices() { | |
689 | let (a, b) = s.split_at(index); | |
690 | assert_eq!(&s[..a.len()], a); | |
691 | assert_eq!(&s[a.len()..], b); | |
692 | } | |
693 | let (a, b) = s.split_at(s.len()); | |
694 | assert_eq!(a, s); | |
695 | assert_eq!(b, ""); | |
696 | } | |
697 | ||
c1a9b12d SL |
698 | #[test] |
699 | fn test_split_at_mut() { | |
700 | use std::ascii::AsciiExt; | |
701 | let mut s = "Hello World".to_string(); | |
702 | { | |
703 | let (a, b) = s.split_at_mut(5); | |
704 | a.make_ascii_uppercase(); | |
705 | b.make_ascii_lowercase(); | |
706 | } | |
707 | assert_eq!(s, "HELLO world"); | |
708 | } | |
709 | ||
62682a34 SL |
710 | #[test] |
711 | #[should_panic] | |
712 | fn test_split_at_boundscheck() { | |
713 | let s = "ศไทย中华Việt Nam"; | |
c1a9b12d | 714 | s.split_at(1); |
62682a34 SL |
715 | } |
716 | ||
c34b1796 AL |
717 | #[test] |
718 | fn test_escape_unicode() { | |
b039eaaf SL |
719 | assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}"); |
720 | assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}"); | |
721 | assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}"); | |
722 | assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}"); | |
723 | assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}"); | |
724 | assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}"); | |
725 | assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}"); | |
726 | assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}"); | |
727 | assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}"); | |
c34b1796 AL |
728 | } |
729 | ||
730 | #[test] | |
731 | fn test_escape_default() { | |
b039eaaf SL |
732 | assert_eq!("abc".escape_default(), "abc"); |
733 | assert_eq!("a c".escape_default(), "a c"); | |
734 | assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t"); | |
735 | assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\"); | |
736 | assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}"); | |
737 | assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}"); | |
738 | assert_eq!("ab\u{fb00}".escape_default(), "ab\\u{fb00}"); | |
739 | assert_eq!("\u{1d4ea}\r".escape_default(), "\\u{1d4ea}\\r"); | |
c34b1796 AL |
740 | } |
741 | ||
742 | #[test] | |
743 | fn test_total_ord() { | |
b039eaaf SL |
744 | assert_eq!("1234".cmp("123"), Greater); |
745 | assert_eq!("123".cmp("1234"), Less); | |
746 | assert_eq!("1234".cmp("1234"), Equal); | |
747 | assert_eq!("12345555".cmp("123456"), Less); | |
748 | assert_eq!("22".cmp("1234"), Greater); | |
c34b1796 AL |
749 | } |
750 | ||
751 | #[test] | |
54a0048b | 752 | #[allow(deprecated)] |
c34b1796 AL |
753 | fn test_char_range_at() { |
754 | let data = "b¢€𤭢𤭢€¢b"; | |
755 | assert_eq!('b', data.char_range_at(0).ch); | |
756 | assert_eq!('¢', data.char_range_at(1).ch); | |
757 | assert_eq!('€', data.char_range_at(3).ch); | |
758 | assert_eq!('𤭢', data.char_range_at(6).ch); | |
759 | assert_eq!('𤭢', data.char_range_at(10).ch); | |
760 | assert_eq!('€', data.char_range_at(14).ch); | |
761 | assert_eq!('¢', data.char_range_at(17).ch); | |
762 | assert_eq!('b', data.char_range_at(19).ch); | |
763 | } | |
764 | ||
765 | #[test] | |
54a0048b | 766 | #[allow(deprecated)] |
c34b1796 AL |
767 | fn test_char_range_at_reverse_underflow() { |
768 | assert_eq!("abc".char_range_at_reverse(0).next, 0); | |
769 | } | |
770 | ||
771 | #[test] | |
772 | fn test_iterator() { | |
773 | let s = "ศไทย中华Việt Nam"; | |
774 | let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; | |
775 | ||
776 | let mut pos = 0; | |
777 | let it = s.chars(); | |
778 | ||
779 | for c in it { | |
780 | assert_eq!(c, v[pos]); | |
781 | pos += 1; | |
782 | } | |
783 | assert_eq!(pos, v.len()); | |
784 | } | |
785 | ||
786 | #[test] | |
787 | fn test_rev_iterator() { | |
788 | let s = "ศไทย中华Việt Nam"; | |
789 | let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ']; | |
790 | ||
791 | let mut pos = 0; | |
792 | let it = s.chars().rev(); | |
793 | ||
794 | for c in it { | |
795 | assert_eq!(c, v[pos]); | |
796 | pos += 1; | |
797 | } | |
798 | assert_eq!(pos, v.len()); | |
799 | } | |
800 | ||
801 | #[test] | |
802 | fn test_chars_decoding() { | |
c34b1796 | 803 | for c in (0..0x110000).filter_map(::std::char::from_u32) { |
54a0048b SL |
804 | let bytes = c.encode_utf8(); |
805 | let s = ::std::str::from_utf8(bytes.as_slice()).unwrap(); | |
c34b1796 AL |
806 | if Some(c) != s.chars().next() { |
807 | panic!("character {:x}={} does not decode correctly", c as u32, c); | |
808 | } | |
809 | } | |
810 | } | |
811 | ||
812 | #[test] | |
813 | fn test_chars_rev_decoding() { | |
c34b1796 | 814 | for c in (0..0x110000).filter_map(::std::char::from_u32) { |
54a0048b SL |
815 | let bytes = c.encode_utf8(); |
816 | let s = ::std::str::from_utf8(bytes.as_slice()).unwrap(); | |
c34b1796 AL |
817 | if Some(c) != s.chars().rev().next() { |
818 | panic!("character {:x}={} does not decode correctly", c as u32, c); | |
819 | } | |
820 | } | |
821 | } | |
822 | ||
823 | #[test] | |
824 | fn test_iterator_clone() { | |
825 | let s = "ศไทย中华Việt Nam"; | |
826 | let mut it = s.chars(); | |
827 | it.next(); | |
828 | assert!(it.clone().zip(it).all(|(x,y)| x == y)); | |
829 | } | |
830 | ||
831 | #[test] | |
832 | fn test_bytesator() { | |
833 | let s = "ศไทย中华Việt Nam"; | |
834 | let v = [ | |
835 | 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, | |
836 | 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, | |
837 | 109 | |
838 | ]; | |
839 | let mut pos = 0; | |
840 | ||
841 | for b in s.bytes() { | |
842 | assert_eq!(b, v[pos]); | |
843 | pos += 1; | |
844 | } | |
845 | } | |
846 | ||
847 | #[test] | |
848 | fn test_bytes_revator() { | |
849 | let s = "ศไทย中华Việt Nam"; | |
850 | let v = [ | |
851 | 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, | |
852 | 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, | |
853 | 109 | |
854 | ]; | |
855 | let mut pos = v.len(); | |
856 | ||
857 | for b in s.bytes().rev() { | |
858 | pos -= 1; | |
859 | assert_eq!(b, v[pos]); | |
860 | } | |
861 | } | |
862 | ||
e9174d1e SL |
863 | #[test] |
864 | fn test_bytesator_nth() { | |
865 | let s = "ศไทย中华Việt Nam"; | |
866 | let v = [ | |
867 | 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, | |
868 | 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, | |
869 | 109 | |
870 | ]; | |
871 | ||
872 | let mut b = s.bytes(); | |
873 | assert_eq!(b.nth(2).unwrap(), v[2]); | |
874 | assert_eq!(b.nth(10).unwrap(), v[10]); | |
875 | assert_eq!(b.nth(200), None); | |
876 | } | |
877 | ||
878 | #[test] | |
879 | fn test_bytesator_count() { | |
880 | let s = "ศไทย中华Việt Nam"; | |
881 | ||
882 | let b = s.bytes(); | |
883 | assert_eq!(b.count(), 28) | |
884 | } | |
885 | ||
886 | #[test] | |
887 | fn test_bytesator_last() { | |
888 | let s = "ศไทย中华Việt Nam"; | |
889 | ||
890 | let b = s.bytes(); | |
891 | assert_eq!(b.last().unwrap(), 109) | |
892 | } | |
893 | ||
c34b1796 AL |
894 | #[test] |
895 | fn test_char_indicesator() { | |
896 | let s = "ศไทย中华Việt Nam"; | |
897 | let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27]; | |
898 | let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; | |
899 | ||
900 | let mut pos = 0; | |
901 | let it = s.char_indices(); | |
902 | ||
903 | for c in it { | |
904 | assert_eq!(c, (p[pos], v[pos])); | |
905 | pos += 1; | |
906 | } | |
907 | assert_eq!(pos, v.len()); | |
908 | assert_eq!(pos, p.len()); | |
909 | } | |
910 | ||
911 | #[test] | |
912 | fn test_char_indices_revator() { | |
913 | let s = "ศไทย中华Việt Nam"; | |
914 | let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0]; | |
915 | let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ']; | |
916 | ||
917 | let mut pos = 0; | |
918 | let it = s.char_indices().rev(); | |
919 | ||
920 | for c in it { | |
921 | assert_eq!(c, (p[pos], v[pos])); | |
922 | pos += 1; | |
923 | } | |
924 | assert_eq!(pos, v.len()); | |
925 | assert_eq!(pos, p.len()); | |
926 | } | |
927 | ||
928 | #[test] | |
929 | fn test_splitn_char_iterator() { | |
930 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
931 | ||
932 | let split: Vec<&str> = data.splitn(4, ' ').collect(); | |
933 | assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); | |
934 | ||
935 | let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect(); | |
936 | assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); | |
937 | ||
938 | // Unicode | |
939 | let split: Vec<&str> = data.splitn(4, 'ä').collect(); | |
940 | assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); | |
941 | ||
942 | let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect(); | |
943 | assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); | |
944 | } | |
945 | ||
946 | #[test] | |
947 | fn test_split_char_iterator_no_trailing() { | |
948 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
949 | ||
950 | let split: Vec<&str> = data.split('\n').collect(); | |
951 | assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); | |
952 | ||
953 | let split: Vec<&str> = data.split_terminator('\n').collect(); | |
954 | assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); | |
955 | } | |
956 | ||
957 | #[test] | |
958 | fn test_rsplit() { | |
959 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
960 | ||
961 | let split: Vec<&str> = data.rsplit(' ').collect(); | |
962 | assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]); | |
963 | ||
964 | let split: Vec<&str> = data.rsplit("lämb").collect(); | |
965 | assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]); | |
966 | ||
967 | let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect(); | |
968 | assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]); | |
969 | } | |
970 | ||
971 | #[test] | |
972 | fn test_rsplitn() { | |
973 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
974 | ||
975 | let split: Vec<&str> = data.rsplitn(2, ' ').collect(); | |
976 | assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]); | |
977 | ||
978 | let split: Vec<&str> = data.rsplitn(2, "lämb").collect(); | |
979 | assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]); | |
980 | ||
981 | let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect(); | |
982 | assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]); | |
983 | } | |
984 | ||
985 | #[test] | |
d9579d0f | 986 | fn test_split_whitespace() { |
c34b1796 | 987 | let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n"; |
d9579d0f | 988 | let words: Vec<&str> = data.split_whitespace().collect(); |
c34b1796 AL |
989 | assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"]) |
990 | } | |
991 | ||
c34b1796 AL |
992 | #[test] |
993 | fn test_lines() { | |
e9174d1e | 994 | let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n"; |
c34b1796 AL |
995 | let lines: Vec<&str> = data.lines().collect(); |
996 | assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); | |
997 | ||
e9174d1e | 998 | let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n |
c34b1796 AL |
999 | let lines: Vec<&str> = data.lines().collect(); |
1000 | assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); | |
1001 | } | |
1002 | ||
c34b1796 AL |
1003 | #[test] |
1004 | fn test_splitator() { | |
1005 | fn t(s: &str, sep: &str, u: &[&str]) { | |
1006 | let v: Vec<&str> = s.split(sep).collect(); | |
1007 | assert_eq!(v, u); | |
1008 | } | |
1009 | t("--1233345--", "12345", &["--1233345--"]); | |
1010 | t("abc::hello::there", "::", &["abc", "hello", "there"]); | |
1011 | t("::hello::there", "::", &["", "hello", "there"]); | |
1012 | t("hello::there::", "::", &["hello", "there", ""]); | |
1013 | t("::hello::there::", "::", &["", "hello", "there", ""]); | |
1014 | t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]); | |
1015 | t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]); | |
1016 | t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]); | |
1017 | t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]); | |
1018 | t("", ".", &[""]); | |
1019 | t("zz", "zz", &["",""]); | |
1020 | t("ok", "z", &["ok"]); | |
1021 | t("zzz", "zz", &["","z"]); | |
1022 | t("zzzzz", "zz", &["","","z"]); | |
1023 | } | |
1024 | ||
1025 | #[test] | |
1026 | fn test_str_default() { | |
1027 | use std::default::Default; | |
1028 | ||
1029 | fn t<S: Default + AsRef<str>>() { | |
1030 | let s: S = Default::default(); | |
1031 | assert_eq!(s.as_ref(), ""); | |
1032 | } | |
1033 | ||
1034 | t::<&str>(); | |
1035 | t::<String>(); | |
1036 | } | |
1037 | ||
1038 | #[test] | |
1039 | fn test_str_container() { | |
1040 | fn sum_len(v: &[&str]) -> usize { | |
1041 | v.iter().map(|x| x.len()).sum() | |
1042 | } | |
1043 | ||
b039eaaf | 1044 | let s = "01234"; |
c34b1796 | 1045 | assert_eq!(5, sum_len(&["012", "", "34"])); |
b039eaaf SL |
1046 | assert_eq!(5, sum_len(&["01", "2", "34", ""])); |
1047 | assert_eq!(5, sum_len(&[s])); | |
c34b1796 AL |
1048 | } |
1049 | ||
1050 | #[test] | |
1051 | fn test_str_from_utf8() { | |
1052 | let xs = b"hello"; | |
1053 | assert_eq!(from_utf8(xs), Ok("hello")); | |
1054 | ||
1055 | let xs = "ศไทย中华Việt Nam".as_bytes(); | |
1056 | assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam")); | |
1057 | ||
1058 | let xs = b"hello\xFF"; | |
9346a6ac AL |
1059 | assert!(from_utf8(xs).is_err()); |
1060 | } | |
1061 | ||
1062 | #[test] | |
1063 | fn test_pattern_deref_forward() { | |
1064 | let data = "aabcdaa"; | |
1065 | assert!(data.contains("bcd")); | |
1066 | assert!(data.contains(&"bcd")); | |
1067 | assert!(data.contains(&"bcd".to_string())); | |
1068 | } | |
1069 | ||
1070 | #[test] | |
1071 | fn test_empty_match_indices() { | |
1072 | let data = "aä中!"; | |
1073 | let vec: Vec<_> = data.match_indices("").collect(); | |
b039eaaf | 1074 | assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]); |
9346a6ac AL |
1075 | } |
1076 | ||
1077 | #[test] | |
1078 | fn test_bool_from_str() { | |
1079 | assert_eq!("true".parse().ok(), Some(true)); | |
1080 | assert_eq!("false".parse().ok(), Some(false)); | |
1081 | assert_eq!("not even a boolean".parse::<bool>().ok(), None); | |
1082 | } | |
1083 | ||
1084 | fn check_contains_all_substrings(s: &str) { | |
1085 | assert!(s.contains("")); | |
1086 | for i in 0..s.len() { | |
1087 | for j in i+1..s.len() + 1 { | |
1088 | assert!(s.contains(&s[i..j])); | |
1089 | } | |
1090 | } | |
1091 | } | |
1092 | ||
1093 | #[test] | |
1094 | fn strslice_issue_16589() { | |
1095 | assert!("bananas".contains("nana")); | |
1096 | ||
1097 | // prior to the fix for #16589, x.contains("abcdabcd") returned false | |
1098 | // test all substrings for good measure | |
1099 | check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd"); | |
1100 | } | |
1101 | ||
1102 | #[test] | |
1103 | fn strslice_issue_16878() { | |
1104 | assert!(!"1234567ah012345678901ah".contains("hah")); | |
1105 | assert!(!"00abc01234567890123456789abc".contains("bcabc")); | |
1106 | } | |
1107 | ||
1108 | ||
1109 | #[test] | |
1110 | fn test_strslice_contains() { | |
1111 | let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'"; | |
1112 | check_contains_all_substrings(x); | |
1113 | } | |
1114 | ||
1115 | #[test] | |
1116 | fn test_rsplitn_char_iterator() { | |
1117 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
1118 | ||
1119 | let mut split: Vec<&str> = data.rsplitn(4, ' ').collect(); | |
1120 | split.reverse(); | |
1121 | assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); | |
1122 | ||
1123 | let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect(); | |
1124 | split.reverse(); | |
1125 | assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); | |
1126 | ||
1127 | // Unicode | |
1128 | let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect(); | |
1129 | split.reverse(); | |
1130 | assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); | |
1131 | ||
1132 | let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect(); | |
1133 | split.reverse(); | |
1134 | assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); | |
1135 | } | |
1136 | ||
1137 | #[test] | |
1138 | fn test_split_char_iterator() { | |
1139 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
1140 | ||
1141 | let split: Vec<&str> = data.split(' ').collect(); | |
1142 | assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); | |
1143 | ||
1144 | let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); | |
1145 | rsplit.reverse(); | |
1146 | assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); | |
1147 | ||
1148 | let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); | |
1149 | assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); | |
1150 | ||
1151 | let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); | |
1152 | rsplit.reverse(); | |
1153 | assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); | |
1154 | ||
1155 | // Unicode | |
1156 | let split: Vec<&str> = data.split('ä').collect(); | |
1157 | assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); | |
1158 | ||
1159 | let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); | |
1160 | rsplit.reverse(); | |
1161 | assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); | |
1162 | ||
1163 | let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); | |
1164 | assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); | |
1165 | ||
1166 | let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); | |
1167 | rsplit.reverse(); | |
1168 | assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); | |
1169 | } | |
1170 | ||
1171 | #[test] | |
1172 | fn test_rev_split_char_iterator_no_trailing() { | |
1173 | let data = "\nMäry häd ä little lämb\nLittle lämb\n"; | |
1174 | ||
1175 | let mut split: Vec<&str> = data.split('\n').rev().collect(); | |
1176 | split.reverse(); | |
1177 | assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); | |
1178 | ||
1179 | let mut split: Vec<&str> = data.split_terminator('\n').rev().collect(); | |
1180 | split.reverse(); | |
1181 | assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); | |
1182 | } | |
1183 | ||
1184 | #[test] | |
1185 | fn test_utf16_code_units() { | |
d9579d0f | 1186 | use rustc_unicode::str::Utf16Encoder; |
9346a6ac AL |
1187 | assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(), |
1188 | [0xE9, 0xD83D, 0xDCA9]) | |
1189 | } | |
1190 | ||
1191 | #[test] | |
1192 | fn starts_with_in_unicode() { | |
1193 | assert!(!"├── Cargo.toml".starts_with("# ")); | |
1194 | } | |
1195 | ||
1196 | #[test] | |
1197 | fn starts_short_long() { | |
1198 | assert!(!"".starts_with("##")); | |
1199 | assert!(!"##".starts_with("####")); | |
1200 | assert!("####".starts_with("##")); | |
1201 | assert!(!"##ä".starts_with("####")); | |
1202 | assert!("####ä".starts_with("##")); | |
1203 | assert!(!"##".starts_with("####ä")); | |
1204 | assert!("##ä##".starts_with("##ä")); | |
1205 | ||
1206 | assert!("".starts_with("")); | |
1207 | assert!("ä".starts_with("")); | |
1208 | assert!("#ä".starts_with("")); | |
1209 | assert!("##ä".starts_with("")); | |
1210 | assert!("ä###".starts_with("")); | |
1211 | assert!("#ä##".starts_with("")); | |
1212 | assert!("##ä#".starts_with("")); | |
1213 | } | |
1214 | ||
1215 | #[test] | |
1216 | fn contains_weird_cases() { | |
1217 | assert!("* \t".contains(' ')); | |
1218 | assert!(!"* \t".contains('?')); | |
1219 | assert!(!"* \t".contains('\u{1F4A9}')); | |
1220 | } | |
1221 | ||
1222 | #[test] | |
1223 | fn trim_ws() { | |
1224 | assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()), | |
1225 | "a \t "); | |
1226 | assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()), | |
1227 | " \t a"); | |
1228 | assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()), | |
1229 | "a"); | |
1230 | assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()), | |
1231 | ""); | |
1232 | assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()), | |
1233 | ""); | |
1234 | assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()), | |
1235 | ""); | |
1236 | } | |
1237 | ||
62682a34 SL |
1238 | #[test] |
1239 | fn to_lowercase() { | |
1240 | assert_eq!("".to_lowercase(), ""); | |
1241 | assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé "); | |
1242 | ||
1243 | // https://github.com/rust-lang/rust/issues/26035 | |
1244 | assert_eq!("ΑΣ".to_lowercase(), "ας"); | |
1245 | assert_eq!("Α'Σ".to_lowercase(), "α'ς"); | |
1246 | assert_eq!("Α''Σ".to_lowercase(), "α''ς"); | |
1247 | ||
1248 | assert_eq!("ΑΣ Α".to_lowercase(), "ας α"); | |
1249 | assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α"); | |
1250 | assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α"); | |
1251 | ||
1252 | assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α"); | |
1253 | assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α"); | |
1254 | ||
1255 | assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α"); | |
1256 | assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α"); | |
1257 | ||
1258 | assert_eq!("Α Σ".to_lowercase(), "α σ"); | |
1259 | assert_eq!("Α 'Σ".to_lowercase(), "α 'σ"); | |
1260 | assert_eq!("Α ''Σ".to_lowercase(), "α ''σ"); | |
1261 | ||
1262 | assert_eq!("Σ".to_lowercase(), "σ"); | |
1263 | assert_eq!("'Σ".to_lowercase(), "'σ"); | |
1264 | assert_eq!("''Σ".to_lowercase(), "''σ"); | |
1265 | ||
1266 | assert_eq!("ΑΣΑ".to_lowercase(), "ασα"); | |
1267 | assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α"); | |
1268 | assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α"); | |
1269 | } | |
1270 | ||
1271 | #[test] | |
1272 | fn to_uppercase() { | |
1273 | assert_eq!("".to_uppercase(), ""); | |
1274 | assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ"); | |
1275 | } | |
1276 | ||
c1a9b12d SL |
1277 | #[test] |
1278 | fn test_into_string() { | |
1279 | // The only way to acquire a Box<str> in the first place is through a String, so just | |
1280 | // test that we can round-trip between Box<str> and String. | |
1281 | let string = String::from("Some text goes here"); | |
e9174d1e | 1282 | assert_eq!(string.clone().into_boxed_str().into_string(), string); |
c1a9b12d SL |
1283 | } |
1284 | ||
1285 | #[test] | |
1286 | fn test_box_slice_clone() { | |
1287 | let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!"); | |
e9174d1e | 1288 | let data2 = data.clone().into_boxed_str().clone().into_string(); |
c1a9b12d SL |
1289 | |
1290 | assert_eq!(data, data2); | |
1291 | } | |
1292 | ||
7453a54e SL |
1293 | #[test] |
1294 | fn test_cow_from() { | |
1295 | let borrowed = "borrowed"; | |
1296 | let owned = String::from("owned"); | |
1297 | match (Cow::from(owned.clone()), Cow::from(borrowed)) { | |
1298 | (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed), | |
1299 | _ => panic!("invalid `Cow::from`"), | |
1300 | } | |
1301 | } | |
1302 | ||
9346a6ac AL |
1303 | mod pattern { |
1304 | use std::str::pattern::Pattern; | |
1305 | use std::str::pattern::{Searcher, ReverseSearcher}; | |
1306 | use std::str::pattern::SearchStep::{self, Match, Reject, Done}; | |
1307 | ||
1308 | macro_rules! make_test { | |
1309 | ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => { | |
62682a34 | 1310 | #[allow(unused_imports)] |
9346a6ac AL |
1311 | mod $name { |
1312 | use std::str::pattern::SearchStep::{Match, Reject}; | |
1313 | use super::{cmp_search_to_vec}; | |
1314 | #[test] | |
1315 | fn fwd() { | |
1316 | cmp_search_to_vec(false, $p, $h, vec![$($e),*]); | |
1317 | } | |
1318 | #[test] | |
1319 | fn bwd() { | |
1320 | cmp_search_to_vec(true, $p, $h, vec![$($e),*]); | |
1321 | } | |
1322 | } | |
1323 | } | |
1324 | } | |
1325 | ||
1326 | fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str, | |
1327 | right: Vec<SearchStep>) | |
1328 | where P::Searcher: ReverseSearcher<'a> | |
1329 | { | |
1330 | let mut searcher = pat.into_searcher(haystack); | |
1331 | let mut v = vec![]; | |
1332 | loop { | |
1333 | match if !rev {searcher.next()} else {searcher.next_back()} { | |
1334 | Match(a, b) => v.push(Match(a, b)), | |
1335 | Reject(a, b) => v.push(Reject(a, b)), | |
1336 | Done => break, | |
1337 | } | |
1338 | } | |
1339 | if rev { | |
1340 | v.reverse(); | |
1341 | } | |
1342 | ||
1343 | let mut first_index = 0; | |
1344 | let mut err = None; | |
1345 | ||
1346 | for (i, e) in right.iter().enumerate() { | |
1347 | match *e { | |
1348 | Match(a, b) | Reject(a, b) | |
1349 | if a <= b && a == first_index => { | |
1350 | first_index = b; | |
1351 | } | |
1352 | _ => { | |
1353 | err = Some(i); | |
1354 | break; | |
1355 | } | |
1356 | } | |
1357 | } | |
1358 | ||
1359 | if let Some(err) = err { | |
1360 | panic!("Input skipped range at {}", err); | |
1361 | } | |
1362 | ||
1363 | if first_index != haystack.len() { | |
1364 | panic!("Did not cover whole input"); | |
1365 | } | |
1366 | ||
1367 | assert_eq!(v, right); | |
1368 | } | |
1369 | ||
1370 | make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [ | |
1371 | Reject(0, 1), | |
1372 | Match (1, 3), | |
1373 | Reject(3, 4), | |
1374 | Match (4, 6), | |
1375 | Reject(6, 7), | |
1376 | ]); | |
c1a9b12d SL |
1377 | make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [ |
1378 | Reject(0, 1), | |
1379 | Match (1, 3), | |
1380 | Reject(3, 4), | |
1381 | Match (4, 6), | |
1382 | Match (6, 8), | |
1383 | Reject(8, 9), | |
1384 | ]); | |
9346a6ac AL |
1385 | make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [ |
1386 | Match (0, 0), | |
1387 | Reject(0, 1), | |
1388 | Match (1, 1), | |
1389 | Reject(1, 2), | |
1390 | Match (2, 2), | |
1391 | Reject(2, 3), | |
1392 | Match (3, 3), | |
1393 | Reject(3, 4), | |
1394 | Match (4, 4), | |
1395 | Reject(4, 5), | |
1396 | Match (5, 5), | |
1397 | Reject(5, 6), | |
1398 | Match (6, 6), | |
1399 | Reject(6, 7), | |
1400 | Match (7, 7), | |
1401 | ]); | |
1402 | make_test!(str_searcher_mulibyte_haystack, " ", "├──", [ | |
1403 | Reject(0, 3), | |
1404 | Reject(3, 6), | |
1405 | Reject(6, 9), | |
1406 | ]); | |
1407 | make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [ | |
1408 | Match (0, 0), | |
1409 | Reject(0, 3), | |
1410 | Match (3, 3), | |
1411 | Reject(3, 6), | |
1412 | Match (6, 6), | |
1413 | Reject(6, 9), | |
1414 | Match (9, 9), | |
1415 | ]); | |
1416 | make_test!(str_searcher_empty_needle_empty_haystack, "", "", [ | |
1417 | Match(0, 0), | |
1418 | ]); | |
1419 | make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [ | |
1420 | ]); | |
1421 | make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [ | |
1422 | Reject(0, 1), | |
1423 | Match (1, 2), | |
1424 | Match (2, 3), | |
1425 | Reject(3, 4), | |
1426 | Match (4, 5), | |
1427 | Match (5, 6), | |
1428 | Reject(6, 7), | |
1429 | ]); | |
1430 | make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [ | |
1431 | Reject(0, 3), | |
1432 | Reject(3, 6), | |
1433 | Reject(6, 9), | |
1434 | ]); | |
1435 | make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [ | |
1436 | Reject(0, 1), | |
1437 | Reject(1, 2), | |
1438 | Reject(2, 3), | |
1439 | ]); | |
1440 | ||
1441 | } | |
1442 | ||
1443 | macro_rules! generate_iterator_test { | |
1444 | { | |
1445 | $name:ident { | |
1446 | $( | |
1447 | ($($arg:expr),*) -> [$($t:tt)*]; | |
1448 | )* | |
1449 | } | |
1450 | with $fwd:expr, $bwd:expr; | |
1451 | } => { | |
1452 | #[test] | |
1453 | fn $name() { | |
1454 | $( | |
1455 | { | |
1456 | let res = vec![$($t)*]; | |
1457 | ||
1458 | let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect(); | |
1459 | assert_eq!(fwd_vec, res); | |
1460 | ||
1461 | let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect(); | |
1462 | bwd_vec.reverse(); | |
1463 | assert_eq!(bwd_vec, res); | |
1464 | } | |
1465 | )* | |
1466 | } | |
1467 | }; | |
1468 | { | |
1469 | $name:ident { | |
1470 | $( | |
1471 | ($($arg:expr),*) -> [$($t:tt)*]; | |
1472 | )* | |
1473 | } | |
1474 | with $fwd:expr; | |
1475 | } => { | |
1476 | #[test] | |
1477 | fn $name() { | |
1478 | $( | |
1479 | { | |
1480 | let res = vec![$($t)*]; | |
1481 | ||
1482 | let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect(); | |
1483 | assert_eq!(fwd_vec, res); | |
1484 | } | |
1485 | )* | |
1486 | } | |
1487 | } | |
1488 | } | |
1489 | ||
1490 | generate_iterator_test! { | |
1491 | double_ended_split { | |
1492 | ("foo.bar.baz", '.') -> ["foo", "bar", "baz"]; | |
1493 | ("foo::bar::baz", "::") -> ["foo", "bar", "baz"]; | |
1494 | } | |
1495 | with str::split, str::rsplit; | |
1496 | } | |
1497 | ||
1498 | generate_iterator_test! { | |
1499 | double_ended_split_terminator { | |
1500 | ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"]; | |
1501 | } | |
1502 | with str::split_terminator, str::rsplit_terminator; | |
1503 | } | |
1504 | ||
1505 | generate_iterator_test! { | |
1506 | double_ended_matches { | |
1507 | ("a1b2c3", char::is_numeric) -> ["1", "2", "3"]; | |
1508 | } | |
1509 | with str::matches, str::rmatches; | |
1510 | } | |
1511 | ||
1512 | generate_iterator_test! { | |
1513 | double_ended_match_indices { | |
b039eaaf | 1514 | ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")]; |
9346a6ac AL |
1515 | } |
1516 | with str::match_indices, str::rmatch_indices; | |
1517 | } | |
1518 | ||
1519 | generate_iterator_test! { | |
1520 | not_double_ended_splitn { | |
1521 | ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"]; | |
1522 | } | |
1523 | with str::splitn; | |
1524 | } | |
1525 | ||
1526 | generate_iterator_test! { | |
1527 | not_double_ended_rsplitn { | |
1528 | ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"]; | |
1529 | } | |
1530 | with str::rsplitn; | |
c34b1796 AL |
1531 | } |
1532 | ||
54a0048b SL |
1533 | #[test] |
1534 | fn different_str_pattern_forwarding_lifetimes() { | |
1535 | use std::str::pattern::Pattern; | |
1536 | ||
1537 | fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> { | |
1538 | for _ in 0..3 { | |
1539 | "asdf".find(&p); | |
1540 | } | |
1541 | } | |
1542 | ||
1543 | foo::<&str>("x"); | |
1544 | } | |
1545 | ||
c34b1796 AL |
1546 | mod bench { |
1547 | use test::{Bencher, black_box}; | |
1548 | ||
1549 | #[bench] | |
1550 | fn char_iterator(b: &mut Bencher) { | |
1551 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1552 | ||
1553 | b.iter(|| s.chars().count()); | |
1554 | } | |
1555 | ||
1556 | #[bench] | |
1557 | fn char_iterator_for(b: &mut Bencher) { | |
1558 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1559 | ||
1560 | b.iter(|| { | |
1561 | for ch in s.chars() { black_box(ch); } | |
1562 | }); | |
1563 | } | |
1564 | ||
1565 | #[bench] | |
1566 | fn char_iterator_ascii(b: &mut Bencher) { | |
1567 | let s = "Mary had a little lamb, Little lamb | |
1568 | Mary had a little lamb, Little lamb | |
1569 | Mary had a little lamb, Little lamb | |
1570 | Mary had a little lamb, Little lamb | |
1571 | Mary had a little lamb, Little lamb | |
1572 | Mary had a little lamb, Little lamb"; | |
1573 | ||
1574 | b.iter(|| s.chars().count()); | |
1575 | } | |
1576 | ||
1577 | #[bench] | |
1578 | fn char_iterator_rev(b: &mut Bencher) { | |
1579 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1580 | ||
1581 | b.iter(|| s.chars().rev().count()); | |
1582 | } | |
1583 | ||
1584 | #[bench] | |
1585 | fn char_iterator_rev_for(b: &mut Bencher) { | |
1586 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1587 | ||
1588 | b.iter(|| { | |
1589 | for ch in s.chars().rev() { black_box(ch); } | |
1590 | }); | |
1591 | } | |
1592 | ||
1593 | #[bench] | |
1594 | fn char_indicesator(b: &mut Bencher) { | |
1595 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1596 | let len = s.chars().count(); | |
1597 | ||
1598 | b.iter(|| assert_eq!(s.char_indices().count(), len)); | |
1599 | } | |
1600 | ||
1601 | #[bench] | |
1602 | fn char_indicesator_rev(b: &mut Bencher) { | |
1603 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; | |
1604 | let len = s.chars().count(); | |
1605 | ||
1606 | b.iter(|| assert_eq!(s.char_indices().rev().count(), len)); | |
1607 | } | |
1608 | ||
1609 | #[bench] | |
1610 | fn split_unicode_ascii(b: &mut Bencher) { | |
1611 | let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam"; | |
1612 | ||
1613 | b.iter(|| assert_eq!(s.split('V').count(), 3)); | |
1614 | } | |
1615 | ||
1616 | #[bench] | |
1617 | fn split_ascii(b: &mut Bencher) { | |
1618 | let s = "Mary had a little lamb, Little lamb, little-lamb."; | |
1619 | let len = s.split(' ').count(); | |
1620 | ||
1621 | b.iter(|| assert_eq!(s.split(' ').count(), len)); | |
1622 | } | |
1623 | ||
1624 | #[bench] | |
1625 | fn split_extern_fn(b: &mut Bencher) { | |
1626 | let s = "Mary had a little lamb, Little lamb, little-lamb."; | |
1627 | let len = s.split(' ').count(); | |
1628 | fn pred(c: char) -> bool { c == ' ' } | |
1629 | ||
1630 | b.iter(|| assert_eq!(s.split(pred).count(), len)); | |
1631 | } | |
1632 | ||
1633 | #[bench] | |
1634 | fn split_closure(b: &mut Bencher) { | |
1635 | let s = "Mary had a little lamb, Little lamb, little-lamb."; | |
1636 | let len = s.split(' ').count(); | |
1637 | ||
1638 | b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len)); | |
1639 | } | |
1640 | ||
1641 | #[bench] | |
1642 | fn split_slice(b: &mut Bencher) { | |
1643 | let s = "Mary had a little lamb, Little lamb, little-lamb."; | |
1644 | let len = s.split(' ').count(); | |
1645 | ||
1646 | let c: &[char] = &[' ']; | |
1647 | b.iter(|| assert_eq!(s.split(c).count(), len)); | |
1648 | } | |
1649 | ||
1650 | #[bench] | |
c1a9b12d | 1651 | fn bench_join(b: &mut Bencher) { |
c34b1796 AL |
1652 | let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; |
1653 | let sep = "→"; | |
1654 | let v = vec![s, s, s, s, s, s, s, s, s, s]; | |
1655 | b.iter(|| { | |
c1a9b12d | 1656 | assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9); |
c34b1796 AL |
1657 | }) |
1658 | } | |
1659 | ||
1660 | #[bench] | |
1661 | fn bench_contains_short_short(b: &mut Bencher) { | |
1662 | let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; | |
1663 | let needle = "sit"; | |
1664 | ||
1665 | b.iter(|| { | |
1666 | assert!(haystack.contains(needle)); | |
1667 | }) | |
1668 | } | |
1669 | ||
1670 | #[bench] | |
1671 | fn bench_contains_short_long(b: &mut Bencher) { | |
1672 | let haystack = "\ | |
1673 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ | |
1674 | ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ | |
1675 | eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \ | |
1676 | sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \ | |
1677 | tempus vel, gravida nec quam. | |
1678 | ||
1679 | In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \ | |
1680 | sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \ | |
1681 | diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \ | |
1682 | lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \ | |
1683 | eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \ | |
1684 | interdum. Curabitur ut nisi justo. | |
1685 | ||
1686 | Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \ | |
1687 | mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \ | |
1688 | lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \ | |
1689 | est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \ | |
1690 | felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \ | |
1691 | ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \ | |
1692 | feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \ | |
1693 | Aliquam sit amet placerat lorem. | |
1694 | ||
1695 | Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \ | |
1696 | mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \ | |
1697 | Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \ | |
1698 | lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \ | |
1699 | suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \ | |
1700 | cursus accumsan. | |
1701 | ||
1702 | Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \ | |
1703 | feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \ | |
1704 | vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \ | |
1705 | leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \ | |
1706 | malesuada sollicitudin quam eu fermentum."; | |
1707 | let needle = "english"; | |
1708 | ||
1709 | b.iter(|| { | |
1710 | assert!(!haystack.contains(needle)); | |
1711 | }) | |
1712 | } | |
1713 | ||
1714 | #[bench] | |
1715 | fn bench_contains_bad_naive(b: &mut Bencher) { | |
1716 | let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | |
1717 | let needle = "aaaaaaaab"; | |
1718 | ||
1719 | b.iter(|| { | |
1720 | assert!(!haystack.contains(needle)); | |
1721 | }) | |
1722 | } | |
1723 | ||
1724 | #[bench] | |
1725 | fn bench_contains_equal(b: &mut Bencher) { | |
1726 | let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; | |
1727 | let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; | |
1728 | ||
1729 | b.iter(|| { | |
1730 | assert!(haystack.contains(needle)); | |
1731 | }) | |
1732 | } | |
9346a6ac AL |
1733 | |
1734 | macro_rules! make_test_inner { | |
1735 | ($s:ident, $code:expr, $name:ident, $str:expr) => { | |
1736 | #[bench] | |
1737 | fn $name(bencher: &mut Bencher) { | |
1738 | let mut $s = $str; | |
1739 | black_box(&mut $s); | |
1740 | bencher.iter(|| $code); | |
1741 | } | |
1742 | } | |
1743 | } | |
1744 | ||
1745 | macro_rules! make_test { | |
1746 | ($name:ident, $s:ident, $code:expr) => { | |
1747 | mod $name { | |
1748 | use test::Bencher; | |
1749 | use test::black_box; | |
1750 | ||
1751 | // Short strings: 65 bytes each | |
1752 | make_test_inner!($s, $code, short_ascii, | |
1753 | "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!"); | |
1754 | make_test_inner!($s, $code, short_mixed, | |
1755 | "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!"); | |
1756 | make_test_inner!($s, $code, short_pile_of_poo, | |
1757 | "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!"); | |
1758 | make_test_inner!($s, $code, long_lorem_ipsum,"\ | |
1759 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ | |
1760 | ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ | |
1761 | eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \ | |
1762 | sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \ | |
1763 | tempus vel, gravida nec quam. | |
1764 | ||
1765 | In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \ | |
1766 | sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \ | |
1767 | diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \ | |
1768 | lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \ | |
1769 | eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \ | |
1770 | interdum. Curabitur ut nisi justo. | |
1771 | ||
1772 | Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \ | |
1773 | mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \ | |
1774 | lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \ | |
1775 | est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \ | |
1776 | felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \ | |
1777 | ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \ | |
1778 | feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \ | |
1779 | Aliquam sit amet placerat lorem. | |
1780 | ||
1781 | Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \ | |
1782 | mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \ | |
1783 | Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \ | |
1784 | lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \ | |
1785 | suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \ | |
1786 | cursus accumsan. | |
1787 | ||
1788 | Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \ | |
1789 | feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \ | |
1790 | vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \ | |
1791 | leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \ | |
1792 | malesuada sollicitudin quam eu fermentum!"); | |
1793 | } | |
1794 | } | |
1795 | } | |
1796 | ||
1797 | make_test!(chars_count, s, s.chars().count()); | |
1798 | ||
1799 | make_test!(contains_bang_str, s, s.contains("!")); | |
1800 | make_test!(contains_bang_char, s, s.contains('!')); | |
1801 | ||
1802 | make_test!(match_indices_a_str, s, s.match_indices("a").count()); | |
1803 | ||
1804 | make_test!(split_a_str, s, s.split("a").count()); | |
1805 | ||
1806 | make_test!(trim_ascii_char, s, { | |
1807 | use std::ascii::AsciiExt; | |
1808 | s.trim_matches(|c: char| c.is_ascii()) | |
1809 | }); | |
1810 | make_test!(trim_left_ascii_char, s, { | |
1811 | use std::ascii::AsciiExt; | |
1812 | s.trim_left_matches(|c: char| c.is_ascii()) | |
1813 | }); | |
1814 | make_test!(trim_right_ascii_char, s, { | |
1815 | use std::ascii::AsciiExt; | |
1816 | s.trim_right_matches(|c: char| c.is_ascii()) | |
1817 | }); | |
1818 | ||
1819 | make_test!(find_underscore_char, s, s.find('_')); | |
1820 | make_test!(rfind_underscore_char, s, s.rfind('_')); | |
1821 | make_test!(find_underscore_str, s, s.find("_")); | |
1822 | ||
1823 | make_test!(find_zzz_char, s, s.find('\u{1F4A4}')); | |
1824 | make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}')); | |
1825 | make_test!(find_zzz_str, s, s.find("\u{1F4A4}")); | |
1826 | ||
1827 | make_test!(split_space_char, s, s.split(' ').count()); | |
1828 | make_test!(split_terminator_space_char, s, s.split_terminator(' ').count()); | |
1829 | ||
1830 | make_test!(splitn_space_char, s, s.splitn(10, ' ').count()); | |
1831 | make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count()); | |
1832 | ||
1833 | make_test!(split_space_str, s, s.split(" ").count()); | |
1834 | make_test!(split_ad_str, s, s.split("ad").count()); | |
c34b1796 | 1835 | } |