123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- ;;; cedet-utests.el --- Run all unit tests in the CEDET suite.
- ;; Copyright (C) 2008-2012 Free Software Foundation, Inc.
- ;; Author: Eric M. Ludlam <eric@siege-engine.com>
- ;; This file is part of GNU Emacs.
- ;; GNU Emacs 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 3 of the License, or
- ;; (at your option) any later version.
- ;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;;
- ;; Remembering to run all the unit tests available in CEDET one at a
- ;; time is a bit time consuming. This links all the tests together
- ;; into one command.
- (require 'cedet)
- ;;; Code:
- (defvar cedet-utest-test-alist
- '(
- ;;
- ;; COMMON
- ;;
- ;; Test inversion
- ("inversion" . inversion-unit-test)
- ;; EZ Image dumping.
- ("ezimage associations" . ezimage-image-association-dump)
- ("ezimage images" . ezimage-image-dump)
- ;; Pulse
- ("pulse interactive test" . (lambda () (pulse-test t)))
- ;; Files
- ("cedet file conversion" . cedet-files-utest)
- ;;
- ;; EIEIO
- ;;
- ("eieio" . (lambda () (let ((lib (locate-library "eieio-tests.el"
- t)))
- (load-file lib))))
- ("eieio: browser" . eieio-browse)
- ("eieio: custom" . (lambda ()
- (require 'eieio-custom)
- (customize-variable 'eieio-widget-test)))
- ("eieio: chart" . (lambda ()
- (if (cedet-utest-noninteractive)
- (message " ** Skipping test in noninteractive mode.")
- (chart-test-it-all))))
- ;;
- ;; EDE
- ;;
- ;; @todo - Currently handled in the integration tests. Need
- ;; some simpler unit tests here.
- ;;
- ;; SEMANTIC
- ;;
- ("semantic: lex spp table write" . semantic-lex-spp-write-utest)
- ("semantic: multi-lang parsing" . semantic-utest-main)
- ("semantic: C preprocessor" . semantic-utest-c)
- ("semantic: analyzer tests" . semantic-ia-utest)
- ("semanticdb: data cache" . semantic-test-data-cache)
- ("semantic: throw-on-input" .
- (lambda ()
- (if (cedet-utest-noninteractive)
- (message " ** Skipping test in noninteractive mode.")
- (semantic-test-throw-on-input))))
- ("semantic: gcc: output parse test" . semantic-gcc-test-output-parser)
- ;;
- ;; SRECODE
- ;;
- ("srecode: fields" . srecode-field-utest)
- ("srecode: templates" . srecode-utest-template-output)
- ("srecode: show maps" . srecode-get-maps)
- ("srecode: getset" . srecode-utest-getset-output)
- )
- "Alist of all the tests in CEDET we should run.")
- (defvar cedet-running-master-tests nil
- "Non-nil when CEDET-utest is running all the tests.")
- (defun cedet-utest (&optional exit-on-error)
- "Run the CEDET unit tests.
- EXIT-ON-ERROR causes the test suite to exit on an error, instead
- of just logging the error."
- (interactive)
- (if (or (not (featurep 'semanticdb-mode))
- (not (semanticdb-minor-mode-p)))
- (error "CEDET Tests require: M-x semantic-load-enable-minimum-features"))
- (cedet-utest-log-setup "ALL TESTS")
- (let ((tl cedet-utest-test-alist)
- (notes nil)
- (err nil)
- (start (current-time))
- (end nil)
- (cedet-running-master-tests t)
- )
- (dolist (T tl)
- (cedet-utest-add-log-item-start (car T))
- (setq notes nil err nil)
- (condition-case Cerr
- (progn
- (funcall (cdr T))
- )
- (error
- (setq err (format "ERROR: %S" Cerr))
- ;;(message "Error caught: %s" Cerr)
- ))
- ;; Cleanup stray input and events that are in the way.
- ;; Not doing this causes sit-for to not refresh the screen.
- ;; Doing this causes the user to need to press keys more frequently.
- (when (and (interactive-p) (input-pending-p))
- (if (fboundp 'read-event)
- (read-event)
- (read-char)))
- (cedet-utest-add-log-item-done notes err)
- (when (and exit-on-error err)
- (message "to debug this test point, execute:")
- (message "%S" (cdr T))
- (message "\n ** Exiting Test Suite. ** \n")
- (throw 'cedet-utest-exit-on-error t)
- )
- )
- (setq end (current-time))
- (cedet-utest-log-shutdown-msg "ALL TESTS" start end)
- nil))
- (defun cedet-utest-noninteractive ()
- "Return non-nil if running non-interactively."
- (if (featurep 'xemacs)
- (noninteractive)
- noninteractive))
- ;;;###autoload
- (defun cedet-utest-batch ()
- "Run the CEDET unit test in BATCH mode."
- (unless (cedet-utest-noninteractive)
- (error "`cedet-utest-batch' is to be used only with -batch"))
- (condition-case err
- (when (catch 'cedet-utest-exit-on-error
- ;; Get basic semantic features up.
- (semantic-load-enable-minimum-features)
- ;; Disables all caches related to semantic DB so all
- ;; tests run as if we have bootstrapped CEDET for the
- ;; first time.
- (setq-default semanticdb-new-database-class 'semanticdb-project-database)
- (message "Disabling existing Semantic Database Caches.")
- ;; Disabling the srecoder map, we won't load a pre-existing one
- ;; and will be forced to bootstrap a new one.
- (setq srecode-map-save-file nil)
- ;; Run the tests
- (cedet-utest t)
- )
- (kill-emacs 1))
- (error
- (error "Error in unit test harness:\n %S" err))
- )
- )
- ;;; Logging utility.
- ;;
- (defvar cedet-utest-frame nil
- "Frame used during cedet unit test logging.")
- (defvar cedet-utest-buffer nil
- "Frame used during cedet unit test logging.")
- (defvar cedet-utest-frame-parameters
- '((name . "CEDET-UTEST")
- (width . 80)
- (height . 25)
- (minibuffer . t))
- "Frame parameters used for the cedet utest log frame.")
- (defvar cedet-utest-last-log-item nil
- "Remember the last item we were logging for.")
- (defvar cedet-utest-log-timer nil
- "During a test, track the start time.")
- (defun cedet-utest-log-setup (&optional title)
- "Setup a frame and buffer for unit testing.
- Optional argument TITLE is the title of this testing session."
- (setq cedet-utest-log-timer (current-time))
- (if (cedet-utest-noninteractive)
- (message "\n>> Setting up %s tests to run @ %s\n"
- (or title "")
- (current-time-string))
- ;; Interactive mode needs a frame and buffer.
- (when (or (not cedet-utest-frame) (not (frame-live-p cedet-utest-frame)))
- (setq cedet-utest-frame (make-frame cedet-utest-frame-parameters)))
- (when (or (not cedet-utest-buffer) (not (buffer-live-p cedet-utest-buffer)))
- (setq cedet-utest-buffer (get-buffer-create "*CEDET utest log*")))
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (setq cedet-utest-last-log-item nil)
- (when (not cedet-running-master-tests)
- (erase-buffer))
- (insert "\n\nSetting up "
- (or title "")
- " tests to run @ " (current-time-string) "\n\n"))
- (let ((oframe (selected-frame)))
- (unwind-protect
- (progn
- (select-frame cedet-utest-frame)
- (switch-to-buffer cedet-utest-buffer t))
- (select-frame oframe)))
- ))
- (defun cedet-utest-elapsed-time (start end)
- "Copied from elp.el. Was elp-elapsed-time.
- Argument START and END bound the time being calculated."
- (+ (* (- (car end) (car start)) 65536.0)
- (- (car (cdr end)) (car (cdr start)))
- (/ (- (car (cdr (cdr end))) (car (cdr (cdr start)))) 1000000.0)))
- (defun cedet-utest-log-shutdown (title &optional errorcondition)
- "Shut-down a larger test suite.
- TITLE is the section that is done.
- ERRORCONDITION is some error that may have occurred during testing."
- (let ((endtime (current-time))
- )
- (cedet-utest-log-shutdown-msg title cedet-utest-log-timer endtime)
- (setq cedet-utest-log-timer nil)
- ))
- (defun cedet-utest-log-shutdown-msg (title startime endtime)
- "Show a shutdown message with TITLE, STARTIME, and ENDTIME."
- (if (cedet-utest-noninteractive)
- (progn
- (message "\n>> Test Suite %s ended at @ %s"
- title
- (format-time-string "%c" endtime))
- (message " Elapsed Time %.2f Seconds\n"
- (cedet-utest-elapsed-time startime endtime)))
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (goto-char (point-max))
- (insert "\n>> Test Suite " title " ended at @ "
- (format-time-string "%c" endtime) "\n"
- " Elapsed Time "
- (number-to-string
- (cedet-utest-elapsed-time startime endtime))
- " Seconds\n * "))
- ))
- (defun cedet-utest-show-log-end ()
- "Show the end of the current unit test log."
- (unless (cedet-utest-noninteractive)
- (let* ((cb (current-buffer))
- (cf (selected-frame))
- (bw (or (get-buffer-window cedet-utest-buffer t)
- (get-buffer-window (switch-to-buffer cedet-utest-buffer) t)))
- (lf (window-frame bw))
- )
- (select-frame lf)
- (select-window bw)
- (goto-char (point-max))
- (select-frame cf)
- (set-buffer cb)
- )))
- (defun cedet-utest-post-command-hook ()
- "Hook run after the current log command was run."
- (if (cedet-utest-noninteractive)
- (message "")
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (goto-char (point-max))
- (insert "\n\n")))
- (setq cedet-utest-last-log-item nil)
- (remove-hook 'post-command-hook 'cedet-utest-post-command-hook)
- )
- (defun cedet-utest-add-log-item-start (item)
- "Add ITEM into the log as being started."
- (unless (equal item cedet-utest-last-log-item)
- (setq cedet-utest-last-log-item item)
- ;; This next line makes sure we clear out status during logging.
- (add-hook 'post-command-hook 'cedet-utest-post-command-hook)
- (if (cedet-utest-noninteractive)
- (message " - Running %s ..." item)
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (goto-char (point-max))
- (when (not (bolp)) (insert "\n"))
- (insert "Running " item " ... ")
- (sit-for 0)
- ))
- (cedet-utest-show-log-end)
- ))
- (defun cedet-utest-add-log-item-done (&optional notes err precr)
- "Add into the log that the last item is done.
- Apply NOTES to the doneness of the log.
- Apply ERR if there was an error in previous item.
- Optional argument PRECR indicates to prefix the done msg w/ a newline."
- (if (cedet-utest-noninteractive)
- ;; Non-interactive-mode - show a message.
- (if notes
- (message " * %s {%s}" (or err "done") notes)
- (message " * %s" (or err "done")))
- ;; Interactive-mode - insert into the buffer.
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (goto-char (point-max))
- (when precr (insert "\n"))
- (if err
- (insert err)
- (insert "done")
- (when notes (insert " (" notes ")")))
- (insert "\n")
- (setq cedet-utest-last-log-item nil)
- (sit-for 0)
- )))
- ;;; INDIVIDUAL TEST API
- ;;
- ;; Use these APIs to start and log information.
- ;;
- ;; The other fcns will be used to log across all the tests at once.
- (defun cedet-utest-log-start (testname)
- "Setup the log for the test TESTNAME."
- ;; Make sure we have a log buffer.
- (save-window-excursion
- (when (or (not cedet-utest-buffer)
- (not (buffer-live-p cedet-utest-buffer))
- (not (get-buffer-window cedet-utest-buffer t))
- )
- (cedet-utest-log-setup))
- ;; Add our startup message.
- (cedet-utest-add-log-item-start testname)
- ))
- (defun cedet-utest-log(format &rest args)
- "Log the text string FORMAT.
- The rest of the ARGS are used to fill in FORMAT with `format'."
- (if (cedet-utest-noninteractive)
- (apply 'message format args)
- (save-excursion
- (set-buffer cedet-utest-buffer)
- (goto-char (point-max))
- (when (not (bolp)) (insert "\n"))
- (insert (apply 'format format args))
- (insert "\n")
- (sit-for 0)
- ))
- (cedet-utest-show-log-end)
- )
- ;;; Inversion tests
- (defun inversion-unit-test ()
- "Test inversion to make sure it can identify different version strings."
- (interactive)
- (let ((c1 (inversion-package-version 'inversion))
- (c1i (inversion-package-incompatibility-version 'inversion))
- (c2 (inversion-decode-version "1.3alpha2"))
- (c3 (inversion-decode-version "1.3beta4"))
- (c4 (inversion-decode-version "1.3 beta5"))
- (c5 (inversion-decode-version "1.3.4"))
- (c6 (inversion-decode-version "2.3alpha"))
- (c7 (inversion-decode-version "1.3"))
- (c8 (inversion-decode-version "1.3pre1"))
- (c9 (inversion-decode-version "2.4 (patch 2)"))
- (c10 (inversion-decode-version "2.4 (patch 3)"))
- (c11 (inversion-decode-version "2.4.2.1"))
- (c12 (inversion-decode-version "2.4.2.2"))
- )
- (if (not (and
- (inversion-= c1 c1)
- (inversion-< c1i c1)
- (inversion-< c2 c3)
- (inversion-< c3 c4)
- (inversion-< c4 c5)
- (inversion-< c5 c6)
- (inversion-< c2 c4)
- (inversion-< c2 c5)
- (inversion-< c2 c6)
- (inversion-< c3 c5)
- (inversion-< c3 c6)
- (inversion-< c7 c6)
- (inversion-< c4 c7)
- (inversion-< c2 c7)
- (inversion-< c8 c6)
- (inversion-< c8 c7)
- (inversion-< c4 c8)
- (inversion-< c2 c8)
- (inversion-< c9 c10)
- (inversion-< c10 c11)
- (inversion-< c11 c12)
- ;; Negatives
- (not (inversion-< c3 c2))
- (not (inversion-< c4 c3))
- (not (inversion-< c5 c4))
- (not (inversion-< c6 c5))
- (not (inversion-< c7 c2))
- (not (inversion-< c7 c8))
- (not (inversion-< c12 c11))
- ;; Test the tester on inversion
- (not (inversion-test 'inversion inversion-version))
- ;; Test that we throw an error
- (inversion-test 'inversion "0.0.0")
- (inversion-test 'inversion "1000.0")
- ))
- (error "Inversion tests failed")
- (message "Inversion tests passed."))))
- ;;; cedet-files unit test
- (defvar cedet-files-utest-list
- '(
- ( "/home/me/src/myproj/src/foo.c" . "!home!me!src!myproj!src!foo.c" )
- ( "c:/work/myproj/foo.el" . "!drive_c!work!myproj!foo.el" )
- ( "//windows/proj/foo.java" . "!!windows!proj!foo.java" )
- ( "/home/me/proj!bang/foo.c" . "!home!me!proj!!bang!foo.c" )
- )
- "List of different file names to test.
- Each entry is a cons cell of ( FNAME . CONVERTED )
- where FNAME is some file name, and CONVERTED is what it should be
- converted into.")
- (defun cedet-files-utest ()
- "Test out some file name conversions."
- (interactive)
- (let ((idx 0))
- (dolist (FT cedet-files-utest-list)
- (setq idx (+ idx 1))
- (let ((dir->file (cedet-directory-name-to-file-name (car FT) t))
- (file->dir (cedet-file-name-to-directory-name (cdr FT) t))
- )
- (unless (string= (cdr FT) dir->file)
- (error "Failed: %d. Found: %S Wanted: %S"
- idx dir->file (cdr FT))
- )
- (unless (string= file->dir (car FT))
- (error "Failed: %d. Found: %S Wanted: %S"
- idx file->dir (car FT)))))))
- ;;; pulse test
- (defun pulse-test (&optional no-error)
- "Test the lightening function for pulsing a line.
- When optional NO-ERROR don't throw an error if we can't run tests."
- (interactive)
- (if (or (not pulse-flag) (not (pulse-available-p)))
- (if no-error
- nil
- (error (concat "Pulse test only works on versions of Emacs"
- " that support pulsing")))
- ;; Run the tests
- (when (interactive-p)
- (message "<Press a key> Pulse one line.")
- (read-char))
- (pulse-momentary-highlight-one-line (point))
- (when (interactive-p)
- (message "<Press a key> Pulse a region.")
- (read-char))
- (pulse-momentary-highlight-region (point)
- (save-excursion
- (condition-case nil
- (forward-char 30)
- (error nil))
- (point)))
- (when (interactive-p)
- (message "<Press a key> Pulse line a specific color.")
- (read-char))
- (pulse-momentary-highlight-one-line (point) 'modeline)
- (when (interactive-p)
- (message "<Press a key> Pulse a pre-existing overlay.")
- (read-char))
- (let* ((start (point-at-bol))
- (end (save-excursion
- (end-of-line)
- (when (not (eobp))
- (forward-char 1))
- (point)))
- (o (make-overlay start end))
- )
- (pulse-momentary-highlight-overlay o)
- (if (overlay-buffer o)
- (delete-overlay o)
- (error "Non-temporary overlay was deleted!"))
- )
- (when (interactive-p)
- (message "Done!"))))
- (provide 'cedet-utests)
- ;;; cedet-utests.el ends here
|