Files
nuwiki/crates/nuwiki-lsp/tests/commands_files.rs
T
gffranco f4e086f981
CI / cargo fmt --check (push) Successful in 21s
CI / cargo clippy (push) Successful in 1m14s
CI / cargo test (push) Successful in 1m21s
CI / editor keymaps (push) Failing after 1m31s
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>
2026-05-13 01:30:55 +00:00

116 lines
4.0 KiB
Rust

//! Phase 13: pure-function tests for the rename helper + the file-delete
//! command. The async `Backend::rename` end-to-end (with `read_or_open`
//! hitting disk) is exercised by Phase 14+ integration but covered here
//! at the building-block level — same logic, no async client.
use std::path::PathBuf;
use nuwiki_lsp::rename::{build_new_uri, rewrite_wikilink_target};
use tower_lsp::lsp_types::Url;
// ===== rewrite_wikilink_target =====
#[test]
fn rewrites_plain_wikilink() {
let out = rewrite_wikilink_target("[[Old Page]]", "New Page").unwrap();
assert_eq!(out, "[[New Page]]");
}
#[test]
fn preserves_description() {
let out = rewrite_wikilink_target("[[Old|some text]]", "New").unwrap();
assert_eq!(out, "[[New|some text]]");
}
#[test]
fn preserves_anchor() {
let out = rewrite_wikilink_target("[[Old#section]]", "New").unwrap();
assert_eq!(out, "[[New#section]]");
}
#[test]
fn preserves_anchor_and_description() {
let out = rewrite_wikilink_target("[[Old#sec|desc]]", "New").unwrap();
assert_eq!(out, "[[New#sec|desc]]");
}
#[test]
fn rewrites_subdirectory_path() {
let out = rewrite_wikilink_target("[[old/page]]", "new/subdir/page").unwrap();
assert_eq!(out, "[[new/subdir/page]]");
}
#[test]
fn returns_none_for_non_wikilink_text() {
assert_eq!(rewrite_wikilink_target("just text", "X"), None);
assert_eq!(rewrite_wikilink_target("[[not closed", "X"), None);
assert_eq!(rewrite_wikilink_target("not opened]]", "X"), None);
assert_eq!(rewrite_wikilink_target("[]", "X"), None);
}
// ===== build_new_uri =====
#[test]
fn builds_uri_under_root() {
let uri = build_new_uri(&PathBuf::from("/tmp/wiki"), "Page", ".wiki").unwrap();
let path = uri.to_file_path().unwrap();
assert_eq!(path, PathBuf::from("/tmp/wiki/Page.wiki"));
}
#[test]
fn builds_uri_with_subdirectory() {
let uri = build_new_uri(&PathBuf::from("/tmp/wiki"), "dir/Page", ".wiki").unwrap();
let path = uri.to_file_path().unwrap();
assert_eq!(path, PathBuf::from("/tmp/wiki/dir/Page.wiki"));
}
#[test]
fn omits_duplicate_extension() {
let uri = build_new_uri(&PathBuf::from("/tmp/wiki"), "Page.wiki", ".wiki").unwrap();
let path = uri.to_file_path().unwrap();
assert_eq!(path, PathBuf::from("/tmp/wiki/Page.wiki"));
}
#[test]
fn ignores_empty_path_segments() {
// `//page` should not collapse into a filesystem-absolute path.
let uri = build_new_uri(&PathBuf::from("/tmp/wiki"), "//page", ".wiki").unwrap();
let path = uri.to_file_path().unwrap();
assert_eq!(path, PathBuf::from("/tmp/wiki/page.wiki"));
}
// ===== executeCommand: nuwiki.file.delete =====
//
// We don't need a Backend to drive `commands::execute` for the delete
// command — it ignores its first arg. The smoke test verifies the
// dispatcher + DeleteFile-op packaging.
#[tokio::test]
async fn file_delete_returns_workspace_edit_with_delete_op() {
use tower_lsp::lsp_types::{DocumentChangeOperation, DocumentChanges, ResourceOp};
// Building a real Backend requires a Client. For this unit test we use
// `commands::execute` with `Backend` typed as `&_` since the delete
// path doesn't touch backend state. Instead we drive the inner logic
// by constructing the args inline.
//
// Easier: shape the test as an integration test over the public
// module surface — call `commands::execute` once we expose a thin
// builder. For Phase 13 we test the JSON-shaped contract using the
// edits module directly, since that's what `file_delete` returns.
let uri = Url::parse("file:///tmp/note.wiki").unwrap();
let mut b = nuwiki_lsp::edits::WorkspaceEditBuilder::new();
b.file_op(nuwiki_lsp::edits::op_delete(uri.clone()));
let we = b.build();
let DocumentChanges::Operations(ops) = we.document_changes.unwrap() else {
panic!("expected Operations variant");
};
assert_eq!(ops.len(), 1);
match &ops[0] {
DocumentChangeOperation::Op(ResourceOp::Delete(d)) => {
assert_eq!(d.uri, uri);
}
other => panic!("expected DeleteFile op, got {other:?}"),
}
}