extern crate combine;
use combine::Parser;
use combine::parser::char::{digit, letter};
use combine::parser::range::range;
use combine::combinator::*;
#[test]
fn choice_empty() {
let mut parser = choice::<&mut [Token<&str>]>(&mut []);
let result_err = parser.parse("a");
assert!(result_err.is_err());
}
#[test]
fn tuple() {
let mut parser = (digit(), token(','), digit(), token(','), letter());
assert_eq!(parser.parse("1,2,z"), Ok((('1', ',', '2', ',', 'z'), "")));
}
#[test]
fn issue_99() {
let result = any().map(|_| ()).or(eof()).parse("");
assert!(result.is_ok(), "{:?}", result);
}
#[test]
fn not_followed_by_does_not_consume_any_input() {
let mut parser = not_followed_by(range("a")).map(|_| "").or(range("a"));
assert_eq!(parser.parse("a"), Ok(("a", "")));
let mut parser = range("a").skip(not_followed_by(range("aa")));
assert_eq!(parser.parse("aa"), Ok(("a", "a")));
assert!(parser.parse("aaa").is_err());
}
#[cfg(feature = "std")]
mod tests_std {
use super::*;
use combine::Parser;
use combine::stream::easy::{Error, Errors, ParseError};
use combine::parser::char::{char, digit, letter};
use combine::stream::state::{SourcePosition, State};
#[derive(Clone, PartialEq, Debug)]
struct CloneOnly {
s: String,
}
#[test]
fn token_clone_but_not_copy() {
let input = &[
CloneOnly { s: "x".to_string() },
CloneOnly { s: "y".to_string() },
][..];
let result = token(CloneOnly { s: "x".to_string() }).easy_parse(input);
assert_eq!(
result,
Ok((
CloneOnly { s: "x".to_string() },
&[CloneOnly { s: "y".to_string() }][..]
))
);
}
#[test]
fn sep_by_consumed_error() {
let mut parser2 = sep_by((letter(), letter()), token(','));
let result_err: Result<(Vec<(char, char)>, &str), ParseError<&str>> =
parser2.easy_parse("a,bc");
assert!(result_err.is_err());
}
#[test]
fn expected_retain_errors() {
let mut parser = digit()
.message("message")
.expected("N/A")
.expected("my expected digit");
assert_eq!(
parser.easy_parse(State::new("a")),
Err(Errors {
position: SourcePosition::default(),
errors: vec![
Error::Unexpected('a'.into()),
Error::Message("message".into()),
Error::Expected("my expected digit".into()),
],
})
);
}
#[test]
fn tuple_parse_error() {
let mut parser = (digit(), digit());
let result = parser.easy_parse(State::new("a"));
assert_eq!(
result,
Err(Errors {
position: SourcePosition::default(),
errors: vec![
Error::Unexpected('a'.into()),
Error::Expected("digit".into()),
],
})
);
}
#[test]
fn message_tests() {
let input = "hi";
let mut ok = char('h').message("not expected");
let mut empty0 = char('o').message("expected message");
let mut empty1 = char('o').message("expected message").map(|x| x);
let mut empty2 = char('o').map(|x| x).message("expected message");
let mut consumed0 = char('h').with(char('o')).message("expected message");
let mut consumed1 = char('h')
.with(char('o'))
.message("expected message")
.map(|x| x);
let mut consumed2 = char('h')
.with(char('o'))
.map(|x| x)
.message("expected message");
assert!(ok.easy_parse(State::new(input)).is_ok());
let empty_expected = Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Expected('o'.into()),
Error::Message("expected message".into()),
],
});
let consumed_expected = Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('i'.into()),
Error::Expected('o'.into()),
Error::Message("expected message".into()),
],
});
assert_eq!(empty0.easy_parse(State::new(input)), empty_expected);
assert_eq!(empty1.easy_parse(State::new(input)), empty_expected);
assert_eq!(empty2.easy_parse(State::new(input)), empty_expected);
assert_eq!(consumed0.easy_parse(State::new(input)), consumed_expected);
assert_eq!(consumed1.easy_parse(State::new(input)), consumed_expected);
assert_eq!(consumed2.easy_parse(State::new(input)), consumed_expected);
}
#[test]
fn expected_tests() {
let input = "hi";
let mut ok = char('h').expected("not expected");
let mut empty0 = char('o').expected("expected message");
let mut empty1 = char('o').expected("expected message").map(|x| x);
let mut empty2 = char('o').map(|x| x).expected("expected message");
let mut consumed0 = char('h').with(char('o')).expected("expected message");
let mut consumed1 = char('h')
.with(char('o'))
.expected("expected message")
.map(|x| x);
let mut consumed2 = char('h')
.with(char('o'))
.map(|x| x)
.expected("expected message");
assert!(ok.easy_parse(State::new(input)).is_ok());
let empty_expected = Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Expected("expected message".into()),
],
});
let consumed_expected = Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![Error::Unexpected('i'.into()), Error::Expected('o'.into())],
});
assert_eq!(empty0.easy_parse(State::new(input)), empty_expected);
assert_eq!(empty1.easy_parse(State::new(input)), empty_expected);
assert_eq!(empty2.easy_parse(State::new(input)), empty_expected);
assert_eq!(consumed0.easy_parse(State::new(input)), consumed_expected);
assert_eq!(consumed1.easy_parse(State::new(input)), consumed_expected);
assert_eq!(consumed2.easy_parse(State::new(input)), consumed_expected);
}
#[test]
fn try_tests() {
assert_eq!(
try(unexpected("test")).easy_parse(State::new("hi")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Unexpected("test".into()),
],
})
);
assert_eq!(
try(char('h').with(unexpected("test"))).easy_parse(State::new("hi")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('i'.into()),
Error::Unexpected("test".into()),
],
})
);
}
#[test]
fn sequence_error() {
let mut parser = (char('a'), char('b'), char('c'));
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![Error::Unexpected('c'.into()), Error::Expected('a'.into())],
})
);
assert_eq!(
parser.easy_parse(State::new("ac")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![Error::Unexpected('c'.into()), Error::Expected('b'.into())],
})
);
}
#[test]
fn optional_empty_ok_then_error() {
let mut parser = (optional(char('a')), char('b'));
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn nested_optional_empty_ok_then_error() {
let mut parser = ((optional(char('a')), char('b')), char('c'));
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn consumed_then_optional_empty_ok_then_error() {
let mut parser = (char('b'), optional(char('a')), char('b'));
assert_eq!(
parser.easy_parse(State::new("bc")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_parser_empty_err() {
let mut parser = choice((
(optional(char('a')), char('1')),
(optional(char('b')), char('2')).skip(char('d')),
));
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('a'.into()),
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_array_parser_empty_err() {
let mut parser = choice([
(optional(char('a')), char('1')),
(optional(char('b')), char('2')),
]);
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('a'.into()),
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_array_parser_empty_err_where_first_parser_delay_errors() {
let mut p1 = char('1');
let mut p2 = no_partial((optional(char('b')), char('2')).map(|t| t.1));
let mut parser =
choice::<[&mut Parser<Input = _, Output = _, PartialState = _>; 2]>([&mut p1, &mut p2]);
assert_eq!(
parser.easy_parse(State::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sep_end_by1_dont_eat_separator_twice() {
let mut parser = sep_end_by1(digit(), token(';'));
assert_eq!(parser.parse("1;;"), Ok((vec!['1'], ";")));
}
#[test]
fn count_min_max_empty_error() {
assert_eq!(
count_min_max(1, 1, char('a')).or(value(vec![])).parse("b"),
Ok((vec![], "b"))
);
}
}