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,83 @@
|
||||
//! Heading level rewriter — `nuwiki.heading.addLevel` /
|
||||
//! `nuwiki.heading.removeLevel`.
|
||||
|
||||
use nuwiki_core::syntax::vimwiki::VimwikiSyntax;
|
||||
use nuwiki_core::syntax::SyntaxPlugin;
|
||||
use nuwiki_lsp::commands::ops;
|
||||
use tower_lsp::lsp_types::Url;
|
||||
|
||||
fn parse(src: &str) -> nuwiki_core::ast::DocumentNode {
|
||||
VimwikiSyntax::new().parse(src)
|
||||
}
|
||||
|
||||
fn dummy_uri() -> Url {
|
||||
Url::parse("file:///tmp/note.wiki").unwrap()
|
||||
}
|
||||
|
||||
fn one_text_edit(edit: tower_lsp::lsp_types::WorkspaceEdit) -> tower_lsp::lsp_types::TextEdit {
|
||||
let changes = edit.changes.expect("expected changes map");
|
||||
let (_, edits) = changes.into_iter().next().expect("at least one uri");
|
||||
assert_eq!(edits.len(), 1, "expected exactly one text edit");
|
||||
edits.into_iter().next().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_heading_level_promotes_h2_to_h3() {
|
||||
let src = "== Sub ==\n";
|
||||
let doc = parse(src);
|
||||
let edit =
|
||||
ops::heading_change_level(src, &doc, &dummy_uri(), 0, 0, true, 1).expect("add_level edit");
|
||||
let te = one_text_edit(edit);
|
||||
assert_eq!(te.new_text, "=== Sub ===");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_heading_level_caps_at_6() {
|
||||
let src = "====== Deep ======\n";
|
||||
let doc = parse(src);
|
||||
let edit = ops::heading_change_level(src, &doc, &dummy_uri(), 0, 0, true, 1);
|
||||
// No-op because level 6 is the cap; clamp matched current level.
|
||||
assert!(edit.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_heading_level_demotes() {
|
||||
let src = "=== Mid ===\n";
|
||||
let doc = parse(src);
|
||||
let edit = ops::heading_change_level(src, &doc, &dummy_uri(), 0, 0, true, -1)
|
||||
.expect("remove_level edit");
|
||||
let te = one_text_edit(edit);
|
||||
assert_eq!(te.new_text, "== Mid ==");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_heading_level_at_h1_is_noop() {
|
||||
let src = "= Top =\n";
|
||||
let doc = parse(src);
|
||||
let edit = ops::heading_change_level(src, &doc, &dummy_uri(), 0, 0, true, -1);
|
||||
assert!(edit.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heading_change_returns_none_when_cursor_not_on_heading() {
|
||||
let src = "paragraph\n";
|
||||
let doc = parse(src);
|
||||
let edit = ops::heading_change_level(src, &doc, &dummy_uri(), 0, 0, true, 1);
|
||||
assert!(edit.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rewrite_heading_with_level_keeps_leading_whitespace_outside_span() {
|
||||
// The lexer's heading span starts at the first `=`, not the line's
|
||||
// start, so the leading whitespace that marks a "centered" heading
|
||||
// lives outside the edit range — preserved automatically. The
|
||||
// rewriter's output is just the `=...=` portion.
|
||||
let src = " = Title =\n";
|
||||
let doc = parse(src);
|
||||
let h = match &doc.children[0] {
|
||||
nuwiki_core::ast::BlockNode::Heading(h) => h,
|
||||
_ => panic!("expected heading"),
|
||||
};
|
||||
let new = ops::rewrite_heading_with_level(src, h.span, 2).unwrap();
|
||||
assert_eq!(new, "== Title ==");
|
||||
}
|
||||
Reference in New Issue
Block a user