summaryrefslogtreecommitdiff
path: root/test/manual/cedet/semantic-ia-utest.el
diff options
context:
space:
mode:
Diffstat (limited to 'test/manual/cedet/semantic-ia-utest.el')
-rw-r--r--test/manual/cedet/semantic-ia-utest.el528
1 files changed, 528 insertions, 0 deletions
diff --git a/test/manual/cedet/semantic-ia-utest.el b/test/manual/cedet/semantic-ia-utest.el
new file mode 100644
index 00000000000..71736c816f7
--- /dev/null
+++ b/test/manual/cedet/semantic-ia-utest.el
@@ -0,0 +1,528 @@
+;;; semantic-ia-utest.el --- Analyzer unit tests
+
+;; Copyright (C) 2008-2015 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:
+;;
+;; Use marked-up files in the test directory and run the analyzer
+;; on them. Make sure the answers are correct.
+;;
+;; Each file has cursor keys in them of the form:
+;; // -#- ("ans1" "ans2" )
+;; where # is 1, 2, 3, etc, and some sort of answer list.
+
+;;; Code:
+(require 'semantic)
+(require 'semantic/analyze)
+(require 'semantic/analyze/refs)
+(require 'semantic/symref)
+(require 'semantic/symref/filter)
+
+(load-file "cedet-utests.el")
+
+(defvar semantic-ia-utest-file-list
+ '(
+ "tests/testdoublens.cpp"
+ "tests/testsubclass.cpp"
+ "tests/testtypedefs.cpp"
+ "tests/testfriends.cpp"
+ "tests/testnsp.cpp"
+ "tests/testsppcomplete.c"
+ "tests/testvarnames.c"
+ "tests/testjavacomp.java"
+ )
+ "List of files with analyzer completion test points.")
+
+(defvar semantic-ia-utest-error-log-list nil
+ "List of errors occurring during a run.")
+
+;;;###autoload
+(defun semantic-ia-utest (&optional arg)
+ "Run the semantic ia unit test against stored sources.
+Argument ARG specifies which set of tests to run.
+ 1 - ia utests
+ 2 - regs utests
+ 3 - symrefs utests
+ 4 - symref count utests"
+ (interactive "P")
+ (save-excursion
+
+ (let ((fl semantic-ia-utest-file-list)
+ (semantic-ia-utest-error-log-list nil)
+ )
+
+ (cedet-utest-log-setup "ANALYZER")
+
+ (set-buffer (semantic-find-file-noselect
+ (or (locate-library "semantic-ia-utest.el")
+ "semantic-ia-utest.el")))
+
+ (while fl
+
+ ;; Make sure we have the files we think we have.
+ (when (not (file-exists-p (car fl)))
+ (error "Cannot find unit test file: %s" (car fl)))
+
+ ;; Run the tests.
+ (let ((fb (find-buffer-visiting (car fl)))
+ (b (semantic-find-file-noselect (car fl) t)))
+
+ ;; Run the test on it.
+ (save-excursion
+ (set-buffer b)
+
+ ;; This line will also force the include, scope, and typecache.
+ (semantic-clear-toplevel-cache)
+ ;; Force tags to be parsed.
+ (semantic-fetch-tags)
+
+ (semantic-ia-utest-log " ** Starting tests in %s"
+ (buffer-name))
+
+ (when (or (not arg) (= arg 1))
+ (semantic-ia-utest-buffer))
+
+ (when (or (not arg) (= arg 2))
+ (set-buffer b)
+ (semantic-ia-utest-buffer-refs))
+
+ (when (or (not arg) (= arg 3))
+ (set-buffer b)
+ (semantic-sr-utest-buffer-refs))
+
+ (when (or (not arg) (= arg 4))
+ (set-buffer b)
+ (semantic-src-utest-buffer-refs))
+
+ (semantic-ia-utest-log " ** Completed tests in %s\n"
+ (buffer-name))
+ )
+
+ ;; If it wasn't already in memory, whack it.
+ (when (not fb)
+ (kill-buffer b))
+ )
+ (setq fl (cdr fl)))
+
+ (cedet-utest-log-shutdown
+ "ANALYZER"
+ (when semantic-ia-utest-error-log-list
+ (format "%s Failures found."
+ (length semantic-ia-utest-error-log-list))))
+ (when semantic-ia-utest-error-log-list
+ (error "Failures found during analyzer unit tests"))
+ ))
+ )
+
+(defun semantic-ia-utest-buffer ()
+ "Run analyzer completion unit-test pass in the current buffer."
+
+ (let* ((idx 1)
+ (regex-p nil)
+ (regex-a nil)
+ (p nil)
+ (a nil)
+ (pass nil)
+ (fail nil)
+ (actual nil)
+ (desired nil)
+ ;; Exclude unpredictable system files in the
+ ;; header include list.
+ (semanticdb-find-default-throttle
+ (remq 'system semanticdb-find-default-throttle))
+ )
+ ;; Keep looking for test points until we run out.
+ (while (save-excursion
+ (setq regex-p (concat "//\\s-*-" (number-to-string idx) "-" )
+ regex-a (concat "//\\s-*#" (number-to-string idx) "#" ))
+ (goto-char (point-min))
+ (save-match-data
+ (when (re-search-forward regex-p nil t)
+ (setq p (match-beginning 0))))
+ (save-match-data
+ (when (re-search-forward regex-a nil t)
+ (setq a (match-end 0))))
+ (and p a))
+
+ (save-excursion
+
+ (goto-char p)
+
+ (let* ((ctxt (semantic-analyze-current-context))
+ (acomp
+ (condition-case nil
+ (semantic-analyze-possible-completions ctxt)
+ (error nil))))
+ (setq actual (mapcar 'semantic-tag-name acomp)))
+
+ (goto-char a)
+
+ (let ((bss (buffer-substring-no-properties (point) (point-at-eol))))
+ (condition-case nil
+ (setq desired (read bss))
+ (error (setq desired (format " FAILED TO PARSE: %S"
+ bss)))))
+
+ (if (equal actual desired)
+ (setq pass (cons idx pass))
+ (setq fail (cons idx fail))
+ (semantic-ia-utest-log
+ " Failed %d. Desired: %S Actual %S"
+ idx desired actual)
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx desired actual)
+ )
+
+ )
+ )
+
+ (setq p nil a nil)
+ (setq idx (1+ idx)))
+
+ (if fail
+ (progn
+ (semantic-ia-utest-log
+ " Unit tests (completions) failed tests %S"
+ (reverse fail))
+ )
+ (semantic-ia-utest-log " Unit tests (completions) passed (%d total)"
+ (- idx 1)))
+
+ ))
+
+(defun semantic-ia-utest-buffer-refs ()
+ "Run an analyze-refs unit-test pass in the current buffer."
+
+ (let* ((idx 1)
+ (regex-p nil)
+ (p nil)
+ (pass nil)
+ (fail nil)
+ ;; Exclude unpredictable system files in the
+ ;; header include list.
+ (semanticdb-find-default-throttle
+ (remq 'system semanticdb-find-default-throttle))
+ )
+ ;; Keep looking for test points until we run out.
+ (while (save-excursion
+ (setq regex-p (concat "//\\s-*\\^" (number-to-string idx) "^" )
+ )
+ (goto-char (point-min))
+ (save-match-data
+ (when (re-search-forward regex-p nil t)
+ (setq p (match-beginning 0))))
+ p)
+
+ (save-excursion
+
+ (goto-char p)
+ (forward-char -1)
+
+ (let* ((ct (semantic-current-tag))
+ (refs (semantic-analyze-tag-references ct))
+ (impl (semantic-analyze-refs-impl refs t))
+ (proto (semantic-analyze-refs-proto refs t))
+ (pf nil)
+ )
+ (setq
+ pf
+ (catch 'failed
+ (if (and impl proto (car impl) (car proto))
+ (let (ct2 ref2 impl2 proto2
+ newstart)
+ (cond
+ ((semantic-equivalent-tag-p (car impl) ct)
+ ;; We are on an IMPL. Go To the proto, and find matches.
+ (semantic-go-to-tag (car proto))
+ (setq newstart (car proto))
+ )
+ ((semantic-equivalent-tag-p (car proto) ct)
+ ;; We are on a PROTO. Go to the imple, and find matches
+ (semantic-go-to-tag (car impl))
+ (setq newstart (car impl))
+ )
+ (t
+ ;; No matches is a fail.
+ (throw 'failed t)
+ ))
+ ;; Get the new tag, does it match?
+ (setq ct2 (semantic-current-tag))
+
+ ;; Does it match?
+ (when (not (semantic-equivalent-tag-p ct2 newstart))
+ (throw 'failed t))
+
+ ;; Can we double-jump?
+ (setq ref2 (semantic-analyze-tag-references ct)
+ impl2 (semantic-analyze-refs-impl ref2 t)
+ proto2 (semantic-analyze-refs-proto ref2 t))
+
+ (when (or (not (and impl2 proto2))
+ (not
+ (and (semantic-equivalent-tag-p
+ (car impl) (car impl2))
+ (semantic-equivalent-tag-p
+ (car proto) (car proto2)))))
+ (throw 'failed t))
+ )
+
+ ;; Else, no matches at all, so another fail.
+ (throw 'failed t)
+ )))
+
+ (if (not pf)
+ ;; We passed
+ (setq pass (cons idx pass))
+ ;; We failed.
+ (setq fail (cons idx fail))
+ (semantic-ia-utest-log
+ " Failed %d. For %s (Num impls %d) (Num protos %d)"
+ idx (if ct (semantic-tag-name ct) "<No tag found>")
+ (length impl) (length proto))
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx)
+ )
+ ))
+
+ (setq p nil)
+ (setq idx (1+ idx))
+
+ ))
+
+ (if fail
+ (progn
+ (semantic-ia-utest-log
+ " Unit tests (refs) failed tests")
+ )
+ (semantic-ia-utest-log " Unit tests (refs) passed (%d total)"
+ (- idx 1)))
+
+ ))
+
+(defun semantic-sr-utest-buffer-refs ()
+ "Run a symref unit-test pass in the current buffer."
+
+ ;; This line will also force the include, scope, and typecache.
+ (semantic-clear-toplevel-cache)
+ ;; Force tags to be parsed.
+ (semantic-fetch-tags)
+
+ (let* ((idx 1)
+ (tag nil)
+ (regex-p nil)
+ (desired nil)
+ (actual-result nil)
+ (actual nil)
+ (pass nil)
+ (fail nil)
+ (symref-tool-used nil)
+ ;; Exclude unpredictable system files in the
+ ;; header include list.
+ (semanticdb-find-default-throttle
+ (remq 'system semanticdb-find-default-throttle))
+ )
+ ;; Keep looking for test points until we run out.
+ (while (save-excursion
+ (setq regex-p (concat "//\\s-*\\%" (number-to-string idx) "%" )
+ )
+ (goto-char (point-min))
+ (save-match-data
+ (when (re-search-forward regex-p nil t)
+ (setq tag (semantic-current-tag))
+ (goto-char (match-end 0))
+ (setq desired (read (buffer-substring (point) (point-at-eol))))
+ ))
+ tag)
+
+ (setq actual-result (semantic-symref-find-references-by-name
+ (semantic-tag-name tag) 'target
+ 'symref-tool-used))
+
+ (if (not actual-result)
+ (progn
+ (setq fail (cons idx fail))
+ (semantic-ia-utest-log
+ " Failed FNames %d: No results." idx)
+ (semantic-ia-utest-log
+ " Failed Tool: %s" (object-name symref-tool-used))
+
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx)
+ )
+ )
+
+ (setq actual (list (sort (mapcar
+ 'file-name-nondirectory
+ (semantic-symref-result-get-files actual-result))
+ 'string<)
+ (sort
+ (mapcar
+ 'semantic-format-tag-canonical-name
+ (semantic-symref-result-get-tags actual-result))
+ 'string<)))
+
+
+ (if (equal desired actual)
+ ;; We passed
+ (setq pass (cons idx pass))
+ ;; We failed.
+ (setq fail (cons idx fail))
+ (when (not (equal (car actual) (car desired)))
+ (semantic-ia-utest-log
+ " Failed FNames %d: Actual: %S Desired: %S"
+ idx (car actual) (car desired))
+ (semantic-ia-utest-log
+ " Failed Tool: %s" (object-name symref-tool-used))
+ )
+ (when (not (equal (car (cdr actual)) (car (cdr desired))))
+ (semantic-ia-utest-log
+ " Failed TNames %d: Actual: %S Desired: %S"
+ idx (car (cdr actual)) (car (cdr desired)))
+ (semantic-ia-utest-log
+ " Failed Tool: %s" (object-name symref-tool-used))
+ )
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx)
+ )
+ ))
+
+ (setq idx (1+ idx))
+ (setq tag nil))
+
+ (if fail
+ (progn
+ (semantic-ia-utest-log
+ " Unit tests (symrefs) failed tests")
+ )
+ (semantic-ia-utest-log " Unit tests (symrefs) passed (%d total)"
+ (- idx 1)))
+
+ ))
+
+(defun semantic-symref-test-count-hits-in-tag ()
+ "Lookup in the current tag the symbol under point.
+Then count all the other references to the same symbol within the
+tag that contains point, and return that."
+ (interactive)
+ (let* ((ctxt (semantic-analyze-current-context))
+ (target (car (reverse (oref ctxt prefix))))
+ (tag (semantic-current-tag))
+ (start (current-time))
+ (Lcount 0))
+ (when (semantic-tag-p target)
+ (semantic-symref-hits-in-region
+ target (lambda (start end prefix) (setq Lcount (1+ Lcount)))
+ (semantic-tag-start tag)
+ (semantic-tag-end tag))
+ (when (interactive-p)
+ (message "Found %d occurrences of %s in %.2f seconds"
+ Lcount (semantic-tag-name target)
+ (semantic-elapsed-time start (current-time))))
+ Lcount)))
+
+(defun semantic-src-utest-buffer-refs ()
+ "Run a sym-ref counting unit-test pass in the current buffer."
+
+ ;; This line will also force the include, scope, and typecache.
+ (semantic-clear-toplevel-cache)
+ ;; Force tags to be parsed.
+ (semantic-fetch-tags)
+
+ (let* ((idx 1)
+ (start nil)
+ (regex-p nil)
+ (desired nil)
+ (actual nil)
+ (pass nil)
+ (fail nil)
+ ;; Exclude unpredictable system files in the
+ ;; header include list.
+ (semanticdb-find-default-throttle
+ (remq 'system semanticdb-find-default-throttle))
+ )
+ ;; Keep looking for test points until we run out.
+ (while (save-excursion
+ (setq regex-p (concat "//\\s-*@"
+ (number-to-string idx)
+ "@\\s-+\\(\\w+\\)" ))
+ (goto-char (point-min))
+ (save-match-data
+ (when (re-search-forward regex-p nil t)
+ (goto-char (match-beginning 1))
+ (setq desired (read (buffer-substring (point) (point-at-eol))))
+ (setq start (match-beginning 0))
+ (goto-char start)
+ (setq actual (semantic-symref-test-count-hits-in-tag))
+ start)))
+
+ (if (not actual)
+ (progn
+ (setq fail (cons idx fail))
+ (semantic-ia-utest-log
+ " Failed symref count %d: No results." idx)
+
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx)
+ )
+ )
+
+ (if (equal desired actual)
+ ;; We passed
+ (setq pass (cons idx pass))
+ ;; We failed.
+ (setq fail (cons idx fail))
+ (when (not (equal actual desired))
+ (semantic-ia-utest-log
+ " Failed symref count %d: Actual: %S Desired: %S"
+ idx actual desired)
+ )
+
+ (add-to-list 'semantic-ia-utest-error-log-list
+ (list (buffer-name) idx)
+ )
+ ))
+
+ (setq idx (1+ idx))
+ )
+
+ (if fail
+ (progn
+ (semantic-ia-utest-log
+ " Unit tests (symrefs counter) failed tests")
+ )
+ (semantic-ia-utest-log " Unit tests (symrefs counter) passed (%d total)"
+ (- idx 1)))
+
+ ))
+
+(defun semantic-ia-utest-start-log ()
+ "Start up a testlog for a run."
+ ;; Redo w/ CEDET utest framework.
+ (cedet-utest-log-start "semantic: analyzer tests"))
+
+(defun semantic-ia-utest-log (&rest args)
+ "Log some test results.
+Pass ARGS to format to create the log message."
+ ;; Forward to CEDET utest framework.
+ (apply 'cedet-utest-log args))
+
+(provide 'semantic-ia-utest)
+
+;;; semantic-ia-utest.el ends here