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::many1};
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      c == 'β'
306        || c == 'è'
307        || c == 'ƒ'
308        || c == 'ô'
309        || c == 'ř'
310        || c == 'è'
311        || c == 'Â'
312        || c == 'ß'
313        || c == 'Ç'
314    }
315    fn test(input: &str) -> IResult<&str, &str> {
316      take_while(while_s)(input)
317    }
318    match test(INPUT) {
319      Ok((extra, output)) => {
320        assert!(
321          extra == LEFTOVER,
322          "Parser `take_while` consumed leftover input."
323        );
324        assert!(
325          output == CONSUMED,
326          "Parser `take_while` doesn't return the string it consumed on success. \
327           Expected `{}`, got `{}`.",
328          CONSUMED,
329          output
330        );
331      }
332      other => panic!(
333        "Parser `take_while` didn't succeed when it should have. \
334         Got `{:?}`.",
335        other
336      ),
337    };
338  }
339
340  #[test]
341  fn is_not_fail() {
342    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
343    const AVOID: &str = "βúçƙ¥";
344    fn test(input: &str) -> IResult<&str, &str> {
345      is_not(AVOID)(input)
346    }
347    match test(INPUT) {
348      Err(Err::Error(_)) => (),
349      other => panic!(
350        "Parser `is_not` didn't fail when it should have. Got `{:?}`.",
351        other
352      ),
353    };
354  }
355
356  #[test]
357  fn take_while1_succeed() {
358    use crate::bytes::complete::take_while1;
359
360    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
361    const CONSUMED: &str = "βèƒôřèÂßÇ";
362    const LEFTOVER: &str = "áƒƭèř";
363    fn while1_s(c: char) -> bool {
364      c == 'β'
365        || c == 'è'
366        || c == 'ƒ'
367        || c == 'ô'
368        || c == 'ř'
369        || c == 'è'
370        || c == 'Â'
371        || c == 'ß'
372        || c == 'Ç'
373    }
374    fn test(input: &str) -> IResult<&str, &str> {
375      take_while1(while1_s)(input)
376    }
377    match test(INPUT) {
378      Ok((extra, output)) => {
379        assert!(
380          extra == LEFTOVER,
381          "Parser `take_while1` consumed leftover input."
382        );
383        assert!(
384          output == CONSUMED,
385          "Parser `take_while1` doesn't return the string it consumed on success. \
386           Expected `{}`, got `{}`.",
387          CONSUMED,
388          output
389        );
390      }
391      other => panic!(
392        "Parser `take_while1` didn't succeed when it should have. \
393         Got `{:?}`.",
394        other
395      ),
396    };
397  }
398
399  #[test]
400  fn take_until_incomplete() {
401    use crate::bytes::streaming::take_until;
402
403    const INPUT: &str = "βèƒôřè";
404    const FIND: &str = "βèƒôřèÂßÇ";
405
406    let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT);
407    match res {
408      Err(Err::Incomplete(_)) => (),
409      other => panic!(
410        "Parser `take_until` didn't require more input when it should have. \
411         Got `{:?}`.",
412        other
413      ),
414    };
415  }
416
417  #[test]
418  fn is_a_succeed() {
419    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
420    const MATCH: &str = "βèƒôřèÂßÇ";
421    const CONSUMED: &str = "βèƒôřèÂßÇ";
422    const LEFTOVER: &str = "áƒƭèř";
423    fn test(input: &str) -> IResult<&str, &str> {
424      is_a(MATCH)(input)
425    }
426    match test(INPUT) {
427      Ok((extra, output)) => {
428        assert!(
429          extra == LEFTOVER,
430          "Parser `is_a` consumed leftover input. Leftover `{}`.",
431          extra
432        );
433        assert!(
434          output == CONSUMED,
435          "Parser `is_a` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
436          CONSUMED,
437          output
438        );
439      }
440      other => panic!(
441        "Parser `is_a` didn't succeed when it should have. \
442         Got `{:?}`.",
443        other
444      ),
445    };
446  }
447
448  #[test]
449  fn take_while1_fail() {
450    use crate::bytes::complete::take_while1;
451
452    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
453    fn while1_s(c: char) -> bool {
454      c == '9'
455    }
456    fn test(input: &str) -> IResult<&str, &str> {
457      take_while1(while1_s)(input)
458    }
459    match test(INPUT) {
460      Err(Err::Error(_)) => (),
461      other => panic!(
462        "Parser `take_while1` didn't fail when it should have. \
463         Got `{:?}`.",
464        other
465      ),
466    };
467  }
468
469  #[test]
470  fn is_a_fail() {
471    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
472    const MATCH: &str = "Ûñℓúçƙ¥";
473    fn test(input: &str) -> IResult<&str, &str> {
474      is_a(MATCH)(input)
475    }
476    match test(INPUT) {
477      Err(Err::Error(_)) => (),
478      other => panic!(
479        "Parser `is_a` didn't fail when it should have. Got `{:?}`.",
480        other
481      ),
482    };
483  }
484
485  #[test]
486  fn take_until_error() {
487    use crate::bytes::streaming::take_until;
488
489    const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
490    const FIND: &str = "Ráñδô₥";
491
492    let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT);
493    match res {
494      Err(Err::Incomplete(_)) => (),
495      other => panic!(
496        "Parser `take_until` didn't fail when it should have. \
497         Got `{:?}`.",
498        other
499      ),
500    };
501  }
502
503  #[test]
504  #[cfg(feature = "alloc")]
505  fn recognize_is_a() {
506    let a = "aabbab";
507    let b = "ababcd";
508
509    fn f(i: &str) -> IResult<&str, &str> {
510      recognize(many1(alt((tag("a"), tag("b")))))(i)
511    }
512
513    assert_eq!(f(&a[..]), Ok((&a[6..], &a[..])));
514    assert_eq!(f(&b[..]), Ok((&b[4..], &b[..4])));
515  }
516
517  #[test]
518  fn utf8_indexing() {
519    fn dot(i: &str) -> IResult<&str, &str> {
520      tag(".")(i)
521    }
522
523    let _ = dot("點");
524  }
525
526  #[cfg(feature = "alloc")]
527  #[test]
528  fn case_insensitive() {
529    fn test(i: &str) -> IResult<&str, &str> {
530      tag_no_case("ABcd")(i)
531    }
532    assert_eq!(test("aBCdefgh"), Ok(("efgh", "aBCd")));
533    assert_eq!(test("abcdefgh"), Ok(("efgh", "abcd")));
534    assert_eq!(test("ABCDefgh"), Ok(("efgh", "ABCD")));
535  }
536}