Commit ac318b35 authored by Sean Whitton's avatar Sean Whitton

Merge tag 'v1.8'

Tag v1.8
parents 558fc484 e6f97d0e
language: emacs-lisp
sudo: no
env:
- EVM_EMACS=emacs-24.1-travis
- EVM_EMACS=emacs-24.2-travis
- EVM_EMACS=emacs-24.3-travis
- EVM_EMACS=emacs-24.4-travis
- EVM_EMACS=emacs-24.5-travis
......
EMACS := emacs
VERSION = $(shell sed -ne 's/^;; Version: \(.*\)/\1/p' buttercup.el)
DISTFILES = buttercup.el buttercup-compat.el buttercup-pkg.el README.md
VERSION := $(shell sed -ne 's/^;; Version: \(.*\)/\1/p' buttercup.el)
ELISP_FILES := $(shell ls *.el | grep -v -- '-pkg\.el$$')
DISTFILES := $(ELISP_FILES) buttercup-pkg.el README.md
.PHONY: test
.PHONY: test compile clean
all: test
test:
test: compile
$(EMACS) -batch -L . -l buttercup.el -f buttercup-run-markdown docs/writing-tests.md
./bin/buttercup -L .
compile:
$(EMACS) -batch -L . -f batch-byte-compile *.el
compile: $(patsubst %.el,%.elc,$(ELISP_FILES))
%.elc: %.el
$(EMACS) -batch -L . -f batch-byte-compile $<
release: clean test
mkdir -p dist
......
......@@ -29,18 +29,6 @@
;;; Code:
;;;;;;;;;;;;;;;;;;;;;
;; Introduced in 24.3
(when (not (fboundp 'cl-defstruct))
(defalias 'cl-defstruct 'defstruct))
(when (not (fboundp 'cl-every))
(defalias 'cl-every 'every))
(when (not (fboundp 'cl-subsetp))
(defalias 'cl-subsetp 'subsetp))
;;;;;;;;;;;;;;;;;;;;;
;; Introduced in 24.4
......
This diff is collapsed.
......@@ -165,7 +165,12 @@ that are not included below.
(let ((foo (lambda () (+ a 1)))
(bar (lambda () (+ a 1))))
(expect foo :not :to-throw 'void-variable '(b))
(expect bar :to-throw 'void-variable '(a))))))
(expect bar :to-throw 'void-variable '(a))))
(it "only works on functions"
(expect (lambda () (expect nil :to-throw 'error))
:to-throw 'void-function)
(expect (lambda () (expect "hello" :not :to-throw 'error))
:to-throw 'invalid-function))))
```
## Grouping Related Specs with `describe`
......@@ -359,6 +364,26 @@ the argument list matches any of the recorded calls to the spy.
(expect bar :to-be nil)))
```
The `:to-have-been-called-times` matcher will return true if the spy
was called a certain number of times.
```Lisp
(describe "A spy"
:var (foo bar)
(before-each
(setf (symbol-function 'foo)
(lambda (value)
(setq bar value)))
(spy-on 'foo)
(foo 123)
(foo 456 "another param"))
(it "tracks that the spy was called twice"
(expect 'foo :to-have-been-called-times 2)))
```
### Spies: `:and-call-through`
The keyword argument `:and-call-through` to `spy-on` will make the spy
......
......@@ -18,6 +18,8 @@
;;; Code:
(require 'buttercup)
(require 'autoload)
(require 'ert)
;;;;;;;;;;
;;; expect
......@@ -342,7 +344,10 @@
(it "should expand to a call to the `buttercup-it' function"
(expect (macroexpand '(it "description" body))
:to-equal
'(buttercup-it "description" (lambda () body))))
'(buttercup-it "description"
(lambda ()
(buttercup-with-converted-ert-signals
body)))))
(it "without argument should expand to xit."
(expect (macroexpand '(it "description"))
......@@ -501,9 +506,15 @@
(describe "The Spy "
(let (test-function)
(before-each
;; We use `before-all' here because some tests need to access the
;; same function as previous tests in order to work, so overriding
;; the function before each test would invalidate those tests.
(before-all
(fset 'test-function (lambda (a b)
(+ a b))))
(+ a b)))
(fset 'test-command (lambda ()
(interactive)
t)))
(describe "`spy-on' function"
(it "replaces a symbol's function slot"
......@@ -511,7 +522,51 @@
(expect (test-function 1 2) :to-be nil))
(it "restores the old value after a spec run"
(expect (test-function 1 2) :to-equal 3)))
(expect (test-function 1 2) :to-equal 3))
(it "allows a spied-on command to be executed as a command"
(spy-on 'test-command)
(expect (commandp 'test-command))
(expect (lambda () (command-execute 'test-command))
:not :to-throw)
(expect 'test-command :to-have-been-called))
(it "can spy on autoloaded functions"
(let* ((function-file (make-temp-file "test-file-" nil ".el"))
(function-name 'test-autoloaded-function)
(defun-form `(defun ,function-name ()
"An autoloaded function"
:loaded-successfully))
(autoload-form (make-autoload defun-form function-file)))
(unwind-protect
(progn
;; Create the real function in a file
(with-temp-file function-file
(insert ";; -*-lexical-binding:t-*-\n"
(pp-to-string defun-form)))
;; Define the autoload for the function
(fmakunbound function-name)
(eval autoload-form)
(expect (autoloadp (symbol-function function-name)))
(spy-on function-name :and-call-through)
(expect (not (autoloadp (symbol-function function-name))))
(expect (funcall function-name)
:to-be :loaded-successfully))
(delete-file function-file nil))))
(it "only accepts ARG for keywords that use it"
(expect
(lambda () (spy-on 'test-function :and-call-through :arg-not-allowed))
:to-throw)
(expect
(lambda () (spy-on 'test-function nil :arg-not-allowed))
:to-throw)
(expect
(lambda () (spy-on 'test-function :and-throw-error))
:not :to-throw)
(expect
(lambda () (test-function 1 2))
:to-throw 'error)))
(describe ":to-have-been-called matcher"
(before-each
......@@ -556,6 +611,57 @@
:to-be
t)))
(describe ":to-have-been-called-times matcher"
(before-each
(spy-on 'test-function))
(it "returns error if the spy was called less than expected"
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 1))
:to-equal
(cons nil
"Expected `test-function' to have been called 1 time, but it was called 0 times")))
(it "returns error if the spy was called more than expected"
(test-function)
(test-function)
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 1))
:to-equal
(cons nil
"Expected `test-function' to have been called 1 time, but it was called 2 times")))
(it "returns true if the spy was called the expected number of times"
(test-function)
(test-function)
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 2))
:to-equal t))
(it "use plural words in error message"
(test-function)
(test-function)
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 3))
:to-equal
(cons nil
"Expected `test-function' to have been called 3 times, but it was called 2 times")))
(it "use singular expected word in error message"
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 1))
:to-equal
(cons nil
"Expected `test-function' to have been called 1 time, but it was called 0 times")))
(it "use singular actual word in error message"
(test-function)
(expect (buttercup--apply-matcher
:to-have-been-called-times '(test-function 2))
:to-equal
(cons nil
"Expected `test-function' to have been called 2 times, but it was called 1 time"))))
(describe ":and-call-through keyword functionality"
(before-each
(spy-on 'test-function :and-call-through))
......@@ -712,6 +818,24 @@
:to-have-been-called-with
"Hello, world")))
;;;;;;;;;;;;;;;;;;;;;
;;; ERT Compatibility
(describe "Buttercup's ERT compatibility wrapper"
(it "should convert `ert-test-failed' into `buttercup-failed"
(expect
(lambda ()
(buttercup-with-converted-ert-signals
(should (equal 1 2))))
:to-throw 'buttercup-failed))
(it "should convert `ert-test-skipped' into `buttercup-pending"
(assume (functionp 'ert-skip) "Loaded ERT version does not provide `ert-skip'")
(expect
(lambda ()
(buttercup-with-converted-ert-signals
(ert-skip "Skipped this test")))
:to-throw 'buttercup-pending)))
;;;;;;;;;;;;;
;;; Utilities
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment