Files
nuwiki/crates/nuwiki-lsp/tests/parity_cluster_1.rs
T

187 lines
5.5 KiB
Rust
Raw Normal View History

//! Cluster 1 of the parity-audit punch list: per-wiki config keys
//! (vimwiki globals shipped through `initializationOptions`) and the
//! HTML renderer's table-span attributes.
use nuwiki_core::ast::{
BlockNode, DocumentNode, InlineNode, ParagraphNode, Span, TableCellNode, TableNode,
TableRowNode, TextNode,
};
use nuwiki_core::render::{HtmlRenderer, Renderer};
use nuwiki_lsp::config::{config_from_json, WikiConfig};
// ===== Per-wiki config keys =====
#[test]
fn defaults_carry_vimwiki_per_wiki_keys() {
let cfg = WikiConfig::empty();
assert_eq!(cfg.index, "index");
assert_eq!(cfg.diary_frequency, "daily");
assert_eq!(cfg.diary_start_week_day, "monday");
assert_eq!(cfg.diary_caption_level, 1);
assert_eq!(cfg.diary_sort, "desc");
assert_eq!(cfg.diary_header, "Diary");
assert_eq!(cfg.maxhi, 1);
assert_eq!(cfg.listsyms, " .oOX");
assert!(cfg.listsyms_propagate);
assert_eq!(cfg.list_margin, -1);
assert_eq!(cfg.links_space_char, " ");
assert!(cfg.nested_syntaxes.is_empty());
assert!(!cfg.auto_toc);
}
#[test]
fn raw_wiki_parses_every_new_key() {
let cfg = config_from_json(serde_json::json!({
"wikis": [{
"root": "/tmp/w",
"index": "home",
"diary_frequency": "weekly",
"diary_start_week_day": "sunday",
"diary_caption_level": 2,
"diary_sort": "asc",
"diary_header": "Journal",
"maxhi": 6,
"listsyms": "abcde",
"listsyms_propagate": false,
"list_margin": 2,
"links_space_char": "_",
"nested_syntaxes": { "python": "python", "ruby": "ruby" },
"auto_toc": true,
}],
}));
let w = &cfg.wikis[0];
assert_eq!(w.index, "home");
assert_eq!(w.diary_frequency, "weekly");
assert_eq!(w.diary_start_week_day, "sunday");
assert_eq!(w.diary_caption_level, 2);
assert_eq!(w.diary_sort, "asc");
assert_eq!(w.diary_header, "Journal");
assert_eq!(w.maxhi, 6);
assert_eq!(w.listsyms, "abcde");
assert!(!w.listsyms_propagate);
assert_eq!(w.list_margin, 2);
assert_eq!(w.links_space_char, "_");
assert_eq!(
w.nested_syntaxes.get("python").map(String::as_str),
Some("python")
);
assert!(w.auto_toc);
}
#[test]
fn legacy_single_wiki_shape_picks_up_defaults() {
let cfg = config_from_json(serde_json::json!({
"wiki_root": "/tmp/legacy",
}));
assert_eq!(cfg.wikis.len(), 1);
assert_eq!(cfg.wikis[0].index, "index");
assert_eq!(cfg.wikis[0].diary_frequency, "daily");
}
// ===== Table colspan/rowspan =====
fn cell(text: &str, col_span: bool, row_span: bool) -> TableCellNode {
let s = Span::default();
TableCellNode {
span: s,
children: vec![InlineNode::Text(TextNode {
span: s,
content: text.into(),
})],
col_span,
row_span,
}
}
fn table(rows: Vec<Vec<TableCellNode>>, has_header: bool) -> DocumentNode {
let span = Span::default();
let rows: Vec<TableRowNode> = rows
.into_iter()
.enumerate()
.map(|(i, cells)| TableRowNode {
span,
cells,
is_header: has_header && i == 0,
})
.collect();
DocumentNode {
span,
metadata: Default::default(),
children: vec![BlockNode::Table(TableNode {
span,
rows,
has_header,
alignments: Vec::new(),
})],
}
}
#[test]
fn colspan_marker_folds_into_lead_cell() {
// | a | b | c |
// | d | > | e | → second row has b spanning 2 cols (cell index 1 is >)
let doc = table(
vec![
vec![
cell("a", false, false),
cell("b", false, false),
cell("c", false, false),
],
vec![
cell("d", false, false),
cell(">", true, false),
cell("e", false, false),
],
],
false,
);
let out = HtmlRenderer::new().render_to_string(&doc).unwrap();
assert!(out.contains(r#"<td colspan="2">d</td>"#), "got: {out}");
assert!(!out.contains(r#"class="col-span""#));
}
#[test]
fn rowspan_marker_folds_into_lead_cell_above() {
let doc = table(
vec![
vec![cell("a", false, false), cell("b", false, false)],
vec![cell("c", false, false), cell("\\/", false, true)],
],
false,
);
let out = HtmlRenderer::new().render_to_string(&doc).unwrap();
assert!(out.contains(r#"<td rowspan="2">b</td>"#), "got: {out}");
}
#[test]
fn no_spans_emits_no_attrs() {
let doc = table(
vec![
vec![cell("a", false, false), cell("b", false, false)],
vec![cell("c", false, false), cell("d", false, false)],
],
false,
);
let out = HtmlRenderer::new().render_to_string(&doc).unwrap();
assert!(!out.contains("colspan="));
assert!(!out.contains("rowspan="));
}
// Make sure ParagraphNode is exercised so the import stays live.
#[test]
fn paragraph_render_is_unchanged() {
let p = DocumentNode {
span: Span::default(),
metadata: Default::default(),
children: vec![BlockNode::Paragraph(ParagraphNode {
span: Span::default(),
children: vec![InlineNode::Text(TextNode {
span: Span::default(),
content: "hi".into(),
})],
})],
};
let out = HtmlRenderer::new().render_to_string(&p).unwrap();
assert!(out.contains("hi"));
}