]> git.lizzy.rs Git - rust.git/blob - src/libcoretest/str.rs
Re-word explanation on closures in intro
[rust.git] / src / libcoretest / str.rs
1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #[test]
12 fn test_pattern_deref_forward() {
13     let data = "aabcdaa";
14     assert!(data.contains("bcd"));
15     assert!(data.contains(&"bcd"));
16     assert!(data.contains(&&"bcd"));
17     assert!(data.contains(&"bcd".to_string()));
18     assert!(data.contains(&&"bcd".to_string()));
19 }
20
21 #[test]
22 fn test_empty_match_indices() {
23     let data = "aä中!";
24     let vec: Vec<_> = data.match_indices("").collect();
25     assert_eq!(vec, [(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]);
26 }
27
28 #[test]
29 fn test_bool_from_str() {
30     assert_eq!("true".parse().ok(), Some(true));
31     assert_eq!("false".parse().ok(), Some(false));
32     assert_eq!("not even a boolean".parse::<bool>().ok(), None);
33 }
34
35 fn check_contains_all_substrings(s: &str) {
36     assert!(s.contains(""));
37     for i in 0..s.len() {
38         for j in i+1..s.len() + 1 {
39             assert!(s.contains(&s[i..j]));
40         }
41     }
42 }
43
44 #[test]
45 fn strslice_issue_16589() {
46     assert!("bananas".contains("nana"));
47
48     // prior to the fix for #16589, x.contains("abcdabcd") returned false
49     // test all substrings for good measure
50     check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
51 }
52
53 #[test]
54 fn strslice_issue_16878() {
55     assert!(!"1234567ah012345678901ah".contains("hah"));
56     assert!(!"00abc01234567890123456789abc".contains("bcabc"));
57 }
58
59
60 #[test]
61 fn test_strslice_contains() {
62     let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
63     check_contains_all_substrings(x);
64 }
65
66 #[test]
67 fn test_rsplitn_char_iterator() {
68     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
69
70     let mut split: Vec<&str> = data.rsplitn(3, ' ').collect();
71     split.reverse();
72     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
73
74     let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect();
75     split.reverse();
76     assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
77
78     // Unicode
79     let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect();
80     split.reverse();
81     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
82
83     let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect();
84     split.reverse();
85     assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
86 }
87
88 #[test]
89 fn test_split_char_iterator() {
90     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
91
92     let split: Vec<&str> = data.split(' ').collect();
93     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
94
95     let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
96     rsplit.reverse();
97     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
98
99     let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
100     assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
101
102     let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
103     rsplit.reverse();
104     assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
105
106     // Unicode
107     let split: Vec<&str> = data.split('ä').collect();
108     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
109
110     let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
111     rsplit.reverse();
112     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
113
114     let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
115     assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
116
117     let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
118     rsplit.reverse();
119     assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
120 }
121
122 #[test]
123 fn test_rev_split_char_iterator_no_trailing() {
124     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
125
126     let mut split: Vec<&str> = data.split('\n').rev().collect();
127     split.reverse();
128     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
129
130     let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
131     split.reverse();
132     assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
133 }
134
135 #[test]
136 fn test_utf16_code_units() {
137     use unicode::str::Utf16Encoder;
138     assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
139                [0xE9, 0xD83D, 0xDCA9])
140 }
141
142 #[test]
143 fn starts_with_in_unicode() {
144     assert!(!"├── Cargo.toml".starts_with("# "));
145 }
146
147 #[test]
148 fn starts_short_long() {
149     assert!(!"".starts_with("##"));
150     assert!(!"##".starts_with("####"));
151     assert!("####".starts_with("##"));
152     assert!(!"##ä".starts_with("####"));
153     assert!("####ä".starts_with("##"));
154     assert!(!"##".starts_with("####ä"));
155     assert!("##ä##".starts_with("##ä"));
156
157     assert!("".starts_with(""));
158     assert!("ä".starts_with(""));
159     assert!("#ä".starts_with(""));
160     assert!("##ä".starts_with(""));
161     assert!("ä###".starts_with(""));
162     assert!("#ä##".starts_with(""));
163     assert!("##ä#".starts_with(""));
164 }
165
166 #[test]
167 fn contains_weird_cases() {
168     assert!("* \t".contains_char(' '));
169     assert!(!"* \t".contains_char('?'));
170     assert!(!"* \t".contains_char('\u{1F4A9}'));
171 }
172
173 #[test]
174 fn trim_ws() {
175     assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
176                     "a \t  ");
177     assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
178                " \t  a");
179     assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
180                     "a");
181     assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
182                          "");
183     assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
184                "");
185     assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
186                "");
187 }
188
189 mod pattern {
190     use std::str::Pattern;
191     use std::str::{Searcher, ReverseSearcher};
192     use std::str::SearchStep::{self, Match, Reject, Done};
193
194     macro_rules! make_test {
195         ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
196             mod $name {
197                 use std::str::SearchStep::{Match, Reject};
198                 use super::{cmp_search_to_vec};
199                 #[test]
200                 fn fwd() {
201                     cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
202                 }
203                 #[test]
204                 fn bwd() {
205                     cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
206                 }
207             }
208         }
209     }
210
211     fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
212                                              right: Vec<SearchStep>)
213     where P::Searcher: ReverseSearcher<'a>
214     {
215         let mut searcher = pat.into_searcher(haystack);
216         let mut v = vec![];
217         loop {
218             match if !rev {searcher.next()} else {searcher.next_back()} {
219                 Match(a, b) => v.push(Match(a, b)),
220                 Reject(a, b) => v.push(Reject(a, b)),
221                 Done => break,
222             }
223         }
224         if rev {
225             v.reverse();
226         }
227         assert_eq!(v, right);
228     }
229
230     make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
231         Reject(0, 1),
232         Match (1, 3),
233         Reject(3, 4),
234         Match (4, 6),
235         Reject(6, 7),
236     ]);
237     make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
238         Match(0, 0),
239         Match(1, 1),
240         Match(2, 2),
241         Match(3, 3),
242         Match(4, 4),
243         Match(5, 5),
244         Match(6, 6),
245         Match(7, 7),
246     ]);
247     make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
248         Reject(0, 3),
249         Reject(3, 6),
250         Reject(6, 9),
251     ]);
252     make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
253         Match(0, 0),
254         Match(3, 3),
255         Match(6, 6),
256         Match(9, 9),
257     ]);
258     make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
259         Match(0, 0),
260     ]);
261     make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
262     ]);
263     make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
264         Reject(0, 1),
265         Match (1, 2),
266         Match (2, 3),
267         Reject(3, 4),
268         Match (4, 5),
269         Match (5, 6),
270         Reject(6, 7),
271     ]);
272     make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
273         Reject(0, 3),
274         Reject(3, 6),
275         Reject(6, 9),
276     ]);
277     make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
278         Reject(0, 1),
279         Reject(1, 2),
280         Reject(2, 3),
281     ]);
282
283 }
284
285 mod bench {
286     macro_rules! make_test_inner {
287         ($s:ident, $code:expr, $name:ident, $str:expr) => {
288             #[bench]
289             fn $name(bencher: &mut Bencher) {
290                 let mut $s = $str;
291                 black_box(&mut $s);
292                 bencher.iter(|| $code);
293             }
294         }
295     }
296
297     macro_rules! make_test {
298         ($name:ident, $s:ident, $code:expr) => {
299             mod $name {
300                 use test::Bencher;
301                 use test::black_box;
302
303                 // Short strings: 65 bytes each
304                 make_test_inner!($s, $code, short_ascii,
305                     "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
306                 make_test_inner!($s, $code, short_mixed,
307                     "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
308                 make_test_inner!($s, $code, short_pile_of_poo,
309                     "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
310                 make_test_inner!($s, $code, long_lorem_ipsum,"\
311 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
312 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
313 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
314 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
315 tempus vel, gravida nec quam.
316
317 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
318 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
319 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
320 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
321 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
322 interdum. Curabitur ut nisi justo.
323
324 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
325 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
326 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
327 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
328 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
329 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
330 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
331 Aliquam sit amet placerat lorem.
332
333 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
334 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
335 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
336 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
337 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
338 cursus accumsan.
339
340 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
341 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
342 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
343 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
344 malesuada sollicitudin quam eu fermentum!");
345             }
346         }
347     }
348
349     make_test!(chars_count, s, s.chars().count());
350
351     make_test!(contains_bang_str, s, s.contains("!"));
352     make_test!(contains_bang_char, s, s.contains_char('!'));
353
354     make_test!(match_indices_a_str, s, s.match_indices("a").count());
355
356     make_test!(split_str_a_str, s, s.split_str("a").count());
357
358     make_test!(trim_ascii_char, s, {
359         use std::ascii::AsciiExt;
360         s.trim_matches(|c: char| c.is_ascii())
361     });
362     make_test!(trim_left_ascii_char, s, {
363         use std::ascii::AsciiExt;
364         s.trim_left_matches(|c: char| c.is_ascii())
365     });
366     make_test!(trim_right_ascii_char, s, {
367         use std::ascii::AsciiExt;
368         s.trim_right_matches(|c: char| c.is_ascii())
369     });
370
371     make_test!(find_underscore_char, s, s.find('_'));
372     make_test!(rfind_underscore_char, s, s.rfind('_'));
373     make_test!(find_underscore_str, s, s.find_str("_"));
374
375     make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
376     make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
377     make_test!(find_zzz_str, s, s.find_str("\u{1F4A4}"));
378
379     make_test!(split_space_char, s, s.split(' ').count());
380     make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
381
382     make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
383     make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
384
385     make_test!(split_str_space_str, s, s.split_str(" ").count());
386     make_test!(split_str_ad_str, s, s.split_str("ad").count());
387 }