generated from eblume/project-template
79 lines
2.9 KiB
Rust
79 lines
2.9 KiB
Rust
//! `Store::export` writes a faithful .md tree (tech-spec §5, slice 7).
|
|
|
|
use heph_core::{FixedClock, LocalStore, NewNode, NewTask, Store};
|
|
|
|
fn store() -> LocalStore {
|
|
LocalStore::open_in_memory(Box::new(FixedClock(1_700_000_000_000))).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn export_writes_a_file_per_node_with_frontmatter_and_body() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let mut s = store();
|
|
|
|
let doc = s
|
|
.create_node(NewNode::doc("Roof log", "# Roof\n\nCalled contractor."))
|
|
.unwrap();
|
|
let task = s
|
|
.create_task(NewTask {
|
|
title: "Fix roof".into(),
|
|
..Default::default()
|
|
})
|
|
.unwrap();
|
|
|
|
// task.create also makes a canonical context doc → 3 nodes total.
|
|
let count = s.export(dir.path()).unwrap();
|
|
assert_eq!(count, 3);
|
|
|
|
// The doc file exists with frontmatter and its body.
|
|
let doc_file = dir.path().join(format!("doc/{}.md", doc.id));
|
|
let doc_text = std::fs::read_to_string(&doc_file).unwrap();
|
|
assert!(doc_text.starts_with("---\n"));
|
|
assert!(doc_text.contains(&format!("id: {}\n", doc.id)));
|
|
assert!(doc_text.contains("kind: doc\n"));
|
|
assert!(doc_text.contains("title: \"Roof log\"\n"));
|
|
assert!(doc_text.ends_with("# Roof\n\nCalled contractor.\n"));
|
|
|
|
// The task file carries its scalars and the canonical-context link.
|
|
let task_file = dir.path().join(format!("task/{}.md", task.node_id));
|
|
let task_text = std::fs::read_to_string(&task_file).unwrap();
|
|
assert!(task_text.contains("kind: task\n"));
|
|
assert!(task_text.contains("state: outstanding\n"));
|
|
assert!(task_text.contains("type: canonical-context"));
|
|
}
|
|
|
|
#[test]
|
|
fn export_excludes_tombstoned_nodes() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let mut s = store();
|
|
|
|
let keep = s.create_node(NewNode::doc("Keep", "kept")).unwrap();
|
|
let gone = s.create_node(NewNode::doc("Gone", "gone")).unwrap();
|
|
s.tombstone_node(&gone.id).unwrap();
|
|
|
|
let count = s.export(dir.path()).unwrap();
|
|
assert_eq!(count, 1);
|
|
assert!(dir.path().join(format!("doc/{}.md", keep.id)).exists());
|
|
assert!(!dir.path().join(format!("doc/{}.md", gone.id)).exists());
|
|
}
|
|
|
|
#[test]
|
|
fn export_expands_bare_id_wiki_links_to_readable_labels() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let mut s = store();
|
|
|
|
let target = s.create_node(NewNode::doc("Roof", "shingles")).unwrap();
|
|
let body = format!(
|
|
"see [[{id}]] and [[{id}|my label]] and [[Unknown]]",
|
|
id = target.id
|
|
);
|
|
let doc = s.create_node(NewNode::doc("Notes", &body)).unwrap();
|
|
|
|
s.export(dir.path()).unwrap();
|
|
let text = std::fs::read_to_string(dir.path().join(format!("doc/{}.md", doc.id))).unwrap();
|
|
// Bare known id gains a readable label; a custom label and an
|
|
// unresolvable target are left as-authored.
|
|
assert!(text.contains(&format!("[[{}|Roof]]", target.id)), "{text}");
|
|
assert!(text.contains(&format!("[[{}|my label]]", target.id)));
|
|
assert!(text.contains("[[Unknown]]"));
|
|
}
|