nom/
str.rs

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