slope parser test, fix for longest string matching first
This commit is contained in:
parent
fb39301b31
commit
69c2869388
1 changed files with 82 additions and 3 deletions
|
@ -189,8 +189,16 @@ impl<'s> Slope<'s> {
|
||||||
N: AsRef<str> + Clone,
|
N: AsRef<str> + Clone,
|
||||||
{
|
{
|
||||||
|input| {
|
|input| {
|
||||||
let iter: std::collections::hash_map::Iter<'s, String, VariableChange> =
|
let iter: std::iter::Rev<std::vec::IntoIter<(&'s String, &'s VariableChange)>> = {
|
||||||
parser.slopes.iter();
|
let mut vec = parser
|
||||||
|
.slopes
|
||||||
|
.iter()
|
||||||
|
.collect::<Vec<(&'s String, &'s VariableChange)>>();
|
||||||
|
vec.sort_by_key(|(name, _)| name.len());
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
.into_iter()
|
||||||
|
.rev();
|
||||||
delimited(
|
delimited(
|
||||||
char('{'),
|
char('{'),
|
||||||
alt(iter
|
alt(iter
|
||||||
|
@ -259,7 +267,7 @@ mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
compiler::{
|
compiler::{
|
||||||
Loop, LoopCount, Marker, Note, Silence, Slope, Token, TokenVec, Tuplet, VariableChange,
|
Loop, LoopCount, Marker, Note, Silence, Slope, TokenVec, Tuplet, VariableChange,
|
||||||
},
|
},
|
||||||
parser::expression_parser,
|
parser::expression_parser,
|
||||||
};
|
};
|
||||||
|
@ -531,4 +539,75 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn slope() {
|
||||||
|
let normal = || VariableChange('n', "1".parse().unwrap());
|
||||||
|
let very_fancy = || VariableChange('n', "1+1".parse().unwrap());
|
||||||
|
let slopes = HashMap::from([
|
||||||
|
("nor".to_string(), very_fancy()),
|
||||||
|
("normal".to_string(), normal()),
|
||||||
|
]);
|
||||||
|
fn parser_builder<'s>(
|
||||||
|
slopes: &'s HashMap<String, VariableChange>,
|
||||||
|
) -> impl Fn(&str) -> IResult<&str, Slope<'s>> {
|
||||||
|
move |input: &str| {
|
||||||
|
Slope::parser(
|
||||||
|
&ParserBuilder::create_empty()
|
||||||
|
.notes(&["do", "ré", "mi"])
|
||||||
|
.slopes(slopes)
|
||||||
|
.variables(&['n'])
|
||||||
|
.build()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.parse(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let parser = parser_builder(&slopes);
|
||||||
|
let normal_value = normal();
|
||||||
|
let very_fancy_value = very_fancy();
|
||||||
|
let mut working_cases = vec![
|
||||||
|
(
|
||||||
|
"{normal.%}",
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
Slope(
|
||||||
|
&normal_value,
|
||||||
|
TokenVec(vec![Box::new(Silence), Box::new(Marker)]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("{normal}", ("", Slope(&normal_value, TokenVec(vec![])))),
|
||||||
|
("{nor}", ("", Slope(&very_fancy_value, TokenVec(vec![])))),
|
||||||
|
(
|
||||||
|
"{normal do}f",
|
||||||
|
("f", Slope(&normal_value, TokenVec(vec![Box::new(Note(0))]))),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
let mut not_working_cases = vec![
|
||||||
|
"",
|
||||||
|
"{",
|
||||||
|
"}",
|
||||||
|
"{normal",
|
||||||
|
"{fancy}",
|
||||||
|
"{norma do}",
|
||||||
|
"{do}",
|
||||||
|
"{}",
|
||||||
|
];
|
||||||
|
for (test, expected) in working_cases.drain(..) {
|
||||||
|
let output = parser(test);
|
||||||
|
if let Ok(result) = output {
|
||||||
|
assert_eq!(expected, result, "case \"{test}\"");
|
||||||
|
} else {
|
||||||
|
panic!("result of \"{test}\" was not Ok: {output:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for test in not_working_cases.drain(..) {
|
||||||
|
let output = parser(test);
|
||||||
|
assert!(
|
||||||
|
output.is_err(),
|
||||||
|
"result of \"{test}\" was not Err: {output:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue