Permalink
Browse files

Manually incorporated the changes from nex3's master branch.

This includes the changes from technomancy's former branch.
  • Loading branch information...
1 parent 424913f commit cc061e0b07c47bfaeeabc9606bf3241a3e35debe Christian Ohler committed Jun 14, 2010
Showing with 536 additions and 117 deletions.
  1. +3 −0 .gitignore
  2. +96 −0 ert-experimental-tests.el
  3. +108 −0 ert-experimental.el
  4. +7 −4 ert-tests.el
  5. +2 −0 ert-ui.el
  6. +11 −113 ert.el
  7. +309 −0 ert.texinfo
View
@@ -0,0 +1,3 @@
+ert.info
+*~
+*.elc
View
@@ -0,0 +1,96 @@
+;;; ert-experimental-tests.el --- Tests for ert-experimental.el
+
+;; Copyright (C) 2008 Phil Hagelberg
+
+;; Author: Phil Hagelberg
+;; Version: 0.2
+;; Keywords: lisp, tools
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see `http://www.gnu.org/licenses/'.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl))
+(require 'ert)
+(require 'ert-experimental)
+
+;;; Predicates
+
+(ert-deftest ert-buffer-changes-p ()
+ (with-temp-buffer
+ (should (buffer-changes-p
+ (insert "hello")))
+ (should-not (buffer-changes-p
+ (message "hello")))))
+
+(ert-deftest ert-buffer-contains-p ()
+ (with-temp-buffer
+ (insert "hello world")
+ (should (buffer-contains-p "hello"))
+ (should-not (buffer-contains-p "goodbye"))))
+
+(ert-deftest ert-correctly-indented-p ()
+ (let ((well-indented (concat "(hello (world\n"
+ " 'elisp)\n"))
+ (badly-indented (concat "(hello\n"
+ " world)")))
+ (with-temp-buffer
+ (insert well-indented)
+ (emacs-lisp-mode)
+ (should (correctly-indented-p)))
+ (with-temp-buffer
+ (insert badly-indented)
+ (emacs-lisp-mode)
+ (should-not (correctly-indented-p)))))
+
+
+;;; Utilities
+
+(ert-deftest ert-with-test-buffer ()
+ (let ((contents "Foo bar\n baz\n\tbip"))
+ (with-test-buffer contents
+ (should (string-equal (buffer-string) contents)))))
+
+(ert-deftest ert-with-test-buffer-inserting ()
+ (let ((contents "Foo bar\n baz\n\tbip"))
+ (with-test-buffer contents
+ (insert "Hello\n")
+ (should (string-equal (buffer-string) (concat "Hello\n" contents))))))
+
+(ert-deftest ert-with-test-buffer-mark ()
+ (with-test-buffer "Foo<mark> bar baz"
+ (should (string-equal (buffer-substring (point) (mark)) "Foo"))
+ (should (string-equal (buffer-string) "Foo bar baz"))))
+
+(ert-deftest ert-with-test-buffer-fake-mark ()
+ (with-test-buffer "Foo\\<mark> bar baz"
+ (should (string-equal (buffer-string) "Foo<mark> bar baz"))))
+
+(ert-deftest ert-with-test-buffer-point ()
+ (with-test-buffer "Foo bar<point> baz"
+ (insert "bell")
+ (should (string-equal (buffer-string) "Foo barbell baz"))))
+
+(ert-deftest ert-with-test-buffer-mark-and-point ()
+ (with-test-buffer "Foo <mark>bar<point> baz"
+ (upcase-region (mark) (point))
+ (should (string-equal (buffer-string) "Foo BAR baz"))))
+
+
+(provide 'ert-experimental-tests)
+
+;;; ert-experimental-tests.el ends here
View
@@ -0,0 +1,108 @@
+;;; ert-experimental.el --- Staging area for proposed extensions to ERT
+
+;; Copyright (C) 2008 Phil Hagelberg
+
+;; Author: Phil Hagelberg
+;; Version: 0.2
+;; Keywords: lisp, tools
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see `http://www.gnu.org/licenses/'.
+
+;;; Commentary:
+
+;; This file includes some extra helper functions to use while writing
+;; automated tests with ERT. These have been proposed as extensions
+;; to ERT but are not mature yet and likely to change.
+;;
+;; Since it is not meant to be loaded during normal use, this file
+;; includes functions that are not prefixed for readability's sake.
+
+;;; Code:
+
+(defmacro buffer-changes-p (&rest body)
+ "Execute BODY and return true if it changed the buffer content."
+ (let ((original-buffer-content (make-symbol "original-buffer-content")))
+ `(let ((,original-buffer-content (buffer-string)))
+ (progn ,@body
+ (not (string= ,original-buffer-content
+ (buffer-string)))))))
+
+(defun buffer-contains-p (regexp &optional buffer)
+ "Return true if regexp is found anywhere in BUFFER (default current buffer)."
+ (with-current-buffer (or buffer (current-buffer))
+ (save-excursion
+ (goto-char (point-min))
+ (not (not (search-forward-regexp regexp nil t))))))
+
+;; TODO(ohler): modify this to allow better error reporting in the
+;; case of failure, e.g., by changing it to
+;; `should-be-correctly-indented' or
+;; `buffer-contents-after-reindentation', or add an explainer.
+(defun correctly-indented-p (&optional buffer)
+ "Returns true if BUFFER is indented the way Emacs would indent it.
+
+BUFFER defaults to current buffer."
+ (with-current-buffer (or buffer (current-buffer))
+ (with-current-buffer
+ (let ((buffer-file-name nil)) ; otherwise clone-buffer would refuse
+ (clone-buffer))
+ (unwind-protect
+ (let ((buffer-original-indentation (buffer-string)))
+ (indent-region (point-min) (point-max))
+ (let ((buffer-new-indentation (buffer-string)))
+ (string= buffer-original-indentation buffer-new-indentation)))
+ (let ((kill-buffer-query-functions nil))
+ (kill-buffer nil))))))
+
+(defun ert-test-buffer-substitute (string fn)
+ "Removes the all occurrences of STRING in the buffer
+and runs FN with at that point each one is removed.
+
+Backslash-escaped STRINGs are unescaped and ignored."
+ (let ((len (length string)))
+ (save-excursion
+ (goto-char (point-min))
+ (while (search-forward string nil t)
+ (save-excursion
+ (backward-char len)
+ (if (eq (char-before (point)) ?\\) (delete-char -1)
+ (delete-char len)
+ (funcall fn)))))))
+
+(defmacro with-test-buffer (contents &rest body)
+ "Runs BODY in a buffer containing CONTENTS.
+
+The mark may be set in the buffer using the string \"<mark>\".
+This can be escaped with a backslash to unclude it literally."
+ `(with-temp-buffer
+ (insert ,contents)
+ (goto-char (point-min))
+
+ (let ((new-mark))
+ (ert-test-buffer-substitute "<mark>" (lambda () (setq new-mark (point))))
+ (set-mark new-mark))
+
+ (let ((new-point (point)))
+ (ert-test-buffer-substitute "<point>"
+ (lambda () (setq new-point (point))))
+ (goto-char new-point))
+ ,@body))
+(put 'with-test-buffer 'lisp-indent-function 1)
+
+
+(provide 'ert-experimental)
+
+;;; ert-experimental.el ends here
View
@@ -23,8 +23,12 @@
(eval-when-compile
(require 'cl))
+;; Test definitions should normally depend just on ert, not ert-ui.
+;; However, this file includes tests for ert-ui, so it has to depend
+;; on it.
(require 'ert-ui)
+
;;; Self-test that doesn't rely on ERT, for bootstrapping.
;; This is used to test that bodies actually run.
@@ -259,8 +263,7 @@
:type 'singularity-error
:test (lambda (error) t))))))
(let ((result (ert-run-test test)))
- (should (typep result 'ert-test-passed))))
- )
+ (should (typep result 'ert-test-passed)))))
(ert-deftest ert-test-should-error-subtypes ()
(let ((test (make-ert-test
@@ -318,8 +321,8 @@
:form (signal singularity-error nil)
:condition (singularity-error)
:fail-reason
- "the error signalled was a subtype of the expected type"))))))
- )
+ "the error signalled was a subtype of the expected type")))))
+ ))
;; Test that `should' errors contain the information we expect them to.
(defmacro ert-test-my-list (&rest args)
View
@@ -399,6 +399,8 @@ SELECTOR works as described in `ert-select-tests'."
(ert-run-tests
selector
listener)))
+;;;###autoload
+(defalias 'ert 'ert-run-tests-interactively)
;;; Simple view mode for auxiliary information like stack traces or
View
124 ert.el
@@ -48,118 +48,14 @@
;; `should' is more sophisticated). For information on `should-not'
;; and `should-error', see their docstrings.
;;
-;; For example,
+;; See ERT's info manual as well as the docstrings for more details.
+;; To compile the manual, run `makeinfo ert.texinfo' in the ERT
+;; directory, then C-u M-x info ert.info in Emacs to view it.
;;
-;; ;; Define a test named `foo'.
-;; (ert-deftest foo ()
-;; (should (= (+ 1 2) 4)))
-;;
-;; ;; Run it.
-;; (ert-run-tests-interactively 'foo)
-;;
-;; generates the following output (in addition to some statistics) in
-;; the *ert* results buffer:
-;;
-;; F foo
-;; (ert-test-failed
-;; ((should
-;; (=
-;; (+ 1 2)
-;; 4))
-;; :form
-;; (= 3 4)
-;; :value nil))
-;;
-;; This indicates that the test failed. The `should' form that failed
-;; was (should (= (+ 1 2) 4)), because its inner form, after
-;; evaluation of its arguments, was the function call (= 3 4), which
-;; returned nil.
-;;
-;; Obviously, this is a bug in the test case, not in the functions `+'
-;; or `='. In the results buffer, with point on the test result, the
-;; key "." can be used to jump to the definition of the test to modify
-;; it to correct the bug. After evaluating the modified definition
-;; and switching back to the results buffer, the key "r" will re-run
-;; the test and show the new result.
-
-
-;; Test selectors
-;;
-;; Functions like `ert-run-tests-interactively' accept a test
-;; selector, which is a Lisp expression specifying a set of tests.
-;; Each test name is a selector that refers to that test, the selector
-;; `t' refers to all tests, and the selector `:failed' refers to all
-;; tests that failed; but more complex selectors are available. Test
-;; selector syntax is similar to cl's type specifier syntax. See the
-;; docstring of `ert-select-tests' for details.
-
-
-;; Comparison with other testing tools
-;;
-;; ERT allows test-driven development similar to *Unit frameworks for
-;; other languages. However, two common *Unit features are notably
-;; absent from ERT: fixtures and test suites.
-;;
-;; Fixtures, as used e.g. in SUnit or JUnit, have two main purposes:
-;; Setting up (and tearing down) an environment for a set of test
-;; cases, and making that environment accessible through object
-;; attributes that can be used like local variables.
-;;
-;; While fixtures are a great syntactic simplification in other
-;; languages, they are not very useful in Lisp, where higher-order
-;; functions and `unwind-protect' are available. One way to implement
-;; and use a fixture in ERT is
-;;
-;; (defun my-fixture (body)
-;; (unwind-protect
-;; (progn ...set up...
-;; (funcall body))
-;; ...tear down...))
-;;
-;; (ert-deftest my-test ()
-;; (my-fixture
-;; (lambda ()
-;; ...test code...)))
-;;
-;; (Another way would be a `with-my-fixture' macro.) This solves the
-;; set-up and tear-down part, and additionally allows any test case to
-;; use any combination of fixtures, so it is more general than what
-;; other tools typically allow.
-;;
-;; If the test case needs access to the environment the fixture sets
-;; up, the fixture can be modified to pass arguments to the body.
-;;
-;; These are standard Lisp idioms. Special syntax for them could be
-;; added easily enough, but would provide only a minor simplification.
-;;
-;; (Note that splitting set-up and tear-down into separate functions,
-;; like *Unit tools usually do, makes it impossible to establish
-;; dynamic `let' bindings as part of the fixture. So, blindly
-;; imitating the way fixtures are implemented in other languages would
-;; be counter-productive in Lisp.)
-;;
-;;
-;; The purpose of test suites is to group related test cases together.
-;; The most common use of this is to run just the tests for one
-;; particular module. Since symbol prefixes are the usual way of
-;; separating module namespaces in Emacs Lisp, test selectors already
-;; solve this by allowing regexp matching on test names; e.g., the
-;; selector "^ert-" selects ERT's self-tests.
-;;
-;; If test suites containing arbitrary sets of tests are found to be
-;; desirable, it would be easy to add a `define-test-selector'
-;; mechanism that introduces a new selector, defined in terms of
-;; existing ones; e.g.
-;;
-;; ;; Note that `define-test-selector' does not exist yet.
-;; (define-test-selector my-test-suite () `(member foo-test bar-test))
-;;
-;; would define a test suite named `my-test-suite' consisting of
-;; `foo-test' and `bar-test'. See also `deftype' in Common Lisp.
-
-
-;; TODO: Add `skip' feature for tests that can't run in current environment.
-
+;; To see some examples of tests written in ERT, see its self-tests in
+;; ert-tests.el. Some of these are tricky due to the bootstrapping
+;; problem of writing tests for a testing tool, others test simple
+;; functions and are straightforward.
;;; Code:
@@ -323,8 +219,10 @@ See `ert-test-result-type-p' for a description of valid values for RESULT-TYPE.
',name)))
;; TODO(ohler): figure out what this means
-(put 'ert-deftest 'lisp-indent-function 2)
-(put 'ert-deftest 'lisp-indent-hook 2)
+;;;###autoload
+(progn
+ (put 'ert-deftest 'lisp-indent-function 2)
+ (put 'ert-deftest 'lisp-indent-hook 2))
(defvar ert-find-test-regexp
(concat "^\\s-*(ert-deftest"
Oops, something went wrong.

0 comments on commit cc061e0

Please sign in to comment.