emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Assistance Writing Test for Org Agenda Custom Bulk Function
@ 2021-02-15 23:21 Kevin Foley
  2021-02-18  3:58 ` Kyle Meyer
  0 siblings, 1 reply; 3+ messages in thread
From: Kevin Foley @ 2021-02-15 23:21 UTC (permalink / raw)
  To: emacs-orgmode

I'm trying write a test for a recently merged patch[1].

The patch adds the ability for users to specify a function to collect
args to be passed to a custom bulk function.

I'm trying to mock the argument collecting function and the custom bulk
function and then test that the arguments returned from the former are
passed to the latter.  I'd also like to test the argument function is
only called once while the bulk function is called multiple times.

Here is an example of what I'm trying to do:

(org-test-with-temp-text-in-file
    "* TODO a\n*TODO b"
  (let ((org-agenda-files `(,(buffer-file-name))))
    (org-todo-list)
    (org-agenda-bulk-mark-all)

    ;; Fails without these
    ;; (defvar f-called-cnt)
    ;; (defvar arg-f-call-cnt)
    ;; (defvar f-called-args)

    (let ((f-called-cnt 0)
          (arg-f-call-cnt 0)
          (f-called-args nil))
      (cl-letf (((symbol-function 'read-char-exclusive)
                 (lambda () ?P))
                (org-agenda-bulk-custom-functions
                 '((?P (lambda (&rest args)
                         (message "test" args)
                         (setq f-called-cnt (1+ f-called-cnt)
                               f-called-args args))
                       (lambda ()
                         (setq arg-f-call-cnt (1+ arg-f-call-cnt))
                         '(1 2 3))))))
        (org-agenda-bulk-action)
        (org-test-agenda--kill-all-agendas)

        (should (= f-called-cnt 2))
        (should (= arg-f-call-cnt 1))
        (should (equal f-called-args '(1 2 3)))))))

However, this fails with the error void-variable unless I first define
the variables for storing the call counts/arguments.  I understand that
defvar makes the variables dynamically bound, however I'm struggling to
understand why that's needed here.  I've read the manual entries on
variable binding but I seem to be missing something.

Can someone help me understand what's going on here?  Also, is there a
better way to approach this?

[1] https://code.orgmode.org/bzg/org-mode/commit/885ee086dde4ec2a9e303ff101e55d55c4b2363f


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Assistance Writing Test for Org Agenda Custom Bulk Function
  2021-02-15 23:21 Assistance Writing Test for Org Agenda Custom Bulk Function Kevin Foley
@ 2021-02-18  3:58 ` Kyle Meyer
  2021-02-18 14:08   ` Kevin Foley
  0 siblings, 1 reply; 3+ messages in thread
From: Kyle Meyer @ 2021-02-18  3:58 UTC (permalink / raw)
  To: Kevin Foley; +Cc: emacs-orgmode

Kevin Foley writes:

> I'm trying to mock the argument collecting function and the custom bulk
> function and then test that the arguments returned from the former are
> passed to the latter.  I'd also like to test the argument function is
> only called once while the bulk function is called multiple times.
>
> Here is an example of what I'm trying to do:
>
> (org-test-with-temp-text-in-file
>     "* TODO a\n*TODO b"

Unrelated note: there's a missing a space between the second "*" and
"TODO".

[...]
>     (let ((f-called-cnt 0)
>           (arg-f-call-cnt 0)
>           (f-called-args nil))
>       (cl-letf (((symbol-function 'read-char-exclusive)
>                  (lambda () ?P))
>                 (org-agenda-bulk-custom-functions
>                  '((?P (lambda (&rest args)
>                          (message "test" args)
>                          (setq f-called-cnt (1+ f-called-cnt)
>                                f-called-args args))
>                        (lambda ()
>                          (setq arg-f-call-cnt (1+ arg-f-call-cnt))
>                          '(1 2 3))))))
>         (org-agenda-bulk-action)
>         (org-test-agenda--kill-all-agendas)
>
>         (should (= f-called-cnt 2))
>         (should (= arg-f-call-cnt 1))
>         (should (equal f-called-args '(1 2 3)))))))
>
> However, this fails with the error void-variable unless I first define
> the variables for storing the call counts/arguments.  I understand that
> defvar makes the variables dynamically bound, however I'm struggling to
> understand why that's needed here.  I've read the manual entries on
> variable binding but I seem to be missing something.
>
> Can someone help me understand what's going on here?

Perhaps you're not capturing the environment due to your quoting:

  ;; -*- lexical-binding: t; -*-

  (let ((x 0))
    '(t (lambda () x)))  ;; => (y (lambda nil x))
  
  (let ((x 0))
    (list t (lambda () x)))  ;; => (t (closure ((x . 0) t) nil x))

So try something like

  (org-agenda-bulk-custom-functions
   `((?P ,(lambda (&rest args)
            (message "test" args)
            (setq f-called-cnt (1+ f-called-cnt)
                  f-called-args args))
         ,(lambda ()
            (setq arg-f-call-cnt (1+ arg-f-call-cnt))
            '(1 2 3)))))

or

  (org-agenda-bulk-custom-functions
   (list
    (list ?P
          (lambda (&rest args)
            (message "test" args)
            (setq f-called-cnt (1+ f-called-cnt)
                  f-called-args args))
          (lambda ()
            (setq arg-f-call-cnt (1+ arg-f-call-cnt))
            '(1 2 3)))))


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Assistance Writing Test for Org Agenda Custom Bulk Function
  2021-02-18  3:58 ` Kyle Meyer
@ 2021-02-18 14:08   ` Kevin Foley
  0 siblings, 0 replies; 3+ messages in thread
From: Kevin Foley @ 2021-02-18 14:08 UTC (permalink / raw)
  To: Kyle Meyer; +Cc: emacs-orgmode

Kyle Meyer <kyle@kyleam.com> writes:

> Unrelated note: there's a missing a space between the second "*" and
> "TODO".

Good catch, thank you.

> Perhaps you're not capturing the environment due to your quoting:
>
>   ;; -*- lexical-binding: t; -*-
>
>   (let ((x 0))
>     '(t (lambda () x)))  ;; => (y (lambda nil x))
>   
>   (let ((x 0))
>     (list t (lambda () x)))  ;; => (t (closure ((x . 0) t) nil x))
>
> So try something like
>
>   (org-agenda-bulk-custom-functions
>    `((?P ,(lambda (&rest args)
>             (message "test" args)
>             (setq f-called-cnt (1+ f-called-cnt)
>                   f-called-args args))
>          ,(lambda ()
>             (setq arg-f-call-cnt (1+ arg-f-call-cnt))
>             '(1 2 3)))))

This was exactly it, thank you.  I'll hopefully have this in a patch
shortly.

Kevin



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-18 14:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-15 23:21 Assistance Writing Test for Org Agenda Custom Bulk Function Kevin Foley
2021-02-18  3:58 ` Kyle Meyer
2021-02-18 14:08   ` Kevin Foley

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).