use sashite_sin::{Identifier, ParseError};
const REJECTED: &[(&str, ParseError)] = &[
("", ParseError::Empty),
("+", ParseError::InvalidLetter),
("-", ParseError::InvalidLetter),
("^", ParseError::InvalidLetter),
("1", ParseError::InvalidLetter),
("0", ParseError::InvalidLetter),
(" ", ParseError::InvalidLetter),
("\n", ParseError::InvalidLetter),
("\t", ParseError::InvalidLetter),
("@", ParseError::InvalidLetter),
("[", ParseError::InvalidLetter),
("`", ParseError::InvalidLetter),
("{", ParseError::InvalidLetter),
("CC", ParseError::TooLong),
("Kk", ParseError::TooLong),
("WW", ParseError::TooLong),
("c1", ParseError::TooLong),
("+C", ParseError::TooLong),
("C^", ParseError::TooLong),
(" C", ParseError::TooLong), ("C ", ParseError::TooLong), ("K\n", ParseError::TooLong),
(" ", ParseError::TooLong),
("abc", ParseError::TooLong),
("WWWW", ParseError::TooLong),
(" ", ParseError::TooLong),
("hello world", ParseError::TooLong),
("é", ParseError::TooLong), ("♔", ParseError::TooLong), ("Ké", ParseError::TooLong), ("🨀", ParseError::TooLong), ];
#[test]
fn every_entry_point_agrees_on_rejection() {
for &(input, expected) in REJECTED {
assert_eq!(Identifier::parse(input), Err(expected), "parse {input:?}");
assert_eq!(
input.parse::<Identifier>(),
Err(expected),
"FromStr {input:?}"
);
assert_eq!(
Identifier::try_from(input),
Err(expected),
"TryFrom<&str> {input:?}"
);
assert_eq!(
Identifier::try_from(input.as_bytes()),
Err(expected),
"TryFrom<&[u8]> {input:?}"
);
assert!(!Identifier::is_valid(input), "is_valid {input:?}");
}
}
#[test]
fn spec_section_6_4_invalid_forms_map_to_documented_errors() {
assert_eq!(Identifier::parse(""), Err(ParseError::Empty));
assert_eq!(Identifier::parse("CC"), Err(ParseError::TooLong));
assert_eq!(Identifier::parse("c1"), Err(ParseError::TooLong));
assert_eq!(Identifier::parse("+C"), Err(ParseError::TooLong));
assert_eq!(Identifier::parse("C^"), Err(ParseError::TooLong));
assert_eq!(Identifier::parse(" C"), Err(ParseError::TooLong));
assert_eq!(Identifier::parse("C "), Err(ParseError::TooLong));
assert_eq!(Identifier::parse("1"), Err(ParseError::InvalidLetter));
assert_eq!(Identifier::parse("é"), Err(ParseError::TooLong));
}
#[test]
fn error_messages_are_nonempty_distinct_and_usable_as_std_error() {
let variants = [
ParseError::Empty,
ParseError::TooLong,
ParseError::InvalidLetter,
];
let mut messages: Vec<String> = variants.iter().map(ToString::to_string).collect();
assert!(messages.iter().all(|m| !m.is_empty()));
messages.sort();
messages.dedup();
assert_eq!(
messages.len(),
variants.len(),
"Display messages must be distinct"
);
let as_error: &dyn std::error::Error = &ParseError::Empty;
assert!(!as_error.to_string().is_empty());
}