From 26dc7cf048e74924ff7989f8f0b84aa4910c3bf5 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Wed, 10 May 2023 10:23:56 -0500 Subject: [PATCH] restructure for better testing --- src/filetype/builder.rs | 88 ++++++++++++++++--- src/parser/parse.rs | 7 +- src/tests/test_metafile.rs | 19 ++-- .../pattern/base/default.meta | 0 .../pattern/test/array.meta | 0 .../pattern/test/blank/default.meta | 0 .../pattern/test/default/default.meta | 0 .../pattern/test/new/default.meta | 0 .../pattern/test/new/new.meta | 0 .../pattern/test/overwrite/default.meta | 0 .../pattern/test/overwrite/overwrite.meta | 0 .../pattern/test/parent/default.meta | 0 .../pattern/test/parent/parent.meta | 0 .../pattern/test/pattern.meta | 0 .../pattern/test/sub_pat/default.meta | 0 .../pattern/test/sub_pat/sub_pattern.meta | 0 .../source/expand.meta | 11 +-- .../source/sub_dir/sub_source.meta | 0 .../source/test_source.meta | 0 tests/files/expanded | 14 +-- .../pat/default.meta => expanded_html} | 0 .../files/test_site/pattern/pat/pattern.meta | 0 tests/metafile_builder.rs | 22 ++++- 23 files changed, 120 insertions(+), 41 deletions(-) rename {tests/files/test_site => test_site}/pattern/base/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/array.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/blank/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/default/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/new/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/new/new.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/overwrite/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/overwrite/overwrite.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/parent/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/parent/parent.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/pattern.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/sub_pat/default.meta (100%) rename {tests/files/test_site => test_site}/pattern/test/sub_pat/sub_pattern.meta (100%) rename {tests/files/test_site => test_site}/source/expand.meta (82%) rename {tests/files/test_site => test_site}/source/sub_dir/sub_source.meta (100%) rename {tests/files/test_site => test_site}/source/test_source.meta (100%) rename tests/files/{test_site/pattern/pat/default.meta => expanded_html} (100%) delete mode 100644 tests/files/test_site/pattern/pat/pattern.meta diff --git a/src/filetype/builder.rs b/src/filetype/builder.rs index f1f3c64..d9eb1d6 100644 --- a/src/filetype/builder.rs +++ b/src/filetype/builder.rs @@ -1,20 +1,37 @@ use crate::{parse_file, MetaFile, RootDirs, Source, Substitution}; -use color_eyre::Result; +use color_eyre::{eyre::bail, Result}; +use pandoc::{InputFormat, InputKind, OutputFormat, OutputKind, Pandoc, PandocOutput}; use std::{ collections::HashMap, fs, path::{Path, PathBuf}, }; -pub fn build_metafile(file: &MetaFile, dirs: &RootDirs, path: &Path) -> Result<()> { - Ok(std::fs::write( - find_dest(path, dirs)?, - metafile_to_string(file, dirs, None)?, - )?) +pub fn build_metafile(path: &Path, dirs: &RootDirs) -> Result<()> { + eprintln!("{:?}", path); + let file = fs::read_to_string(path)?; + let file = parse_file(&file)?; + + let pattern = get_pattern("base", &file, dirs)?; + let mut base = parse_file(&pattern)?; + + let html = get_source_html(&file, dirs)?; + + base.variables = file.variables; + base.arrays = file.arrays; + base.patterns = file.patterns; + + base.patterns.insert("SOURCE", &html); + + let output = metafile_to_string(&base, dirs, Some("base"))?; + + fs::write(find_dest(path, dirs)?, output)?; + Ok(()) } pub fn metafile_to_string(file: &MetaFile, dirs: &RootDirs, name: Option<&str>) -> Result { let mut output = String::default(); + let mut arrays = false; for section in file.source.iter() { match section { @@ -27,30 +44,77 @@ pub fn metafile_to_string(file: &MetaFile, dirs: &RootDirs, name: Option<&str>) let expanded = match sub { Substitution::Variable(key) => file .get_var(key) + // blank and default dont need to be processed + .filter(|val| *val != "BLANK" && *val != "DEFAULT") .map(|val| val.to_string()) .unwrap_or_default(), Substitution::Pattern(key) => get_pattern(key, file, dirs)?, // comments have already been removed at this point, // so we use them to mark keys for array substitution - Substitution::Array(key) => format!("-{{{key}}}"), + Substitution::Array(key) => { + arrays = true; + format!("-{{{key}}}") + } }; output.push_str(&format!("\n{}\n", expanded)); } } } - // deal with arrays - expand_arrays(output, file, name) + if arrays { + expand_arrays(output, file, name) + } else { + Ok(output) + } +} + +fn get_source_html(file: &MetaFile, dirs: &RootDirs) -> Result { + let file = metafile_to_string(file, dirs, Some("SOURCE"))?; + let mut pandoc = Pandoc::new(); + + pandoc + .set_input(InputKind::Pipe(file)) + .set_output(OutputKind::Pipe) + .set_input_format(InputFormat::Markdown, vec![]) + .set_output_format(OutputFormat::Html, vec![]); + + if let Ok(PandocOutput::ToBuffer(html)) = pandoc.execute() { + Ok(html) + } else { + bail!("pandoc could not write to buffer") + } } fn get_pattern(key: &str, file: &MetaFile, dirs: &RootDirs) -> Result { - let filename = file.get_pat(key).unwrap_or("default"); + // SOURCE is already expanded in the initial build_metafile() call + // we just need to return that + if key == "SOURCE" { + let source = file.patterns.get("SOURCE").unwrap_or(&""); + return Ok(source.to_string()); + } + + let mut filename = file.get_pat(key).unwrap_or("default"); + // BLANK returns nothing, so no more processing needs to be done + if filename == "BLANK" { + return Ok(String::new()); + }; + + if filename == "DEFAULT" { + filename = "default"; + } let pattern_path = key.replace('.', "/") + "/" + filename; let mut path = dirs.pattern.join(pattern_path); path.set_extension("meta"); + let pattern = &fs::read_to_string(path.to_str().unwrap_or_default())?; - let pattern = parse_file(pattern)?; + let mut pattern = parse_file(pattern)?; + + // copy over maps for expanding contained variables + pattern.variables = file.variables.clone(); + pattern.arrays = file.arrays.clone(); + pattern.patterns = file.patterns.clone(); + metafile_to_string(&pattern, dirs, Some(key)) } @@ -75,7 +139,7 @@ fn expand_arrays(output: String, file: &MetaFile, name: Option<&str>) -> Result< None } }) - // make a hash map of keys in the source to previously defined arrays + // make a hash map of [keys in source] -> [defined arrays] .map(|array| { let key: String; if let Some(name) = name { diff --git a/src/parser/parse.rs b/src/parser/parse.rs index c509760..7dbb3ae 100644 --- a/src/parser/parse.rs +++ b/src/parser/parse.rs @@ -84,8 +84,8 @@ fn parse_sub(pair: Pair) -> &'_ str { // all substitutions have the format of // *{ ... } // we return everything except: - // first two characters: (sigil and preceding brace) - // and the trailing brace + // first two chars (sigil and preceding brace) + // last char (trailing brace) &str[2..str.len() - 1] } // this function only gets called to parse substituiton patterns @@ -105,9 +105,8 @@ fn parse_assign(pair: Pair) -> (&'_ str, &'_ str) { if Rule::value == pair.as_rule() { let tmp = pair.as_str(); // blank and default shoud be handled by whoever is getting the value - // set it to empty strings to remove it from the HashMap if tmp == "BLANK" || tmp == "DEFAULT" { - return ("", ""); + return (key, tmp); } // remove surrounding quotes from values by returning // everything except first and last characters diff --git a/src/tests/test_metafile.rs b/src/tests/test_metafile.rs index 144849c..04cc4ea 100644 --- a/src/tests/test_metafile.rs +++ b/src/tests/test_metafile.rs @@ -1,10 +1,9 @@ -use crate::{metafile_to_string, parse_file, source, RootDirs, Source, Substitution}; +use crate::{parse_file, source, Source, Substitution}; use color_eyre::Result; use pretty_assertions::assert_eq; -use std::{fs, path::PathBuf}; -static SOURCE: &str = include_str!("../../tests/files/test_site/source/test_source.meta"); -static PATTERN: &str = include_str!("../../tests/files//test_site/pattern/test/pattern.meta"); +static SOURCE: &str = include_str!("../../test_site/source/test_source.meta"); +static PATTERN: &str = include_str!("../../test_site/pattern/test/pattern.meta"); #[test] fn test_metafile_gets() -> Result<()> { @@ -12,7 +11,7 @@ fn test_metafile_gets() -> Result<()> { assert_eq!(source.get_var("var").unwrap(), "GOOD"); assert_eq!(source.get_var("single_quotes").unwrap(), "GOOD"); - assert_eq!(source.get_var("blank"), None); + assert_eq!(source.get_var("blank").unwrap(), "BLANK"); assert_eq!(source.get_var("not_defined"), None); assert_eq!(source.get_arr("sub.array").unwrap(), ["GOOD", "GOOD"]); @@ -24,8 +23,8 @@ fn test_metafile_gets() -> Result<()> { assert_eq!(source.get_arr("not_defined"), None); assert_eq!(source.get_pat("test").unwrap(), "pattern"); - assert_eq!(source.get_pat("test.sub_pat"), None); - assert_eq!(source.get_pat("blank_pat"), None); + assert_eq!(source.get_pat("test.sub_pat").unwrap(), "DEFAULT"); + assert_eq!(source.get_pat("blank_pat").unwrap(), "BLANK"); assert_eq!(source.get_pat("not_defined"), None); Ok(()) @@ -36,7 +35,7 @@ fn parse_meta_file() -> Result<()> { let source = parse_file(SOURCE)?; assert_eq!(source.variables.get("var").unwrap(), &"GOOD"); - assert_eq!(source.variables.get("blank"), None); + assert_eq!(source.variables.get("blank").unwrap(), &"BLANK"); assert_eq!(source.variables.get("not_here"), None); assert_eq!( @@ -54,8 +53,8 @@ fn parse_meta_file() -> Result<()> { assert_eq!(source.arrays.get("not_defined"), None); assert_eq!(source.patterns.get("test").unwrap(), &"pattern"); - assert_eq!(source.patterns.get("test.sub_pat"), None); - assert_eq!(source.patterns.get("blank_pat"), None); + assert_eq!(source.patterns.get("test.sub_pat").unwrap(), &"DEFAULT"); + assert_eq!(source.patterns.get("blank_pat").unwrap(), &"BLANK"); assert_eq!(source.patterns.get("not_defined"), None); Ok(()) diff --git a/tests/files/test_site/pattern/base/default.meta b/test_site/pattern/base/default.meta similarity index 100% rename from tests/files/test_site/pattern/base/default.meta rename to test_site/pattern/base/default.meta diff --git a/tests/files/test_site/pattern/test/array.meta b/test_site/pattern/test/array.meta similarity index 100% rename from tests/files/test_site/pattern/test/array.meta rename to test_site/pattern/test/array.meta diff --git a/tests/files/test_site/pattern/test/blank/default.meta b/test_site/pattern/test/blank/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/blank/default.meta rename to test_site/pattern/test/blank/default.meta diff --git a/tests/files/test_site/pattern/test/default/default.meta b/test_site/pattern/test/default/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/default/default.meta rename to test_site/pattern/test/default/default.meta diff --git a/tests/files/test_site/pattern/test/new/default.meta b/test_site/pattern/test/new/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/new/default.meta rename to test_site/pattern/test/new/default.meta diff --git a/tests/files/test_site/pattern/test/new/new.meta b/test_site/pattern/test/new/new.meta similarity index 100% rename from tests/files/test_site/pattern/test/new/new.meta rename to test_site/pattern/test/new/new.meta diff --git a/tests/files/test_site/pattern/test/overwrite/default.meta b/test_site/pattern/test/overwrite/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/overwrite/default.meta rename to test_site/pattern/test/overwrite/default.meta diff --git a/tests/files/test_site/pattern/test/overwrite/overwrite.meta b/test_site/pattern/test/overwrite/overwrite.meta similarity index 100% rename from tests/files/test_site/pattern/test/overwrite/overwrite.meta rename to test_site/pattern/test/overwrite/overwrite.meta diff --git a/tests/files/test_site/pattern/test/parent/default.meta b/test_site/pattern/test/parent/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/parent/default.meta rename to test_site/pattern/test/parent/default.meta diff --git a/tests/files/test_site/pattern/test/parent/parent.meta b/test_site/pattern/test/parent/parent.meta similarity index 100% rename from tests/files/test_site/pattern/test/parent/parent.meta rename to test_site/pattern/test/parent/parent.meta diff --git a/tests/files/test_site/pattern/test/pattern.meta b/test_site/pattern/test/pattern.meta similarity index 100% rename from tests/files/test_site/pattern/test/pattern.meta rename to test_site/pattern/test/pattern.meta diff --git a/tests/files/test_site/pattern/test/sub_pat/default.meta b/test_site/pattern/test/sub_pat/default.meta similarity index 100% rename from tests/files/test_site/pattern/test/sub_pat/default.meta rename to test_site/pattern/test/sub_pat/default.meta diff --git a/tests/files/test_site/pattern/test/sub_pat/sub_pattern.meta b/test_site/pattern/test/sub_pat/sub_pattern.meta similarity index 100% rename from tests/files/test_site/pattern/test/sub_pat/sub_pattern.meta rename to test_site/pattern/test/sub_pat/sub_pattern.meta diff --git a/tests/files/test_site/source/expand.meta b/test_site/source/expand.meta similarity index 82% rename from tests/files/test_site/source/expand.meta rename to test_site/source/expand.meta index 3bfb4d6..0d3754d 100644 --- a/tests/files/test_site/source/expand.meta +++ b/test_site/source/expand.meta @@ -1,22 +1,23 @@ ${ - var1 = "GOOD" + var1 = 'GOOD' var2 = BLANK var3 = 'GOOD GOOD' } @{ - arr1 = ['GOOD'] + arr1 = [ 'GOOD' ] arr2 = [] - test.arr = ["GOOD", "GOOD GOOD"] + test.arr = [ 'GOOD', 'GOOD GOOD' ] } &{ - test = "array" + test = 'array' test.sub_pat = 'sub_pattern' - test.default = DEFAULT test.blank = BLANK + test.default = DEFAULT } + TESTS: var1 [VALUE]: ${var1} diff --git a/tests/files/test_site/source/sub_dir/sub_source.meta b/test_site/source/sub_dir/sub_source.meta similarity index 100% rename from tests/files/test_site/source/sub_dir/sub_source.meta rename to test_site/source/sub_dir/sub_source.meta diff --git a/tests/files/test_site/source/test_source.meta b/test_site/source/test_source.meta similarity index 100% rename from tests/files/test_site/source/test_source.meta rename to test_site/source/test_source.meta diff --git a/tests/files/expanded b/tests/files/expanded index 8e3f4dd..bc2fff8 100644 --- a/tests/files/expanded +++ b/tests/files/expanded @@ -6,20 +6,22 @@ var2 [BLANK]: var3 [VAL WITH SPACES]: GOOD GOOD - arr1 [VALUE]: GOOD arr2 [BLANK]: Pattern subs: -test [WITH ARRAY]: -

GOOD

-

GOOD GOOD

+test [WITH ARRAY]: +

+GOOD +

+GOOD GOOD +

test.sub_pat:

SUBPATTERN

test.default:

DEFAULT

-test.blank: +test.blank: -This comment should not be rendered: +This comment should not be rendered: diff --git a/tests/files/test_site/pattern/pat/default.meta b/tests/files/expanded_html similarity index 100% rename from tests/files/test_site/pattern/pat/default.meta rename to tests/files/expanded_html diff --git a/tests/files/test_site/pattern/pat/pattern.meta b/tests/files/test_site/pattern/pat/pattern.meta deleted file mode 100644 index e69de29..0000000 diff --git a/tests/metafile_builder.rs b/tests/metafile_builder.rs index 262ee9e..fd1da34 100644 --- a/tests/metafile_builder.rs +++ b/tests/metafile_builder.rs @@ -3,7 +3,7 @@ use metaforge::*; use pretty_assertions::assert_eq; use std::{fs, path::PathBuf}; -static PRE_EXPAND: &str = include_str!("./files/test_site/source/expand.meta"); +static PRE_EXPAND: &str = include_str!("../test_site/source/expand.meta"); static POST_EXPAND: &str = include_str!("./files/expanded"); #[test] @@ -13,13 +13,28 @@ fn test_metafile_to_str() -> Result<()> { let file = metafile_to_string(&metafile, &dirs, None)?; - assert_eq!(file, POST_EXPAND); + // requires newline to match with files ending newline + assert_eq!(file + "\n", POST_EXPAND); + + Ok(()) +} + +#[test] +#[ignore = "use different source file than expanded"] +fn test_metafile_builder() -> Result<()> { + let dirs = build_rootdir()?; + let path = PathBuf::from("test_site/source/expand_html.meta"); + build_metafile(&path, &dirs)?; + let source = fs::read_to_string("../test_site/site/expand_html.html")?; + let html = fs::read_to_string("./files/expand_html")?; + + assert_eq!(source, html); Ok(()) } fn build_rootdir() -> Result { - let dir = PathBuf::from("./tests/files/test_site"); + let dir = PathBuf::from("./test_site").canonicalize()?; let dirs = RootDirs { source: dir.join("source"), @@ -30,7 +45,6 @@ fn build_rootdir() -> Result { if dirs.build.exists() { fs::remove_dir(&dirs.build)?; } - fs::create_dir(&dirs.build)?; Ok(dirs) -- 2.44.2