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>
57 lines
2.6 KiB
Rust
57 lines
2.6 KiB
Rust
//! The calendar through the CLI: `run <id> <json>` gives the engine's answer.
|
|
|
|
mod common;
|
|
|
|
use common::{empty_vault, exists, note, read_file, run};
|
|
use notescraft_engine::{Registry, Session, register_core};
|
|
use serde_json::{Value, json};
|
|
|
|
fn vault(name: &str) -> std::path::PathBuf {
|
|
let root = empty_vault(name);
|
|
note(&root, "Calendar/lunch.md", "---\ntitle: Lunch\nstart: 2026-10-20T12:00\nend: 2026-10-20T13:00\n---\n");
|
|
note(&root, "Calendar/clash.md", "---\ntitle: Dentist\nstart: 2026-10-20T12:30\nend: 2026-10-20T13:30\n---\n");
|
|
note(&root, "Calendar/standup.md", "---\ntitle: Standup\nstart: 2026-10-19T09:30\nrepeat: weekly\n---\n");
|
|
root
|
|
}
|
|
|
|
fn engine(root: &std::path::Path, id: &str, params: &Value) -> Value {
|
|
let mut registry = Registry::new();
|
|
register_core(&mut registry).expect("register");
|
|
let mut session = Session::open_read_only(root).expect("open");
|
|
registry.run(id, &mut session, params).expect("engine run")
|
|
}
|
|
|
|
#[test]
|
|
fn reads_match_the_engine_with_json() {
|
|
let root = vault("cal-cli-read");
|
|
for (id, params) in [
|
|
("calendar.agenda", json!({ "from": "2026-10-19", "to": "2026-11-02", "group": "day" })),
|
|
("calendar.free", json!({ "day": "2026-10-20", "min_minutes": 15 })),
|
|
("calendar.conflicts", json!({ "from": "2026-10-19", "to": "2026-10-25" })),
|
|
("calendar.year", json!({ "year": 2026 })),
|
|
] {
|
|
let out = run(&root, &["--json", "run", id, ¶ms.to_string()]);
|
|
assert_eq!(out.code, 0, "{id}: {}", out.stderr);
|
|
assert_eq!(out.result(), engine(&root, id, ¶ms), "{id}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn writes_work_and_a_repeating_event_needs_a_scope() {
|
|
let root = vault("cal-cli-write");
|
|
let added = run(&root, &["--json", "run", "calendar.add", &json!({ "text": "Gym 2026-11-03 at 7:00 for 1h" }).to_string()]);
|
|
assert_eq!(added.code, 0, "{}", added.stderr);
|
|
assert!(exists(&root, "Calendar/2026-11-03-gym.md"));
|
|
|
|
let missing = run(&root, &["--json", "run", "calendar.edit", &json!({ "id": "Calendar/standup.md", "fields": { "title": "x" } }).to_string()]);
|
|
assert_eq!(missing.code, 1);
|
|
assert_eq!(missing.error_code(), "command_failed");
|
|
assert!(missing.stdout.contains("this, following or all"), "{}", missing.stdout);
|
|
assert!(read_file(&root, "Calendar/standup.md").contains("title: Standup"), "nothing changed");
|
|
|
|
let scoped =
|
|
run(&root, &["--json", "run", "calendar.edit", &json!({ "id": "Calendar/standup.md", "scope": "all", "fields": { "title": "Sync" } }).to_string()]);
|
|
assert_eq!(scoped.code, 0, "{}", scoped.stderr);
|
|
assert!(read_file(&root, "Calendar/standup.md").contains("title: Sync"));
|
|
}
|