From 1a20478bbcec1c98c065553b4b0d4ccaec96b24a Mon Sep 17 00:00:00 2001 From: Chris Bernard Date: Sat, 29 May 2010 21:16:51 -0400 Subject: Add Emacs EUnit feature: auto-save If the variable 'erlang-eunit-autosave' is non-nil, buffers will be automatically saved just before running tests -- the "Do you want to save?" prompt will be inhibited. This can be useful, reducing the save-compile-load-test cycle to just one keychord. --- lib/tools/emacs/erlang-eunit.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el index 803c26c5b1..4952ab7d2e 100644 --- a/lib/tools/emacs/erlang-eunit.el +++ b/lib/tools/emacs/erlang-eunit.el @@ -33,6 +33,10 @@ if there is no match.") a source file. The first directory in the list will be used, if there is no match.") +(defvar erlang-eunit-autosave nil + "*Set to non-nil to automtically save unsaved buffers before running tests. +This is useful, reducing the save-compile-load-test cycle to one keychord.") + ;;; ;;; Switch between src/EUnit test buffers ;;; @@ -271,7 +275,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." ;; below, is to ask the question about saving buffers only once, ;; instead of possibly several: one for each file to compile, ;; for instance for both x.erl and x_tests.erl. - (save-some-buffers) + (save-some-buffers erlang-eunit-autosave) (flet ((save-some-buffers (&optional any) nil)) ;; Compilation of the source file is mandatory (the file must -- cgit v1.2.3 From be2ea4ee8e7cfb10e76f7cb15fa7cae725c06eed Mon Sep 17 00:00:00 2001 From: Chris Bernard Date: Sat, 29 May 2010 21:20:14 -0400 Subject: Add Emacs EUnit feature: run recent This determines the most recent invocation of EUnit and runs it again -- whether one test or all tests in a module were run (and if all a module's tests were run, whether cover compilation was involved). This can be especially handy when one test is being run repeatedly, eliminating the need to position the cursor in the desired test just to run it. Default keybinding: C-c C-e l --- lib/tools/emacs/erlang-eunit.el | 93 +++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el index 4952ab7d2e..7453c59390 100644 --- a/lib/tools/emacs/erlang-eunit.el +++ b/lib/tools/emacs/erlang-eunit.el @@ -37,6 +37,9 @@ if there is no match.") "*Set to non-nil to automtically save unsaved buffers before running tests. This is useful, reducing the save-compile-load-test cycle to one keychord.") +(defvar erlang-eunit-recent-info '((mode . nil) (module . nil) (test . nil) (cover . nil)) + "Info about the most recent running of an EUnit test representation.") + ;;; ;;; Switch between src/EUnit test buffers ;;; @@ -55,7 +58,6 @@ buffer and vice versa" "Open the EUnit test file which corresponds to a src file" (find-file-other-window (erlang-eunit-test-filename src-file-path))) - ;;; ;;; Open the src file which corresponds to the an EUnit test file ;;; @@ -151,12 +153,28 @@ buffer and vice versa" (concat dir file) (concat dir "/" file))) +;;; Get info about the most recent running of EUnit +(defun erlang-eunit-recent (key) + (cdr (assq key erlang-eunit-recent-info))) + +;;; Record info about the most recent running of EUnit +;;; Known modes are 'module-mode and 'test-mode +(defun erlang-eunit-record-recent (mode module test) + (setq erlang-eunit-recent-info (pairlis '(mode module test cover) + (list mode module test + (erlang-eunit-recent 'cover))))) + +;;; Record whether the most recent running of EUnit included cover +;;; compilation +(defun erlang-eunit-record-recent-compile (under-cover) + (setcdr (assq 'cover erlang-eunit-recent-info) under-cover)) + ;;; Determine options for EUnit. (defun erlang-eunit-opts () (if current-prefix-arg ", [verbose]" "")) ;;; Determine current test function -(defun erlang-eunit-test-name () +(defun erlang-eunit-current-test () (save-excursion (erlang-end-of-function 1) (erlang-beginning-of-function 1) @@ -168,30 +186,41 @@ buffer and vice versa" (defun erlang-eunit-test-generator-p (test-name) (if (erlang-eunit-string-match-p "^\\(.+\\)_test_$" test-name) t nil)) -;;; Run the current EUnit test -(defun erlang-eunit-run-current-test () - (let* ((module-name (erlang-add-quotes-if-needed - (erlang-eunit-module-name buffer-file-name))) - (test-name (erlang-eunit-test-name)) - (command - (cond ((erlang-eunit-simple-test-p test-name) - (format "eunit:test({%s, %s}%s)." - module-name test-name (erlang-eunit-opts))) - ((erlang-eunit-test-generator-p test-name) - (format "eunit:test({generator, %s, %s}%s)." - module-name test-name (erlang-eunit-opts))) - (t - (format "%% WARNING: '%s' is not a test function" - test-name))))) +;;; Run one EUnit test +(defun erlang-eunit-run-test (module-name test-name) + (let ((command + (cond ((erlang-eunit-simple-test-p test-name) + (format "eunit:test({%s, %s}%s)." + module-name test-name (erlang-eunit-opts))) + ((erlang-eunit-test-generator-p test-name) + (format "eunit:test({generator, %s, %s}%s)." + module-name test-name (erlang-eunit-opts))) + (t (format "%% WARNING: '%s' is not a test function" test-name))))) + (erlang-eunit-record-recent 'test-mode module-name test-name) (erlang-eunit-inferior-erlang-send-command command))) ;;; Run EUnit tests for the current module -(defun erlang-eunit-run-module-tests () - (let* ((module-name (erlang-add-quotes-if-needed - (erlang-eunit-source-module-name buffer-file-name))) - (command (format "eunit:test(%s%s)." module-name (erlang-eunit-opts)))) +(defun erlang-eunit-run-module-tests (module-name) + (let ((command (format "eunit:test(%s%s)." module-name (erlang-eunit-opts)))) + (erlang-eunit-record-recent 'module-mode module-name nil) (erlang-eunit-inferior-erlang-send-command command))) +(defun erlang-eunit-compile-and-run-recent () + "Compile the source and test files and repeat the most recent EUnit test run. + +With prefix arg, compiles for debug and runs tests with the verbose flag set." + (interactive) + (case (erlang-eunit-recent 'mode) + ('test-mode + (erlang-eunit-compile-and-test + 'erlang-eunit-run-test (list (erlang-eunit-recent 'module) + (erlang-eunit-recent 'test)))) + ('module-mode + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list (erlang-eunit-recent 'module)) + (erlang-eunit-recent 'cover))) + (t (error "EUnit has not yet been run. Please run a test first.")))) + (defun erlang-eunit-cover-compile () "Cover compile current module." (interactive) @@ -246,18 +275,25 @@ code along with the coverage analysis results." With prefix arg, compiles for debug and runs tests with the verbose flag set." (interactive) - (erlang-eunit-compile-and-test 'erlang-eunit-run-current-test)) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-module-name buffer-file-name))) + (test-name (erlang-eunit-current-test))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-test (list module-name test-name)))) (defun erlang-eunit-compile-and-run-module-tests () "Compile the source and test files and run all EUnit tests in the module. With prefix arg, compiles for debug and runs tests with the verbose flag set." (interactive) - (erlang-eunit-compile-and-test 'erlang-eunit-run-module-tests)) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-source-module-name buffer-file-name)))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list module-name)))) ;;; Compile source and EUnit test file and finally run EUnit tests for ;;; the current module -(defun erlang-eunit-compile-and-test (run-tests &optional under-cover) +(defun erlang-eunit-compile-and-test (test-fun test-args &optional under-cover) "Compile the source and test files and run the EUnit test suite. If under-cover is set to t, the module under test is compile for @@ -268,6 +304,7 @@ uncovered functions in a module) and written to a buffer called * coverage* (which shows the source code for the module and the number of times each line is covered). With prefix arg, compiles for debug and runs tests with the verbose flag set." + (erlang-eunit-record-recent-compile under-cover) (let ((src-filename (erlang-eunit-src-filename buffer-file-name)) (test-filename (erlang-eunit-test-filename buffer-file-name))) @@ -287,7 +324,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." (if (file-readable-p test-filename) (erlang-eunit-compile-file test-filename) t) - (funcall run-tests) + (apply test-fun test-args) (if under-cover (save-excursion (set-buffer (find-file-noselect src-filename)) @@ -299,7 +336,10 @@ code coverage. With prefix arg, compiles for debug and runs tests with the verbose flag set." (interactive) - (erlang-eunit-compile-and-test 'erlang-eunit-run-module-tests t)) + (let ((module-name (erlang-add-quotes-if-needed + (erlang-eunit-source-module-name buffer-file-name)))) + (erlang-eunit-compile-and-test + 'erlang-eunit-run-module-tests (list module-name) t))) (defun erlang-eunit-compile-file (file-path &optional under-cover) (if (file-readable-p file-path) @@ -379,6 +419,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." '(("\C-c\C-et" erlang-eunit-toggle-src-and-test-file-other-window) ("\C-c\C-ek" erlang-eunit-compile-and-run-module-tests) ("\C-c\C-ej" erlang-eunit-compile-and-run-current-test) + ("\C-c\C-el" erlang-eunit-compile-and-run-recent) ("\C-c\C-ec" erlang-eunit-compile-and-run-module-tests-under-cover) ("\C-c\C-ev" erlang-eunit-cover-compile) ("\C-c\C-ea" erlang-eunit-analyze-coverage))) -- cgit v1.2.3 From 61054475298d4adaca40eb2fbf60c743a3f82fbc Mon Sep 17 00:00:00 2001 From: Chris Bernard Date: Tue, 1 Jun 2010 13:02:53 -0400 Subject: erlang-eunit: remove runtime dependency on cl package Follow the GNU recommendation of not introducing runtime dependencies on the Common Lisp package in ELisp packages that will be distributed for widespread use. In practice this means it's ok to use cl macros but not functions. --- lib/tools/emacs/erlang-eunit.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el index 7453c59390..f2c0db67dd 100644 --- a/lib/tools/emacs/erlang-eunit.el +++ b/lib/tools/emacs/erlang-eunit.el @@ -160,9 +160,9 @@ buffer and vice versa" ;;; Record info about the most recent running of EUnit ;;; Known modes are 'module-mode and 'test-mode (defun erlang-eunit-record-recent (mode module test) - (setq erlang-eunit-recent-info (pairlis '(mode module test cover) - (list mode module test - (erlang-eunit-recent 'cover))))) + (setcdr (assq 'mode erlang-eunit-recent-info) mode) + (setcdr (assq 'module erlang-eunit-recent-info) module) + (setcdr (assq 'test erlang-eunit-recent-info) test)) ;;; Record whether the most recent running of EUnit included cover ;;; compilation -- cgit v1.2.3