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"; 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}