]> git.huck.website - metaforge.git/commitdiff
restructure for better testing
authorHuck Boles <huck@huck.website>
Wed, 10 May 2023 15:23:56 +0000 (10:23 -0500)
committerHuck Boles <huck@huck.website>
Wed, 10 May 2023 15:23:56 +0000 (10:23 -0500)
23 files changed:
src/filetype/builder.rs
src/parser/parse.rs
src/tests/test_metafile.rs
test_site/pattern/base/default.meta [moved from tests/files/test_site/pattern/base/default.meta with 100% similarity]
test_site/pattern/test/array.meta [moved from tests/files/test_site/pattern/test/array.meta with 100% similarity]
test_site/pattern/test/blank/default.meta [moved from tests/files/test_site/pattern/test/blank/default.meta with 100% similarity]
test_site/pattern/test/default/default.meta [moved from tests/files/test_site/pattern/test/default/default.meta with 100% similarity]
test_site/pattern/test/new/default.meta [moved from tests/files/test_site/pattern/test/new/default.meta with 100% similarity]
test_site/pattern/test/new/new.meta [moved from tests/files/test_site/pattern/test/new/new.meta with 100% similarity]
test_site/pattern/test/overwrite/default.meta [moved from tests/files/test_site/pattern/test/overwrite/default.meta with 100% similarity]
test_site/pattern/test/overwrite/overwrite.meta [moved from tests/files/test_site/pattern/test/overwrite/overwrite.meta with 100% similarity]
test_site/pattern/test/parent/default.meta [moved from tests/files/test_site/pattern/test/parent/default.meta with 100% similarity]
test_site/pattern/test/parent/parent.meta [moved from tests/files/test_site/pattern/test/parent/parent.meta with 100% similarity]
test_site/pattern/test/pattern.meta [moved from tests/files/test_site/pattern/test/pattern.meta with 100% similarity]
test_site/pattern/test/sub_pat/default.meta [moved from tests/files/test_site/pattern/test/sub_pat/default.meta with 100% similarity]
test_site/pattern/test/sub_pat/sub_pattern.meta [moved from tests/files/test_site/pattern/test/sub_pat/sub_pattern.meta with 100% similarity]
test_site/source/expand.meta [moved from tests/files/test_site/source/expand.meta with 82% similarity]
test_site/source/sub_dir/sub_source.meta [moved from tests/files/test_site/source/sub_dir/sub_source.meta with 100% similarity]
test_site/source/test_source.meta [moved from tests/files/test_site/source/test_source.meta with 100% similarity]
tests/files/expanded
tests/files/expanded_html [moved from tests/files/test_site/pattern/pat/default.meta with 100% similarity]
tests/files/test_site/pattern/pat/pattern.meta [deleted file]
tests/metafile_builder.rs

index f1f3c646ca2b50652125c282e2c64afe362d7a0e..d9eb1d63c9ed53abf067bd6de621c23c8e87f1cb 100644 (file)
@@ -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<String> {
     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<String> {
+    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<String> {
-    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 {
index c50976049cda8c0477e718e23090ebca0aa5e9d5..7dbb3ae6f8d5f2ddc1a4f838308d669816c7873f 100644 (file)
@@ -84,8 +84,8 @@ fn parse_sub(pair: Pair<Rule>) -> &'_ 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<Rule>) -> (&'_ 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
index 144849c9ba5a742cd71a2bc98c32fda6787de0b0..04cc4ea0902ace2f992b0a8566fa2c00f968a0f7 100644 (file)
@@ -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(())
similarity index 82%
rename from tests/files/test_site/source/expand.meta
rename to test_site/source/expand.meta
index 3bfb4d606c4c6952a2b280924789b5d90bcce134..0d3754da62668037642d6b26570264fb919776bc 100644 (file)
@@ -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}
index 8e3f4dd8dc3ef5cd612712e9a39e761559e17095..bc2fff8dd1989384dc6367d9ec784315883fa826 100644 (file)
@@ -6,20 +6,22 @@ var2 [BLANK]:
 
 var3 [VAL WITH SPACES]:
 GOOD GOOD
-
 arr1 [VALUE]:
 GOOD
 arr2 [BLANK]:
 
 Pattern subs:
 
-test [WITH ARRAY]: 
-<p>GOOD</p>
-<p>GOOD GOOD</p>
+test [WITH ARRAY]:
+<p>
+GOOD
+</p><p>
+GOOD GOOD
+</p>
 test.sub_pat:
 <h1>SUBPATTERN</h1>
 test.default:
 <h1>DEFAULT</h1>
-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/pattern.meta b/tests/files/test_site/pattern/pat/pattern.meta
deleted file mode 100644 (file)
index e69de29..0000000
index 262ee9e56dc8b75d93f0d6bbc34e4d58fdbf5880..fd1da34ff6b23862f1483d63caa07529022d34ad 100644 (file)
@@ -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<RootDirs> {
-    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<RootDirs> {
     if dirs.build.exists() {
         fs::remove_dir(&dirs.build)?;
     }
-
     fs::create_dir(&dirs.build)?;
 
     Ok(dirs)