elisp-mode-tests.el 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. ;;; elisp-mode-tests.el --- Tests for emacs-lisp-mode -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
  3. ;; Author: Dmitry Gutov <dgutov@yandex.ru>
  4. ;; Author: Stephen Leake <stephen_leake@member.fsf.org>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Code:
  17. (require 'ert)
  18. (require 'xref)
  19. ;;; Completion
  20. (defun elisp--test-completions ()
  21. (let ((data (elisp-completion-at-point)))
  22. (all-completions (buffer-substring (nth 0 data) (nth 1 data))
  23. (nth 2 data)
  24. (plist-get (nthcdr 3 data) :predicate))))
  25. (ert-deftest elisp-completes-functions ()
  26. (with-temp-buffer
  27. (emacs-lisp-mode)
  28. (insert "(ba")
  29. (let ((comps (elisp--test-completions)))
  30. (should (member "backup-buffer" comps))
  31. (should-not (member "backup-inhibited" comps)))))
  32. (ert-deftest elisp-completes-variables ()
  33. (with-temp-buffer
  34. (emacs-lisp-mode)
  35. (insert "(foo ba")
  36. (let ((comps (elisp--test-completions)))
  37. (should (member "backup-inhibited" comps))
  38. (should-not (member "backup-buffer" comps)))))
  39. (ert-deftest elisp-completes-anything-quoted ()
  40. (dolist (text '("`(foo ba" "(foo 'ba"
  41. "`(,foo ba" "`,(foo `ba"
  42. "'(foo (ba"))
  43. (with-temp-buffer
  44. (emacs-lisp-mode)
  45. (insert text)
  46. (let ((comps (elisp--test-completions)))
  47. (should (member "backup-inhibited" comps))
  48. (should (member "backup-buffer" comps))
  49. (should (member "backup" comps))))))
  50. (ert-deftest elisp-completes-variables-unquoted ()
  51. (dolist (text '("`(foo ,ba" "`(,(foo ba" "`(,ba"))
  52. (with-temp-buffer
  53. (emacs-lisp-mode)
  54. (insert text)
  55. (let ((comps (elisp--test-completions)))
  56. (should (member "backup-inhibited" comps))
  57. (should-not (member "backup-buffer" comps))))))
  58. (ert-deftest elisp-completes-functions-in-special-macros ()
  59. (dolist (text '("(declare-function ba" "(cl-callf2 ba"))
  60. (with-temp-buffer
  61. (emacs-lisp-mode)
  62. (insert text)
  63. (let ((comps (elisp--test-completions)))
  64. (should (member "backup-buffer" comps))
  65. (should-not (member "backup-inhibited" comps))))))
  66. (ert-deftest elisp-completes-functions-after-hash-quote ()
  67. (ert-deftest elisp-completes-functions-after-let-bindings ()
  68. (with-temp-buffer
  69. (emacs-lisp-mode)
  70. (insert "#'ba")
  71. (let ((comps (elisp--test-completions)))
  72. (should (member "backup-buffer" comps))
  73. (should-not (member "backup-inhibited" comps))))))
  74. (ert-deftest elisp-completes-local-variables ()
  75. (with-temp-buffer
  76. (emacs-lisp-mode)
  77. (insert "(let ((bar 1) baz) (foo ba")
  78. (let ((comps (elisp--test-completions)))
  79. (should (member "backup-inhibited" comps))
  80. (should (member "bar" comps))
  81. (should (member "baz" comps)))))
  82. (ert-deftest elisp-completest-variables-in-let-bindings ()
  83. (dolist (text '("(let (ba" "(let* ((ba"))
  84. (with-temp-buffer
  85. (emacs-lisp-mode)
  86. (insert text)
  87. (let ((comps (elisp--test-completions)))
  88. (should (member "backup-inhibited" comps))
  89. (should-not (member "backup-buffer" comps))))))
  90. (ert-deftest elisp-completes-functions-after-let-bindings ()
  91. (with-temp-buffer
  92. (emacs-lisp-mode)
  93. (insert "(let ((bar 1) (baz 2)) (ba")
  94. (let ((comps (elisp--test-completions)))
  95. (should (member "backup-buffer" comps))
  96. (should-not (member "backup-inhibited" comps)))))
  97. ;;; xref
  98. (defun xref-elisp-test-descr-to-target (xref)
  99. "Return an appropriate `looking-at' match string for XREF."
  100. (let* ((loc (xref-item-location xref))
  101. (type (or (xref-elisp-location-type loc)
  102. 'defun)))
  103. (cl-case type
  104. (defalias
  105. ;; summary: "(defalias xref)"
  106. ;; target : "(defalias 'xref"
  107. (concat "(defalias '" (substring (xref-item-summary xref) 10 -1)))
  108. (defun
  109. (let ((summary (xref-item-summary xref))
  110. (file (xref-elisp-location-file loc)))
  111. (cond
  112. ((string= "c" (file-name-extension file))
  113. ;; summary: "(defun buffer-live-p)"
  114. ;; target : "DEFUN (buffer-live-p"
  115. (concat
  116. (upcase (substring summary 1 6))
  117. " (\""
  118. (substring summary 7 -1)
  119. "\""))
  120. (t
  121. (substring summary 0 -1))
  122. )))
  123. (defvar
  124. (let ((summary (xref-item-summary xref))
  125. (file (xref-elisp-location-file loc)))
  126. (cond
  127. ((string= "c" (file-name-extension file))
  128. ;; summary: "(defvar system-name)"
  129. ;; target : "DEFVAR_LISP ("system-name", "
  130. ;; summary: "(defvar abbrev-mode)"
  131. ;; target : DEFVAR_PER_BUFFER ("abbrev-mode"
  132. (concat
  133. (upcase (substring summary 1 7))
  134. (if (bufferp (variable-binding-locus (xref-elisp-location-symbol loc)))
  135. "_PER_BUFFER (\""
  136. "_LISP (\"")
  137. (substring summary 8 -1)
  138. "\""))
  139. (t
  140. (substring summary 0 -1))
  141. )))
  142. (feature
  143. ;; summary: "(feature xref)"
  144. ;; target : "(provide 'xref)"
  145. (concat "(provide '" (substring (xref-item-summary xref) 9 -1)))
  146. (otherwise
  147. (substring (xref-item-summary xref) 0 -1))
  148. )))
  149. (defun xref-elisp-test-run (xrefs expected-xrefs)
  150. (should (= (length xrefs) (length expected-xrefs)))
  151. (while xrefs
  152. (let* ((xref (pop xrefs))
  153. (expected (pop expected-xrefs))
  154. (expected-xref (or (when (consp expected) (car expected)) expected))
  155. (expected-source (when (consp expected) (cdr expected))))
  156. ;; Downcase the filenames for case-insensitive file systems.
  157. (setf (xref-elisp-location-file (oref xref location))
  158. (downcase (xref-elisp-location-file (oref xref location))))
  159. (setf (xref-elisp-location-file (oref expected-xref location))
  160. (downcase (xref-elisp-location-file (oref expected-xref location))))
  161. (should (equal xref expected-xref))
  162. (xref--goto-location (xref-item-location xref))
  163. (back-to-indentation)
  164. (should (looking-at (or expected-source
  165. (xref-elisp-test-descr-to-target expected)))))
  166. ))
  167. (defmacro xref-elisp-deftest (name computed-xrefs expected-xrefs)
  168. "Define an ert test for an xref-elisp feature.
  169. COMPUTED-XREFS and EXPECTED-XREFS are lists of xrefs, except if
  170. an element of EXPECTED-XREFS is a cons (XREF . TARGET), TARGET is
  171. matched to the found location; otherwise, match
  172. to (xref-elisp-test-descr-to-target xref)."
  173. (declare (indent defun)
  174. (debug (symbolp "name")))
  175. `(ert-deftest ,(intern (concat "xref-elisp-test-" (symbol-name name))) ()
  176. (let ((find-file-suppress-same-file-warnings t))
  177. (xref-elisp-test-run ,computed-xrefs ,expected-xrefs)
  178. )))
  179. ;; When tests are run from the Makefile, 'default-directory' is $HOME,
  180. ;; so we must provide this dir to expand-file-name in the expected
  181. ;; results. This also allows running these tests from other
  182. ;; directories.
  183. ;;
  184. ;; We add 'downcase' here to deliberately cause a potential problem on
  185. ;; case-insensitive file systems. On such systems, `load-file-name'
  186. ;; may not have the same case as the real file system, since the user
  187. ;; can set `load-path' to have the wrong case (on my Windows system,
  188. ;; `load-path' has the correct case, so this causes the expected test
  189. ;; values to have the wrong case). This is handled in
  190. ;; `xref-elisp-test-run'.
  191. (defconst emacs-test-dir (downcase (file-name-directory (or load-file-name (buffer-file-name)))))
  192. ;; alphabetical by test name
  193. ;; Autoloads require no special support; they are handled as functions.
  194. ;; FIXME: defalias-defun-c cmpl-prefix-entry-head
  195. ;; FIXME: defalias-defvar-el allout-mode-map
  196. (xref-elisp-deftest find-defs-constructor
  197. (elisp--xref-find-definitions 'xref-make-elisp-location)
  198. ;; 'xref-make-elisp-location' is just a name for the default
  199. ;; constructor created by the cl-defstruct, so the location is the
  200. ;; cl-defstruct location.
  201. (list
  202. (cons
  203. (xref-make "(cl-defstruct (xref-elisp-location (:constructor xref-make-elisp-location)))"
  204. (xref-make-elisp-location
  205. 'xref-elisp-location 'define-type
  206. (expand-file-name "../../../lisp/progmodes/elisp-mode.el" emacs-test-dir)))
  207. ;; It's not worth adding another special case to `xref-elisp-test-descr-to-target' for this
  208. "(cl-defstruct (xref-elisp-location")
  209. ))
  210. (xref-elisp-deftest find-defs-defalias-defun-el
  211. (elisp--xref-find-definitions 'Buffer-menu-sort)
  212. (list
  213. (xref-make "(defalias Buffer-menu-sort)"
  214. (xref-make-elisp-location
  215. 'Buffer-menu-sort 'defalias
  216. (expand-file-name "../../../lisp/buff-menu.elc" emacs-test-dir)))
  217. (xref-make "(defun tabulated-list-sort)"
  218. (xref-make-elisp-location
  219. 'tabulated-list-sort nil
  220. (expand-file-name "../../../lisp/emacs-lisp/tabulated-list.el" emacs-test-dir)))
  221. ))
  222. ;; FIXME: defconst
  223. ;; FIXME: eieio defclass
  224. ;; Possible ways of defining the default method implementation for a
  225. ;; generic function. We declare these here, so we know we cover all
  226. ;; cases, and we don't rely on other code not changing.
  227. ;;
  228. ;; When the generic and default method are declared in the same place,
  229. ;; elisp--xref-find-definitions only returns one.
  230. (cl-defstruct (xref-elisp-root-type)
  231. slot-1)
  232. (cl-defgeneric xref-elisp-generic-no-methods (arg1 arg2)
  233. "doc string generic no-methods"
  234. ;; No default implementation, no methods, but fboundp is true for
  235. ;; this symbol; it calls cl-no-applicable-method
  236. )
  237. ;; WORKAROUND: ‘this’ is unused, and the byte compiler complains, so
  238. ;; it should be spelled ‘_this’. But for some unknown reason, that
  239. ;; causes the batch mode test to fail; the symbol shows up as
  240. ;; ‘this’. It passes in interactive tests, so I haven't been able to
  241. ;; track down the problem.
  242. (cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2)
  243. "doc string generic no-default xref-elisp-root-type"
  244. "non-default for no-default")
  245. ;; defgeneric after defmethod in file to ensure the fallback search
  246. ;; method of just looking for the function name will fail.
  247. (cl-defgeneric xref-elisp-generic-no-default (arg1 arg2)
  248. "doc string generic no-default generic"
  249. ;; No default implementation; this function calls the cl-generic
  250. ;; dispatching code.
  251. )
  252. (cl-defgeneric xref-elisp-generic-co-located-default (arg1 arg2)
  253. "doc string generic co-located-default"
  254. "co-located default")
  255. (cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2)
  256. "doc string generic co-located-default xref-elisp-root-type"
  257. "non-default for co-located-default")
  258. (cl-defgeneric xref-elisp-generic-separate-default (arg1 arg2)
  259. "doc string generic separate-default"
  260. ;; default implementation provided separately
  261. )
  262. (cl-defmethod xref-elisp-generic-separate-default (arg1 arg2)
  263. "doc string generic separate-default default"
  264. "separate default")
  265. (cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2)
  266. "doc string generic separate-default xref-elisp-root-type"
  267. "non-default for separate-default")
  268. (cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2)
  269. "doc string generic implicit-generic default"
  270. "default for implicit generic")
  271. (cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2)
  272. "doc string generic implicit-generic xref-elisp-root-type"
  273. "non-default for implicit generic")
  274. (xref-elisp-deftest find-defs-defgeneric-no-methods
  275. (elisp--xref-find-definitions 'xref-elisp-generic-no-methods)
  276. (list
  277. (xref-make "(cl-defgeneric xref-elisp-generic-no-methods)"
  278. (xref-make-elisp-location
  279. 'xref-elisp-generic-no-methods 'cl-defgeneric
  280. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  281. ))
  282. (xref-elisp-deftest find-defs-defgeneric-no-default
  283. (elisp--xref-find-definitions 'xref-elisp-generic-no-default)
  284. (list
  285. (xref-make "(cl-defgeneric xref-elisp-generic-no-default)"
  286. (xref-make-elisp-location
  287. 'xref-elisp-generic-no-default 'cl-defgeneric
  288. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  289. (xref-make "(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2))"
  290. (xref-make-elisp-location
  291. (cl--generic-load-hist-format
  292. 'xref-elisp-generic-no-default nil '(xref-elisp-root-type t))
  293. 'cl-defmethod
  294. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  295. ))
  296. (xref-elisp-deftest find-defs-defgeneric-co-located-default
  297. (elisp--xref-find-definitions 'xref-elisp-generic-co-located-default)
  298. (list
  299. (xref-make "(cl-defgeneric xref-elisp-generic-co-located-default)"
  300. (xref-make-elisp-location
  301. 'xref-elisp-generic-co-located-default 'cl-defgeneric
  302. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  303. (xref-make "(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2))"
  304. (xref-make-elisp-location
  305. (cl--generic-load-hist-format
  306. 'xref-elisp-generic-co-located-default nil
  307. '(xref-elisp-root-type t))
  308. 'cl-defmethod
  309. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  310. ))
  311. (xref-elisp-deftest find-defs-defgeneric-separate-default
  312. (elisp--xref-find-definitions 'xref-elisp-generic-separate-default)
  313. (list
  314. (xref-make "(cl-defgeneric xref-elisp-generic-separate-default)"
  315. (xref-make-elisp-location
  316. 'xref-elisp-generic-separate-default 'cl-defgeneric
  317. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  318. (xref-make "(cl-defmethod xref-elisp-generic-separate-default (arg1 arg2))"
  319. (xref-make-elisp-location
  320. (cl--generic-load-hist-format
  321. 'xref-elisp-generic-separate-default nil '(t t))
  322. 'cl-defmethod
  323. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  324. (xref-make "(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2))"
  325. (xref-make-elisp-location
  326. (cl--generic-load-hist-format
  327. 'xref-elisp-generic-separate-default nil
  328. '(xref-elisp-root-type t))
  329. 'cl-defmethod
  330. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  331. ))
  332. (xref-elisp-deftest find-defs-defgeneric-implicit-generic
  333. (elisp--xref-find-definitions 'xref-elisp-generic-implicit-generic)
  334. (list
  335. (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2))"
  336. (xref-make-elisp-location
  337. (cl--generic-load-hist-format
  338. 'xref-elisp-generic-implicit-generic nil '(t t))
  339. 'cl-defmethod
  340. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  341. (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2))"
  342. (xref-make-elisp-location
  343. (cl--generic-load-hist-format
  344. 'xref-elisp-generic-implicit-generic nil
  345. '(xref-elisp-root-type t))
  346. 'cl-defmethod
  347. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  348. ))
  349. ;; Test that we handle more than one method
  350. ;; When run from the Makefile, etags is not loaded at compile time,
  351. ;; but it is by the time this test is run. interactively; don't fail
  352. ;; for that.
  353. (require 'etags)
  354. (xref-elisp-deftest find-defs-defgeneric-el
  355. (elisp--xref-find-definitions 'xref-location-marker)
  356. (list
  357. (xref-make "(cl-defgeneric xref-location-marker)"
  358. (xref-make-elisp-location
  359. 'xref-location-marker 'cl-defgeneric
  360. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  361. (xref-make "(cl-defmethod xref-location-marker ((l xref-elisp-location)))"
  362. (xref-make-elisp-location
  363. (cl--generic-load-hist-format
  364. 'xref-location-marker nil '(xref-elisp-location))
  365. 'cl-defmethod
  366. (expand-file-name "../../../lisp/progmodes/elisp-mode.el" emacs-test-dir)))
  367. (xref-make "(cl-defmethod xref-location-marker ((l xref-file-location)))"
  368. (xref-make-elisp-location
  369. (cl--generic-load-hist-format
  370. 'xref-location-marker nil '(xref-file-location))
  371. 'cl-defmethod
  372. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  373. (xref-make "(cl-defmethod xref-location-marker ((l xref-buffer-location)))"
  374. (xref-make-elisp-location
  375. (cl--generic-load-hist-format
  376. 'xref-location-marker nil '(xref-buffer-location))
  377. 'cl-defmethod
  378. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  379. (xref-make "(cl-defmethod xref-location-marker ((l xref-bogus-location)))"
  380. (xref-make-elisp-location
  381. (cl--generic-load-hist-format
  382. 'xref-location-marker nil '(xref-bogus-location))
  383. 'cl-defmethod
  384. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  385. (xref-make "(cl-defmethod xref-location-marker ((l xref-etags-location)))"
  386. (xref-make-elisp-location
  387. (cl--generic-load-hist-format
  388. 'xref-location-marker nil '(xref-etags-location))
  389. 'cl-defmethod
  390. (expand-file-name "../../../lisp/progmodes/etags.el" emacs-test-dir)))
  391. ))
  392. (xref-elisp-deftest find-defs-defgeneric-eval
  393. (elisp--xref-find-definitions (eval '(cl-defgeneric stephe-leake-cl-defgeneric ())))
  394. nil)
  395. ;; Define some mode-local overloadable/overridden functions for xref to find
  396. (require 'mode-local)
  397. (define-overloadable-function xref-elisp-overloadable-no-methods ()
  398. "doc string overloadable no-methods")
  399. (define-overloadable-function xref-elisp-overloadable-no-default ()
  400. "doc string overloadable no-default")
  401. ;; FIXME: byte compiler complains about unused lexical arguments
  402. ;; generated by this macro.
  403. (define-mode-local-override xref-elisp-overloadable-no-default c-mode
  404. (start end &optional nonterminal depth returnonerror)
  405. "doc string overloadable no-default c-mode."
  406. "result overloadable no-default c-mode.")
  407. (define-overloadable-function xref-elisp-overloadable-co-located-default ()
  408. "doc string overloadable co-located-default"
  409. "result overloadable co-located-default.")
  410. (define-mode-local-override xref-elisp-overloadable-co-located-default c-mode
  411. (start end &optional nonterminal depth returnonerror)
  412. "doc string overloadable co-located-default c-mode."
  413. "result overloadable co-located-default c-mode.")
  414. (define-overloadable-function xref-elisp-overloadable-separate-default ()
  415. "doc string overloadable separate-default.")
  416. (defun xref-elisp-overloadable-separate-default-default ()
  417. "doc string overloadable separate-default default"
  418. "result overloadable separate-default.")
  419. (define-mode-local-override xref-elisp-overloadable-separate-default c-mode
  420. (start end &optional nonterminal depth returnonerror)
  421. "doc string overloadable separate-default c-mode."
  422. "result overloadable separate-default c-mode.")
  423. (xref-elisp-deftest find-defs-define-overload-no-methods
  424. (elisp--xref-find-definitions 'xref-elisp-overloadable-no-methods)
  425. (list
  426. (xref-make "(define-overloadable-function xref-elisp-overloadable-no-methods)"
  427. (xref-make-elisp-location
  428. 'xref-elisp-overloadable-no-methods 'define-overloadable-function
  429. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  430. ))
  431. (xref-elisp-deftest find-defs-define-overload-no-default
  432. (elisp--xref-find-definitions 'xref-elisp-overloadable-no-default)
  433. (list
  434. (xref-make "(define-overloadable-function xref-elisp-overloadable-no-default)"
  435. (xref-make-elisp-location
  436. 'xref-elisp-overloadable-no-default 'define-overloadable-function
  437. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  438. (xref-make "(define-mode-local-override xref-elisp-overloadable-no-default c-mode)"
  439. (xref-make-elisp-location
  440. '(xref-elisp-overloadable-no-default-c-mode . c-mode) 'define-mode-local-override
  441. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  442. ))
  443. (xref-elisp-deftest find-defs-define-overload-co-located-default
  444. (elisp--xref-find-definitions 'xref-elisp-overloadable-co-located-default)
  445. (list
  446. (xref-make "(define-overloadable-function xref-elisp-overloadable-co-located-default)"
  447. (xref-make-elisp-location
  448. 'xref-elisp-overloadable-co-located-default 'define-overloadable-function
  449. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  450. (xref-make "(define-mode-local-override xref-elisp-overloadable-co-located-default c-mode)"
  451. (xref-make-elisp-location
  452. '(xref-elisp-overloadable-co-located-default-c-mode . c-mode) 'define-mode-local-override
  453. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  454. ))
  455. (xref-elisp-deftest find-defs-define-overload-separate-default
  456. (elisp--xref-find-definitions 'xref-elisp-overloadable-separate-default)
  457. (list
  458. (xref-make "(define-overloadable-function xref-elisp-overloadable-separate-default)"
  459. (xref-make-elisp-location
  460. 'xref-elisp-overloadable-separate-default 'define-overloadable-function
  461. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  462. (xref-make "(defun xref-elisp-overloadable-separate-default-default)"
  463. (xref-make-elisp-location
  464. 'xref-elisp-overloadable-separate-default-default nil
  465. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  466. (xref-make "(define-mode-local-override xref-elisp-overloadable-separate-default c-mode)"
  467. (xref-make-elisp-location
  468. '(xref-elisp-overloadable-separate-default-c-mode . c-mode) 'define-mode-local-override
  469. (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
  470. ))
  471. (xref-elisp-deftest find-defs-defun-el
  472. (elisp--xref-find-definitions 'xref-find-definitions)
  473. (list
  474. (xref-make "(defun xref-find-definitions)"
  475. (xref-make-elisp-location
  476. 'xref-find-definitions nil
  477. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))))
  478. (xref-elisp-deftest find-defs-defun-eval
  479. (elisp--xref-find-definitions (eval '(defun stephe-leake-defun ())))
  480. nil)
  481. (xref-elisp-deftest find-defs-defun-c
  482. (elisp--xref-find-definitions 'buffer-live-p)
  483. (list
  484. (xref-make "(defun buffer-live-p)"
  485. (xref-make-elisp-location 'buffer-live-p nil "src/buffer.c"))))
  486. ;; FIXME: deftype
  487. (xref-elisp-deftest find-defs-defun-c-defvar-c
  488. (xref-backend-definitions 'elisp "system-name")
  489. (list
  490. (xref-make "(defvar system-name)"
  491. (xref-make-elisp-location 'system-name 'defvar "src/editfns.c"))
  492. (xref-make "(defun system-name)"
  493. (xref-make-elisp-location 'system-name nil "src/editfns.c")))
  494. )
  495. (xref-elisp-deftest find-defs-defun-el-defvar-c
  496. (xref-backend-definitions 'elisp "abbrev-mode")
  497. ;; It's a minor mode, but the variable is defined in buffer.c
  498. (list
  499. (xref-make "(defvar abbrev-mode)"
  500. (xref-make-elisp-location 'abbrev-mode 'defvar "src/buffer.c"))
  501. (cons
  502. (xref-make "(defun abbrev-mode)"
  503. (xref-make-elisp-location
  504. 'abbrev-mode nil
  505. (expand-file-name "../../../lisp/abbrev.el" emacs-test-dir)))
  506. "(define-minor-mode abbrev-mode"))
  507. )
  508. ;; Source for both variable and defun is "(define-minor-mode
  509. ;; compilation-minor-mode". There is no way to tell that directly from
  510. ;; the symbol, but we can use (memq sym minor-mode-list) to detect
  511. ;; that the symbol is a minor mode. See `elisp--xref-find-definitions'
  512. ;; for more comments.
  513. ;;
  514. ;; IMPROVEME: return defvar instead of defun if source near starting
  515. ;; point indicates the user is searching for a variable, not a
  516. ;; function.
  517. (require 'compile) ;; not loaded by default at test time
  518. (xref-elisp-deftest find-defs-defun-defvar-el
  519. (elisp--xref-find-definitions 'compilation-minor-mode)
  520. (list
  521. (cons
  522. (xref-make "(defun compilation-minor-mode)"
  523. (xref-make-elisp-location
  524. 'compilation-minor-mode nil
  525. (expand-file-name "../../../lisp/progmodes/compile.el" emacs-test-dir)))
  526. "(define-minor-mode compilation-minor-mode")
  527. ))
  528. (xref-elisp-deftest find-defs-defvar-el
  529. (elisp--xref-find-definitions 'xref--marker-ring)
  530. (list
  531. (xref-make "(defvar xref--marker-ring)"
  532. (xref-make-elisp-location
  533. 'xref--marker-ring 'defvar
  534. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  535. ))
  536. (xref-elisp-deftest find-defs-defvar-c
  537. (elisp--xref-find-definitions 'default-directory)
  538. (list
  539. (cons
  540. (xref-make "(defvar default-directory)"
  541. (xref-make-elisp-location 'default-directory 'defvar "src/buffer.c"))
  542. ;; IMPROVEME: we might be able to compute this target
  543. "DEFVAR_PER_BUFFER (\"default-directory\"")))
  544. (xref-elisp-deftest find-defs-defvar-eval
  545. (elisp--xref-find-definitions (eval '(defvar stephe-leake-defvar nil)))
  546. nil)
  547. (xref-elisp-deftest find-defs-face-el
  548. (elisp--xref-find-definitions 'font-lock-keyword-face)
  549. ;; 'font-lock-keyword-face is both a face and a var
  550. (list
  551. (xref-make "(defvar font-lock-keyword-face)"
  552. (xref-make-elisp-location
  553. 'font-lock-keyword-face 'defvar
  554. (expand-file-name "../../../lisp/font-lock.el" emacs-test-dir)))
  555. (xref-make "(defface font-lock-keyword-face)"
  556. (xref-make-elisp-location
  557. 'font-lock-keyword-face 'defface
  558. (expand-file-name "../../../lisp/font-lock.el" emacs-test-dir)))
  559. ))
  560. (xref-elisp-deftest find-defs-face-eval
  561. (elisp--xref-find-definitions (eval '(defface stephe-leake-defface nil "")))
  562. nil)
  563. (xref-elisp-deftest find-defs-feature-el
  564. (elisp--xref-find-definitions 'xref)
  565. (list
  566. (cons
  567. (xref-make "(feature xref)"
  568. (xref-make-elisp-location
  569. 'xref 'feature
  570. (expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
  571. ";;; Code:")
  572. ))
  573. (xref-elisp-deftest find-defs-feature-eval
  574. (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature)))
  575. nil)
  576. (ert-deftest elisp--preceding-sexp--char-name ()
  577. (with-temp-buffer
  578. (emacs-lisp-mode)
  579. (insert "?\\N{HEAVY CHECK MARK}")
  580. (should (equal (elisp--preceding-sexp) ?\N{HEAVY CHECK MARK}))))
  581. (provide 'elisp-mode-tests)
  582. ;;; elisp-mode-tests.el ends here