use super::*;
#[test]
fn test_normalize_keyword() {
assert_eq!(normalize_keyword("Hello World"), "helloworld");
assert_eq!(normalize_keyword(" Test "), "test");
assert_eq!(normalize_keyword("CAFÉ"), "cafe\u{0301}");
}
#[test]
fn test_parse_frontmatter_simple() {
let content = "---\ntitle: Hello\nauthor: World\n---\n\nBody text.";
let result = parse_frontmatter(content);
assert_eq!(result.body.trim(), "Body text.");
assert!(result.frontmatter.contains_key("title"));
assert!(result.frontmatter.contains_key("author"));
}
#[test]
fn frontmatter_tags_skip_non_string_yaml_scalars() {
let content = "---\ntags: [rust, 4, true, \"5\"]\n---\n\n#inline";
let result = parse_frontmatter(content);
assert_eq!(result.tags, vec!["rust", "5", "inline"]);
}
#[test]
fn date_like_frontmatter_string_gets_date_type() {
let content = "---\ndue: 2026-04-29\n---\n\nBody text.";
let result = parse_frontmatter(content);
assert_eq!(
result.frontmatter.get("due"),
Some(&FrontmatterValue::Date("2026-04-29".to_string()))
);
}
#[test]
fn parse_frontmatter_accepts_obsidian_unquoted_colon_scalars() {
let content = "---\ntitle: Artist: Song\nstatus: draft\n---\n\nBody text.";
let result = parse_frontmatter(content);
assert_eq!(result.body.trim(), "Body text.");
assert_eq!(
result.frontmatter.get("title"),
Some(&FrontmatterValue::String("Artist: Song".to_string()))
);
}
#[test]
fn yaml_sequence_items_with_commas_stay_atomic() {
let content = "---\nsources:\n - \"v4 recipe pipeline (oracle gpt-5.5-pro, 2026-05-26)\"\n---\n\nBody text.";
let result = parse_frontmatter(content);
assert_eq!(
result.frontmatter.get("sources"),
Some(&FrontmatterValue::List(vec![
"v4 recipe pipeline (oracle gpt-5.5-pro, 2026-05-26)".to_string()
]))
);
}
#[test]
fn test_parse_frontmatter_no_frontmatter() {
let content = "No frontmatter here.";
let result = parse_frontmatter(content);
assert_eq!(result.body, content);
assert!(result.frontmatter.is_empty());
}
#[test]
fn parse_frontmatter_ignores_horizontal_rule_after_body_text() {
let content = "# Long Note\n\nOpening section.\n\n---\n\nClosing section.";
let result = parse_frontmatter(content);
assert_eq!(result.body, content);
assert!(result.frontmatter.is_empty());
}
#[test]
fn parse_frontmatter_keeps_invalid_top_delimited_body() {
let content = "---\n# Morning notes\n\n- prep\n- service\n---\n\nLater section.";
let result = parse_frontmatter(content);
assert_eq!(result.body, content);
assert!(result.frontmatter.is_empty());
}
#[test]
fn test_extract_wikilinks() {
let content =
"Check [[My Note]] and [[Other#section]].\n```\n[[not a link]]\n```\nAnd [[Target|alias]].";
let links = extract_wikilinks(content);
assert_eq!(links.len(), 3);
assert_eq!(links[0].target, "My Note");
assert_eq!(links[1].target, "Other");
assert_eq!(links[1].heading, Some("section".to_string()));
assert_eq!(links[2].target, "Target");
assert_eq!(links[2].alias, Some("alias".to_string()));
}
#[test]
fn extract_wikilinks_skips_inline_code_spans() {
let content = "Show syntax as `[[wikilink]]` and ``[[wikilinks]]``.\nKeep [[Real Note]].";
let links = extract_wikilinks(content);
assert_eq!(links.len(), 1);
assert_eq!(links[0].target, "Real Note");
}
#[test]
fn test_extract_inline_tags() {
let content = "Some text #hello #world and #foo.\n```\n#not a tag\n```";
let tags = links::extract_inline_tags(content);
assert!(tags.contains(&"hello".to_string()));
assert!(tags.contains(&"world".to_string()));
assert!(tags.contains(&"foo".to_string()));
}
#[test]
fn test_reverse_index() {
let mut idx = FrontmatterReverseIndex::default();
idx.insert("path1.md", "tag", "rust");
idx.insert("path2.md", "tag", "rust");
idx.insert("path3.md", "tag", "python");
let results = idx.lookup("tag", "rust");
assert!(results.is_some());
assert_eq!(results.unwrap().len(), 2);
let results = idx.lookup("tag", "python");
assert!(results.is_some());
assert_eq!(results.unwrap().len(), 1);
}
#[test]
fn test_reverse_source_index() {
let mut idx = ReverseSourceIndex::default();
idx.insert("a.md".to_string(), "b.md".to_string());
idx.insert("c.md".to_string(), "b.md".to_string());
let sources = idx.get("b.md");
assert!(sources.is_some());
assert_eq!(sources.unwrap().len(), 2);
}