1. Dan Lipsitt
  2. nosemacs

Source

nosemacs / nose.el

Chris Bilson 311de57 
Augie Fackler c3e735f 




Augie Fackler 3a893d9 
Augie Fackler c3e735f 















Dan Lipsitt 403e586 
Augie Fackler 585b428 
Augie Fackler c3e735f 









Augie Fackler 9e9cc1b 

Dan Lipsitt 403e586 































Augie Fackler c3e735f 
Augie Fackler 9302529 
Augie Fackler c3e735f 

Jason Pellerin 4873393 
Augie Fackler 9302529 


Augie Fackler c3e735f 
Augie Fackler e3adb21 



Augie Fackler 585b428 

Jason Pellerin b0d1000 



Augie Fackler 585b428 

Augie Fackler 858ef60 
Augie Fackler 585b428 

Augie Fackler c3e735f 

Augie Fackler 9302529 
Augie Fackler c3e735f 

Augie Fackler 9302529 




Augie Fackler c3e735f 

























Augie Fackler 585b428 
Jason Pellerin b0d1000 

Augie Fackler c3e735f 





Augie Fackler 585b428 
Jason Pellerin b0d1000 
Augie Fackler c3e735f 









Jason Pellerin b0d1000 







Augie Fackler 585b428 
Jason Pellerin b0d1000 

Augie Fackler c3e735f 

Jason Pellerin b0d1000 



Augie Fackler c3e735f 

Augie Fackler 585b428 
Jason Pellerin b0d1000 

Augie Fackler 585b428 
Jason Pellerin b0d1000 

Augie Fackler c3e735f 
Augie Fackler 585b428 
Jason Pellerin b0d1000 

Augie Fackler 585b428 
Jason Pellerin b0d1000 
Jason Pellerin fea37a2 
Jason Pellerin b0d1000 
Augie Fackler 4fdb2c3 
Jason Pellerin b0d1000 
Jason Pellerin 4873393 




Augie Fackler 585b428 
Augie Fackler c3e735f 
Chris Bilson 311de57 
;;; nose.el --- Easy Python test running in Emacs

;; Copyright (C) 2009 Jason Pellerin, Augie Fackler

;; Licensed under the same terms as Emacs.

;; Version: 0.1.1
;; Keywords: nose python testing
;; Created: 04 Apr 2009

;; This file is NOT part of GNU Emacs.

;; Licensed under the same terms as Emacs.

;;; Commentary:
;; This gives a bunch of functions that handle running nosetests on a
;; particular buffer or part of a buffer.

;;; Installation

;; In your emacs config:
;;
;; (require 'nose)
;; Run `customize-group nose' to configure.

;; Probably also want some keybindings:
;; (add-hook 'python-mode-hook
;;           (lambda ()
;;             (local-set-key "\C-ca" 'nosetests-all)
;;             (local-set-key "\C-cm" 'nosetests-module)
;;             (local-set-key "\C-c." 'nosetests-one)
;;             (local-set-key "\C-cpa" 'nosetests-pdb-all)
;;             (local-set-key "\C-cpm" 'nosetests-pdb-module)
;;             (local-set-key "\C-cp." 'nosetests-pdb-one)))

(require 'cl) ;; for "reduce"

(defgroup nose nil
  "A tool for Python unit testing."
  :group 'python)

(defcustom nose-project-names nil
  "Location of non-global test runners."
  :type '(repeat directory)
  :group 'nose)

(defcustom nose-project-root-files '("setup.py" ".hg" ".git")
  "The presence of one of these files indicates the project root directory.
You may choose to use a custom function instead by setting
`nose-project-root-test'"
  :type '(repeat string)
  :group 'nose)

(defcustom nose-project-root-test 'nose-project-root
  "This function is used to detect the project root.
It can be a lambda expression. For example:
  '(lambda (dirname) (equal dirname \"foo\"))"
  :type '(function)
  :group 'nose)

(defcustom nose-global-name "nosetests"
  "Name of the nose shell command."
  :type '(string)
  :group 'nose)

(defcustom nose-use-verbose t
  "Only dots will be output if this variable is nil."
  :type '(boolean)
  :group 'nose)

(defun run-nose (&optional tests debug failed)
  "run nosetests"
  (let* ((nose (nose-find-test-runner))
         (where (nose-find-project-root))
         (args (concat (if debug "--pdb" "")
                       " "
                       (if failed "--failed" "")))
         (tnames (if tests tests "")))
    (if (not where)
        (error
         (format (concat "abort: nosemacs couldn't find a project root, "
                         "looked for any of %S") nose-project-root-files)))
    (funcall (if debug
                 'pdb
               '(lambda (command)
                  (compilation-start command
                                     nil
                                     (lambda (mode) (concat "*nosetests*")))))
             (format
              (concat "%s "
                      (if nose-use-verbose "-v " "")
                      "%s -w %s -c %ssetup.cfg %s")
              (nose-find-test-runner) args where where tnames)))
  )

(defun nosetests-all (&optional debug failed)
  "run all tests"
  (interactive)
  (run-nose nil debug failed))

(defun nosetests-failed (&optional debug)
  (interactive)
  (nosetests-all debug t))

(defun nosetests-pdb-all ()
  (interactive)
  (nosetests-all t))

(defun nosetests-module (&optional debug)
  "run nosetests (via eggs/bin/test) on current buffer"
  (interactive)
  (run-nose buffer-file-name debug))

(defun nosetests-pdb-module ()
  (interactive)
  (nosetests-module t))

(defun nosetests-one (&optional debug)
  "run nosetests (via eggs/bin/test) on testable thing
 at point in current buffer"
  (interactive)
  (run-nose (format "%s:%s" buffer-file-name (nose-py-testable)) debug))

(defun nosetests-pdb-one ()
  (interactive)
  (nosetests-one t))

(defun nose-find-test-runner ()
  (message
   (let ((result
          (reduce '(lambda (x y) (or x y))
        (mapcar 'nose-find-test-runner-names nose-project-names))))
     (if result
         result
       nose-global-name))))

(defun nose-find-test-runner-names (runner)
  "find eggs/bin/test in a parent dir of current buffer's file"
  (nose-find-test-runner-in-dir-named
   (file-name-directory buffer-file-name) runner))

(defun nose-find-test-runner-in-dir-named (dn runner)
  (let ((fn (expand-file-name runner dn)))
    (cond ((file-regular-p fn) fn)
      ((equal dn "/") nil)
      (t (nose-find-test-runner-in-dir-named
          (file-name-directory (directory-file-name dn))
          runner)))))

(defun nose-py-testable ()
  (let* ((inner-obj (inner-testable))
         (outer (outer-testable))
         ;; elisp can't return multiple values
         (outer-def (car outer))
         (outer-obj (cdr outer)))
    (cond ((equal outer-def "def") outer-obj)
          ((equal inner-obj outer-obj) outer-obj)
          (t (format "%s.%s" outer-obj inner-obj)))))

(defun inner-testable ()
  (save-excursion
    (re-search-backward
     "^ \\{0,4\\}\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t)
    (buffer-substring-no-properties (match-beginning 2) (match-end 2))))

(defun outer-testable ()
  (save-excursion
    (re-search-backward
     "^\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t)
    (let ((result
            (buffer-substring-no-properties (match-beginning 2) (match-end 2))))

      (cons
       (buffer-substring-no-properties (match-beginning 1) (match-end 1))
       result))))

(defun nose-find-project-root (&optional dirname)
  (let ((dn
         (if dirname
             dirname
           (file-name-directory buffer-file-name))))
    (cond ((funcall nose-project-root-test dn) (expand-file-name dn))
          ((equal (expand-file-name dn) "/") nil)
        (t (nose-find-project-root
             (file-name-directory (directory-file-name dn)))))))

(defun nose-project-root (dirname)
  (reduce '(lambda (x y) (or x y))
          (mapcar (lambda (d) (member d (directory-files dirname)))
                  nose-project-root-files)))

(provide 'nose)

;;; nose.el ends here