use mipl::prelude::*; mod common; use common::*; /// Assert that two parsers successively yield a certain number /// `n` of the same token. fn assert_parsers_same_till( mut a: Parser, mut b: Parser, n: usize ) { let mut i: usize = 0; while i < n { assert_eq!(a.next(), b.next()); i += 1; } } fn not_assert_parsers_same_till( mut a: Parser, mut b: Parser, n: usize ) { let mut i: usize = 0; let mut not: bool = false; while i < n { if a.next() != b.next() { not = true; break; } i += i; } assert!(not) } #[test] fn test_collect_until_exact_match_subparser() { let mut parser = setup_space_seps_parser( "a b c d e f g h" ); let mut known_subparser = setup_space_seps_parser( "a b c d" ); let mut subparser = CollectUntil::::subparse( "e".to_string(), &mut parser ); let mut i: usize = 0; while i < 4 { assert_eq!(known_subparser.next(), subparser.next()); i += 1; } } #[test] fn test_collect_until_is_newline() { let mut parser = setup_space_seps_parser( "a b\n c d e f g h" ); let mut known_subparser = setup_space_seps_parser( "a b" ); let mut subparser = CollectUntil::::subparse( (), &mut parser ); let mut i: usize = 0; while i < 2 { assert_eq!(known_subparser.next(), subparser.next()); i += 1; } } #[test] fn test_collect_while_exact_match() { let mut parser = setup_space_seps_parser( "a a a a e f g h" ); let mut known_subparser = setup_space_seps_parser( "a a a a" ); let mut subparser = CollectWhile::::subparse( "a".to_string(), &mut parser ); let mut i: usize = 0; while i < 4 { assert_eq!(known_subparser.next(), subparser.next()); i += 1; } } #[test] fn test_collect_if_sequence() { let mut parser = setup_space_seps_parser( "a b c d e f g h i j" ); let known_subparser = setup_space_seps_parser( "a b c d" ); let values: Vec = vec!["a", "b", "c", "d", "e"] .into_iter() .map(String::from) .collect(); let subparser = CollectIfSeq::::subparse( values, &mut parser ); assert_parsers_same_till( known_subparser, subparser, 4 ); } #[test] fn test_collect_if_exact_sequence() { let mut parser = setup_space_seps_parser( "a b c d e f g h i j" ); let known_subparser = setup_space_seps_parser( "a b" ); let values: Vec = vec!["a", "b", "c", "d"] .into_iter() .map(String::from) .collect(); let subparser = CollectIfExactSeq::::subparse( values, &mut parser ); assert_parsers_same_till( known_subparser, subparser, 2 ); } #[test] fn test_fail_collect_if_exact_sequence() { let mut parser = setup_space_seps_parser( "a b c d e f g h i j" ); let known_subparser = setup_space_seps_parser( "a b c d" ); let values: Vec = vec!["a", "b", "c", "d", "f"] .into_iter() .map(String::from) .collect(); let subparser = CollectIfExactSeq::::subparse( values, &mut parser ); not_assert_parsers_same_till( known_subparser, subparser, 4 ); } #[test] fn test_fail_collect_if_exact_keeps_parent_parser_intact() { let mut parser = setup_space_seps_parser( "a b c d" ); let initial_parser = parser.clone(); let values: Vec = vec!["a", "b", "c", "e"] .into_iter() .map(String::from) .collect(); let _subparser = CollectIfExactSeq::::subparse( values, &mut parser ); println!("{:#?}", parser); assert_parsers_same_till(parser, initial_parser, 4); } pub fn tokenize(src: String) -> Parser { let del_param = DelimitersParam{ discard: DiscardDelimiters::new( vec![ ' ', '\n', '\t' ] ), keep: KeepDelimiters::new( vec![ '(', ')', '~', '&', '|', '=', '>', '<', '*', '#' ] ) }; Parser::from(src, del_param) } fn test_until_doesnt_eat_ending_states_subparser(parser: &mut Parser) -> Parser { let states: Vec = vec!["*", "#"] .into_iter() .map(String::from) .collect(); let _expr_parser = CollectUntil::::subparse(states.clone(), parser); let states_parser = CollectWhile::::subparse(states, parser); states_parser } #[test] fn test_until_doesnt_eat_ending() { let src = "(l | r) & (~l | ~r) **# 16".to_string(); let mut flat_parser = tokenize(src); let known_parser_a = tokenize("**#".to_string()); let states_parser = test_until_doesnt_eat_ending_states_subparser(&mut flat_parser); assert_parsers_same_till(known_parser_a, states_parser, 3); }