Add document test macro

This commit is contained in:
ef3d0c3e 2024-08-01 14:23:41 +02:00
parent 4c8eb686ab
commit bdb1c9d1c9
4 changed files with 119 additions and 16 deletions

View file

@ -231,3 +231,44 @@ impl<'a> DocumentAccessors<'a> for dyn Document<'a> + '_ {
.ok() .ok()
} }
} }
#[cfg(test)]
pub mod tests
{
#[macro_export]
macro_rules! validate_document {
($container:expr, $idx:expr,) => {};
($container:expr, $idx:expr, $t:ty; $($tail:tt)*) => {{
let elem = &$container[$idx];
assert!(elem.downcast_ref::<$t>().is_some(), "Invalid element at index {}, expected {}", $idx, stringify!($t));
validate_document!($container, ($idx+1), $($tail)*);
}};
($container:expr, $idx:expr, $t:ty { $($field:ident == $value:expr),* }; $($tail:tt)*) => {{
let elem = &$container[$idx];
assert!(elem.downcast_ref::<$t>().is_some(), "Invalid element at index {}, expected {}", $idx, stringify!($t));
$(
let val = &elem.downcast_ref::<$t>().unwrap().$field;
assert!(*val == $value, "Invalid field {} for {} at index {}, expected {:#?}, found {:#?}",
stringify!($field),
stringify!($t),
$idx,
$value,
val);
)*
validate_document!($container, ($idx+1), $($tail)*);
}};
($container:expr, $idx:expr, $t:ty { $($ts:tt)* }; $($tail:tt)*) => {{
let elem = &$container[$idx];
assert!(elem.downcast_ref::<$t>().is_some(), "Invalid container element at index {}, expected {}", $idx, stringify!($t));
let contained = elem.as_container().unwrap().contained();
validate_document!(contained, 0, $($ts)*);
validate_document!($container, ($idx+1), $($tail)*);
}};
}
}

View file

@ -665,7 +665,7 @@ mod tests {
static int INT32_MIN = 0x80000000; static int INT32_MIN = 0x80000000;
``` ```
%<nml.code.push_block("Lua", "From Lua", "print(\"Hello, World!\")", nil)>% %<nml.code.push_block("Lua", "From Lua", "print(\"Hello, World!\")", nil)>%
``Rust ``Rust,
fn fact(n: usize) -> usize fn fact(n: usize) -> usize
{ {
match n match n
@ -681,7 +681,6 @@ fn fact(n: usize) -> usize
None, None,
)); ));
let parser = LangParser::default(); let parser = LangParser::default();
//let compiler = Compiler::new(Target::HTML, None);
let doc = parser.parse(source, None); let doc = parser.parse(source, None);
let borrow = doc.content().borrow(); let borrow = doc.content().borrow();

View file

@ -30,9 +30,9 @@ use std::rc::Rc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum LayoutToken { pub(crate) enum LayoutToken {
BEGIN, Begin,
NEXT, Next,
END, End,
} }
/// Represents the type of a layout /// Represents the type of a layout
@ -133,9 +133,9 @@ mod default_layouts {
str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)), str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)),
}; };
match token { match token {
LayoutToken::BEGIN => Ok(format!(r#"<div class="centered"{style}>"#)), LayoutToken::Begin => Ok(format!(r#"<div class="centered"{style}>"#)),
LayoutToken::NEXT => panic!(), LayoutToken::Next => panic!(),
LayoutToken::END => Ok(r#"</div>"#.to_string()), LayoutToken::End => Ok(r#"</div>"#.to_string()),
} }
} }
_ => todo!(""), _ => todo!(""),
@ -211,11 +211,11 @@ mod default_layouts {
str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)), str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)),
}; };
match token { match token {
LayoutToken::BEGIN => Ok(format!( LayoutToken::Begin => Ok(format!(
r#"<div class="split-container"><div class="split"{style}>"# r#"<div class="split-container"><div class="split"{style}>"#
)), )),
LayoutToken::NEXT => Ok(format!(r#"</div><div class="split"{style}>"#)), LayoutToken::Next => Ok(format!(r#"</div><div class="split"{style}>"#)),
LayoutToken::END => Ok(r#"</div></div>"#.to_string()), LayoutToken::End => Ok(r#"</div></div>"#.to_string()),
} }
} }
_ => todo!(""), _ => todo!(""),
@ -506,7 +506,7 @@ impl RegexRule for LayoutRule {
location: token.clone(), location: token.clone(),
layout: layout_type.clone(), layout: layout_type.clone(),
id: 0, id: 0,
token: LayoutToken::BEGIN, token: LayoutToken::Begin,
properties, properties,
}), }),
); );
@ -583,7 +583,7 @@ impl RegexRule for LayoutRule {
tokens.push(token.clone()); tokens.push(token.clone());
( (
tokens.len() - 1, tokens.len() - 1,
LayoutToken::NEXT, LayoutToken::Next,
layout_type.clone(), layout_type.clone(),
properties, properties,
) )
@ -646,7 +646,7 @@ impl RegexRule for LayoutRule {
let layout_type = layout_type.clone(); let layout_type = layout_type.clone();
let id = tokens.len(); let id = tokens.len();
state.stack.pop(); state.stack.pop();
(id, LayoutToken::END, layout_type, properties) (id, LayoutToken::End, layout_type, properties)
}; };
parser.push( parser.push(
@ -666,3 +666,66 @@ impl RegexRule for LayoutRule {
// TODO // TODO
fn lua_bindings<'lua>(&self, _lua: &'lua Lua) -> Option<Vec<(String, Function<'lua>)>> { None } fn lua_bindings<'lua>(&self, _lua: &'lua Lua) -> Option<Vec<(String, Function<'lua>)>> { None }
} }
#[cfg(test)]
mod tests {
use crate::elements::paragraph::Paragraph;
use crate::elements::text::Text;
use crate::parser::langparser::LangParser;
use crate::parser::source::SourceFile;
use crate::validate_document;
use super::*;
#[test]
fn parser() {
let source = Rc::new(SourceFile::with_content(
"".to_string(),
r#"
#+LAYOUT_BEGIN[style=A] Split
A
#+LAYOUT_BEGIN[style=B] Centered
B
#+LAYOUT_END
#+LAYOUT_NEXT[style=C]
C
#+LAYOUT_BEGIN[style=D] Split
D
#+LAYOUT_NEXT[style=E]
E
#+LAYOUT_END
#+LAYOUT_END
"#
.to_string(),
None,
));
let parser = LangParser::default();
let doc = parser.parse(source, None);
validate_document!(doc.content().borrow(), 0,
Layout { token == LayoutToken::Begin };
Paragraph {
Text { content == "A" };
};
Layout { token == LayoutToken::Begin };
Paragraph {
Text { content == "B" };
};
Layout { token == LayoutToken::End };
Layout { token == LayoutToken::Next };
Paragraph {
Text { content == "C" };
};
Layout { token == LayoutToken::Begin };
Paragraph {
Text { content == "D" };
};
Layout { token == LayoutToken::Next };
Paragraph {
Text { content == "E" };
};
Layout { token == LayoutToken::End };
Layout { token == LayoutToken::End };
);
}
}

View file

@ -19,8 +19,8 @@ use crate::parser::source::Token;
#[derive(Debug)] #[derive(Debug)]
pub struct Text { pub struct Text {
pub(self) location: Token, pub location: Token,
pub(self) content: String, pub content: String,
} }
impl Text { impl Text {