Skip to content
Snippets Groups Projects
Commit 1f78541f authored by tnias's avatar tnias
Browse files

Add tests, reorganize and add length awareness

parent b55ee552
No related branches found
No related tags found
No related merge requests found
......@@ -5,8 +5,6 @@ it and implement a decoder it.
## ToDo
- [ ] make sure we do not parse more than we are supposed to do (limit ourselves by `size`)
- [ ] port the table driven tests from go
- [ ] write example cli that pretty prints the fixture's contents
- [ ] create documentation/tutorial/walkthrough and give it to `nom` community
- [ ] describt binary format (result of re)
......
......@@ -2,11 +2,12 @@
extern crate nom;
pub mod parser;
mod tests;
use std::fmt;
#[derive(Debug)]
pub struct Pattern {
size: u64,
version: String,
tempo: f32,
lines: Vec<Line>,
......@@ -41,7 +42,6 @@ impl fmt::Display for Line {
"{}{}",
if i%4 == 0 { "|" } else {""},
match *x { 0 => "-", 1 => "x", _ => "?" }
).as_str();
}
......
......@@ -17,18 +17,16 @@ named!(parse_line<&[u8], Line>,
)
);
named!(parse_pattern<&[u8], Pattern>,
/*
* _Assumption_: All provided data is to be interpreted
*/
named!(parse_pattern_inner<&[u8], Pattern>,
do_parse!(
tag!(b"SPLICE") >>
size: be_u64 >>
version: take_str!(32) >>
tempo: le_f32 >>
// TODO: make sure we do not parse more than we are supposed to do
// limit ourselves by `size`
lines: many0!(parse_line) >>
(
Pattern{
size: size,
version: version.trim_matches('\u{0}').to_string(),
tempo: tempo,
lines: lines,
......@@ -37,30 +35,28 @@ named!(parse_pattern<&[u8], Pattern>,
)
);
named!(parse_pattern<&[u8], Pattern>,
do_parse!(
// make sure magic bytes are present
tag!(b"SPLICE") >>
// read the length field and give that many bytes to `parse_pattern_inner`
data: map!(length_data!(be_u64), parse_pattern_inner) >>
(
match data {
// ignore all unused bytes at the end
IResult::Done(_,pattern) => pattern,
// XXX: what type of input could trigger this?
// TODO: make it not panic and handle it gracefully
// TODO: add extra testcase, that triggers this path
_ => panic!("this should never be reached")
}
)
)
);
/*
* Wrapper around inner macros.
*/
pub fn parse(i: &[u8]) -> IResult<&[u8], Pattern> {
parse_pattern(i)
}
/* - - - - - - - */
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {}
#[test]
fn test_fixtures() {
// TODO: implement(port) table based test
let b = include_bytes!("../fixtures/pattern_1.splice");
match parse_pattern(b) {
IResult::Done(_, p) => {
println!("{}", p);
panic!("yes.")
},
_ => panic!("nope.")
}
}
}
#[test]
fn gochallenge_tests() {
use parser::parse;
use nom::IResult;
use std::io::prelude::*;
use std::fs::File;
let table: Vec<(&str, &str)> = vec![
(
"fixtures/pattern_1.splice",
"Saved with HW Version: 0.808-alpha
Tempo: 120
(0) kick |x---|x---|x---|x---|
(1) snare |----|x---|----|x---|
(2) clap |----|x-x-|----|----|
(3) hh-open |--x-|--x-|x-x-|--x-|
(4) hh-close |x---|x---|----|x--x|
(5) cowbell |----|----|--x-|----|
"
),
(
"fixtures/pattern_2.splice",
"Saved with HW Version: 0.808-alpha
Tempo: 98.4
(0) kick |x---|----|x---|----|
(1) snare |----|x---|----|x---|
(3) hh-open |--x-|--x-|x-x-|--x-|
(5) cowbell |----|----|x---|----|
"
),
(
"fixtures/pattern_3.splice",
"Saved with HW Version: 0.808-alpha
Tempo: 118
(40) kick |x---|----|x---|----|
(1) clap |----|x---|----|x---|
(3) hh-open |--x-|--x-|x-x-|--x-|
(5) low-tom |----|---x|----|----|
(12) mid-tom |----|----|x---|----|
(9) hi-tom |----|----|-x--|----|
",
),
(
"fixtures/pattern_4.splice",
"Saved with HW Version: 0.909
Tempo: 240
(0) SubKick |----|----|----|----|
(1) Kick |x---|----|x---|----|
(99) Maracas |x-x-|x-x-|x-x-|x-x-|
(255) Low Conga |----|x---|----|x---|
",
),
(
"fixtures/pattern_5.splice",
"Saved with HW Version: 0.708-alpha
Tempo: 999
(1) Kick |x---|----|x---|----|
(2) HiHat |x-x-|x-x-|x-x-|x-x-|
",
),
];
for r in table.iter() {
println!("expected of {}:\n{}", r.0, r.1);
let mut buf: Vec<u8> = vec![];
let mut file = File::open(r.0).expect("file exists");
let _ = file.read_to_end(&mut buf).expect("file can be read");
match parse(&buf[..]) {
IResult::Done(_, pattern) => {
println!("Parsing is done.");
assert_eq!(r.1, format!("{}", pattern));
}
e => {
panic!("something went wrong. {:?}", e);
}
}
println!("--------------");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment