Skip to content

Latest commit

 

History

History
221 lines (181 loc) · 9.71 KB

File metadata and controls

221 lines (181 loc) · 9.71 KB

Test Catalog

Total: 170 tests (74 parse + 47 mutation + 49 unit)

Parse Tests (74 tests)

Golden tests that verify markdown → Task object parsing.

basic/ (10 tests)

Test Description
simple Single open task with title only
subtask Parent task with one child subtask (2-space indent)
deep_subtasks 4-level nested subtasks (level 0→1→2→3) with sibling at level 1
subtask_metadata Subtasks with their own tags, assignees, and projects
state_open Open state marker [ ] parsed as "open"
state_done Done state marker [x] parsed as "done"
state_blocked Blocked state marker [!] parsed as "blocked"
state_cancelled Cancelled state marker [-] parsed as "cancelled"
star_marker Asterisk * as list marker (alternative to -)
frontmatter YAML frontmatter block ignored, tasks parsed after

metadata/ (24 tests)

Test Description
assignee Single @name parsed into assignees list
multiple_assignees Multiple @alice @bob in one task
tag Single #tag parsed into tags list
multiple_tags Multiple #tag1 #tag2 in one task
project Simple +project sets project_path
hierarchical_project Nested +parent/child/leaf creates path hierarchy
version_project Version numbers in project +app/v1.2.3
project_decomposition Complex project path parsing and normalization
priority Priority marker (A) through (Z)
priority_first Priority at start of line before title text
due_date Due date due:2025-01-15 as explicit key:value
duration Time estimates ~2h, ~30m, ~1d converted to minutes
recurrence Recurrence patterns repeat:daily, repeat:weekly
position_date Single positional date becomes planned_date
position_dates_both Two positional dates: first=planned, second=done
custom_field Arbitrary key:value pairs stored in custom_fields
quoted_value Quoted values key:"value with spaces"
url_custom_field URL as custom field value link:https://...
escape_at Escaped \@ becomes literal @ in title
comprehensive All metadata types combined in one task
frontmatter_timezone YAML frontmatter with timezone and locale
frontmatter_locale Locale field in YAML frontmatter
frontmatter_invalid_timezone Invalid timezone stored without validation error
duplicate_priority Multiple priorities - first one used

inheritance/ (16 tests)

Test Description
inherit_project Task inherits +project from parent heading
inherit_tag Task inherits #tag from parent heading
inherit_section Tasks under heading inherit section context
heading_assignees @owner on heading inherited by tasks below
heading_custom_fields key:value on heading inherited by tasks below
heading_level_pop H1→H2→H1 resets inheritance context
heading_skip_level H1→H4 (skipping H2, H3) still builds path correctly
deep_heading_nesting 4+ heading levels build deep project paths
all_levels_max All 6 heading levels (H1-H6) with full metadata accumulation
custom_field_override Child heading env:prod overrides parent env:dev
multiple_custom_field_levels Custom fields accumulated from multiple heading levels
empty_project_segment Heading without +project between project headings
tag_deduplication Duplicate tags (heading + task) appear once in merged list
subtask_inheritance Subtask inherits parent task's tags and assignees
subtask_override_parent Subtask adds own metadata to inherited parent metadata
inheritance_tracking Separate tracking of inherited_* vs explicit_* fields

edge_cases/ (13 tests)

Test Description
empty_title Task line with only metadata, no title text
metadata_only_task Task with just #tag @user, empty title allowed
multiple_priorities (A) (B) (C) - only first priority used, others stripped
multiple_escapes Multiple \@ and \# escapes in same title
invalid_date_format Malformed dates: 2025-13-45 stored as-is, 25-01-15 ignored
duration_boundaries Edge values: ~0h, ~1m, ~999d
malformed_keyvalue key:value:extra:colons - only first colon splits
three_positional_dates Third date silently consumed, not in title
heading_level_7 Seven ####### is invalid heading, treated as text
odd_indent 3-space indent still creates subtask hierarchy
mixed_list_markers Both - and * markers in same file
unicode_title Unicode characters (emoji, CJK) in task title
long_title Very long title line with many metadata tokens

multifile/ (5 tests)

Test Description
file_links [[other.md]] link resolves and includes tasks
nested_links Linked file contains its own [[deeper.md]] links
link_after_heading Link within heading scope inherits heading context
circular_links A→B→A circular reference handled without infinite loop
missing_link [[nonexistent.md]] produces warning, continues parsing

realworld/ (4 tests)

Test Description
personal_tasks Typical personal todo list with mixed projects
project_hierarchy Multi-level project organization with teams
sprint_planning Agile sprint board with epics, stories, subtasks
team_standup Daily standup notes with blockers and assignments

Mutation Tests (47 tests)

Golden tests that verify Task modification and file rewriting.

basic/ (9 tests)

Test Description
mark_done state: done adds done_date, changes [ ] to [x]
mark_open state: open clears done_date, changes [x] to [ ]
mark_blocked state: blocked adds paused_date, changes to [!]
unblock state: open from blocked clears paused_date
change_title Update task title text, preserve other metadata
change_priority Add or change priority (A)
add_due_date Add due:2025-01-15 to existing task
update_estimate Change ~2h to ~4h
remove_field REMOVE sentinel clears optional field

metadata/ (4 tests)

Test Description
set_tags Replace explicit_tags list, merged with inherited
set_assignees Replace explicit_assignees list
set_custom_fields Replace explicit_custom_fields dict
preserve_inherited Mutation preserves inherited_* metadata from heading

recurrence/ (20 tests)

Test Description
daily Complete daily recurring task
weekly Complete weekly recurring task
biweekly Complete biweekly (2 weeks) recurring task
monthly Complete monthly recurring task
yearly Complete yearly recurring task
cancelled Cancel recurring task: no new occurrence created
blocked Block recurring task: paused_date set
no_planned_date Recurrence uses due_date when no planned_date
month_end Jan 31 monthly → Feb 28 (clamped)
year_end Dec 31 yearly → Dec 31 next year
leap_year Feb 29 yearly → Feb 28 in non-leap year
leap_month_end Jan 31 monthly in leap year → Feb 29
with_metadata Recurring task with tags, assignees preserved
2nd_tuesday Nth weekday pattern: 2nd Tuesday of month
last_friday Last weekday pattern: last Friday of month
15th_of_month Day of month pattern: 15th
31st_clamping 31st clamps to month end (Feb 28)
5th_monday_missing 5th Monday skips months without 5 Mondays
same_day_nth_weekday Complete on exact nth weekday → next month
natural_language_every_other Natural language: "every other week"

errors/ (2 tests)

Test Description
not_found Target task doesn't exist → fail status
ambiguous Multiple tasks match target → fail status

edge_cases/ (6 tests)

Test Description
remove_title title: REMOVE rejected, returns partial status
remove_state state: REMOVE rejected, returns partial status
blocked_to_done Blocked→done transition: done_date set, paused_date kept
done_date_already_set Reopen done task: clears done_date, keeps planned_date
multiple_changes Apply state, title, priority, tags, due_date, estimate at once
modify_subtask Target and mutate a subtask by title

multifile/ (1 test)

Test Description
linked_file_update Mutation targets task in linked file, updates correct file

realworld/ (4 tests)

Test Description
comprehensive Complex real-world mutation scenario
project_subtasks Mutate tasks within project hierarchy
batch_operations Multiple updates in batch
inherited_context Mutation preserves heading context

Unit Tests (49 tests)

Python unit tests for serialization and equality.

test_serialization.py

Class Tests Description
TestToMarkdownLine 4 Single task → markdown line conversion
TestToMarkdownBlock 3 Task with subtasks → indented block
TestToMarkdown 4 Full document reconstruction
TestFormatDuration 3 Minutes → ~Xh / ~Xm formatting
TestEquality 8 Task __eq__, __hash__, content_eq, identical_to

test_golden.py

Function Description
test_parse Parameterized: runs all parse/ golden tests
test_mutation Parameterized: runs all mutate/ golden tests