unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* 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 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

* 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

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).