;;; rails-test.el --- tests integration with the compile library ;; Copyright (C) 2006 Dmitry Galinsky ;; Authors: Dmitry Galinsky , ;; Keywords: ruby rails languages oop ;; $URL: svn+ssh://rubyforge/var/svn/emacs-rails/trunk/rails-ws.el $ ;; $Id: rails-ws.el 140 2007-03-27 23:33:36Z dimaexe $ ;;; License ;; 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-1307, USA. ;;; Code: (defvar rails-test:history nil) (defconst rails-test:result-regexp "\\([0-9]+ tests, [0-9]+ assertions, \\([0-9]+\\) failures, \\([0-9]+\\) errors\\)") (defconst rails-test:progress-regexp "^[\\.EF]+$") (defun rails-test:file-ext-regexp () (let ((rails-templates-list (append rails-templates-list (list "rb")))) (substring (rails-core:regex-for-match-view) 0 -1))) (defun rails-test:line-regexp (&optional append prepend) (concat append (format "\\(#{RAILS_ROOT}\/\\)?\\(\\(\\.\\|[A-Za-z]:\\)?\\([a-z/_.]+%s\\)\\):\\([0-9]+\\)" (rails-test:file-ext-regexp)) prepend)) (defun rails-test:error-regexp-alist () (list (list 'rails-test-trace (rails-test:line-regexp) 2 6 nil 0) (list 'rails-test-failure (rails-test:line-regexp "\\[" "\\]") 2 6 nil 2) (list 'rails-test-error (rails-test:line-regexp nil ".*\n$") 2 6 nil 2))) (defun rails-test:print-result () (with-current-buffer (get-buffer rails-script:buffer-name) (let ((msg (list)) (failures 0) (errors 0)) (save-excursion (goto-char (point-min)) (while (re-search-forward rails-test:result-regexp (point-max) t) (setq failures (+ failures (string-to-number (match-string-no-properties 2)))) (setq errors (+ errors (string-to-number (match-string-no-properties 3)))) (add-to-list 'msg (match-string-no-properties 1)))) (unless (zerop (length msg)) (message (strings-join " || " (reverse msg)))) (when (and (or (not (zerop rails-script:output-mode-ret-value)) (not (zerop errors)) (not (zerop failures))) (not (buffer-visible-p (current-buffer)))) (rails-script:popup-buffer))))) (defun rails-test:print-progress (start end len) (let (content) (save-excursion (goto-char (point-min)) (while (re-search-forward "^Started" end t) (line-move 1) (save-match-data (let ((progress (string=~ rails-test:progress-regexp (current-line-string) $m))) (when progress (setq content (concat content progress))))))) (when content (message "Progress of %s: %s" rails-script:running-script-name content)))) (define-derived-mode rails-test:compilation-mode compilation-mode "RTest" "Major mode for RoR tests." (rails-script:setup-output-buffer) (set (make-local-variable 'compilation-error-regexp-alist-alist) (rails-test:error-regexp-alist)) (set (make-local-variable 'compilation-error-regexp-alist) '(rails-test-error rails-test-failure rails-test-trace)) (add-hook 'after-change-functions 'rails-test:print-progress nil t) (add-hook 'rails-script:run-after-stop-hook 'rails-test:print-result nil t) (add-hook 'rails-script:show-buffer-hook #'(lambda() (let ((win (get-buffer-window (current-buffer)))) (when (window-live-p win) (set-window-point win 0) (unless (buffer-visible-p (current-buffer)) (compilation-set-window-height win))))) t t)) (defun rails-test:list-of-tasks () "Return a list contains test tasks." (append (list "all") (delete* nil (mapcar #'(lambda (task) (string=~ "^test\\:\\([^ ]+\\)" task $1)) (rails-rake:list-of-tasks)) :if 'null))) (defun rails-test:run (task) "Run rake tests in RAILS_ROOT." (interactive (rails-completing-read "What test run" (rails-test:list-of-tasks) 'rails-test:history t)) (unless task (setq task "all") (add-to-list rails-test:history task)) (let ((task-name (if (string= "all" task) "test" (concat "test:" task)))) (rails-rake:task task-name 'rails-test:compilation-mode))) (defun rails-test:run-single-file (file &optional param) "Run test for single file FILE." (let ((param (if param (append (list file) (list param)) (list file)))) (rails-script:run "ruby" param 'rails-test:compilation-mode))) (defun rails-test:run-current () "Run a test for the current controller/model/mailer." (interactive) (let* ((model (rails-core:current-model)) (controller (rails-core:current-controller)) (func-test (rails-core:functional-test-file controller)) (unit-test (rails-core:unit-test-file model)) (mailer-test (rails-core:unit-test-file controller))) (rails-test:run-single-file (cond ;; model ((and model unit-test) unit-test) ;; controller ((and controller (not (rails-core:mailer-p controller)) func-test) func-test) ;; mailer ((and controller (rails-core:mailer-p controller) unit-test) unit-test))))) (defun rails-test:run-current-method () "Run a test for the current method." (interactive) (let ((file (substring (buffer-file-name) (length (rails-project:root)))) (method (rails-core:current-method-name))) (when method (rails-test:run-single-file file (format "--name=%s" method))))) (provide 'rails-test)