From bdb1c9d1c93c531638e6f6b85a92319428d0a959 Mon Sep 17 00:00:00 2001 From: ef3d0c3e Date: Thu, 1 Aug 2024 14:23:41 +0200 Subject: [PATCH] Add document test macro --- src/document/document.rs | 41 +++++++++++++++++++ src/elements/code.rs | 3 +- src/elements/layout.rs | 87 ++++++++++++++++++++++++++++++++++------ src/elements/text.rs | 4 +- 4 files changed, 119 insertions(+), 16 deletions(-) diff --git a/src/document/document.rs b/src/document/document.rs index 6bbb1cd..a932721 100644 --- a/src/document/document.rs +++ b/src/document/document.rs @@ -231,3 +231,44 @@ impl<'a> DocumentAccessors<'a> for dyn Document<'a> + '_ { .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)*); + }}; +} +} diff --git a/src/elements/code.rs b/src/elements/code.rs index 06e5c66..d1fcf83 100644 --- a/src/elements/code.rs +++ b/src/elements/code.rs @@ -665,7 +665,7 @@ mod tests { static int INT32_MIN = 0x80000000; ``` %% -``Rust +``Rust, fn fact(n: usize) -> usize { match n @@ -681,7 +681,6 @@ fn fact(n: usize) -> usize None, )); let parser = LangParser::default(); - //let compiler = Compiler::new(Target::HTML, None); let doc = parser.parse(source, None); let borrow = doc.content().borrow(); diff --git a/src/elements/layout.rs b/src/elements/layout.rs index 9c481ec..d338180 100644 --- a/src/elements/layout.rs +++ b/src/elements/layout.rs @@ -30,9 +30,9 @@ use std::rc::Rc; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum LayoutToken { - BEGIN, - NEXT, - END, + Begin, + Next, + End, } /// Represents the type of a layout @@ -133,9 +133,9 @@ mod default_layouts { str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)), }; match token { - LayoutToken::BEGIN => Ok(format!(r#"
"#)), - LayoutToken::NEXT => panic!(), - LayoutToken::END => Ok(r#"
"#.to_string()), + LayoutToken::Begin => Ok(format!(r#"
"#)), + LayoutToken::Next => panic!(), + LayoutToken::End => Ok(r#"
"#.to_string()), } } _ => todo!(""), @@ -211,11 +211,11 @@ mod default_layouts { str => format!(r#" style={}"#, Compiler::sanitize(compiler.target(), str)), }; match token { - LayoutToken::BEGIN => Ok(format!( + LayoutToken::Begin => Ok(format!( r#"
"# )), - LayoutToken::NEXT => Ok(format!(r#"
"#)), - LayoutToken::END => Ok(r#"
"#.to_string()), + LayoutToken::Next => Ok(format!(r#"
"#)), + LayoutToken::End => Ok(r#"
"#.to_string()), } } _ => todo!(""), @@ -506,7 +506,7 @@ impl RegexRule for LayoutRule { location: token.clone(), layout: layout_type.clone(), id: 0, - token: LayoutToken::BEGIN, + token: LayoutToken::Begin, properties, }), ); @@ -583,7 +583,7 @@ impl RegexRule for LayoutRule { tokens.push(token.clone()); ( tokens.len() - 1, - LayoutToken::NEXT, + LayoutToken::Next, layout_type.clone(), properties, ) @@ -646,7 +646,7 @@ impl RegexRule for LayoutRule { let layout_type = layout_type.clone(); let id = tokens.len(); state.stack.pop(); - (id, LayoutToken::END, layout_type, properties) + (id, LayoutToken::End, layout_type, properties) }; parser.push( @@ -666,3 +666,66 @@ impl RegexRule for LayoutRule { // TODO fn lua_bindings<'lua>(&self, _lua: &'lua Lua) -> Option)>> { 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 }; + ); + } +} diff --git a/src/elements/text.rs b/src/elements/text.rs index 54a4ccd..8843bc4 100644 --- a/src/elements/text.rs +++ b/src/elements/text.rs @@ -19,8 +19,8 @@ use crate::parser::source::Token; #[derive(Debug)] pub struct Text { - pub(self) location: Token, - pub(self) content: String, + pub location: Token, + pub content: String, } impl Text {