Re: [PATCH] jde-junit.el

Ole Arndt <[email protected]> Fri, 15 Oct 2004 21:29:38 +0200
Newsgroups gmane.emacs.jdee,gmane.emacs.jdee.patches
Organization Private
Message-ID <[email protected]>
--=-=-=

Hi Paul, Len, 

Paul Kinnucan <[email protected]> writes:

> Len Trigg writes:
>  > JDE. I've had some functions for ages that I use for running test
>  > classes ...

> I am planning to provide a command like this. However, I want to make
> the JDEE's support of unit testing more flexible. 

Here is the plugin I use for switching forth and back between Class
source and test file and running tests. It uses some customisation
variables, perhaps you can use it as a base. The mapping from class
source to test source can surely be improved.

It is based on some code from the list, I don't remember whose work it
was, shame on me.

See attachment. This is only the lisp file from the plugin. The only
other file in the plugin is junit.jar in java/lib/junit.jar.

-- 
Ole Arndt                     http://www.sugarshark.com


--=-=-=
Content-Type: application/emacs-lisp
Content-Disposition: attachment
Content-Transfer-Encoding: 8bit
Content-Description: jde junit plugin

;;; jde-junit.el   -- more junit integration for JDEE

;; Copyright (C) 2003 Ole Arndt <ole AT shugarshark DOT com>

;; Author:  Ole Arndt <ole AT shugarshark DOT com>
;; Version: 0.1

;; 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 2
;; 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, write to the Free Software
;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.

;;; Commentary:
;;
;;  Base on some code from the jde list

(defcustom jde-junit-test-directory "/test/"
  "Test case directory fragment. This is the part of a path name which 
matches the top directory of the test hierarchy.
When toggling between main class and test case this part is 
replaced by `jde-junit-source-directory'"
  :group 'jde-junit
  :type 'string)

(defcustom jde-junit-source-directory "/java/"
  "Source directory fragment. This is the part of a path name which 
matches the top directory of the java source hierarchy.
When toggling between main class and test case this part is 
replaced by `jde-junit-test-directory'"
  :group 'jde-junit
  :type 'string)

(defcustom jde-junit-runner-class "junit.textui.TestRunner"
  "the class used to run testcases. Common values are:
  \"junit.textui.TestRunner\" or 
  \"junit.swingui.TestRunner\"
The class has to have a main method which takes the test class
to run as an argument."
  :group 'jde-junit
  :type 'string)

(defcustom jde-junit-testcase-suffix "Test"
  "The ending of testcase classes"
  :group 'jde-junit
  :type 'string)

(defcustom jde-junit-testsuite-suffix "Suite"
  "The suffix string of testsuite classes"
  :group 'jde-junit
  :type 'string)

;;
;; compat
;;

(if (not (fboundp 'replace-in-string))
    (defun replace-in-string (string regexp replacement)
      "Replace regex in string with replacement"
      (replace-regexp-in-string regexp replacement string)))

(defconst jde-junit-classname-regex  "\\([A-Za-z$][0-9A-Za-z_$]*\\)")

;;
;; helpers
;;

(defun jde-junit-buffer-basename ()
  "The name of the current class sans the package prefix"
  (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))

(defun jde-junit-toggle-test-buffers ()
  "Jumps back and forth from a test buffer to the class buffer."
  (interactive)
  (if (string-match 
       (concat jde-junit-classname-regex jde-junit-testcase-suffix) 
       (jde-junit-buffer-basename))
      (jde-junit-jump-to-testee)
    (jde-junit-jump-to-testcase)))

(defun jde-junit-jump-to-testee ()
  "Jumps to a buffer containg the source to the class being tested by
the test case in the current buffer" 
  (interactive)
  (let ((class-source (concat (jde-junit-get-class-name-for-buffer) ".java")))
    (if (not (or (jde-find-class-source (jde-junit-class-name-for-test-with-package))
		 (get-buffer class-source)))
	(progn
	  (find-file 
	   (expand-file-name
	    class-source
	    (replace-in-string
	     (file-name-directory buffer-file-name)
	     jde-junit-test-directory jde-junit-source-directory)))
	  (if (= (point-min) (point-max))
	      (jde-gen-class))
	  )
      (switch-to-buffer (get-buffer class-source))
      (make-directory default-directory 't))))

(defun jde-junit-jump-to-testcase ()
  "Jump to a buffer containg the test case for the class in the current buffer
If no such file exists, one will be created.
"
  (interactive)
  (let ((test-source (concat (jde-junit-get-test-name) ".java")))
    (if (not (or (jde-find-class-source (jde-junit-get-test-fqn))
		 (get-buffer test-source)))
	(progn
	  (find-file 
	   (expand-file-name 
	    test-source
	    (replace-in-string (file-name-directory buffer-file-name)
			       jde-junit-source-directory jde-junit-test-directory)))
	  (jde-gen-junit-test-class))
      (switch-to-buffer test-source)
      (make-directory default-directory 't))))

(defun jde-junit-get-class-name-for-buffer ()
  "The class name that the current buffer is writing a test for"
  (let ((class-name (jde-junit-buffer-basename)))
    (if (string-match (concat "\\([A-Za-z$][0-9A-Za-z_$]*\\)" jde-junit-testcase-suffix) class-name)
	(match-string 1  class-name)
      class-name)))

(defun jde-junit-class-name-for-test-with-package ()
  "the name of the current TestCase's class with package"
  (concat (jde-db-get-package) (jde-junit-get-test-name)))

(defun jde-junit-get-test-name ()
  "Returns the name of the current class's testcase sans the package prefix"
  (let ((class-name (jde-junit-get-class-name-for-buffer)))
    (concat class-name 
	    (if (not (string-match jde-junit-testcase-suffix class-name)) 
		jde-junit-testcase-suffix))))

(defun jde-junit-get-test-fqn ()
  "the name of the current classe's TestCase"
  (concat (jde-db-get-package) (jde-junit-get-test-name)))

(defun jde-junit-testsuite-fqn ()
  "Gets the package test class for the current buffer"
  (let ((package-test-class (concat (jde-db-get-package) jde-junit-testsuite-suffix)))
    package-test-class))

;; running stuff

(defun jde-junit-run-test ()
  "run the associated test case for the class specified"
  (interactive)
  ;; prepend test to the class name, and keep the current package context...
  (jde-jeval-cm (concat jde-junit-runner-class ".main(new String[] {\"" 
			(jde-junit-get-test-fqn) "\"});")))

;;(let* ((jde-run-application-class jde-junit-runner-class)
;;         (jde-run-option-application-args 
;;	  (list (jde-junit-get-test-fqn))))
;;    (jde-run-main-class)))

(defun jde-junit-run-suite ()
  "run test suite for current package"
  (interactive)
  (let* ((jde-run-application-class jde-junit-runner-class)
         (jde-run-option-application-args 
	  (list (jde-junit-testsuite-fqn))))
    (jde-run-main-class)))

;; register plugin with jde
(jde-pi-register
 (jde-plugin 
  "junit"
  :bsh-cp (list (expand-file-name "java/lib/junit.jar"  (jde-pi-get-plugin-dir "junit")))
  :menu-spec (list 
	      (list "JUnit" 
		    ["Toggle Class/Test" jde-junit-toggle-test-buffers :active t]
		    ["Run Test Case" jde-junit-run-test :active t]
		    ["Run Test Suite" jde-junit-run-suite :active t]
		    ))
  )
)

(provide 'jde-junit)
--=-=-=--