ddc1fa1609beee2cbec1043fab2ac8d265af2c76
[riece] / lisp / test / lunit-report.el
1 ;;; lunit-report.el --- output test report in XML compatible with JUnitTask
2
3 ;; Copyright (C) 2004 Daiki Ueno.
4
5 ;; Author: Daiki Ueno <ueno@unixuser.org>
6
7 ;; This file is part of Riece.
8
9 ;; This program is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;;; Code:
25
26 (require 'lunit)
27
28 (eval-and-compile
29   (luna-define-class lunit-test-reporter (lunit-test-listener)
30                      (buffer
31                       start-time))
32
33   (luna-define-internal-accessors 'lunit-test-reporter))
34
35 ;; stolen (and renamed) from time-date.el.
36 (defun lunit-time-since (time)
37   "Return the time elapsed since TIME."
38   (let* ((current (current-time))
39          (rest (when (< (nth 1 current) (nth 1 time))
40                  (expt 2 16))))
41     (list (- (+ (car current) (if rest -1 0)) (car time))
42           (- (+ (or rest 0) (nth 1 current)) (nth 1 time))
43           (- (nth 2 current) (nth 2 time)))))
44
45 (defun lunit-escape-quote (string)
46   (let ((index 0))
47     (while (string-match "\"" string index)
48       (setq string (replace-match "&quot;" nil t string)
49             index (+ 5 index)))
50     string))
51     
52 (luna-define-method lunit-test-listener-error ((reporter lunit-test-reporter)
53                                                case error)
54   (save-excursion
55     (set-buffer (lunit-test-reporter-buffer-internal reporter))
56     (insert (format "\
57       <error message=\"%s\" type=\"error\"/>
58 "
59                     (lunit-escape-quote (pp-to-string error))))))
60
61 (luna-define-method lunit-test-listener-failure ((reporter lunit-test-reporter)
62                                                  case failure)
63   (save-excursion
64     (set-buffer (lunit-test-reporter-buffer-internal reporter))
65     (insert (format "\
66       <failure message=\"%s\" type=\"failure\"/>
67 "
68                     (lunit-escape-quote (pp-to-string failure))))))
69
70 (luna-define-method lunit-test-listener-start ((reporter lunit-test-reporter)
71                                                case)
72   (save-excursion
73     (set-buffer (lunit-test-reporter-buffer-internal reporter))
74     (goto-char (point-max))
75     (narrow-to-region (point) (point))
76     (insert (format "\
77     <testcase name=\"%s\" classname=\"%s\">
78 "
79                     (lunit-test-name-internal case)
80                     (luna-class-name case)))
81     (lunit-test-reporter-set-start-time-internal reporter (current-time))))
82
83 (luna-define-method lunit-test-listener-end ((reporter lunit-test-reporter)
84                                              case)
85   (let ((elapsed
86          (lunit-time-since
87           (lunit-test-reporter-start-time-internal reporter))))
88     (save-excursion
89       (set-buffer (lunit-test-reporter-buffer-internal reporter))
90     
91       (insert "\
92     </testcase>
93 ")
94       (goto-char (point-min))
95       (looking-at " *<testcase\\>")
96       (goto-char (match-end 0))
97       (insert (format " time=\"%.03f\" "
98                       (+ (nth 1 elapsed)
99                          (/ (nth 2 elapsed) 1000000.0))))
100       (widen))))
101
102 (defun lunit-report (test file)
103   "Run TEST and output result as XML."
104   (let* ((printer
105           (luna-make-entity 'lunit-test-printer))
106          (result
107           (lunit-make-test-result printer))
108          (buffer (find-file-noselect file))
109          start-time)
110     (save-excursion
111       (set-buffer buffer)
112       (erase-buffer))
113     (lunit-test-result-add-listener
114      result
115      (luna-make-entity 'lunit-test-reporter :buffer buffer))
116     (setq start-time (current-time))
117     (lunit-test-run test result)
118     (let ((assert-count
119            (lunit-test-result-assert-count-internal result))
120           (failures
121            (lunit-test-result-failures-internal result))
122           (errors
123            (lunit-test-result-errors-internal result))
124           
125           (elapsed (lunit-time-since start-time)))
126       (princ (format "%d runs, %d assertions, %d failures, %d errors\n"
127                      (lunit-test-number-of-tests test)
128                      assert-count
129                      (length failures)
130                      (length errors)))
131       (save-excursion
132         (set-buffer buffer)
133         (goto-char (point-min))
134         (insert (format "\
135 <?xml version=\"1.0\" encoding=\"UTF-8\"?>
136 <testsuites>
137   <testsuite name=\"\" tests=\"%d\" failures=\"%d\" \
138 errors=\"%d\" time =\"%.03f\">
139     <properties>
140       <property name=\"emacs-version\" value=\"%s\"/>
141     </properties>
142 "
143                         (lunit-test-number-of-tests test)
144                         (length failures)
145                         (length errors)
146                         (+ (nth 1 elapsed)
147                            (/ (nth 2 elapsed) 1000000.0))
148                         (lunit-escape-quote (emacs-version))))
149         (goto-char (point-max))
150         (insert "\
151   </testsuite>
152 </testsuites>")
153         (save-buffer)))))
154
155 (provide 'lunit-report)