#!/usr/bin/env python3 """Cases the prune rule has to get right, including ones the corpus lacks.""" import os import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from prune import prune class TestPrune(unittest.TestCase): def assertPrune(self, src, want): self.assertEqual(prune(src.strip("\n")), want.strip("\n")) def test_completed_top_level_item_goes(self): self.assertPrune("## To-Do\n- [x] Climb\n- [ ] Finish the backpack", "## To-Do\n- [ ] Finish the backpack") def test_finished_child_of_unfinished_parent_stays(self): src = ("## To-Do\n- [ ] Add OpenID to any apps that I control\n" " - [x] Runway\n - [ ] Shanty") self.assertPrune(src, src) def test_completed_checkbox_group_goes_entirely(self): self.assertPrune("## To-Do\n- [x] Add OpenID\n - [x] Runway\n - [x] Shanty\n- [ ] Keep", "## To-Do\n- [ ] Keep") def test_plain_group_label_protects_finished_children(self): src = ('## To-Do\n- Trellis "Ergonomics" Fixes\n' " - [x] Build up a justfile\n - [ ] Add in some unit tests") self.assertPrune(src, src) def test_plain_group_label_goes_when_group_completes(self): self.assertPrune('## To-Do\n- Trellis "Ergonomics" Fixes\n' " - [x] Build up a justfile\n - [x] Add in some unit tests\n- [ ] Keep", "## To-Do\n- [ ] Keep") def test_prose_bullets_are_never_touched(self): src = ("### DSA Election Research Tool\n - Work on android rust app\n" " - Move bike components that I want over") self.assertPrune(src, src) def test_headings_survive_an_emptied_section(self): self.assertPrune("## To-Do\n- [x] Climb\n\n## Personal\n- [ ] Keep", "## To-Do\n\n## Personal\n- [ ] Keep") def test_question_state_is_not_complete(self): src = "## To-Do\n - [?] Cincinnati Trash" self.assertPrune(src, src) def test_question_state_blocks_its_group(self): src = "## To-Do\n- [x] Parent\n - [?] Unsure" self.assertPrune(src, src) def test_wrapped_continuation_travels_with_its_item(self): self.assertPrune("## To-Do\n- [x] Could be good to do a review of the band-aids\n" " and instabilities\n- [ ] Keep", "## To-Do\n- [ ] Keep") def test_headings_reset_scope(self): # The [x] under Personal is top-level despite following a deeper bullet. self.assertPrune("## Work\n - [ ] Deep unfinished\n## Personal\n- [x] Climb", "## Work\n - [ ] Deep unfinished\n## Personal") def test_checkboxes_inside_a_code_fence_are_inert(self): src = "## Notes\n```\n- [x] not a real item\n```\n- [ ] Keep" self.assertPrune(src, src) def test_two_space_base_indent_corpus_style(self): self.assertPrune("## Work\n - [ ] Letter of Determination\n - [x] Check e-mails", "## Work\n - [ ] Letter of Determination") def test_date_heading_and_blank_structure_survive(self): self.assertPrune("# 2026-09-09\n\n## To-Do\n- [x] Climb\n\n# Notes\n", "# 2026-09-09\n\n## To-Do\n\n# Notes\n") if __name__ == "__main__": unittest.main(verbosity=2)