branch: master commit c02a28f3883a5b0189357b71a93944063079a87c Author: Ian Dunn <du...@gnu.org> Commit: Ian Dunn <du...@gnu.org>
Various fixes from testing * org-edna.el (org-edna--function-for-key): Return nil on invalid input (org-edna--expand-single-sexp-form): Quote arguments to consideration. (org-edna-finder/match): Introduced 'buffer SCOPE to match the nil argument in org-map-entries. * org-edna-tests.el: Protect all access to the test file in unwind-protect. Use `org-edna-find-test-heading' in all tests instead of org-id-find. (org-edna-test-restore-test-file): New function to revert test file. (org-edna-test-compare-todos): (org-edna-test-change-todo-state): (org-edna-test-check-block): (org-edna-test-mark-done): (org-edna-test-mark-todo): New helper functions. (org-edna-doc-test/ancestors): (org-edna-doc-test/descendants): (org-edna-doc-test/laundry): (org-edna-doc-test/nightly): (org-edna-doc-test/daily): (org-edna-doc-test/weekly): (org-edna-doc-test/basic-shower): New full tests from the documentation. * org-edna.org (Scheduled/Deadline): Fixed up examples to render on info. (TODO State): Added example. (Chain Property): Added example. (Property): Fixed examples. (Conditions): Changed heading names. --- org-edna-tests.el | 963 +++++++++++++++++++++++++++++++++++------------------ org-edna-tests.org | 131 ++++++++ org-edna.el | 19 +- org-edna.info | 192 +++++++---- org-edna.org | 107 ++++-- 5 files changed, 1006 insertions(+), 406 deletions(-) diff --git a/org-edna-tests.el b/org-edna-tests.el index da766a9..da8e437 100644 --- a/org-edna-tests.el +++ b/org-edna-tests.el @@ -64,10 +64,42 @@ (defconst org-edna-test-relative-archived-child "a4b6131e-0560-4201-86d5-f32b36363431") (defconst org-edna-test-relative-child-with-done "4a1d74a2-b032-47da-a823-b32f5cab0aae") +(defun org-edna-test-restore-test-file () + "Restore the test file back to its original state." + (with-current-buffer (get-file-buffer org-edna-test-file) + (revert-buffer nil t))) + (defun org-edna-find-test-heading (id) - "Find the test heading with id ID." + "Find the test heading with id ID. + +This avoids org-id digging into its internal database." (org-id-find-id-in-file id org-edna-test-file t)) +;; _test exists to give more detailed reports in ERT output. +(defun org-edna-test-compare-todos (pom expected-state _test) + (string-equal (org-entry-get pom "TODO") expected-state)) + +(defun org-edna-test-change-todo-state (pom new-state) + (org-with-point-at pom (org-todo new-state))) + +(defun org-edna-test-check-block (pom _test) + "Check if the heading at point-or-marker POM is blocked." + (org-edna-test-change-todo-state pom "DONE") + (org-edna-test-compare-todos pom "TODO" _test)) + +(defun org-edna-test-mark-done (&rest poms) + "Mark all points-or-markers in POMS as DONE." + (dolist (pom poms) + (org-edna-test-change-todo-state pom "DONE"))) + +(defun org-edna-test-mark-todo (&rest poms) + "Mark all points-or-markers in POMS as TODO." + (dolist (pom poms) + (org-edna-test-change-todo-state pom "TODO"))) + + +;;;; Parser Tests + (ert-deftest org-edna-parse-form-no-arguments () (let* ((input-string "test-string") (parsed (org-edna-parse-string-form input-string))) @@ -471,7 +503,7 @@ (ert-deftest org-edna-finder/match-blocker () (let* ((org-agenda-files `(,org-edna-test-file)) - (heading (org-id-find "caccd0a6-d400-410a-9018-b0635b07a37e" t)) + (heading (org-edna-find-test-heading "caccd0a6-d400-410a-9018-b0635b07a37e")) (blocker (org-entry-get heading "BLOCKER")) blocking-entry) (should (string-equal "match(\"test&1\")" blocker)) @@ -499,16 +531,16 @@ (ert-deftest org-edna-finder/self () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find "82a4ac3d-9565-4f94-bc84-2bbfd8d7d96c" t)) + (current (org-edna-find-test-heading "82a4ac3d-9565-4f94-bc84-2bbfd8d7d96c")) (targets (org-with-point-at current (org-edna-finder/self)))) (should (= (length targets) 1)) (should (equal current (nth 0 targets))))) (ert-deftest org-edna-finder/siblings () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-one-id t)) + (current (org-edna-find-test-heading org-edna-test-sibling-one-id)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-one-id ,org-edna-test-sibling-two-id ,org-edna-test-sibling-three-id))) @@ -518,9 +550,9 @@ (ert-deftest org-edna-finder/siblings-wrap () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find "72534efa-e932-460b-ae2d-f044a0074815" t)) + (current (org-edna-find-test-heading "72534efa-e932-460b-ae2d-f044a0074815")) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) '("06aca55e-ce09-46df-80d7-5b52e55d6505" "82a4ac3d-9565-4f94-bc84-2bbfd8d7d96c"))) (targets (org-with-point-at current @@ -530,9 +562,9 @@ (ert-deftest org-edna-finder/rest-of-siblings () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find "72534efa-e932-460b-ae2d-f044a0074815" t)) + (current (org-edna-find-test-heading "72534efa-e932-460b-ae2d-f044a0074815")) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) '("06aca55e-ce09-46df-80d7-5b52e55d6505"))) (targets (org-with-point-at current (org-edna-finder/rest-of-siblings)))) @@ -541,9 +573,9 @@ (ert-deftest org-edna-finder/next-sibling () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find "72534efa-e932-460b-ae2d-f044a0074815" t)) + (current (org-edna-find-test-heading "72534efa-e932-460b-ae2d-f044a0074815")) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) '("06aca55e-ce09-46df-80d7-5b52e55d6505"))) (targets (org-with-point-at current (org-edna-finder/next-sibling)))) @@ -552,9 +584,9 @@ (ert-deftest org-edna-finder/next-sibling-wrap-next () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-two-id t)) + (current (org-edna-find-test-heading org-edna-test-sibling-two-id)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-three-id))) (targets (org-with-point-at current (org-edna-finder/next-sibling-wrap)))) @@ -563,9 +595,9 @@ (ert-deftest org-edna-finder/next-sibling-wrap-wrap () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-three-id t)) + (current (org-edna-find-test-heading org-edna-test-sibling-three-id)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-one-id))) (targets (org-with-point-at current (org-edna-finder/next-sibling-wrap)))) @@ -574,9 +606,9 @@ (ert-deftest org-edna-finder/previous-sibling () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find "06aca55e-ce09-46df-80d7-5b52e55d6505" t)) + (current (org-edna-find-test-heading "06aca55e-ce09-46df-80d7-5b52e55d6505")) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) '("72534efa-e932-460b-ae2d-f044a0074815"))) (targets (org-with-point-at current (org-edna-finder/previous-sibling)))) @@ -585,8 +617,8 @@ (ert-deftest org-edna-finder/first-child () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-parent-id t)) - (first-child (list (org-id-find org-edna-test-sibling-one-id t))) + (current (org-edna-find-test-heading org-edna-test-parent-id)) + (first-child (list (org-edna-find-test-heading org-edna-test-sibling-one-id))) (targets (org-with-point-at current (org-edna-finder/first-child)))) (should (= (length targets) 1)) @@ -594,9 +626,9 @@ (ert-deftest org-edna-finder/children () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-parent-id t)) + (current (org-edna-find-test-heading org-edna-test-parent-id)) (children (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-one-id ,org-edna-test-sibling-two-id ,org-edna-test-sibling-three-id))) @@ -607,8 +639,8 @@ (ert-deftest org-edna-finder/parent () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-one-id t)) - (parent (list (org-id-find org-edna-test-parent-id t))) + (current (org-edna-find-test-heading org-edna-test-sibling-one-id)) + (parent (list (org-edna-find-test-heading org-edna-test-parent-id))) (targets (org-with-point-at current (org-edna-finder/parent)))) (should (= (length targets) 1)) @@ -616,9 +648,9 @@ (ert-deftest org-edna-relatives/from-top () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-one-id t)) + (current (org-edna-find-test-heading org-edna-test-sibling-one-id)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-one-id))) (targets (org-with-point-at current (org-edna-finder/relatives 'from-top 1)))) @@ -626,9 +658,9 @@ (ert-deftest org-edna-relatives/from-bottom () (let* ((org-agenda-files `(,org-edna-test-file)) - (current (org-id-find org-edna-test-sibling-one-id t)) + (current (org-edna-find-test-heading org-edna-test-sibling-one-id)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) `(,org-edna-test-sibling-three-id))) (targets (org-with-point-at current (org-edna-finder/relatives 'from-bottom 1)))) @@ -639,9 +671,9 @@ (target-list `(,org-edna-test-sibling-two-id)) (arg 'forward-wrap) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -652,9 +684,9 @@ (target-list `(,org-edna-test-sibling-one-id)) (arg 'forward-wrap) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -665,9 +697,9 @@ (target-list `(,org-edna-test-sibling-two-id)) (arg 'forward-no-wrap) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -678,9 +710,9 @@ (target-list nil) (arg 'forward-no-wrap) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg)))) @@ -692,9 +724,9 @@ (arg 'backward-wrap) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -706,9 +738,9 @@ (arg 'backward-wrap) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -720,9 +752,9 @@ (arg 'backward-no-wrap) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -734,9 +766,9 @@ (arg 'backward-no-wrap) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -748,9 +780,9 @@ (arg 'walk-up) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -761,9 +793,9 @@ (target-list `(,org-edna-test-sibling-one-id)) (arg 'walk-up-with-self) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -774,9 +806,9 @@ (target-list `(,org-edna-test-sibling-one-id)) (arg 'walk-down) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -787,9 +819,9 @@ (target-list `(,org-edna-test-parent-id)) (arg 'walk-down-with-self) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -800,9 +832,9 @@ (target-list `(,org-edna-test-sibling-one-id)) (arg 'walk-down) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 1)))) @@ -821,9 +853,9 @@ (arg 'walk-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -840,9 +872,9 @@ (arg 'step-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg size)))) @@ -853,9 +885,9 @@ (target-list `(,org-edna-test-relative-child-with-todo)) (arg 'step-down) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 'todo-only)))) @@ -867,9 +899,9 @@ ,org-edna-test-relative-child-with-done)) (arg 'step-down) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg 'todo-and-done-only)))) @@ -886,9 +918,9 @@ (filter 'no-comment) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg filter size)))) @@ -905,9 +937,9 @@ (filter 'no-archive) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg filter size)))) @@ -920,9 +952,9 @@ (filter "+ARCHIVE") (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg filter size)))) @@ -939,9 +971,9 @@ (filter "-ARCHIVE") (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg filter size)))) @@ -956,9 +988,9 @@ (filter "Child Heading With .*") (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg filter size)))) @@ -976,9 +1008,9 @@ (sort 'reverse-sort) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets (org-with-point-at current (org-edna-finder/relatives arg sort size)))) @@ -995,9 +1027,9 @@ (arg 'step-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list)) (targets )) (should (equal siblings @@ -1018,9 +1050,9 @@ (arg 'step-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list))) (should (equal siblings (org-with-point-at current @@ -1040,9 +1072,9 @@ (arg 'step-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list))) (should (equal siblings (org-with-point-at current @@ -1062,9 +1094,9 @@ (arg 'step-down) (size (length target-list)) (org-agenda-files `(,org-edna-test-file)) - (current (org-id-find start-marker t)) + (current (org-edna-find-test-heading start-marker)) (siblings (mapcar - (lambda (uuid) (org-id-find uuid t)) + (lambda (uuid) (org-edna-find-test-heading uuid)) target-list))) (should (equal siblings (org-with-point-at current @@ -1133,287 +1165,315 @@ (ert-deftest org-edna-action/todo-test () (let* ((org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "0d491588-7da3-43c5-b51a-87fbd34f79f7" t))) - (org-with-point-at target - (org-edna-action/todo! nil "DONE") - (should (string-equal (org-entry-get nil "TODO") "DONE")) - (org-edna-action/todo! nil "TODO") - (should (string-equal (org-entry-get nil "TODO") "TODO")) - (org-edna-action/todo! nil 'DONE) - (should (string-equal (org-entry-get nil "TODO") "DONE")) - (org-edna-action/todo! nil 'TODO) - (should (string-equal (org-entry-get nil "TODO") "TODO"))))) + (target (org-edna-find-test-heading "0d491588-7da3-43c5-b51a-87fbd34f79f7"))) + (unwind-protect + (org-with-point-at target + (org-edna-action/todo! nil "DONE") + (should (string-equal (org-entry-get nil "TODO") "DONE")) + (org-edna-action/todo! nil "TODO") + (should (string-equal (org-entry-get nil "TODO") "TODO")) + (org-edna-action/todo! nil 'DONE) + (should (string-equal (org-entry-get nil "TODO") "DONE")) + (org-edna-action/todo! nil 'TODO) + (should (string-equal (org-entry-get nil "TODO") "TODO"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/wkdy () ;; Override `current-time' so we can get a deterministic value (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) (org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "0d491588-7da3-43c5-b51a-87fbd34f79f7" t))) - (org-with-point-at target - (org-edna-action/scheduled! nil "Mon") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-17 Mon>")) - (org-edna-action/scheduled! nil 'rm) - (should (not (org-entry-get nil "SCHEDULED"))) - (org-edna-action/scheduled! nil "Mon 9:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-17 Mon 09:00>")) - (org-edna-action/scheduled! nil 'rm) - (should (not (org-entry-get nil "SCHEDULED")))))) + (target (org-edna-find-test-heading "0d491588-7da3-43c5-b51a-87fbd34f79f7"))) + (unwind-protect + (org-with-point-at target + (org-edna-action/scheduled! nil "Mon") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-17 Mon>")) + (org-edna-action/scheduled! nil 'rm) + (should (not (org-entry-get nil "SCHEDULED"))) + (org-edna-action/scheduled! nil "Mon 9:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-17 Mon 09:00>")) + (org-edna-action/scheduled! nil 'rm) + (should (not (org-entry-get nil "SCHEDULED")))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/cp () (let* ((org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "0d491588-7da3-43c5-b51a-87fbd34f79f7" t)) - (source (org-id-find "97e6b0f0-40c4-464f-b760-6e5ca9744eb5" t)) + (target (org-edna-find-test-heading "0d491588-7da3-43c5-b51a-87fbd34f79f7")) + (source (org-edna-find-test-heading "97e6b0f0-40c4-464f-b760-6e5ca9744eb5")) (pairs '((cp . rm) (copy . remove) ("cp" . "rm") ("copy" . "remove")))) - (org-with-point-at target - (dolist (pair pairs) - (org-edna-action/scheduled! source (car pair)) - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - (org-edna-action/scheduled! source (cdr pair)) - (should (not (org-entry-get nil "SCHEDULED"))))))) + (unwind-protect + (org-with-point-at target + (dolist (pair pairs) + (org-edna-action/scheduled! source (car pair)) + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + (org-edna-action/scheduled! source (cdr pair)) + (should (not (org-entry-get nil "SCHEDULED"))))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/inc () ;; Override `current-time' so we can get a deterministic value (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) (org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "97e6b0f0-40c4-464f-b760-6e5ca9744eb5" t))) - (org-with-point-at target - ;; Time starts at Jan 15, 2000 - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - ;; Increment 1 minute - (org-edna-action/scheduled! nil "+1M") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:01>")) - ;; Decrement 1 minute - (org-edna-action/scheduled! nil "-1M") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - ;; +1 day - (org-edna-action/scheduled! nil "+1d") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-16 Sun 00:00>")) - ;; +1 hour from current time - (org-edna-action/scheduled! nil "++1h") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 01:00>")) - ;; Back to Saturday - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - ;; -1 day to Friday - (org-edna-action/scheduled! nil "-1d") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-14 Fri 00:00>")) - ;; Increment two days to the next weekday - (org-edna-action/scheduled! nil "+2wkdy") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-17 Mon 00:00>")) - ;; Increment one day, expected to land on a weekday - (org-edna-action/scheduled! nil "+1wkdy") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-18 Tue 00:00>")) - ;; Move forward 8 days, then backward until we find a weekend - (org-edna-action/scheduled! nil "+8d -wknd") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-23 Sun 00:00>")) - ;; Move forward one week, then forward until we find a weekday - ;; (org-edna-action/scheduled! nil "+1w +wkdy") - ;; (should (string-equal (org-entry-get nil "SCHEDULED") - ;; "<2000-01-31 Mon 00:00>")) - ;; Back to Saturday for other tests - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>"))))) + (target (org-edna-find-test-heading "97e6b0f0-40c4-464f-b760-6e5ca9744eb5"))) + (unwind-protect + (org-with-point-at target + ;; Time starts at Jan 15, 2000 + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + ;; Increment 1 minute + (org-edna-action/scheduled! nil "+1M") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:01>")) + ;; Decrement 1 minute + (org-edna-action/scheduled! nil "-1M") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + ;; +1 day + (org-edna-action/scheduled! nil "+1d") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-16 Sun 00:00>")) + ;; +1 hour from current time + (org-edna-action/scheduled! nil "++1h") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 01:00>")) + ;; Back to Saturday + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + ;; -1 day to Friday + (org-edna-action/scheduled! nil "-1d") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-14 Fri 00:00>")) + ;; Increment two days to the next weekday + (org-edna-action/scheduled! nil "+2wkdy") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-17 Mon 00:00>")) + ;; Increment one day, expected to land on a weekday + (org-edna-action/scheduled! nil "+1wkdy") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-18 Tue 00:00>")) + ;; Move forward 8 days, then backward until we find a weekend + (org-edna-action/scheduled! nil "+8d -wknd") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-23 Sun 00:00>")) + ;; Move forward one week, then forward until we find a weekday + ;; (org-edna-action/scheduled! nil "+1w +wkdy") + ;; (should (string-equal (org-entry-get nil "SCHEDULED") + ;; "<2000-01-31 Mon 00:00>")) + ;; Back to Saturday for other tests + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/landing () "Test landing arguments to scheduled increment." ;; Override `current-time' so we can get a deterministic value (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) (org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "97e6b0f0-40c4-464f-b760-6e5ca9744eb5" t))) - (org-with-point-at target - ;; Time starts at Jan 15, 2000 - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - ;; Move forward 10 days, then backward until we find a weekend - (org-edna-action/scheduled! nil "+10d -wknd") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-23 Sun 00:00>")) - ;; Move forward one week, then forward until we find a weekday - (org-edna-action/scheduled! nil "+1w +wkdy") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-31 Mon 00:00>")) - ;; Back to Saturday for other tests - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>"))))) + (target (org-edna-find-test-heading "97e6b0f0-40c4-464f-b760-6e5ca9744eb5"))) + (unwind-protect + (org-with-point-at target + ;; Time starts at Jan 15, 2000 + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + ;; Move forward 10 days, then backward until we find a weekend + (org-edna-action/scheduled! nil "+10d -wknd") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-23 Sun 00:00>")) + ;; Move forward one week, then forward until we find a weekday + (org-edna-action/scheduled! nil "+1w +wkdy") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-31 Mon 00:00>")) + ;; Back to Saturday for other tests + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/landing-no-hour () "Test landing arguments to scheduled increment, without hour." ;; Override `current-time' so we can get a deterministic value (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) (org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "caf27724-0887-4565-9765-ed2f1edcfb16" t))) - (org-with-point-at target - ;; Time starts at Jan 1, 2017 - (org-edna-action/scheduled! nil "2017-01-01 Sun") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2017-01-01 Sun>")) - ;; Move forward 10 days, then backward until we find a weekend - (org-edna-action/scheduled! nil "+10d -wknd") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2017-01-08 Sun>")) - ;; Move forward one week, then forward until we find a weekday - (org-edna-action/scheduled! nil "+1w +wkdy") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2017-01-16 Mon>")) - ;; Back to Saturday for other tests - (org-edna-action/scheduled! nil "2017-01-01 Sun") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2017-01-01 Sun>"))))) + (target (org-edna-find-test-heading "caf27724-0887-4565-9765-ed2f1edcfb16"))) + (unwind-protect + (org-with-point-at target + ;; Time starts at Jan 1, 2017 + (org-edna-action/scheduled! nil "2017-01-01 Sun") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2017-01-01 Sun>")) + ;; Move forward 10 days, then backward until we find a weekend + (org-edna-action/scheduled! nil "+10d -wknd") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2017-01-08 Sun>")) + ;; Move forward one week, then forward until we find a weekday + (org-edna-action/scheduled! nil "+1w +wkdy") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2017-01-16 Mon>")) + ;; Back to Saturday for other tests + (org-edna-action/scheduled! nil "2017-01-01 Sun") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2017-01-01 Sun>"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-scheduled/float () (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) (org-agenda-files `(,org-edna-test-file)) - (target (org-id-find "97e6b0f0-40c4-464f-b760-6e5ca9744eb5" t))) - (org-with-point-at target - ;; Time starts at Jan 15, 2000 - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>")) - ;; The third Tuesday of next month (Feb 15th) - (org-edna-action/scheduled! nil "float 3 Tue") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-02-15 Tue 00:00>")) - ;; The second Friday of the following May (May 12th) - (org-edna-action/scheduled! nil "float 2 5 May") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-05-12 Fri 00:00>")) - ;; Move forward to the second Wednesday of the next month (June 14th) - (org-edna-action/scheduled! nil "float 2 Wednesday") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-06-14 Wed 00:00>")) - ;; Move forward to the first Thursday in the following Jan (Jan 4th, 2001) - (org-edna-action/scheduled! nil "float 1 4 Jan") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2001-01-04 Thu 00:00>")) - ;; The fourth Monday in Feb, 2000 (Feb 28th) - (org-edna-action/scheduled! nil "float ++4 monday") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-02-28 Mon 00:00>")) - ;; The second Monday after Mar 12th, 2000 (Mar 20th) - (org-edna-action/scheduled! nil "float 2 monday Mar 12") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-03-20 Mon 00:00>")) - ;; Back to Saturday for other tests - (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") - (should (string-equal (org-entry-get nil "SCHEDULED") - "<2000-01-15 Sat 00:00>"))))) + (target (org-edna-find-test-heading "97e6b0f0-40c4-464f-b760-6e5ca9744eb5"))) + (unwind-protect + (org-with-point-at target + ;; Time starts at Jan 15, 2000 + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>")) + ;; The third Tuesday of next month (Feb 15th) + (org-edna-action/scheduled! nil "float 3 Tue") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-02-15 Tue 00:00>")) + ;; The second Friday of the following May (May 12th) + (org-edna-action/scheduled! nil "float 2 5 May") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-05-12 Fri 00:00>")) + ;; Move forward to the second Wednesday of the next month (June 14th) + (org-edna-action/scheduled! nil "float 2 Wednesday") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-06-14 Wed 00:00>")) + ;; Move forward to the first Thursday in the following Jan (Jan 4th, 2001) + (org-edna-action/scheduled! nil "float 1 4 Jan") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2001-01-04 Thu 00:00>")) + ;; The fourth Monday in Feb, 2000 (Feb 28th) + (org-edna-action/scheduled! nil "float ++4 monday") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-02-28 Mon 00:00>")) + ;; The second Monday after Mar 12th, 2000 (Mar 20th) + (org-edna-action/scheduled! nil "float 2 monday Mar 12") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-03-20 Mon 00:00>")) + ;; Back to Saturday for other tests + (org-edna-action/scheduled! nil "2000-01-15 Sat 00:00") + (should (string-equal (org-entry-get nil "SCHEDULED") + "<2000-01-15 Sat 00:00>"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-tag () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/tag! nil "tag") - (should (equal (org-get-tags) '("tag"))) - (org-edna-action/tag! nil "") - (should (equal (org-get-tags) '("")))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/tag! nil "tag") + (should (equal (org-get-tags) '("tag"))) + (org-edna-action/tag! nil "") + (should (equal (org-get-tags) '("")))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-property () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/set-property! nil "TEST" "1") - (should (equal (org-entry-get nil "TEST") "1")) - (org-edna-action/delete-property! nil "TEST") - (should-not (org-entry-get nil "TEST"))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/set-property! nil "TEST" "1") + (should (equal (org-entry-get nil "TEST") "1")) + (org-edna-action/delete-property! nil "TEST") + (should-not (org-entry-get nil "TEST"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-property/inc-dec () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/set-property! nil "TEST" "1") - (should (equal (org-entry-get nil "TEST") "1")) - (org-edna-action/set-property! nil "TEST" 'inc) - (should (equal (org-entry-get nil "TEST") "2")) - (org-edna-action/set-property! nil "TEST" 'dec) - (should (equal (org-entry-get nil "TEST") "1")) - (org-edna-action/delete-property! nil "TEST") - (should-not (org-entry-get nil "TEST")) - (should-error (org-edna-action/set-property! nil "TEST" 'inc)) - (should-error (org-edna-action/set-property! nil "TEST" 'dec)) - (org-edna-action/set-property! nil "TEST" "a") - (should (equal (org-entry-get nil "TEST") "a")) - (should-error (org-edna-action/set-property! nil "TEST" 'inc)) - (should-error (org-edna-action/set-property! nil "TEST" 'dec)) - (org-edna-action/delete-property! nil "TEST") - (should-not (org-entry-get nil "TEST"))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/set-property! nil "TEST" "1") + (should (equal (org-entry-get nil "TEST") "1")) + (org-edna-action/set-property! nil "TEST" 'inc) + (should (equal (org-entry-get nil "TEST") "2")) + (org-edna-action/set-property! nil "TEST" 'dec) + (should (equal (org-entry-get nil "TEST") "1")) + (org-edna-action/delete-property! nil "TEST") + (should-not (org-entry-get nil "TEST")) + (should-error (org-edna-action/set-property! nil "TEST" 'inc)) + (should-error (org-edna-action/set-property! nil "TEST" 'dec)) + (org-edna-action/set-property! nil "TEST" "a") + (should (equal (org-entry-get nil "TEST") "a")) + (should-error (org-edna-action/set-property! nil "TEST" 'inc)) + (should-error (org-edna-action/set-property! nil "TEST" 'dec)) + (org-edna-action/delete-property! nil "TEST") + (should-not (org-entry-get nil "TEST"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-property/next-prev () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/set-property! nil "TEST" "a") - (should (equal (org-entry-get nil "TEST") "a")) - (should-error (org-edna-action/set-property! nil "TEST" 'next)) - (should-error (org-edna-action/set-property! nil "TEST" 'prev)) - (should-error (org-edna-action/set-property! nil "TEST" 'previous)) - (org-edna-action/delete-property! nil "TEST") - (should-not (org-entry-get nil "TEST")) - ;; Test moving forwards - (org-edna-action/set-property! nil "COUNTER" "a") - (should (equal (org-entry-get nil "COUNTER") "a")) - (org-edna-action/set-property! nil "COUNTER" 'next) - (should (equal (org-entry-get nil "COUNTER") "b")) - ;; Test moving forwards past the last one - (org-edna-action/set-property! nil "COUNTER" "d") - (should (equal (org-entry-get nil "COUNTER") "d")) - (org-edna-action/set-property! nil "COUNTER" 'next) - (should (equal (org-entry-get nil "COUNTER") "a")) - ;; Test moving backwards past the first one - (org-edna-action/set-property! nil "COUNTER" 'prev) - (should (equal (org-entry-get nil "COUNTER") "d")) - ;; Test moving backwards normally - (org-edna-action/set-property! nil "COUNTER" 'previous) - (should (equal (org-entry-get nil "COUNTER") "c")) - (org-edna-action/delete-property! nil "COUNTER") - (should-not (org-entry-get nil "COUNTER"))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/set-property! nil "TEST" "a") + (should (equal (org-entry-get nil "TEST") "a")) + (should-error (org-edna-action/set-property! nil "TEST" 'next)) + (should-error (org-edna-action/set-property! nil "TEST" 'prev)) + (should-error (org-edna-action/set-property! nil "TEST" 'previous)) + (org-edna-action/delete-property! nil "TEST") + (should-not (org-entry-get nil "TEST")) + ;; Test moving forwards + (org-edna-action/set-property! nil "COUNTER" "a") + (should (equal (org-entry-get nil "COUNTER") "a")) + (org-edna-action/set-property! nil "COUNTER" 'next) + (should (equal (org-entry-get nil "COUNTER") "b")) + ;; Test moving forwards past the last one + (org-edna-action/set-property! nil "COUNTER" "d") + (should (equal (org-entry-get nil "COUNTER") "d")) + (org-edna-action/set-property! nil "COUNTER" 'next) + (should (equal (org-entry-get nil "COUNTER") "a")) + ;; Test moving backwards past the first one + (org-edna-action/set-property! nil "COUNTER" 'prev) + (should (equal (org-entry-get nil "COUNTER") "d")) + ;; Test moving backwards normally + (org-edna-action/set-property! nil "COUNTER" 'previous) + (should (equal (org-entry-get nil "COUNTER") "c")) + (org-edna-action/delete-property! nil "COUNTER") + (should-not (org-entry-get nil "COUNTER"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-clock () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/clock-in! nil) - (should (org-clocking-p)) - (should (equal org-clock-hd-marker pom)) - (org-edna-action/clock-out! nil) - (should-not (org-clocking-p))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/clock-in! nil) + (should (org-clocking-p)) + (should (equal org-clock-hd-marker pom)) + (org-edna-action/clock-out! nil) + (should-not (org-clocking-p))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-priority () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one)) (org-lowest-priority ?C) (org-highest-priority ?A) (org-default-priority ?B)) - (org-with-point-at pom - (org-edna-action/set-priority! nil "A") - (should (equal (org-entry-get nil "PRIORITY") "A")) - (org-edna-action/set-priority! nil 'down) - (should (equal (org-entry-get nil "PRIORITY") "B")) - (org-edna-action/set-priority! nil 'up) - (should (equal (org-entry-get nil "PRIORITY") "A")) - (org-edna-action/set-priority! nil ?C) - (should (equal (org-entry-get nil "PRIORITY") "C")) - (org-edna-action/set-priority! nil 'remove) - (should (equal (org-entry-get nil "PRIORITY") "B"))))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/set-priority! nil "A") + (should (equal (org-entry-get nil "PRIORITY") "A")) + (org-edna-action/set-priority! nil 'down) + (should (equal (org-entry-get nil "PRIORITY") "B")) + (org-edna-action/set-priority! nil 'up) + (should (equal (org-entry-get nil "PRIORITY") "A")) + (org-edna-action/set-priority! nil ?C) + (should (equal (org-entry-get nil "PRIORITY") "C")) + (org-edna-action/set-priority! nil 'remove) + (should (equal (org-entry-get nil "PRIORITY") "B"))) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-effort () (let ((pom (org-edna-find-test-heading org-edna-test-id-heading-one))) - (org-with-point-at pom - (org-edna-action/set-effort! nil "0:01") - (should (equal (org-entry-get nil "EFFORT") "0:01")) - (org-edna-action/set-effort! nil 'increment) - (should (equal (org-entry-get nil "EFFORT") "0:02")) - (org-entry-delete nil "EFFORT")))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/set-effort! nil "0:01") + (should (equal (org-entry-get nil "EFFORT") "0:01")) + (org-edna-action/set-effort! nil 'increment) + (should (equal (org-entry-get nil "EFFORT") "0:02")) + (org-entry-delete nil "EFFORT")) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-archive () (let ((org-archive-save-context-info '(todo)) @@ -1421,20 +1481,25 @@ ;; Archive it to the same location (org-archive-location "::** Archive") (org-edna-prompt-for-archive nil)) - (org-with-point-at pom - (org-edna-action/archive! nil) - (should (equal (org-entry-get nil "ARCHIVE_TODO") "TODO")) - (org-entry-delete nil "ARCHIVE_TODO")))) + (unwind-protect + (org-with-point-at pom + (org-edna-action/archive! nil) + (should (equal (org-entry-get nil "ARCHIVE_TODO") "TODO")) + (org-entry-delete nil "ARCHIVE_TODO")) + (org-edna-test-restore-test-file)))) (ert-deftest org-edna-action-chain () (let ((old-pom (org-edna-find-test-heading org-edna-test-id-heading-one)) (new-pom (org-edna-find-test-heading org-edna-test-id-heading-two))) - (org-entry-put old-pom "TEST" "1") - (org-with-point-at new-pom - (org-edna-action/chain! old-pom "TEST") - (should (equal (org-entry-get nil "TEST") "1"))) - (org-entry-delete old-pom "TEST") - (org-entry-delete new-pom "TEST"))) + (unwind-protect + (progn + (org-entry-put old-pom "TEST" "1") + (org-with-point-at new-pom + (org-edna-action/chain! old-pom "TEST") + (should (equal (org-entry-get nil "TEST") "1"))) + (org-entry-delete old-pom "TEST") + (org-entry-delete new-pom "TEST")) + (org-edna-test-restore-test-file)))) ;; Conditions @@ -1547,6 +1612,268 @@ (should (not (org-edna-handle-consideration 0.25 blocks-no-blocking))) (should (not (org-edna-handle-consideration 0.25 blocks-empty))))) + +;;; Full Run-through Tests from the Documentation + +(ert-deftest org-edna-doc-test/ancestors () + (let* ((start-heading (org-edna-find-test-heading "24a0c3bb-7e69-4e9e-bb98-5aba2ff17bb1")) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function)) + (unwind-protect + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (let* ((heading1-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading2-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading3-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading4-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading5-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Verify that we can't change the TODO state to DONE + (should (org-edna-test-check-block heading5-pom "Initial state of heading 5")) + ;; Change the state at 4 to DONE + (org-edna-test-change-todo-state heading4-pom "DONE") + ;; Verify that ALL ancestors need to be changed + (should (org-edna-test-check-block heading5-pom "Heading 5 after parent changed")) + (org-edna-test-mark-done heading1-pom heading3-pom) + ;; Only need 1, 3, and 4 to change 5 + (should (not (org-edna-test-check-block heading5-pom + "Heading 5 after all parents changed"))) + ;; Change the state back to TODO on all of them + (org-edna-test-mark-todo heading1-pom heading3-pom heading4-pom heading5-pom)))) + (org-edna-test-restore-test-file)))) + +(ert-deftest org-edna-doc-test/descendants () + (let* ((start-heading (org-edna-find-test-heading "cc18dc74-00e8-4081-b46f-e36800041fe7")) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function)) + (unwind-protect + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (let* ((heading1-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading2-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading3-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading4-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading5-pom (progn (org-next-visible-heading 1) (point-marker)))) + (should (org-edna-test-check-block heading1-pom "Heading 1 initial state")) + ;; Change the state at 2 to DONE + (org-edna-test-mark-done heading2-pom) + ;; Verify that ALL descendants need to be changed + (should (org-edna-test-check-block heading1-pom "Heading 1 after changing 2")) + ;; Try 3 + (org-edna-test-mark-done heading3-pom) + ;; Verify that ALL descendants need to be changed + (should (org-edna-test-check-block heading1-pom "Heading 1 after changing 3")) + ;; Try 4 + (org-edna-test-mark-done heading4-pom) + ;; Verify that ALL descendants need to be changed + (should (org-edna-test-check-block heading1-pom "Heading 1 after changing 4")) + ;; Try 5 + (org-edna-test-mark-done heading5-pom) + ;; Verify that ALL descendants need to be changed + (should (not (org-edna-test-check-block heading1-pom "Heading 1 after changing 5")))))) + (org-edna-test-restore-test-file)))) + +(ert-deftest org-edna-doc-test/laundry () + "Test for the \"laundry\" example in the documentation." + (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) + (start-heading (org-edna-find-test-heading "e57ce099-9f37-47f4-a6bb-61a84eb1fbbe")) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function) + ;; Only trigger based on Edna + (org-trigger-hook 'org-edna-trigger-function)) + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (unwind-protect + (let* ((heading1-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading2-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading3-pom (progn (org-next-visible-heading 1) (point-marker))) + (heading4-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Verify that headings 2, 3, and 4 are all blocked + (should (org-edna-test-check-block heading2-pom + "Initial attempt to change heading 2")) + (should (org-edna-test-check-block heading3-pom + "Initial attempt to change heading 3")) + (should (org-edna-test-check-block heading4-pom + "Initial attempt to change heading 4")) + ;; Mark heading 1 as DONE + (should (not (org-edna-test-check-block heading1-pom + "Set heading 1 to DONE"))) + ;; Only heading 2 should have a scheduled time + (should (string-equal (org-entry-get heading2-pom "SCHEDULED") + "<2000-01-15 Sat 01:00>")) + (should (not (org-entry-get heading3-pom "SCHEDULED"))) + (should (not (org-entry-get heading4-pom "SCHEDULED"))) + ;; The others should still be blocked. + (should (org-edna-test-check-block heading3-pom + "Second attempt to change heading 3")) + (should (org-edna-test-check-block heading4-pom + "Second attempt to change heading 4")) + ;; Try changing heading 2 + (should (not (org-edna-test-check-block heading2-pom + "Set heading 2 to DONE"))) + (should (string-equal (org-entry-get heading3-pom "SCHEDULED") + "<2000-01-16 Sun 09:00>")) + ;; 4 should still be blocked + (should (org-edna-test-check-block heading4-pom + "Second attempt to change heading 4"))) + ;; Change the test file back to its original state. + (org-edna-test-restore-test-file)))))) + +(ert-deftest org-edna-doc-test/nightly () + (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) + (start-heading (org-edna-find-test-heading "8b6d9820-d943-4622-85c9-4a346e033453")) + ;; Only use the test file in the agenda + (org-agenda-files `(,org-edna-test-file)) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function) + ;; Only trigger based on Edna + (org-trigger-hook 'org-edna-trigger-function)) + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (unwind-protect + (let* ((nightly-pom (progn (org-next-visible-heading 1) (point-marker))) + (lunch-pom (progn (org-next-visible-heading 1) (point-marker))) + (door-pom (progn (org-next-visible-heading 1) (point-marker))) + (dog-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Verify that Nightly is blocked + (should (org-edna-test-check-block nightly-pom "Initial Nightly Check")) + ;; Check off Lunch, and verify that nightly is still blocked + (org-edna-test-mark-done lunch-pom) + (should (org-edna-test-check-block nightly-pom "Nightly after Lunch")) + ;; Check off Door, and verify that nightly is still blocked + (org-edna-test-mark-done door-pom) + (should (org-edna-test-check-block nightly-pom "Nightly after Door")) + ;; Check off Dog. This should trigger the others. + (org-edna-test-mark-done dog-pom) + (should (org-edna-test-compare-todos lunch-pom "TODO" "Lunch after Nightly Trigger")) + (should (org-edna-test-compare-todos door-pom "TODO" "Door after Nightly Trigger")) + (should (org-edna-test-compare-todos dog-pom "TODO" "Dog after Nightly Trigger")) + (should (string-equal (org-entry-get nightly-pom "DEADLINE") + "<2000-01-16 Sun +1d>"))) + ;; Change the test file back to its original state. + (org-edna-test-restore-test-file)))))) + +(ert-deftest org-edna-doc-test/daily () + (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) + (start-heading (org-edna-find-test-heading "630805bb-a864-4cdc-9a6f-0f126e887c66")) + ;; Only use the test file in the agenda + (org-agenda-files `(,org-edna-test-file)) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function) + ;; Only trigger based on Edna + (org-trigger-hook 'org-edna-trigger-function)) + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (unwind-protect + (let* ((daily-pom (progn (org-next-visible-heading 1) (point-marker))) + (lunch-pom (progn (org-next-visible-heading 1) (point-marker))) + (door-pom (progn (org-next-visible-heading 1) (point-marker))) + (dog-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Check off Lunch. This should trigger the others. + (org-edna-test-mark-done lunch-pom) + (should (org-edna-test-compare-todos lunch-pom "TODO" "Lunch after Daily Trigger")) + (should (org-edna-test-compare-todos door-pom "TODO" "Door after Daily Trigger")) + (should (org-edna-test-compare-todos dog-pom "TODO" "Dog after Daily Trigger")) + (should (string-equal (org-entry-get daily-pom "DEADLINE") + "<2000-01-16 Sun +1d>"))) + ;; Change the test file back to its original state. + (org-edna-test-restore-test-file)))))) + +(ert-deftest org-edna-doc-test/weekly () + (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) + (start-heading (org-edna-find-test-heading "cf529a5e-1b0c-40c3-8f85-fe2fc4df0ffd")) + ;; Only use the test file in the agenda + (org-agenda-files `(,org-edna-test-file)) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function) + ;; Only trigger based on Edna + (org-trigger-hook 'org-edna-trigger-function)) + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (unwind-protect + (let* ((weekly-pom (progn (org-next-visible-heading 1) (point-marker))) + (lunch-pom (progn (org-next-visible-heading 1) (point-marker))) + (door-pom (progn (org-next-visible-heading 1) (point-marker))) + (dog-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Check off Lunch. This should trigger the others. + (org-edna-test-mark-done lunch-pom) + (should (org-edna-test-compare-todos lunch-pom "TODO" "Lunch after Weekly Trigger")) + (should (org-edna-test-compare-todos door-pom "TODO" "Door after Weekly Trigger")) + (should (org-edna-test-compare-todos dog-pom "TODO" "Dog after Weekly Trigger")) + (should (string-equal (org-entry-get weekly-pom "DEADLINE") + "<2000-01-16 Sun +1d>"))) + ;; Change the test file back to its original state. + (org-edna-test-restore-test-file)))))) + +(ert-deftest org-edna-doc-test/basic-shower () + (cl-letf* (((symbol-function 'current-time) (lambda () org-edna-test-time)) + (start-heading (org-edna-find-test-heading "34d67756-927b-4a21-a62d-7989bd138946")) + ;; Only use the test file in the agenda + (org-agenda-files `(,org-edna-test-file)) + (org-todo-keywords '((sequence "TODO" "|" "DONE"))) + ;; Only block based on Edna + (org-blocker-hook 'org-edna-blocker-function) + ;; Only trigger based on Edna + (org-trigger-hook 'org-edna-trigger-function)) + (org-with-point-at start-heading + (save-restriction + ;; Only allow operating on the current tree + (org-narrow-to-subtree) + ;; Show the entire subtree + (outline-show-all) + (unwind-protect + (let* ((shower-pom (progn (org-next-visible-heading 1) (point-marker))) + (towels-pom (progn (org-next-visible-heading 1) (point-marker)))) + ;; Verify towels is blocked + (should (org-edna-test-check-block towels-pom "Initial Towels Check")) + ;; Check off "Take Shower" and verify that it incremented the property + (org-edna-test-mark-done shower-pom) + (should (string-equal (org-entry-get shower-pom "COUNT") "1")) + ;; Verify towels is blocked + (should (org-edna-test-check-block towels-pom "Towels Check, Count=1")) + ;; Check off "Take Shower" and verify that it incremented the property + (org-edna-test-mark-done shower-pom) + (should (string-equal (org-entry-get shower-pom "COUNT") "2")) + ;; Verify towels is blocked + (should (org-edna-test-check-block towels-pom "Towels Check, Count=2")) + ;; Check off "Take Shower" and verify that it incremented the property + (org-edna-test-mark-done shower-pom) + (should (string-equal (org-entry-get shower-pom "COUNT") "3")) + ;; Verify that towels is no longer blocked. + (should (not (org-edna-test-check-block towels-pom "Towels Check, Count=3"))) + ;; Verify that the property was reset. + (should (string-equal (org-entry-get shower-pom "COUNT") "0"))) + ;; Change the test file back to its original state. + (org-edna-test-restore-test-file)))))) (provide 'org-edna-tests) ;;; org-edna-tests.el ends here diff --git a/org-edna-tests.org b/org-edna-tests.org index 5e20614..9eb8756 100644 --- a/org-edna-tests.org +++ b/org-edna-tests.org @@ -1,4 +1,5 @@ #+STARTUP: nologdone +#+STARTUP: indent #+PROPERTY: Effort_ALL 0:01 0:02 0:03 #+PROPERTY: COUNTER_ALL a b c d @@ -137,3 +138,133 @@ DEADLINE: <2017-01-05 Thu> SCHEDULED: <2017-01-05 Thu> :PROPERTIES: :ID: 4fe67f03-2b35-4708-8c38-54d2c4dfab81 :END: +* Documentation Tests +** Ancestors +:PROPERTIES: +:ID: 24a0c3bb-7e69-4e9e-bb98-5aba2ff17bb1 +:END: +*** TODO Heading 1 +**** TODO Heading 2 +**** TODO Heading 3 +***** TODO Heading 4 +****** TODO Heading 5 +:PROPERTIES: +:BLOCKER: ancestors +:END: +** Descendants +:PROPERTIES: +:ID: cc18dc74-00e8-4081-b46f-e36800041fe7 +:END: +*** TODO Heading 1 +:PROPERTIES: +:BLOCKER: descendants +:END: +**** TODO Heading 2 +**** TODO Heading 3 +***** TODO Heading 4 +****** TODO Heading 5 +** Laundry +:PROPERTIES: +:ID: e57ce099-9f37-47f4-a6bb-61a84eb1fbbe +:END: +*** TODO Put clothes in washer +SCHEDULED: <2000-01-15 Sat 00:00> +:PROPERTIES: +:TRIGGER: next-sibling scheduled!("++1h") +:END: +*** TODO Put clothes in dryer +:PROPERTIES: +:TRIGGER: next-sibling scheduled!("Sun 9:00") +:BLOCKER: previous-sibling +:END: +*** TODO Fold laundry +:PROPERTIES: +:TRIGGER: next-sibling scheduled!("++1h") +:BLOCKER: previous-sibling +:END: +*** TODO Put clothes away +:PROPERTIES: +:TRIGGER: next-sibling scheduled!("++1h") +:BLOCKER: previous-sibling +:END: +** Nightlies - Standard +:PROPERTIES: +:ID: 8b6d9820-d943-4622-85c9-4a346e033453 +:END: +*** TODO Nightly +DEADLINE: <2000-01-15 Sat +1d> +:PROPERTIES: +:ID: 2d94abf9-2d63-46fd-8dc5-cd396555bcfe +:BLOCKER: match("nightly") +:TRIGGER: match("nightly") todo!(TODO) +:END: +*** TODO Prepare Tomorrow's Lunch :nightly: +:PROPERTIES: +:TRIGGER: if match("nightly") then ids(2d94abf9-2d63-46fd-8dc5-cd396555bcfe) todo!(DONE) endif +:END: +*** TODO Lock Back Door :nightly: +:PROPERTIES: +:TRIGGER: if match("nightly") then ids(2d94abf9-2d63-46fd-8dc5-cd396555bcfe) todo!(DONE) endif +:END: +*** TODO Feed Dog :nightly: +:PROPERTIES: +:TRIGGER: if match("nightly") then ids(2d94abf9-2d63-46fd-8dc5-cd396555bcfe) todo!(DONE) endif +:END: +** Dailies - Consideration +:PROPERTIES: +:ID: 630805bb-a864-4cdc-9a6f-0f126e887c66 +:END: +*** TODO Daily +DEADLINE: <2000-01-15 Sat +1d> +:PROPERTIES: +:ID: 96f7e46c-40c3-4f5b-8f00-81a6e3cb122b +:TRIGGER: match("daily") todo!(TODO) +:END: +*** TODO Prepare Tomorrow's Lunch :daily: +:PROPERTIES: +:TRIGGER: if consider(any) match("daily") then ids(96f7e46c-40c3-4f5b-8f00-81a6e3cb122b) todo!(DONE) endif +:END: +*** TODO Lock Back Door :daily: +:PROPERTIES: +:TRIGGER: if consider(any) match("daily") then ids(96f7e46c-40c3-4f5b-8f00-81a6e3cb122b) todo!(DONE) endif +:END: +*** TODO Feed Dog :daily: +:PROPERTIES: +:TRIGGER: if consider(any) match("daily") then ids(96f7e46c-40c3-4f5b-8f00-81a6e3cb122b) todo!(DONE) endif +:END: +** Weeklies - Inverted Conditional +:PROPERTIES: +:ID: cf529a5e-1b0c-40c3-8f85-fe2fc4df0ffd +:END: +*** TODO Weekly +DEADLINE: <2000-01-15 Sat +1d> +:PROPERTIES: +:ID: 9a0c4b00-64be-4971-a93e-c530cbdd4b2b +:TRIGGER: match("weekly") todo!(TODO) +:END: +*** TODO Prepare Tomorrow's Lunch :weekly: +:PROPERTIES: +:TRIGGER: if match("weekly") then else ids(9a0c4b00-64be-4971-a93e-c530cbdd4b2b) todo!(DONE) endif +:END: +*** TODO Lock Back Door :weekly: +:PROPERTIES: +:TRIGGER: if match("weekly") then else ids(9a0c4b00-64be-4971-a93e-c530cbdd4b2b) todo!(DONE) endif +:END: +*** TODO Feed Dog :weekly: +:PROPERTIES: +:TRIGGER: if match("weekly") then else ids(9a0c4b00-64be-4971-a93e-c530cbdd4b2b) todo!(DONE) endif +:END: +** Basic Shower - No Conditional +:PROPERTIES: +:ID: 34d67756-927b-4a21-a62d-7989bd138946 +:END: +*** TODO Take Shower +:PROPERTIES: +:COUNT: 0 +:TRIGGER: self set-property!("COUNT" inc) todo!("TODO") +:END: +*** TODO Wash Towels +:PROPERTIES: +:BLOCKER: previous-sibling !has-property?("COUNT" "3") +:TRIGGER: previous-sibling set-property!("COUNT" "0") +:END: diff --git a/org-edna.el b/org-edna.el index dcb3157..3247989 100644 --- a/org-edna.el +++ b/org-edna.el @@ -96,7 +96,8 @@ Currently, the following are handled: Everything else is returned as is." (pcase arg - ((and (pred symbolp) + ((and (pred symbolp) ;; Symbol + ;; Name matches `org-uuidgen-p' (let (pred org-uuidgen-p) (symbol-name arg))) (symbol-name arg)) (_ @@ -127,7 +128,8 @@ If KEY is an invalid Edna keyword, then return nil." (cond ;; Just return nil if it's not a symbol ((or (not key) - (not (symbolp key)))) + (not (symbolp key))) + nil) ((memq key '(consideration consider)) ;; Function is ignored here, but `org-edna-describe-keyword' needs this ;; function. @@ -397,7 +399,7 @@ correspond to internal variables." ,target-var ,consideration-var)))) ('consideration - `(setq ,consideration-var ,(nth 0 args)))))) + `(setq ,consideration-var ',(nth 0 args)))))) (defun org-edna--expand-sexp-form (form &optional use-old-scope @@ -664,7 +666,11 @@ MATCH-SPEC may be any valid match string; it is passed straight into `org-map-entries'. SCOPE and SKIP are their counterparts in `org-map-entries'. -SCOPE defaults to agenda, and SKIP defaults to nil. +SCOPE defaults to agenda, and SKIP defaults to nil. Because of +the different defaults in SCOPE, the symbol 'buffer may also be +used. This indicates that scope should be the current buffer, +honoring any restriction (the equivalent of the nil SCOPE in +`org-map-entries'.) * TODO Test :PROPERTIES: @@ -673,7 +679,10 @@ SCOPE defaults to agenda, and SKIP defaults to nil. \"Test\" will block until all entries tagged \"test\" and \"mine\" in the agenda files are marked DONE." + ;; Our default is agenda... (setq scope (or scope 'agenda)) + ;; ...but theirs is the buffer + (when (eq scope 'buffer) (setq scope nil)) (org-map-entries ;; Find all entries in the agenda files that match the given tag. (lambda nil (point-marker)) @@ -2206,7 +2215,7 @@ SUFFIX is an additional suffix to use when matching keywords." "Return a list of all allowed Edna keywords for a blocker." `(,@(org-edna--collect-finders) ,@(org-edna--collect-conditions) - "consideration")) + "consideration" "consider")) (defun org-edna-completions-for-trigger () "Return a list of all allowed Edna keywords for a trigger." diff --git a/org-edna.info b/org-edna.info index d1f6a35..2bc5847 100644 --- a/org-edna.info +++ b/org-edna.info @@ -865,19 +865,23 @@ following, PLANNING is either scheduled or deadline. Examples: - • scheduled!(“Mon 09:00”) -> Set SCHEDULED to the following Monday at - 9:00 - • deadline!(“++2h”) -> Set DEADLINE to two hours from now. - • deadline!(copy) deadline!(“+1h”) -> Copy the source deadline to the - target, then increment it by an hour. - • scheduled!(“+1wkdy”) -> Set SCHEDULED to the next weekday - • scheduled!(“+1d +wkdy”) -> Same as above - • deadline!(“+1m -wkdy”) -> Set SCHEDULED up one month, but move - backward to find a weekend - • scheduled!(“float 2 Tue Feb”) -> Set SCHEDULED to the second - Tuesday in the following February - • scheduled!(“float 3 Thu”) -> Set SCHEDULED to the third Thursday in - the following month +scheduled!(“Mon 09:00”) + Set SCHEDULED to the following Monday at 9:00 +deadline!(“++2h”) + Set DEADLINE to two hours from now. +deadline!(copy) deadline!(“+1h”) + Copy the source deadline to the target, then increment it by an + hour. +scheduled!(“+1wkdy”) + Set SCHEDULED to the next weekday +scheduled!(“+1d +wkdy”) + Same as above +deadline!(“+1m -wkdy”) + Set SCHEDULED up one month, but move backward to find a weekend +scheduled!(“float 2 Tue Feb”) + Set SCHEDULED to the second Tuesday in the following February +scheduled!(“float 3 Thu”) + Set SCHEDULED to the third Thursday in the following month File: org-edna.info, Node: TODO State, Next: Archive, Prev: Scheduled/Deadline, Up: Actions @@ -893,6 +897,23 @@ TODO State state. It can also be the empty string, in which case the TODO state is removed. + Example: + + * TODO Heading 1 + :PROPERTIES: + :TRIGGER: next-sibling todo!(DONE) + :END: + * TODO Heading 2 + + In this example, when “Heading 1” is marked as DONE, it will also +mark “Heading 2” as DONE: + + * DONE Heading 1 + :PROPERTIES: + :TRIGGER: next-sibling todo!(DONE) + :END: + * DONE Heading 2 + File: org-edna.info, Node: Archive, Next: Chain Property, Prev: TODO State, Up: Actions @@ -917,6 +938,28 @@ Chain Property Copies PROPERTY from the source entry to all targets. Does nothing if the source heading has no property PROPERTY. + Example: + + * TODO Heading 1 + :PROPERTIES: + :COUNTER: 2 + :TRIGGER: next-sibling chain!("COUNTER") + :END: + * TODO Heading 2 + + In this example, when “Heading 1” is marked as DONE, it will copy its +COUNTER property to “Heading 2”: + + * DONE Heading 1 + :PROPERTIES: + :COUNTER: 2 + :TRIGGER: next-sibling chain!("COUNTER") + :END: + * TODO Heading 2 + :PROPERTIES: + :COUNTER: 2 + :END: + File: org-edna.info, Node: Clocking, Next: Property, Prev: Chain Property, Up: Actions @@ -987,7 +1030,7 @@ already set: * TODO Test :PROPERTIES: - :TRIGGER: self set-property("TEST" inc) + :TRIGGER: self set-property!("TEST" inc) :END: In the above example, if “Test” is set to DONE, Edna will fail to @@ -999,10 +1042,11 @@ increment the TEST property, since it doesn’t exist. Examples: - • set-property!(“COUNTER” “1”) -> Sets the property COUNTER to 1 on - all targets - • set-property!(“COUNTER” inc) -> Increments the property COUNTER by - 1. Following the previous example, it would be 2. +set-property!(“COUNTER” “1”) + Sets the property COUNTER to 1 on all targets +set-property!(“COUNTER” inc) + Increments the property COUNTER by 1. Following the previous + example, it would be 2. File: org-edna.info, Node: Priority, Next: Tag, Prev: Property, Up: Actions @@ -1182,7 +1226,12 @@ against VALUE. Block the source heading if VARIABLE = VALUE. VARIABLE should be a symbol, and VALUE is any valid lisp expression. - self variable-set?(test-variable 12) + Examples: + +self variable-set?(test-variable 12) + Blocks if the variable ‘test-variable’ is set to 12. +self variable-set?(buffer-file-name “org-edna.org”) + Blocks if the variable ‘buffer-file-name’ is set to “org-edna.org”. File: org-edna.info, Node: has-property, Next: re-search, Prev: variable-set, Up: Conditions @@ -1195,6 +1244,22 @@ has-property Tests each target for the property PROPERTY, and blocks if it’s set to VALUE. + Example: + + * TODO Take Shower + :PROPERTIES: + :COUNT: 1 + :TRIGGER: self set-property!("COUNT" inc) todo!("TODO") + :END: + * TODO Wash Towels + :PROPERTIES: + :BLOCKER: previous-sibling !has-property?("COUNT" "3") + :TRIGGER: previous-sibling set-property!("COUNT" "0") + :END: + + In this example, “Wash Towels” can’t be completed until the user has +showered at least three times. + File: org-edna.info, Node: re-search, Next: Negating Conditions, Prev: has-property, Up: Conditions @@ -1228,7 +1293,8 @@ File: org-edna.info, Node: Consideration, Next: Conditional Forms, Prev: Cond Consideration ============= -“Consideration” is a special keyword that’s only valid for blockers. +“Consideration” and “consider” are special keywords that are only valid +for blockers. This says “Allow a task to complete if CONSIDERATION of its targets pass the given condition”. @@ -1812,49 +1878,49 @@ Node: siblings22483 Node: siblings-wrap22720 Node: Actions23024 Node: Scheduled/Deadline23787 -Node: TODO State27362 -Node: Archive27730 -Node: Chain Property28050 -Node: Clocking28333 -Node: Property28745 -Node: Priority30932 -Node: Tag31501 -Node: Effort31718 -Node: Getting Help32107 -Node: Advanced Features32552 -Node: Finder Cache33000 -Node: Conditions34039 -Node: done34675 -Node: headings34839 -Node: todo-state35215 -Node: variable-set35471 -Node: has-property35900 -Node: re-search36169 -Node: Negating Conditions36529 -Node: Consideration36916 -Node: Conditional Forms38485 -Node: Setting the Properties41141 -Node: Extending Edna42225 -Node: Naming Conventions42715 -Node: Finders 143507 -Node: Actions 143869 -Node: Conditions 144328 -Node: Contributing45214 -Node: Bugs46080 -Node: Working with EDE46437 -Node: Compiling Edna47521 -Node: Testing Edna48390 -Node: Before Sending Changes49371 -Node: Developing with Bazaar50058 -Node: Documentation50799 -Node: Changelog51255 -Node: 10beta851505 -Node: 10beta751617 -Node: 10beta651911 -Node: 10beta552187 -Node: 10beta452574 -Node: 10beta352827 -Node: 10beta253266 +Node: TODO State27302 +Node: Archive28027 +Node: Chain Property28347 +Node: Clocking29100 +Node: Property29512 +Node: Priority31685 +Node: Tag32254 +Node: Effort32471 +Node: Getting Help32860 +Node: Advanced Features33305 +Node: Finder Cache33753 +Node: Conditions34792 +Node: done35428 +Node: headings35592 +Node: todo-state35968 +Node: variable-set36224 +Node: has-property36861 +Node: re-search37574 +Node: Negating Conditions37934 +Node: Consideration38321 +Node: Conditional Forms39909 +Node: Setting the Properties42565 +Node: Extending Edna43649 +Node: Naming Conventions44139 +Node: Finders 144931 +Node: Actions 145293 +Node: Conditions 145752 +Node: Contributing46638 +Node: Bugs47504 +Node: Working with EDE47861 +Node: Compiling Edna48945 +Node: Testing Edna49814 +Node: Before Sending Changes50795 +Node: Developing with Bazaar51482 +Node: Documentation52223 +Node: Changelog52679 +Node: 10beta852929 +Node: 10beta753041 +Node: 10beta653335 +Node: 10beta553611 +Node: 10beta453998 +Node: 10beta354251 +Node: 10beta254690 End Tag Table diff --git a/org-edna.org b/org-edna.org index 65d1832..5fd4cf4 100644 --- a/org-edna.org +++ b/org-edna.org @@ -692,14 +692,15 @@ PLANNING is either scheduled or deadline. Examples: -- scheduled!("Mon 09:00") -> Set SCHEDULED to the following Monday at 9:00 -- deadline!("++2h") -> Set DEADLINE to two hours from now. -- deadline!(copy) deadline!("+1h") -> Copy the source deadline to the target, then increment it by an hour. -- scheduled!("+1wkdy") -> Set SCHEDULED to the next weekday -- scheduled!("+1d +wkdy") -> Same as above -- deadline!("+1m -wkdy") -> Set SCHEDULED up one month, but move backward to find a weekend -- scheduled!("float 2 Tue Feb") -> Set SCHEDULED to the second Tuesday in the following February -- scheduled!("float 3 Thu") -> Set SCHEDULED to the third Thursday in the following month +- scheduled!("Mon 09:00") :: Set SCHEDULED to the following Monday at 9:00 +- deadline!("++2h") :: Set DEADLINE to two hours from now. +- deadline!(copy) deadline!("+1h") :: Copy the source deadline to the target, then increment it by an hour. +- scheduled!("+1wkdy") :: Set SCHEDULED to the next weekday +- scheduled!("+1d +wkdy") :: Same as above +- deadline!("+1m -wkdy") :: Set SCHEDULED up one month, but move backward to find a weekend +- scheduled!("float 2 Tue Feb") :: Set SCHEDULED to the second Tuesday in the following February +- scheduled!("float 3 Thu") :: Set SCHEDULED to the third Thursday in the following month + *** TODO State :PROPERTIES: :CUSTOM_ID: todo! @@ -713,6 +714,27 @@ Sets the TODO state of the target heading to NEW-STATE. NEW-STATE may either be a string or a symbol denoting the new TODO state. It can also be the empty string, in which case the TODO state is removed. +Example: + +#+BEGIN_SRC org +,* TODO Heading 1 + :PROPERTIES: + :TRIGGER: next-sibling todo!(DONE) + :END: +,* TODO Heading 2 +#+END_SRC + +In this example, when "Heading 1" is marked as DONE, it will also mark "Heading +2" as DONE: + +#+BEGIN_SRC org +,* DONE Heading 1 + :PROPERTIES: + :TRIGGER: next-sibling todo!(DONE) + :END: +,* DONE Heading 2 +#+END_SRC + *** Archive :PROPERTIES: :CUSTOM_ID: archive! @@ -737,6 +759,32 @@ nil, Edna will not ask before archiving targets. Copies PROPERTY from the source entry to all targets. Does nothing if the source heading has no property PROPERTY. +Example: + +#+BEGIN_SRC org +,* TODO Heading 1 + :PROPERTIES: + :COUNTER: 2 + :TRIGGER: next-sibling chain!("COUNTER") + :END: +,* TODO Heading 2 +#+END_SRC + +In this example, when "Heading 1" is marked as DONE, it will copy its COUNTER +property to "Heading 2": + +#+BEGIN_SRC org +,* DONE Heading 1 + :PROPERTIES: + :COUNTER: 2 + :TRIGGER: next-sibling chain!("COUNTER") + :END: +,* TODO Heading 2 + :PROPERTIES: + :COUNTER: 2 + :END: +#+END_SRC + *** Clocking :PROPERTIES: :CUSTOM_ID: clocking @@ -804,7 +852,7 @@ Additionally, all special forms will fail if the property is not already set: #+begin_src org ,* TODO Test :PROPERTIES: - :TRIGGER: self set-property("TEST" inc) + :TRIGGER: self set-property!("TEST" inc) :END: #+end_src @@ -817,8 +865,8 @@ Deletes the property PROPERTY from all targets. Examples: -- set-property!("COUNTER" "1") -> Sets the property COUNTER to 1 on all targets -- set-property!("COUNTER" inc) -> Increments the property COUNTER by 1. Following the previous example, it would be 2. +- set-property!("COUNTER" "1") :: Sets the property COUNTER to 1 on all targets +- set-property!("COUNTER" inc) :: Increments the property COUNTER by 1. Following the previous example, it would be 2. *** Priority :PROPERTIES: @@ -923,7 +971,7 @@ that target, then the source heading is blocked. If no condition is specified, ~!done?~ is used by default, which means block if any target heading isn't done. -*** done +*** Heading is DONE :PROPERTIES: :CUSTOM_ID: done :END: @@ -932,7 +980,7 @@ any target heading isn't done. Blocks the source heading if any target heading is DONE. -*** headings +*** File Has Headings :PROPERTIES: :CUSTOM_ID: headings :END: @@ -948,7 +996,7 @@ org-file("refile.org") headings? The above example blocks if refile.org has any headings. -*** todo-state +*** Heading TODO State :PROPERTIES: :CUSTOM_ID: todo-state :END: @@ -959,7 +1007,7 @@ Blocks if any target heading has TODO state set to STATE. STATE may be a string or a symbol. -*** variable-set +*** Lisp Variable Set :PROPERTIES: :CUSTOM_ID: variable-set :END: @@ -971,11 +1019,12 @@ against VALUE. Block the source heading if VARIABLE = VALUE. VARIABLE should be a symbol, and VALUE is any valid lisp expression. -#+BEGIN_EXAMPLE -self variable-set?(test-variable 12) -#+END_EXAMPLE +Examples: -*** has-property +- self variable-set?(test-variable 12) :: Blocks if the variable ~test-variable~ is set to 12. +- self variable-set?(buffer-file-name "org-edna.org") :: Blocks if the variable ~buffer-file-name~ is set to "org-edna.org". + +*** Heading Has Property :PROPERTIES: :CUSTOM_ID: has-property :END: @@ -984,7 +1033,25 @@ self variable-set?(test-variable 12) Tests each target for the property PROPERTY, and blocks if it's set to VALUE. -*** re-search +Example: + +#+begin_src org +,* TODO Take Shower + :PROPERTIES: + :COUNT: 1 + :TRIGGER: self set-property!("COUNT" inc) todo!("TODO") + :END: +,* TODO Wash Towels + :PROPERTIES: + :BLOCKER: previous-sibling !has-property?("COUNT" "3") + :TRIGGER: previous-sibling set-property!("COUNT" "0") + :END: +#+end_src + +In this example, "Wash Towels" can't be completed until the user has showered at +least three times. + +*** Regexp Search :PROPERTIES: :CUSTOM_ID: re-search :DESCRIPTION: Search for a regular expression