From 88cce8691340627fc043f4959ea6c09f93c40fc3 Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Sun, 10 Mar 2024 21:32:37 -0700 Subject: [PATCH] Fix regex and add test I'm not sure why the ^$ anchors are not working. --- src/repository.rs | 2 +- src/wiki.rs | 94 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/repository.rs b/src/repository.rs index e0fa3a1..5e0d7d4 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -32,7 +32,7 @@ pub trait Repository { fn enumerate_files(&self, directory: &[&str]) -> Result, MyError>; } -pub struct RepoBox(Box); +pub struct RepoBox(pub Box); impl Deref for RepoBox { type Target = dyn Repository + Sync + Send; diff --git a/src/wiki.rs b/src/wiki.rs index 5318da2..d81c832 100644 --- a/src/wiki.rs +++ b/src/wiki.rs @@ -216,18 +216,23 @@ impl Wiki { pub fn read_file(&self, file_path: &[&str]) -> Result, MyError> { lazy_static! { - static ref RE: Regex = Regex::new(r"^{{(.+?)}}$").unwrap(); + static ref RE: Regex = Regex::new(r"\{\{(.+?)\}\}").unwrap(); } let mut res = self.0.repository.read_file(file_path); if let Ok(mut bytes) = res { while RE.is_match(&bytes) { - bytes = RE.replace(&bytes, |caps: &Captures| { - if let Ok(filename) = str::from_utf8(&caps[1]) { - self.0.repository.read_file(&[filename]).unwrap_or(b"**read error**".to_vec()) - } else { - b"**conversion error**".to_vec() - } - }).to_vec(); + bytes = RE + .replace(&bytes, |caps: &Captures| { + if let Ok(filename) = str::from_utf8(&caps[1]) { + self.0 + .repository + .read_file(&[filename]) + .unwrap_or(b"**read error**".to_vec()) + } else { + b"**conversion error**".to_vec() + } + }) + .to_vec(); } res = Ok(bytes) } @@ -329,3 +334,76 @@ impl Wiki { .collect()) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::repository::Repository; + use std::collections::HashMap; + + struct FakeRepo { + files: HashMap, + } + + impl Repository for FakeRepo { + fn capabilities(&self) -> RepositoryCapability { + RepositoryCapability::empty() + } + fn read_file(&self, file_path: &[&str]) -> Result, MyError> { + let key = file_path.join("/"); + if let Some(f) = self.files.get(&key) { + Ok(f.as_bytes().to_vec()) + } else { + Err(MyError::InvalidPath) + } + } + fn write_file( + &self, + _file_path: &[&str], + _message: &str, + _content: &str, + ) -> Result<(), MyError> { + unimplemented!(); + } + fn directory_exists(&self, _path: &[&str]) -> Result { + unimplemented!(); + } + fn file_exists(&self, _path: &[&str]) -> Result { + unimplemented!(); + } + + fn enumerate_files(&self, _directory: &[&str]) -> Result, MyError> { + Ok(vec![]) + } + } + + fn create_fake_wiki(files: HashMap) -> Wiki { + let settings = Settings::new("index.md", false); + let repo = FakeRepo { files }; + let repo_box = RepoBox(Box::new(repo)); + Wiki::new(settings, repo_box).unwrap() + } + + #[test] + fn test_reading() { + let wiki = create_fake_wiki(HashMap::from([( + "stuff.md".to_owned(), + "things".to_owned(), + )])); + let result = String::from_utf8(wiki.read_file(&["stuff.md"]).unwrap()).unwrap(); + assert_eq!(result, "things"); + } + + #[test] + fn test_transclusion() { + let wiki = create_fake_wiki(HashMap::from([ + ( + "stuff.md".to_owned(), + "things\n{{more_stuff.md}}\nmore things".to_owned(), + ), + ("more_stuff.md".to_owned(), "much more stuff".to_owned()), + ])); + let result = String::from_utf8(wiki.read_file(&["stuff.md"]).unwrap()).unwrap(); + assert_eq!(result, "things\nmuch more stuff\nmore things"); + } +}