f4e086f981
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>
185 lines
4.6 KiB
Rust
185 lines
4.6 KiB
Rust
//! Cluster 4 — diary frequency / period primitives.
|
|
//! Tests the date math for ISO weeks, monthly, yearly periods.
|
|
|
|
use nuwiki_core::date::{DiaryDate, DiaryFrequency, DiaryPeriod};
|
|
|
|
#[test]
|
|
fn frequency_parses_canonical_strings() {
|
|
assert_eq!(DiaryFrequency::parse("daily"), DiaryFrequency::Daily);
|
|
assert_eq!(DiaryFrequency::parse("weekly"), DiaryFrequency::Weekly);
|
|
assert_eq!(DiaryFrequency::parse("monthly"), DiaryFrequency::Monthly);
|
|
assert_eq!(DiaryFrequency::parse("yearly"), DiaryFrequency::Yearly);
|
|
assert_eq!(DiaryFrequency::parse("WeEkLy"), DiaryFrequency::Weekly);
|
|
// Unknown falls back to Daily (mirrors vimwiki's permissive behaviour).
|
|
assert_eq!(DiaryFrequency::parse("hourly"), DiaryFrequency::Daily);
|
|
assert_eq!(DiaryFrequency::parse(""), DiaryFrequency::Daily);
|
|
}
|
|
|
|
#[test]
|
|
fn period_format_round_trips() {
|
|
let cases = [
|
|
(
|
|
"2026-05-12",
|
|
DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 12).unwrap()),
|
|
),
|
|
(
|
|
"2026-W19",
|
|
DiaryPeriod::Week {
|
|
iso_year: 2026,
|
|
iso_week: 19,
|
|
},
|
|
),
|
|
(
|
|
"2026-05",
|
|
DiaryPeriod::Month {
|
|
year: 2026,
|
|
month: 5,
|
|
},
|
|
),
|
|
("2026", DiaryPeriod::Year { year: 2026 }),
|
|
];
|
|
for (s, want) in cases {
|
|
let parsed = DiaryPeriod::parse(s).unwrap_or_else(|| panic!("parse {s}"));
|
|
assert_eq!(parsed, want, "parse({s})");
|
|
assert_eq!(parsed.format(), s, "format({s})");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn period_parse_rejects_garbage() {
|
|
assert!(DiaryPeriod::parse("garbage").is_none());
|
|
assert!(DiaryPeriod::parse("2026-W00").is_none());
|
|
assert!(DiaryPeriod::parse("2026-13").is_none()); // month 13
|
|
assert!(DiaryPeriod::parse("2026-").is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn iso_week_jan_1_can_belong_to_prior_year() {
|
|
// 2021-01-01 was a Friday → ISO week 53 of 2020.
|
|
let d = DiaryDate::from_ymd(2021, 1, 1).unwrap();
|
|
let p = DiaryPeriod::week_containing(d);
|
|
assert_eq!(
|
|
p,
|
|
DiaryPeriod::Week {
|
|
iso_year: 2020,
|
|
iso_week: 53
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn iso_week_dec_31_can_belong_to_next_year() {
|
|
// 2024-12-30 (Monday) is in ISO week 1 of 2025.
|
|
let d = DiaryDate::from_ymd(2024, 12, 30).unwrap();
|
|
let p = DiaryPeriod::week_containing(d);
|
|
assert_eq!(
|
|
p,
|
|
DiaryPeriod::Week {
|
|
iso_year: 2025,
|
|
iso_week: 1
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn iso_week_mid_year_is_consistent() {
|
|
// 2026-05-12 is a Tuesday in ISO week 20.
|
|
let d = DiaryDate::from_ymd(2026, 5, 12).unwrap();
|
|
let p = DiaryPeriod::week_containing(d);
|
|
assert_eq!(
|
|
p,
|
|
DiaryPeriod::Week {
|
|
iso_year: 2026,
|
|
iso_week: 20
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn week_next_and_prev_step_by_seven_days() {
|
|
let p = DiaryPeriod::Week {
|
|
iso_year: 2026,
|
|
iso_week: 20,
|
|
};
|
|
assert_eq!(
|
|
p.next(),
|
|
DiaryPeriod::Week {
|
|
iso_year: 2026,
|
|
iso_week: 21
|
|
}
|
|
);
|
|
assert_eq!(
|
|
p.prev(),
|
|
DiaryPeriod::Week {
|
|
iso_year: 2026,
|
|
iso_week: 19
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn week_next_crosses_year_boundary() {
|
|
// Week 53 of 2020 → week 53 ends; next should be week 1 of 2021.
|
|
let p = DiaryPeriod::Week {
|
|
iso_year: 2020,
|
|
iso_week: 53,
|
|
};
|
|
assert_eq!(
|
|
p.next(),
|
|
DiaryPeriod::Week {
|
|
iso_year: 2021,
|
|
iso_week: 1
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn month_next_wraps_to_january() {
|
|
let dec = DiaryPeriod::Month {
|
|
year: 2026,
|
|
month: 12,
|
|
};
|
|
assert_eq!(
|
|
dec.next(),
|
|
DiaryPeriod::Month {
|
|
year: 2027,
|
|
month: 1
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn month_prev_wraps_to_december() {
|
|
let jan = DiaryPeriod::Month {
|
|
year: 2026,
|
|
month: 1,
|
|
};
|
|
assert_eq!(
|
|
jan.prev(),
|
|
DiaryPeriod::Month {
|
|
year: 2025,
|
|
month: 12
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn year_next_and_prev_increment_by_one() {
|
|
let y = DiaryPeriod::Year { year: 2026 };
|
|
assert_eq!(y.next(), DiaryPeriod::Year { year: 2027 });
|
|
assert_eq!(y.prev(), DiaryPeriod::Year { year: 2025 });
|
|
}
|
|
|
|
#[test]
|
|
fn day_next_and_prev_still_work() {
|
|
let d = DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 12).unwrap());
|
|
assert_eq!(
|
|
d.next(),
|
|
DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 13).unwrap())
|
|
);
|
|
assert_eq!(
|
|
d.prev(),
|
|
DiaryPeriod::Day(DiaryDate::from_ymd(2026, 5, 11).unwrap())
|
|
);
|
|
}
|