#[cfg(test)] mod test { #[cfg(feature = "alloc")] use crate::{branch::alt, bytes::complete::tag_no_case, combinator::recognize, multi::many}; use crate::{ bytes::complete::{is_a, is_not, tag, take, take_till, take_until}, error::{self, ErrorKind}, Err, IResult, }; #[test] fn tagtr_succeed() { const INPUT: &str = "Hello World!"; const TAG: &str = "Hello"; fn test(input: &str) -> IResult<&str, &str> { tag(TAG)(input) } match test(INPUT) { Ok((extra, output)) => { assert!(extra == " World!", "Parser `tag` consumed leftover input."); assert!( output == TAG, "Parser `tag` doesn't return the tag it matched on success. \ Expected `{}`, got `{}`.", TAG, output ); } other => panic!( "Parser `tag` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn tagtr_incomplete() { use crate::bytes::streaming::tag; const INPUT: &str = "Hello"; const TAG: &str = "Hello World!"; let res: IResult<_, _, error::Error<_>> = tag(TAG)(INPUT); match res { Err(Err::Incomplete(_)) => (), other => { panic!( "Parser `tag` didn't require more input when it should have. \ Got `{:?}`.", other ); } }; } #[test] fn tagtr_error() { const INPUT: &str = "Hello World!"; const TAG: &str = "Random"; // TAG must be closer than INPUT. let res: IResult<_, _, error::Error<_>> = tag(TAG)(INPUT); match res { Err(Err::Error(_)) => (), other => { panic!( "Parser `tag` didn't fail when it should have. Got `{:?}`.`", other ); } }; } #[test] fn take_s_succeed() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; let res: IResult<_, _, error::Error<_>> = take(9_usize)(INPUT); match res { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_s` consumed leftover input. Leftover `{}`.", extra ); assert!( output == CONSUMED, "Parser `take_s` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_s` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_until_succeed() { const INPUT: &str = "βèƒôřèÂßÇ∂áƒƭèř"; const FIND: &str = "ÂßÇ∂"; const CONSUMED: &str = "βèƒôřè"; const LEFTOVER: &str = "ÂßÇ∂áƒƭèř"; let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); match res { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_until`\ consumed leftover input. Leftover `{}`.", extra ); assert!( output == CONSUMED, "Parser `take_until`\ doesn't return the string it consumed on success. Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_until` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_s_incomplete() { use crate::bytes::streaming::take; const INPUT: &str = "βèƒôřèÂßÇá"; let res: IResult<_, _, (_, ErrorKind)> = take(13_usize)(INPUT); match res { Err(Err::Incomplete(_)) => (), other => panic!( "Parser `take` didn't require more input when it should have. \ Got `{:?}`.", other ), } } use crate::internal::Needed; fn is_alphabetic(c: char) -> bool { (c as u8 >= 0x41 && c as u8 <= 0x5A) || (c as u8 >= 0x61 && c as u8 <= 0x7A) } #[test] fn take_while() { use crate::bytes::streaming::take_while; fn f(i: &str) -> IResult<&str, &str> { take_while(is_alphabetic)(i) } let a = ""; let b = "abcd"; let c = "abcd123"; let d = "123"; assert_eq!(f(a), Err(Err::Incomplete(Needed::new(1)))); assert_eq!(f(b), Err(Err::Incomplete(Needed::new(1)))); assert_eq!(f(c), Ok((d, b))); assert_eq!(f(d), Ok((d, a))); } #[test] fn take_while1() { use crate::bytes::streaming::take_while1; fn f(i: &str) -> IResult<&str, &str> { take_while1(is_alphabetic)(i) } let a = ""; let b = "abcd"; let c = "abcd123"; let d = "123"; assert_eq!(f(a), Err(Err::Incomplete(Needed::new(1)))); assert_eq!(f(b), Err(Err::Incomplete(Needed::new(1)))); assert_eq!(f(c), Ok(("123", b))); assert_eq!( f(d), Err(Err::Error(error_position!(d, ErrorKind::TakeWhile1))) ); } #[test] fn take_till_s_succeed() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; fn till_s(c: char) -> bool { c == 'á' } fn test(input: &str) -> IResult<&str, &str> { take_till(till_s)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_till` consumed leftover input." ); assert!( output == CONSUMED, "Parser `take_till` doesn't return the string it consumed on success. \ Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_till` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_while_succeed_none() { use crate::bytes::complete::take_while; const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const CONSUMED: &str = ""; const LEFTOVER: &str = "βèƒôřèÂßÇáƒƭèř"; fn while_s(c: char) -> bool { c == '9' } fn test(input: &str) -> IResult<&str, &str> { take_while(while_s)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_while` consumed leftover input." ); assert!( output == CONSUMED, "Parser `take_while` doesn't return the string it consumed on success. \ Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_while` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn is_not_succeed() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const AVOID: &str = "£úçƙ¥á"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; fn test(input: &str) -> IResult<&str, &str> { is_not(AVOID)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `is_not` consumed leftover input. Leftover `{}`.", extra ); assert!( output == CONSUMED, "Parser `is_not` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `is_not` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_while_succeed_some() { use crate::bytes::complete::take_while; const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; fn while_s(c: char) -> bool { matches!(c, 'β' | 'è' | 'ƒ' | 'ô' | 'ř' | 'Â' | 'ß' | 'Ç') } fn test(input: &str) -> IResult<&str, &str> { take_while(while_s)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_while` consumed leftover input." ); assert!( output == CONSUMED, "Parser `take_while` doesn't return the string it consumed on success. \ Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_while` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn is_not_fail() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const AVOID: &str = "βúçƙ¥"; fn test(input: &str) -> IResult<&str, &str> { is_not(AVOID)(input) } match test(INPUT) { Err(Err::Error(_)) => (), other => panic!( "Parser `is_not` didn't fail when it should have. Got `{:?}`.", other ), }; } #[test] fn take_while1_succeed() { use crate::bytes::complete::take_while1; const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; fn while1_s(c: char) -> bool { matches!(c, 'β' | 'è' | 'ƒ' | 'ô' | 'ř' | 'Â' | 'ß' | 'Ç') } fn test(input: &str) -> IResult<&str, &str> { take_while1(while1_s)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `take_while1` consumed leftover input." ); assert!( output == CONSUMED, "Parser `take_while1` doesn't return the string it consumed on success. \ Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `take_while1` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_until_incomplete() { use crate::bytes::streaming::take_until; const INPUT: &str = "βèƒôřè"; const FIND: &str = "βèƒôřèÂßÇ"; let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); match res { Err(Err::Incomplete(_)) => (), other => panic!( "Parser `take_until` didn't require more input when it should have. \ Got `{:?}`.", other ), }; } #[test] fn is_a_succeed() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const MATCH: &str = "βèƒôřèÂßÇ"; const CONSUMED: &str = "βèƒôřèÂßÇ"; const LEFTOVER: &str = "áƒƭèř"; fn test(input: &str) -> IResult<&str, &str> { is_a(MATCH)(input) } match test(INPUT) { Ok((extra, output)) => { assert!( extra == LEFTOVER, "Parser `is_a` consumed leftover input. Leftover `{}`.", extra ); assert!( output == CONSUMED, "Parser `is_a` doesn't return the string it consumed on success. Expected `{}`, got `{}`.", CONSUMED, output ); } other => panic!( "Parser `is_a` didn't succeed when it should have. \ Got `{:?}`.", other ), }; } #[test] fn take_while1_fail() { use crate::bytes::complete::take_while1; const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; fn while1_s(c: char) -> bool { c == '9' } fn test(input: &str) -> IResult<&str, &str> { take_while1(while1_s)(input) } match test(INPUT) { Err(Err::Error(_)) => (), other => panic!( "Parser `take_while1` didn't fail when it should have. \ Got `{:?}`.", other ), }; } #[test] fn is_a_fail() { const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const MATCH: &str = "Ûñℓúçƙ¥"; fn test(input: &str) -> IResult<&str, &str> { is_a(MATCH)(input) } match test(INPUT) { Err(Err::Error(_)) => (), other => panic!( "Parser `is_a` didn't fail when it should have. Got `{:?}`.", other ), }; } #[test] fn take_until_error() { use crate::bytes::streaming::take_until; const INPUT: &str = "βèƒôřèÂßÇáƒƭèř"; const FIND: &str = "Ráñδô₥"; let res: IResult<_, _, (_, ErrorKind)> = take_until(FIND)(INPUT); match res { Err(Err::Incomplete(_)) => (), other => panic!( "Parser `take_until` didn't fail when it should have. \ Got `{:?}`.", other ), }; } #[test] #[cfg(feature = "alloc")] fn recognize_is_a() { use crate::{lib::std::vec::Vec, Parser}; let a = "aabbab"; let b = "ababcd"; fn f(i: &str) -> IResult<&str, &str> { recognize(many::<_, _, Vec<&str>, _, _>( 1.., alt((tag("a"), tag("b"))), )) .parse(i) } assert_eq!(f(a), Ok((&a[6..], a))); assert_eq!(f(b), Ok((&b[4..], &b[..4]))); } #[test] fn utf8_indexing() { fn dot(i: &str) -> IResult<&str, &str> { tag(".")(i) } let _ = dot("點"); } #[cfg(feature = "alloc")] #[test] fn case_insensitive() { fn test(i: &str) -> IResult<&str, &str> { tag_no_case("ABcd")(i) } assert_eq!(test("aBCdefgh"), Ok(("efgh", "aBCd"))); assert_eq!(test("abcdefgh"), Ok(("efgh", "abcd"))); assert_eq!(test("ABCDefgh"), Ok(("efgh", "ABCD"))); } }