2
;;; Generate Python unit tests
4
;;; pythoscope.el --- generate Python unit tests for file
6
;;; This file is part of the pythoscope distribution and can be found at
7
;;; http://pythoscope.org
9
;;; This file is licensed as part of pythoscope.
10
;;; http://pythoscope.org/documentation#License
14
;;; M-x pythoscope-run-on-current-file will generate unit test for the
20
;; Put this file somewhere where Emacs can find it (i.e. in one of the
21
;; directories in your `load-path' such as `site-lisp'), optionally
22
;; byte-compile it, and put this in your .emacs:
24
;; (require 'pythoscope)
29
(defun string-join (separator strings)
30
(mapconcat 'identity strings separator))
32
(defun pluralize (word count)
33
"Return word with a counter in singular or plural form, depending on count."
35
(format "one %s" word)
36
(format "%d %ss" count word)))
38
(defvar *pythoscope-process-output* "")
40
(defun pythoscope-generated-tests ()
41
"Based on output collected in *pythoscope-process-output* return hash
42
mapping modules to number of tests that where added to them."
43
(let ((tests (make-hash-table :test #'equal)))
44
(loop for start = 0 then (match-end 0)
45
while (string-match "Adding generated \\w+ to \\(.*?\\)\\.$"
46
*pythoscope-process-output* start)
48
(let ((modname (match-string 1 *pythoscope-process-output*)))
49
(puthash modname (1+ (gethash modname tests 0)) tests)))
52
(defun pythoscope-tests-hash-to-descriptions (tests)
53
(loop for modname being the hash-keys in tests
54
using (hash-value test-count)
55
collect (format "%s for %s" (pluralize "test" test-count) modname)))
57
(defun pythoscope-generated-tests-summary ()
58
(let ((tests (pythoscope-generated-tests)))
59
(if (zerop (hash-table-count tests))
60
"No tests were generated."
62
(string-join ", " (pythoscope-tests-hash-to-descriptions tests))
65
(defun pythoscope-process-sentinel (process event)
66
(when (memq (process-status process) '(signal exit))
67
(let ((exit-status (process-exit-status process)))
68
(if (zerop exit-status)
69
(message (pythoscope-generated-tests-summary))
70
(message "pythoscope[%d] exited with code %d"
71
(process-id process) exit-status)))))
73
(defun pythoscope-process-filter (process output)
74
"Save all pythoscope output to *pythoscope-process-output* for later
76
(setq *pythoscope-process-output*
77
(concat *pythoscope-process-output* output)))
79
(defun pythoscope-run-on-file (filename)
80
"Generate tests for given file using pythoscope."
82
(setq *pythoscope-process-output* "")
83
(let ((process (start-process "pythoscope-process"
87
(set-process-sentinel process 'pythoscope-process-sentinel)
88
(set-process-filter process 'pythoscope-process-filter))
89
(message "Generating tests..."))
91
(defun pythoscope-run-on-current-file ()
92
"Generate tests for file open in the current buffer."
94
(let ((filename (buffer-file-name)))
96
(pythoscope-run-on-file filename))))