Some ideas about rebinding methods.
[cl-mock.git] / src / facade.lisp
1 ;; -*- mode: lisp; syntax: common-lisp; coding: utf-8-unix; package: cl-mock; -*-
2
3 (in-package #:cl-mock)
4 \f
5 ;;; syntactic sugar for defining the mock interactions
6
7 (defun true (&rest arguments)
8   (declare (ignore arguments))
9   T)
10
11 (defmacro answer (call &body forms)
12   (let ((name (if (listp call) (car call) call))
13         (sym (gensym)))
14     `(if-called
15       ',name
16       (let ((,sym (fdefinition ',name)))
17         (declare (ignorable ,sym))
18         (let ((times 0))
19           (lambda (&rest args)
20             (declare (ignorable args))
21             ,(let ((cases
22                      `(case (prog1 times (incf times))
23                         ,.(loop
24                             for i from 0
25                             for (form . rest) on forms
26                             collect `(,(if rest i T) ,form)))))
27                (if (listp call)
28                    `(optima:match args
29                      ((list . ,(cdr call)) ,cases)
30                      (_ (unhandled)))
31                    cases))))))))