* Best practice for mocking functions/prompts/etc.
@ 2014-11-08 18:34 Jorgen Schaefer
2014-11-08 23:17 ` Nic Ferrier
2014-11-09 0:56 ` Lars Magne Ingebrigtsen
0 siblings, 2 replies; 6+ messages in thread
From: Jorgen Schaefer @ 2014-11-08 18:34 UTC (permalink / raw)
To: emacs-devel
Hi!
When writing a library for Emacs (to be included in the core), what is
the recommended best practice to test for interactive function calls? I
did not see a mock library, so I suspect there is a standard way without
such a library.
For example, given a description such as "it should prompt the user for
a file", how do I test this the best way?
I came up with this way:
(defun the-function ()
(read-file-name "Foo: "))
(ert-deftest the-function ()
;; Describe the-function
;; It should prompt the user for a file name.
(cl-letf* ((called-prompt nil)
(test-file "/test-file")
((symbol-function 'read-file-name)
(lambda (prompt)
(setq called-prompt prompt)
test-file)))
(let ((returned-file (the-function)))
(should (equal returned-file test-file))
(should (equal called-prompt "Foo: ")))))
Is there a better way? Especially one that makes it easier to check if
the function was called at all and with what arguments, as opposed to
carrying around 1-2 extra variables per mocked function?
Also, is there a standard for the granularity of tests (one test per
feature/description, one test per function, or ...?), and for the
naming of tests?
Regards,
Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Best practice for mocking functions/prompts/etc.
2014-11-08 18:34 Best practice for mocking functions/prompts/etc Jorgen Schaefer
@ 2014-11-08 23:17 ` Nic Ferrier
2014-11-09 8:59 ` Jorgen Schaefer
2014-11-09 0:56 ` Lars Magne Ingebrigtsen
1 sibling, 1 reply; 6+ messages in thread
From: Nic Ferrier @ 2014-11-08 23:17 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
Jorgen Schaefer <forcer@forcix.cx> writes:
> (defun the-function ()
> (read-file-name "Foo: "))
>
>
> (ert-deftest the-function ()
> ;; Describe the-function
>
> ;; It should prompt the user for a file name.
> (cl-letf* ((called-prompt nil)
> (test-file "/test-file")
> ((symbol-function 'read-file-name)
> (lambda (prompt)
> (setq called-prompt prompt)
> test-file)))
>
> (let ((returned-file (the-function)))
>
> (should (equal returned-file test-file))
> (should (equal called-prompt "Foo: ")))))
>
>
> Is there a better way? Especially one that makes it easier to check if
> the function was called at all and with what arguments, as opposed to
> carrying around 1-2 extra variables per mocked function?
I don't see any reason to test all those things for every interactive
function. I think interactive working (or not) should be tested once, by
some tests around interactive. You don't have to test that.
In this example, you should just mock read-file-name. Which you're
doing.
Using cl-letf, cl-labels, cl-flet or noflet would all be ok I think.
There are elisp mocking libs. But with lisp you don't really need them.
Nic
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Best practice for mocking functions/prompts/etc.
2014-11-08 23:17 ` Nic Ferrier
@ 2014-11-09 8:59 ` Jorgen Schaefer
2014-11-09 10:36 ` Nic Ferrier
0 siblings, 1 reply; 6+ messages in thread
From: Jorgen Schaefer @ 2014-11-09 8:59 UTC (permalink / raw)
To: Nic Ferrier; +Cc: emacs-devel
On Sat, 08 Nov 2014 23:17:50 +0000
Nic Ferrier <nferrier@ferrier.me.uk> wrote:
> Jorgen Schaefer <forcer@forcix.cx> writes:
>
> > Is there a better way? Especially one that makes it easier to check
> > if the function was called at all and with what arguments, as
> > opposed to carrying around 1-2 extra variables per mocked function?
>
> I don't see any reason to test all those things for every interactive
> function. I think interactive working (or not) should be tested once,
> by some tests around interactive. You don't have to test that.
I am not. I am testing whether a function with some complicated logic
will ask the user for something when certain conditions are true (and
then does the right thing with what it got back from the user).
> In this example, you should just mock read-file-name. Which you're
> doing.
>
> Using cl-letf, cl-labels, cl-flet or noflet would all be ok I think.
>
> There are elisp mocking libs. But with lisp you don't really need
> them.
Yep. I know how I would do this in my own package, and I know how I can
do this with Emacs "on-board" libraries. The latter feels rather
cumbersome to me, so I figured I'd ask if there are recommended ways /
best practices for packages that are meant to go into the Emacs
repository that I am missing. :-)
Regards,
Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Best practice for mocking functions/prompts/etc.
2014-11-09 8:59 ` Jorgen Schaefer
@ 2014-11-09 10:36 ` Nic Ferrier
2014-11-09 11:05 ` Jorgen Schaefer
0 siblings, 1 reply; 6+ messages in thread
From: Nic Ferrier @ 2014-11-09 10:36 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
Jorgen Schaefer <forcer@forcix.cx> writes:
>> There are elisp mocking libs. But with lisp you don't really need
>> them.
>
> Yep. I know how I would do this in my own package, and I know how I can
> do this with Emacs "on-board" libraries. The latter feels rather
> cumbersome to me, so I figured I'd ask if there are recommended ways /
> best practices for packages that are meant to go into the Emacs
> repository that I am missing. :-)
And I don't think there are. The mocking stuff doesn't go anywhere
because we don't need it very often... except in your use case.
Make something!
Nic
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Best practice for mocking functions/prompts/etc.
2014-11-09 10:36 ` Nic Ferrier
@ 2014-11-09 11:05 ` Jorgen Schaefer
0 siblings, 0 replies; 6+ messages in thread
From: Jorgen Schaefer @ 2014-11-09 11:05 UTC (permalink / raw)
To: Nic Ferrier; +Cc: emacs-devel
On Sun, 09 Nov 2014 10:36:47 +0000
Nic Ferrier <nferrier@ferrier.me.uk> wrote:
> Jorgen Schaefer <forcer@forcix.cx> writes:
>
> >> There are elisp mocking libs. But with lisp you don't really need
> >> them.
> >
> > Yep. I know how I would do this in my own package, and I know how I
> > can do this with Emacs "on-board" libraries. The latter feels rather
> > cumbersome to me, so I figured I'd ask if there are recommended
> > ways / best practices for packages that are meant to go into the
> > Emacs repository that I am missing. :-)
>
> And I don't think there are. The mocking stuff doesn't go anywhere
> because we don't need it very often... except in your use case.
>
> Make something!
I just had a quick talk off the list with Nic, because it seemed to me
we were talking past each other, and indeed we were! :-)
The question I had, which I seem to have not explained well, was:
How do we mock this case in the Emacs "core" (i.e. the main Emacs
repository), as we can not use existing mock libraries (that I know of)
because they are not part of Emacs.
I can obviously write my own, as Nic suggests above, or just use the
default verbose options, as I have in the initial mail, but I figured
I'd ask first if there was something I am missing before reinventing the
wheel. :-)
Regards,
Jorgen
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Best practice for mocking functions/prompts/etc.
2014-11-08 18:34 Best practice for mocking functions/prompts/etc Jorgen Schaefer
2014-11-08 23:17 ` Nic Ferrier
@ 2014-11-09 0:56 ` Lars Magne Ingebrigtsen
1 sibling, 0 replies; 6+ messages in thread
From: Lars Magne Ingebrigtsen @ 2014-11-09 0:56 UTC (permalink / raw)
To: Jorgen Schaefer; +Cc: emacs-devel
Jorgen Schaefer <forcer@forcix.cx> writes:
> When writing a library for Emacs (to be included in the core), what is
> the recommended best practice to test for interactive function calls? I
> did not see a mock library, so I suspect there is a standard way without
> such a library.
[...]
> (let ((returned-file (the-function)))
>
> (should (equal returned-file test-file))
> (should (equal called-prompt "Foo: ")))))
>
> Is there a better way?
You seem to want to check whether the Emacs Lisp language works at all
by checking a specific function? I don't think that's a useful level to
perform checks at.
I think you can take it as a given that the Emacs Lisp language works as
specified.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-11-09 11:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-08 18:34 Best practice for mocking functions/prompts/etc Jorgen Schaefer
2014-11-08 23:17 ` Nic Ferrier
2014-11-09 8:59 ` Jorgen Schaefer
2014-11-09 10:36 ` Nic Ferrier
2014-11-09 11:05 ` Jorgen Schaefer
2014-11-09 0:56 ` Lars Magne Ingebrigtsen
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.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).