15d7f5e873
- notescraft-lint (rules, safe fixes, learned style) and notescraft-blocks (block model and edits); engine lint.* and block.* commands with CLI and MCP parity - Lint tab, underlines, slash menu with preview in Source and Visual, block grip and menu, Settings > Editor and lint, Vim block keys - Visual view: tables, note embeds, %% comments, wrapping property chips - Vault knowledge (Related tab, assistant sources, Settings) and calendar plugin - Sidebar top padding fixed, dot grid follows PaperCraft spacing, right-card tabs no longer cover the collapse button Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
60 lines
2.2 KiB
Rust
60 lines
2.2 KiB
Rust
//! Learned style votes and closest-title suggestions.
|
|
|
|
use notescraft_lint::style::{DEFAULT_MIN_NOTES, DEFAULT_THRESHOLD, StyleKind};
|
|
use notescraft_lint::suggest::closest;
|
|
use notescraft_lint::{HeadingStyle, Vote};
|
|
|
|
#[test]
|
|
fn style_needs_enough_notes_and_a_clear_majority() {
|
|
let mut vote = Vote::default();
|
|
for _ in 0..19 {
|
|
vote.add_note("- a\n- b\n\nDone 2026-10-17\n");
|
|
}
|
|
assert_eq!(vote.style(DEFAULT_MIN_NOTES, DEFAULT_THRESHOLD).list_marker, None);
|
|
vote.add_note("- a\n2026-01-02\n");
|
|
let style = vote.style(DEFAULT_MIN_NOTES, DEFAULT_THRESHOLD);
|
|
assert_eq!(style.list_marker, Some('-'));
|
|
assert_eq!(style.date_format.as_deref(), Some("YYYY-MM-DD"));
|
|
assert_eq!(style.heading_style, None);
|
|
for _ in 0..6 {
|
|
vote.add_note("* a\n");
|
|
}
|
|
assert_eq!(vote.style(DEFAULT_MIN_NOTES, DEFAULT_THRESHOLD).list_marker, None);
|
|
let report = vote.report();
|
|
let dash = report.iter().find(|s| s.kind == StyleKind::ListMarker && s.value == "-").expect("dash");
|
|
assert_eq!((dash.count, dash.total), (20, 26));
|
|
}
|
|
|
|
#[test]
|
|
fn removing_a_note_undoes_adding_it() {
|
|
let mut vote = Vote::default();
|
|
let note = "# T\n\n* a\n01/02/2026\n";
|
|
vote.add_note(note);
|
|
assert_eq!(vote.report().len(), 3);
|
|
vote.remove_note(note);
|
|
vote.remove_note(note);
|
|
assert_eq!(vote, Vote::default());
|
|
}
|
|
|
|
#[test]
|
|
fn headings_and_dates() {
|
|
let mut vote = Vote::default();
|
|
for _ in 0..25 {
|
|
vote.add_note("Title\n=====\n\nsee 31.12.2025\n");
|
|
}
|
|
let style = vote.style(DEFAULT_MIN_NOTES, DEFAULT_THRESHOLD);
|
|
assert_eq!(style.heading_style, Some(HeadingStyle::Setext));
|
|
assert_eq!(style.date_format.as_deref(), Some("DD.MM.YYYY"));
|
|
}
|
|
|
|
#[test]
|
|
fn closest_prefers_same_folder() {
|
|
let c = vec![("other/Release notes.md".to_string(), "Release notes".to_string()), ("mine/Release note.md".to_string(), "Release note".to_string())];
|
|
let (title, sim) = closest("Release nots", &c, "mine").expect("match");
|
|
assert_eq!(title, "Release note");
|
|
assert!(sim > 0.8 && sim <= 1.0);
|
|
assert_eq!(closest("Release nots", &c, "x").expect("match").0, "Release notes");
|
|
assert!(closest("Completely different", &c, "x").is_none());
|
|
assert!(closest("", &c, "x").is_none());
|
|
}
|