[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/buttercup c5a9f26 003/340: Add first set of unit tests.
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/buttercup c5a9f26 003/340: Add first set of unit tests. |
Date: |
Thu, 16 Dec 2021 14:58:53 -0500 (EST) |
branch: elpa/buttercup
commit c5a9f265087b04f06089568e5f4a268ae23d6a22
Author: Jorgen Schaefer <contact@jorgenschaefer.de>
Commit: Jorgen Schaefer <contact@jorgenschaefer.de>
Add first set of unit tests.
---
Makefile | 1 +
buttercup-test.el | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
buttercup.el | 84 +++++++++++++++++++++++++++++++++++++++-----------
3 files changed, 159 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile
index 5fc7198..fc542ac 100644
--- a/Makefile
+++ b/Makefile
@@ -4,3 +4,4 @@ all: test
test:
emacs -batch -L . -l buttercup.el -f buttercup-markdown-runner README.md
+ emacs -batch -L . -l buttercup-test.el -f buttercup-run
diff --git a/buttercup-test.el b/buttercup-test.el
index a7296d6..0b123b9 100644
--- a/buttercup-test.el
+++ b/buttercup-test.el
@@ -1 +1,92 @@
(require 'buttercup)
+
+(describe "The buttercup-failed signal"
+ (it "can be raised"
+ (expect (lambda ()
+ (signal 'buttercup-failed t))
+ :to-throw
+ 'buttercup-failed)))
+
+(describe "The buttercup-error signal"
+ (it "can be raised"
+ (expect (lambda ()
+ (signal 'buttercup-error t))
+ :to-throw
+ 'buttercup-error)))
+
+(describe "The `expect' form"
+ (it "with a matcher should translate directly to the function call"
+ (expect (macroexpand '(expect (+ 1 1) :to-equal 2))
+ :to-equal
+ '(buttercup-expect (+ 1 1) :to-equal 2)))
+
+ (it "with a form argument should extract the matcher from the form"
+ (expect (macroexpand '(expect (equal (+ 1 1) 2)))
+ :to-equal
+ '(buttercup-expect (+ 1 1) #'equal 2)))
+
+ (it "with a single argument should pass it to the function"
+ (expect (macroexpand '(expect t))
+ :to-equal
+ '(buttercup-expect t))))
+
+(describe "The `buttercup-expect' function"
+ (describe "with a single argument"
+ (it "should not raise an error if the argument is true"
+ (expect (lambda ()
+ (buttercup-expect t))
+ :not :to-throw
+ 'buttercup-failed))
+
+ (it "should raise an error if the argument is false"
+ (expect (lambda ()
+ (buttercup-expect nil))
+ :to-throw
+ 'buttercup-failed
+ "Expected nil to be non-nil")))
+
+ (describe "with a function as a matcher argument"
+ (it "should not raise an error if the function returns true"
+ (expect (lambda ()
+ (buttercup-expect t #'eq t))
+ :not :to-throw
+ 'buttercup-failed))
+
+ (it "should raise an error if the function returns false"
+ (expect (lambda ()
+ (buttercup-expect t #'eq nil))
+ :to-throw
+ 'buttercup-failed)))
+
+ (describe "with a matcher argument"
+ (buttercup-define-matcher :always-true (a) t)
+ (buttercup-define-matcher :always-false (a) nil)
+
+ (it "should not raise an error if the matcher returns true"
+ (expect (lambda ()
+ (buttercup-expect 1 :always-true))
+ :not :to-throw
+ 'buttercup-failed))
+
+ (it "should raise an error if the matcher returns false"
+ (expect (lambda ()
+ (buttercup-expect 1 :always-false))
+ :to-throw
+ 'buttercup-failed))))
+
+(describe "The `buttercup-fail' function"
+ (it "should raise a signal with its arguments"
+ (expect (lambda ()
+ (buttercup-fail "Explanation" ))
+ :to-throw
+ 'buttercup-failed "Explanation")))
+
+(describe "The `buttercup-define-matcher' macro"
+ (it "should add a buttercup-matcher property"
+ (buttercup-define-matcher :test-matcher (a b)
+ (+ a b))
+
+ (expect (funcall (get :test-matcher 'buttercup-matcher)
+ 1 2)
+ :to-equal
+ 3)))
diff --git a/buttercup.el b/buttercup.el
index 4e6ad5b..4997e6d 100644
--- a/buttercup.el
+++ b/buttercup.el
@@ -38,29 +38,58 @@
(define-error 'buttercup-error
"Buttercup test raised an error")
-(defun expect (arg &optional matcher &rest args)
+(defmacro expect (arg &optional matcher &rest args)
+ "Expect a condition to be true.
+
+This macro knows three forms:
+
+\(expect arg :matcher args...)
+ Fail the current test iff the matcher does not match these arguments.
+ See `buttercup-define-matcher' for more information on matchers.
+
+\(expect (function arg...))
+ Fail the current test iff the function call does not return a true value.
+
+\(expect ARG)
+ Fail the current test iff ARG is not true."
+ (cond
+ ((and (not matcher)
+ (consp arg))
+ `(buttercup-expect ,(cadr arg)
+ #',(car arg)
+ ,@(cddr arg)))
+ ((and (not matcher)
+ (not (consp arg)))
+ `(buttercup-expect ,arg))
+ (t
+ `(buttercup-expect ,arg ,matcher ,@args))))
+
+(defun buttercup-expect (arg &optional matcher &rest args)
+ "The function for the `expect' macro.
+
+See the macro documentation for details."
(if (not matcher)
(when (not arg)
- (signal 'buttercup-failed
- (format "Expected %S to be non-nil" arg)))
+ (buttercup-fail "Expected %S to be non-nil" arg))
(let ((result (buttercup--apply-matcher matcher (cons arg args))))
(if (consp result)
(when (not (car result))
- (signal 'buttercup-failed
- (cdr result)))
+ (buttercup-fail "%s" (cdr result)))
(when (not result)
- (signal 'buttercup-failed
- (format "Expected %S %S %S"
+ (buttercup-fail "Expected %S %S %S"
arg
matcher
(mapconcat (lambda (obj)
(format "%S" obj))
args
- " "))))))))
+ " ")))))))
-(defun buttercup-fail (explanation form)
- (signal 'buttercup-failed (cons explanation
- form)))
+(defun buttercup-fail (format &rest args)
+ "Fail the current test with the given description.
+
+This is the mechanism underlying `expect'. You can use it
+directly if you want to write your own testing functionality."
+ (signal 'buttercup-failed (apply #'format format args)))
(defmacro buttercup-define-matcher (matcher args &rest body)
"Define a matcher to be used in `expect'.
@@ -75,6 +104,7 @@ should describe why a negated matcher failed."
,@body)))
(defun buttercup--apply-matcher (matcher args)
+
(let ((function (or (get matcher 'buttercup-matcher)
matcher)))
(when (not (functionp function))
@@ -133,13 +163,34 @@ should describe why a negated matcher failed."
(cons nil (format "Expected %S to be greater than %S to %s positions"
a b precision))))
-(buttercup-define-matcher :to-throw (function)
+(buttercup-define-matcher :to-throw (function &optional signal signal-args)
(condition-case err
(progn
(funcall function)
(cons nil (format "Expected %S to throw an error" function)))
(error
- (cons t (format "Expected %S not to throw an error" function)))))
+ (cond
+ ((and signal signal-args)
+ (cond
+ ((not (memq signal (get (car err) 'error-conditions)))
+ (cons nil (format "Expected %S to throw a child signal of %S, not %S"
+ function signal (car err))))
+ ((not (equal signal-args (cdr err)))
+ (cons nil (format "Expected %S to throw %S with args %S, not %S with
%S"
+ function signal signal-args (car err) (cdr err))))
+ (t
+ (cons t (format (concat "Expected %S not to throw a child signal "
+ "of %S with args %S, but it did throw %S")
+ function signal signal-args (car err))))))
+ (signal
+ (if (not (memq signal (get (car err) 'error-conditions)))
+ (cons nil (format "Expected %S to throw a child signal of %S, not
%S"
+ function signal (car err)))
+ (cons t (format (concat "Expected %S not to throw a child signal "
+ "of %S, but it threw %S")
+ function signal (car err)))))
+ (t
+ (cons t (format "Expected %S not to throw an error" function)))))))
;;;;;;;;;;;;;;;;;;;;
;;; describe: Suites
@@ -244,17 +295,16 @@ form.")
(defun buttercup-run-suite (suite &optional level)
(let* ((level (or level 0))
(indent (make-string (* 2 level) ?\s)))
- (message "%s%s\n" indent (buttercup-suite-description suite))
+ (message "%s%s" indent (buttercup-suite-description suite))
(dolist (sub (buttercup-suite-nested suite))
(cond
((buttercup-suite-p sub)
- (message "")
(buttercup-run-suite sub (1+ level)))
((buttercup-spec-p sub)
(message "%s%s"
(make-string (* 2 (1+ level)) ?\s)
- (buttercup-spec-description sub)))
- (funcall (buttercup-spec-function sub))))
+ (buttercup-spec-description sub))
+ (funcall (buttercup-spec-function sub)))))
(message "")))
(defun buttercup-markdown-runner ()
- [nongnu] elpa/buttercup 20b87dd 031/340: Refactoring of spy-on to be more concise and DRY., (continued)
- [nongnu] elpa/buttercup 20b87dd 031/340: Refactoring of spy-on to be more concise and DRY., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup bb31c85 043/340: Edebugable., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 5d369cd 007/340: Do not use emacs-snapshot from EVM, that's slow., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 07b1ee6 008/340: Add compatibility definition for define-error, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 7cdb219 028/340: Spies: :and-call-fake, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 5db449f 025/340: Spies, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup d580e5c 011/340: Add build status badge., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 3637e3d 015/340: Add more extensive matcher tests to the README., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup a277b0e 022/340: Setup and teardown: before-each, after-each, before-all, after-all, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 1882d6f 013/340: Comment cleanup. Also, make elisp lexically scoped., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup c5a9f26 003/340: Add first set of unit tests.,
ELPA Syncer <=
- [nongnu] elpa/buttercup 36522b9 006/340: Add .travis.yml, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup f44e65d 004/340: Unit tests for define-matcher and apply-matcher., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup d3cd12a 019/340: Tests for the buttercup-describe function, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 3772ad5 014/340: Use eval-region instead of eval-buffer., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 8aa87c8 026/340: Spy :and-call-through, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 683614d 018/340: Tests for the describe macro., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 0221830 023/340: Remove setup and teardown from ROADMAP.md., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 695e444 016/340: buttercup-markdown-runner: Use setq, not setq-local., ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 7526198 029/340: Spies: :and-throw-error, ELPA Syncer, 2021/12/16
- [nongnu] elpa/buttercup 77d1dac 017/340: Test buttercup-suite-add-child., ELPA Syncer, 2021/12/16