pub mod ast;
pub mod error;
pub mod parser;
pub use ast::{Op, Pattern, Refrain};
pub use error::{RefrainError, Result};
pub use parser::parse;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn refrain_constructor_smoke() {
let r = Refrain::new("melody-a");
assert_eq!(r.name, "melody-a");
assert!(r.territorialize.is_none());
assert!(r.deterritorialize.is_none());
assert!(r.reterritorialize.is_none());
}
#[test]
fn ast_serde_roundtrip() {
let mut r = Refrain::new("t");
r.territorialize = Some(Pattern::Op(Op::Note {
pitch: "C4".into(),
dur: "q".into(),
}));
let s = serde_json::to_string(&r).unwrap();
let r2: Refrain = serde_json::from_str(&s).unwrap();
assert_eq!(r, r2);
}
#[test]
fn op_loop_holds_body() {
let body = Box::new(Pattern::Op(Op::Note {
pitch: "G4".into(),
dur: "e".into(),
}));
let op = Op::Loop { count: 4, body };
let s = serde_json::to_string(&op).unwrap();
assert!(s.contains("Loop"));
assert!(s.contains("\"count\":4"));
}
#[test]
fn parser_parses_empty_refrain() {
let r = parser::parse("(refrain x)").unwrap();
assert_eq!(r.name, "x");
assert!(r.territorialize.is_none());
}
}