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