nom8/
str.rs

1#[cfg(test)]
2mod test {
3  use crate::input::Streaming;
4  use crate::prelude::*;
5  #[cfg(feature = "alloc")]
6  use crate::{branch::alt, bytes::tag_no_case, multi::many1};
7  use crate::{
8    bytes::{tag, take, take_till, take_till1, take_until, take_while1},
9    error::{self, ErrorKind},
10    Err, IResult,
11  };
12
13  #[test]
14  fn tagtr_succeed() {
15    const INPUT: &str = "Hello World!";
16    const TAG: &str = "Hello";
17    fn test(input: &str) -> IResult<&str, &str> {
18      tag(TAG)(input)
19    }
20
21    match test(INPUT) {
22      Ok((extra, output)) => {
23        assert!(extra == " World!", "Parser `tag` consumed leftover input.");
24        assert!(
25          output == TAG,
26          "Parser `tag` doesn't return the tag it matched on success. \
27           Expected `{}`, got `{}`.",
28          TAG,
29          output
30        );
31      }
32      other => panic!(
33        "Parser `tag` didn't succeed when it should have. \
34         Got `{:?}`.",
35        other
36      ),
37    };
38  }
39
40  #[test]
41  fn tagtr_incomplete() {
42    use crate::bytes::tag;
43
44    const INPUT: &str = "Hello";
45    const TAG: &str = "Hello World!";
46
47    let res: IResult<_, _, error::Error<_>> = tag(TAG)(Streaming(INPUT));
48    match res {
49      Err(Err::Incomplete(_)) => (),
50      other => {
51        panic!(
52          "Parser `tag` didn't require more input when it should have. \
53           Got `{:?}`.",
54          other
55        );
56      }
57    };
58  }
59
60  #[test]
61  fn tagtr_error() {
62    const INPUT: &str = "Hello World!";
63    const TAG: &str = "Random"; // TAG must be closer than INPUT.
64
65    let res: IResult<_, _, error::Error<_>> = tag(TAG)(INPUT);
66    match res {
67      Err(Err::Error(_)) => (),
68      other => {
69        panic!(
70          "Parser `tag` didn't fail when it should have. Got `{:?}`.`",
71          other
72        );
73      }
74    };
75  }
76
77  #[test]
78  fn take_s_succeed() {
79    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
80    const CONSUMED: &str = "βèƒôřèÂßÇ";
81    const LEFTOVER: &str = "áƒƭèř";
82
83    let res: IResult<_, _, error::Error<_>> = take(9_usize)(INPUT);
84    match res {
85      Ok((extra, output)) => {
86        assert!(
87          extra == LEFTOVER,
88          "Parser `take_s` consumed leftover input. Leftover `{}`.",
89          extra
90        );
91        assert!(
92          output == CONSUMED,
93          "Parser `take_s` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
94          CONSUMED,
95          output
96        );
97      }
98      other => panic!(
99        "Parser `take_s` didn't succeed when it should have. \
100         Got `{:?}`.",
101        other
102      ),
103    };
104  }
105
106  #[test]
107  fn take_until_succeed() {
108    const INPUT: &str = "βèƒôřèÂßÇ∂áƒƭèř";
109    const FIND: &str = "ÂßÇ∂";
110    const CONSUMED: &str = "βèƒôřè";
111    const LEFTOVER: &str = "ÂßÇ∂áƒƭèř";
112
113    let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT);
114    match res {
115      Ok((extra, output)) => {
116        assert!(
117          extra == LEFTOVER,
118          "Parser `take_until`\
119           consumed leftover input. Leftover `{}`.",
120          extra
121        );
122        assert!(
123          output == CONSUMED,
124          "Parser `take_until`\
125           doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
126          CONSUMED,
127          output
128        );
129      }
130      other => panic!(
131        "Parser `take_until` didn't succeed when it should have. \
132         Got `{:?}`.",
133        other
134      ),
135    };
136  }
137
138  #[test]
139  fn take_s_incomplete() {
140    use crate::bytes::take;
141
142    const INPUT: &str = "βèƒôřèÂßÇá";
143
144    let res: IResult<_, _, (_, ErrorKind)> = take(13_usize)(Streaming(INPUT));
145    match res {
146      Err(Err::Incomplete(_)) => (),
147      other => panic!(
148        "Parser `take` didn't require more input when it should have. \
149         Got `{:?}`.",
150        other
151      ),
152    }
153  }
154
155  use crate::Needed;
156
157  fn is_alphabetic(c: char) -> bool {
158    (c as u8 >= 0x41 && c as u8 <= 0x5A) || (c as u8 >= 0x61 && c as u8 <= 0x7A)
159  }
160
161  #[test]
162  fn take_while() {
163    use crate::bytes::take_while;
164
165    fn f(i: Streaming<&str>) -> IResult<Streaming<&str>, &str> {
166      take_while(is_alphabetic)(i)
167    }
168    let a = "";
169    let b = "abcd";
170    let c = "abcd123";
171    let d = "123";
172
173    assert_eq!(f(Streaming(&a[..])), Err(Err::Incomplete(Needed::new(1))));
174    assert_eq!(f(Streaming(&b[..])), Err(Err::Incomplete(Needed::new(1))));
175    assert_eq!(f(Streaming(&c[..])), Ok((Streaming(&d[..]), &b[..])));
176    assert_eq!(f(Streaming(&d[..])), Ok((Streaming(&d[..]), &a[..])));
177  }
178
179  #[test]
180  fn test_take_while1() {
181    fn f(i: Streaming<&str>) -> IResult<Streaming<&str>, &str> {
182      take_while1(is_alphabetic)(i)
183    }
184    let a = "";
185    let b = "abcd";
186    let c = "abcd123";
187    let d = "123";
188
189    assert_eq!(f(Streaming(&a[..])), Err(Err::Incomplete(Needed::new(1))));
190    assert_eq!(f(Streaming(&b[..])), Err(Err::Incomplete(Needed::new(1))));
191    assert_eq!(f(Streaming(&c[..])), Ok((Streaming(&"123"[..]), &b[..])));
192    assert_eq!(
193      f(Streaming(&d[..])),
194      Err(Err::Error(error_position!(
195        Streaming(&d[..]),
196        ErrorKind::TakeWhile1
197      )))
198    );
199  }
200
201  #[test]
202  fn take_till_s_succeed() {
203    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
204    const CONSUMED: &str = "βèƒôřèÂßÇ";
205    const LEFTOVER: &str = "áƒƭèř";
206    fn till_s(c: char) -> bool {
207      c == 'á'
208    }
209    fn test(input: &str) -> IResult<&str, &str> {
210      take_till(till_s)(input)
211    }
212    match test(INPUT) {
213      Ok((extra, output)) => {
214        assert!(
215          extra == LEFTOVER,
216          "Parser `take_till` consumed leftover input."
217        );
218        assert!(
219          output == CONSUMED,
220          "Parser `take_till` doesn't return the string it consumed on success. \
221           Expected `{}`, got `{}`.",
222          CONSUMED,
223          output
224        );
225      }
226      other => panic!(
227        "Parser `take_till` didn't succeed when it should have. \
228         Got `{:?}`.",
229        other
230      ),
231    };
232  }
233
234  #[test]
235  fn take_while_succeed_none() {
236    use crate::bytes::take_while;
237
238    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
239    const CONSUMED: &str = "";
240    const LEFTOVER: &str = "βèƒôřèÂßÇáƒƭèř";
241    fn while_s(c: char) -> bool {
242      c == '9'
243    }
244    fn test(input: &str) -> IResult<&str, &str> {
245      take_while(while_s)(input)
246    }
247    match test(INPUT) {
248      Ok((extra, output)) => {
249        assert!(
250          extra == LEFTOVER,
251          "Parser `take_while` consumed leftover input."
252        );
253        assert!(
254          output == CONSUMED,
255          "Parser `take_while` doesn't return the string it consumed on success. \
256           Expected `{}`, got `{}`.",
257          CONSUMED,
258          output
259        );
260      }
261      other => panic!(
262        "Parser `take_while` didn't succeed when it should have. \
263         Got `{:?}`.",
264        other
265      ),
266    };
267  }
268
269  #[test]
270  fn is_not_succeed() {
271    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
272    const AVOID: &str = "£úçƙ¥á";
273    const CONSUMED: &str = "βèƒôřèÂßÇ";
274    const LEFTOVER: &str = "áƒƭèř";
275    fn test(input: &str) -> IResult<&str, &str> {
276      take_till1(AVOID)(input)
277    }
278    match test(INPUT) {
279      Ok((extra, output)) => {
280        assert!(
281          extra == LEFTOVER,
282          "Parser `is_not` consumed leftover input. Leftover `{}`.",
283          extra
284        );
285        assert!(
286          output == CONSUMED,
287          "Parser `is_not` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
288          CONSUMED,
289          output
290        );
291      }
292      other => panic!(
293        "Parser `is_not` didn't succeed when it should have. \
294         Got `{:?}`.",
295        other
296      ),
297    };
298  }
299
300  #[test]
301  fn take_while_succeed_some() {
302    use crate::bytes::take_while;
303
304    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
305    const CONSUMED: &str = "βèƒôřèÂßÇ";
306    const LEFTOVER: &str = "áƒƭèř";
307    fn while_s(c: char) -> bool {
308      c == 'β'
309        || c == 'è'
310        || c == 'ƒ'
311        || c == 'ô'
312        || c == 'ř'
313        || c == 'è'
314        || c == 'Â'
315        || c == 'ß'
316        || c == 'Ç'
317    }
318    fn test(input: &str) -> IResult<&str, &str> {
319      take_while(while_s)(input)
320    }
321    match test(INPUT) {
322      Ok((extra, output)) => {
323        assert!(
324          extra == LEFTOVER,
325          "Parser `take_while` consumed leftover input."
326        );
327        assert!(
328          output == CONSUMED,
329          "Parser `take_while` doesn't return the string it consumed on success. \
330           Expected `{}`, got `{}`.",
331          CONSUMED,
332          output
333        );
334      }
335      other => panic!(
336        "Parser `take_while` didn't succeed when it should have. \
337         Got `{:?}`.",
338        other
339      ),
340    };
341  }
342
343  #[test]
344  fn is_not_fail() {
345    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
346    const AVOID: &str = "βúçƙ¥";
347    fn test(input: &str) -> IResult<&str, &str> {
348      take_till1(AVOID)(input)
349    }
350    match test(INPUT) {
351      Err(Err::Error(_)) => (),
352      other => panic!(
353        "Parser `is_not` didn't fail when it should have. Got `{:?}`.",
354        other
355      ),
356    };
357  }
358
359  #[test]
360  fn take_while1_succeed() {
361    use crate::bytes::take_while1;
362
363    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
364    const CONSUMED: &str = "βèƒôřèÂßÇ";
365    const LEFTOVER: &str = "áƒƭèř";
366    fn while1_s(c: char) -> bool {
367      c == 'β'
368        || c == 'è'
369        || c == 'ƒ'
370        || c == 'ô'
371        || c == 'ř'
372        || c == 'è'
373        || c == 'Â'
374        || c == 'ß'
375        || c == 'Ç'
376    }
377    fn test(input: &str) -> IResult<&str, &str> {
378      take_while1(while1_s)(input)
379    }
380    match test(INPUT) {
381      Ok((extra, output)) => {
382        assert!(
383          extra == LEFTOVER,
384          "Parser `take_while1` consumed leftover input."
385        );
386        assert!(
387          output == CONSUMED,
388          "Parser `take_while1` doesn't return the string it consumed on success. \
389           Expected `{}`, got `{}`.",
390          CONSUMED,
391          output
392        );
393      }
394      other => panic!(
395        "Parser `take_while1` didn't succeed when it should have. \
396         Got `{:?}`.",
397        other
398      ),
399    };
400  }
401
402  #[test]
403  fn take_until_incomplete() {
404    use crate::bytes::take_until;
405
406    const INPUT: &str = "βèƒôřè";
407    const FIND: &str = "βèƒôřèÂßÇ";
408
409    let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(Streaming(INPUT));
410    match res {
411      Err(Err::Incomplete(_)) => (),
412      other => panic!(
413        "Parser `take_until` didn't require more input when it should have. \
414         Got `{:?}`.",
415        other
416      ),
417    };
418  }
419
420  #[test]
421  fn is_a_succeed() {
422    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
423    const MATCH: &str = "βèƒôřèÂßÇ";
424    const CONSUMED: &str = "βèƒôřèÂßÇ";
425    const LEFTOVER: &str = "áƒƭèř";
426    fn test(input: &str) -> IResult<&str, &str> {
427      take_while1(MATCH)(input)
428    }
429    match test(INPUT) {
430      Ok((extra, output)) => {
431        assert!(
432          extra == LEFTOVER,
433          "Parser `is_a` consumed leftover input. Leftover `{}`.",
434          extra
435        );
436        assert!(
437          output == CONSUMED,
438          "Parser `is_a` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
439          CONSUMED,
440          output
441        );
442      }
443      other => panic!(
444        "Parser `is_a` didn't succeed when it should have. \
445         Got `{:?}`.",
446        other
447      ),
448    };
449  }
450
451  #[test]
452  fn take_while1_fail() {
453    use crate::bytes::take_while1;
454
455    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
456    fn while1_s(c: char) -> bool {
457      c == '9'
458    }
459    fn test(input: &str) -> IResult<&str, &str> {
460      take_while1(while1_s)(input)
461    }
462    match test(INPUT) {
463      Err(Err::Error(_)) => (),
464      other => panic!(
465        "Parser `take_while1` didn't fail when it should have. \
466         Got `{:?}`.",
467        other
468      ),
469    };
470  }
471
472  #[test]
473  fn is_a_fail() {
474    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
475    const MATCH: &str = "Ûñℓúçƙ¥";
476    fn test(input: &str) -> IResult<&str, &str> {
477      take_while1(MATCH)(input)
478    }
479    match test(INPUT) {
480      Err(Err::Error(_)) => (),
481      other => panic!(
482        "Parser `is_a` didn't fail when it should have. Got `{:?}`.",
483        other
484      ),
485    };
486  }
487
488  #[test]
489  fn take_until_error() {
490    use crate::bytes::take_until;
491
492    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
493    const FIND: &str = "Ráñδô₥";
494
495    let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(Streaming(INPUT));
496    match res {
497      Err(Err::Incomplete(_)) => (),
498      other => panic!(
499        "Parser `take_until` didn't fail when it should have. \
500         Got `{:?}`.",
501        other
502      ),
503    };
504  }
505
506  #[test]
507  #[cfg(feature = "alloc")]
508  fn recognize_is_a() {
509    let a = "aabbab";
510    let b = "ababcd";
511
512    fn f(i: &str) -> IResult<&str, &str> {
513      many1(alt((tag("a"), tag("b")))).recognize().parse(i)
514    }
515
516    assert_eq!(f(&a[..]), Ok((&a[6..], &a[..])));
517    assert_eq!(f(&b[..]), Ok((&b[4..], &b[..4])));
518  }
519
520  #[test]
521  fn utf8_indexing() {
522    fn dot(i: &str) -> IResult<&str, &str> {
523      tag(".")(i)
524    }
525
526    let _ = dot("點");
527  }
528
529  #[cfg(feature = "alloc")]
530  #[test]
531  fn case_insensitive() {
532    fn test(i: &str) -> IResult<&str, &str> {
533      tag_no_case("ABcd")(i)
534    }
535    assert_eq!(test("aBCdefgh"), Ok(("efgh", "aBCd")));
536    assert_eq!(test("abcdefgh"), Ok(("efgh", "abcd")));
537    assert_eq!(test("ABCDefgh"), Ok(("efgh", "ABCD")));
538  }
539}