refactor(tests): group test files by feature, drop phase/cluster naming
Restructures the integration test layout so each file is named after
what it covers, not the implementation phase it landed in.
nuwiki-core (renames only):
vimwiki_lexer → lexer
vimwiki_parser → parser
vimwiki_tags → tags
vimwiki_table_alignment → table_alignment
diary_period → diary
list_continuation → lists
transclusion_attrs → transclusion
+ table colspan/rowspan tests moved here from parity_cluster_1
nuwiki-lsp (renames + merges + one split):
cluster_a_list_rewriters → commands_lists
cluster_b_table_rewriters → commands_tables
cluster_c_link_helpers +
phase19_followlink_creates → commands_links
phase13_rename_commands → commands_files
phase17_colorize → commands_colorize
phase17_html_export → html_export
phase15_link_health → link_health
phase18_multi_wiki → multi_wiki
phase19_folding → folding
nav → navigation
lsp_helpers → helpers
phase16_diary +
diary_frequency → diary
phase11_plumbing +
parity_cluster_1 (config) → index_and_config
tags_index_and_lsp +
phase17_backfill → commands_tags
phase14_edit_commands → split into
commands_checkboxes,
commands_headings,
commands_tasks
Net: 30 → 28 integration-test files. 456 → 455 tests (the one
removed test was a dummy `paragraph_render_is_unchanged` whose only
purpose was to keep a `ParagraphNode` import alive in
parity_cluster_1; the import is exercised elsewhere now).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
//! Cluster 8b — multi-line list-item continuation.
|
||||
//!
|
||||
//! Lines indented strictly past the item's marker attach to the item
|
||||
//! rather than becoming a sibling paragraph. Mirrors upstream vimwiki
|
||||
//! + Markdown.
|
||||
|
||||
use nuwiki_core::ast::{BlockNode, InlineNode};
|
||||
use nuwiki_core::render::{HtmlRenderer, Renderer};
|
||||
use nuwiki_core::syntax::vimwiki::VimwikiSyntax;
|
||||
use nuwiki_core::syntax::SyntaxPlugin;
|
||||
|
||||
fn parse(src: &str) -> nuwiki_core::ast::DocumentNode {
|
||||
VimwikiSyntax::new().parse(src)
|
||||
}
|
||||
|
||||
fn single_list(doc: &nuwiki_core::ast::DocumentNode) -> &nuwiki_core::ast::ListNode {
|
||||
match &doc.children[0] {
|
||||
BlockNode::List(l) => l,
|
||||
other => panic!("expected list, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn text_of(inlines: &[InlineNode]) -> String {
|
||||
let mut out = String::new();
|
||||
for n in inlines {
|
||||
match n {
|
||||
InlineNode::Text(t) => out.push_str(&t.content),
|
||||
InlineNode::Bold(b) => out.push_str(&text_of(&b.children)),
|
||||
InlineNode::Italic(i) => out.push_str(&text_of(&i.children)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indented_line_after_marker_continues_the_item() {
|
||||
let doc = parse("- first item\n continuing here\n- second\n");
|
||||
assert_eq!(doc.children.len(), 1, "should be a single list block");
|
||||
let list = single_list(&doc);
|
||||
assert_eq!(list.items.len(), 2);
|
||||
let first = &list.items[0];
|
||||
let joined = text_of(&first.children);
|
||||
assert_eq!(joined, "first item continuing here");
|
||||
let second = &list.items[1];
|
||||
assert_eq!(text_of(&second.children), "second");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_continuation_lines_both_attach() {
|
||||
let doc = parse("- top\n middle\n bottom\n");
|
||||
let list = single_list(&doc);
|
||||
assert_eq!(list.items.len(), 1);
|
||||
let joined = text_of(&list.items[0].children);
|
||||
assert_eq!(joined, "top middle bottom");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unindented_line_breaks_the_list() {
|
||||
let doc = parse("- item\nflush against margin\n");
|
||||
// Two blocks: a list (just `- item`) and a paragraph.
|
||||
assert!(
|
||||
doc.children.len() >= 2,
|
||||
"want list + paragraph, got {}",
|
||||
doc.children.len()
|
||||
);
|
||||
match &doc.children[0] {
|
||||
BlockNode::List(l) => {
|
||||
assert_eq!(text_of(&l.items[0].children), "item");
|
||||
}
|
||||
other => panic!("expected list first, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blank_line_breaks_the_list_item() {
|
||||
// A blank line ends the current list (paragraph semantics).
|
||||
let doc = parse("- item\n\n orphaned\n");
|
||||
let list = single_list(&doc);
|
||||
assert_eq!(list.items.len(), 1);
|
||||
assert_eq!(text_of(&list.items[0].children), "item");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn continuation_works_for_nested_lists_too() {
|
||||
let doc = parse("- parent\n - child\n continued child\n- sibling\n");
|
||||
let list = single_list(&doc);
|
||||
assert_eq!(list.items.len(), 2);
|
||||
let parent = &list.items[0];
|
||||
let sublist = parent.sublist.as_ref().expect("nested list");
|
||||
assert_eq!(sublist.items.len(), 1);
|
||||
let child = &sublist.items[0];
|
||||
assert_eq!(text_of(&child.children), "child continued child");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn html_renderer_emits_a_single_li_per_item() {
|
||||
let doc = parse("- first item\n continuing here\n- second\n");
|
||||
let out = HtmlRenderer::new().render_to_string(&doc).unwrap();
|
||||
// Single <ul>, two <li> entries — the bug we're fixing produced
|
||||
// two adjacent <ul> elements with an interleaved <p>.
|
||||
assert_eq!(out.matches("<ul>").count(), 1, "got: {out}");
|
||||
assert_eq!(out.matches("<li>").count(), 2, "got: {out}");
|
||||
assert!(!out.contains("<p>"), "no orphan paragraph; got: {out}");
|
||||
assert!(out.contains("first item continuing here"), "got: {out}");
|
||||
}
|
||||
Reference in New Issue
Block a user