ido-ubiquitous-test.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. ;;; ido-ubiquitous-test.el --- -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2015 Ryan C. Thompson
  3. ;; Filename: ido-ubiquitous-test.el
  4. ;; Author: Ryan C. Thompson
  5. ;; Created: Tue Oct 6 20:52:45 2015 (-0700)
  6. ;; This file is NOT part of GNU Emacs.
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  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 3 of the License, or (at
  12. ;; your option) any later version.
  13. ;;
  14. ;; This program is distributed in the hope that it will be useful, but
  15. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. ;; 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. If not, see <http://www.gnu.org/licenses/>.
  21. ;;
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ;;
  24. ;;; Code:
  25. (require 'ido-completing-read+)
  26. (require 'ido-ubiquitous)
  27. (require 'ert)
  28. (require 'cl-lib)
  29. ;; This is a series of macros to facilitate the testing of completion
  30. ;; non-interactively by simulating input.
  31. (defmacro keyboard-quit-to-error (&rest body)
  32. "Evaluate BODY but signal an error on `keyboard-quit'."
  33. `(condition-case nil
  34. (progn ,@body)
  35. (quit
  36. (error "Caught `keyboard-quit'"))))
  37. (defmacro with-simulated-input (keys &rest body)
  38. "Eval body with KEYS as simulated input.
  39. This macro is intended for testing normally interactive functions
  40. by simulating input. If BODY tries to read more input events than
  41. KEYS provides, `keyboard-quit' is invoked (by means of appending
  42. multple C-g keys to KEYS). This is to ensure that BODY will never
  43. block waiting for input, since this macro is intended for
  44. noninteractive use. As such, BODY should not invoke
  45. `keyboard-quit' under normal operation, and KEYS should not
  46. include C-g, or this macro will interpret it as reading past the
  47. end of input."
  48. ;; It would be better to detect end-of-input by overriding
  49. ;; `read-event' to throw an error, since theoretically C-g could be
  50. ;; rebound to something other than `keyboard-quit'. But apparently
  51. ;; some functions read input directly in C code, and redefining
  52. ;; `read-event' has no effect on those. So the suboptimal solution
  53. ;; is to rely on C-g.
  54. (declare (indent 1))
  55. `(let* ((key-sequence (listify-key-sequence (kbd ,keys)))
  56. (C-g-key-sequence
  57. (listify-key-sequence
  58. ;; We *really* want to trigger `keyboard-quit' if we reach
  59. ;; the end of the input.
  60. (kbd "C-g C-g C-g C-g C-g C-g C-g")))
  61. (unread-command-events
  62. (append key-sequence C-g-key-sequence)))
  63. (when (member (car C-g-key-sequence) key-sequence)
  64. (error "KEYS must not include C-g"))
  65. (condition-case nil
  66. (progn ,@body)
  67. (quit
  68. (error "Reached end of simulated input while evaluating body")))))
  69. (defmacro with-mode (mode arg &rest body)
  70. "Eval (MODE ARG), then body, then restore previous status of MODE.
  71. This will only work on modes that respect the normal conventions
  72. for activation and deactivation."
  73. (declare (indent 2))
  74. `(let* ((orig-status ,mode)
  75. (restore-arg (if orig-status 1 0)))
  76. (unwind-protect
  77. (progn
  78. (,mode ,arg)
  79. ,@body)
  80. (message "Restoring mode %s to %s" ',mode restore-arg)
  81. (,mode restore-arg))))
  82. (defmacro with-ido-ubiquitous-standard-env (&rest body)
  83. "Execute BODY with standard ido-ubiquitous settings.\n\nAll ido-ubiquitous and ido-cr+ options will be let-bound to their\ndefault values, and `ido-ubiquitous-mode' will be enabled."
  84. (declare (indent 0))
  85. (let*
  86. ((ido-ubiquitous-options
  87. '(ido-ubiquitous-allow-on-functional-collection
  88. ido-ubiquitous-command-overrides
  89. ido-ubiquitous-debug-mode
  90. ido-ubiquitous-default-state
  91. ido-ubiquitous-function-overrides
  92. ido-cr+-fallback-function
  93. ido-cr+-max-items
  94. ido-cr+-replace-completely))
  95. (idu-bindings
  96. (cl-loop for var in ido-ubiquitous-options collect
  97. (list var
  98. (list 'quote
  99. (eval (car (get var 'standard-value))))))))
  100. `(with-mode ido-ubiquitous-mode 1
  101. (let ,idu-bindings ,@body))))
  102. (defmacro collection-as-function (collection)
  103. "Return a function equivalent to COLLECTION.
  104. The returned function will work equivalently to COLLECTION when
  105. passed to `all-completions' and `try-completion'."
  106. `(completion-table-dynamic (lambda (string) (all-completions string ,collection))))
  107. (cl-defmacro should-with-tag (form &key tag)
  108. "Equivalent to `(should FORM)' but with a TAG on the output.
  109. This is useful if the same `should' form will be called multiple
  110. times in different contexts. Each test can pass a different tag
  111. so it's clear in the ERT output which context is causing the
  112. failure.
  113. Note that although this is a macro, the TAG argument is evaluated normally."
  114. `(let ((tagvalue ,tag))
  115. (condition-case err
  116. (should ,form)
  117. (ert-test-failed
  118. (message "Error symbol: %S" (car err))
  119. (message "Error data: %S" (cdr err))
  120. (when tagvalue
  121. (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
  122. (message "New error data: %S" (cdr err))
  123. (signal (car err) (cdr err))))))
  124. (defun plist-delete (plist property)
  125. "Delete PROPERTY from PLIST.
  126. This is in contrast to merely setting it to 0."
  127. (let (p)
  128. (while plist
  129. (if (not (eq property (car plist)))
  130. (setq p (plist-put p (car plist) (nth 1 plist))))
  131. (setq plist (cddr plist)))
  132. p))
  133. (cl-defmacro should-error-with-tag (form &rest other-keys &key tag &allow-other-keys)
  134. "Equivalent to `(should FORM)' but with a TAG on the output.
  135. See `should-with-tag'.
  136. Note that although this is a macro, the TAG argument is evaluated normally."
  137. (setq other-keys (plist-delete other-keys :tag))
  138. `(let ((tagvalue ,tag))
  139. (condition-case err
  140. (should-error ,form ,@other-keys)
  141. (ert-test-failed
  142. (message "Error symbol: %S" (car err))
  143. (message "Error data: %S" (cdr err))
  144. (when tagvalue
  145. (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
  146. (message "New error data: %S" (cdr err))
  147. (signal (car err) (cdr err))))))
  148. (defun test-ido-ubiquitous-expected-mode (override &optional tag)
  149. "Test whether observed ido-ubiquitous behavior matches OVERRIDE."
  150. (declare (indent 1))
  151. (if (eq override 'disable)
  152. (progn
  153. (should-with-tag
  154. ;; Verify that we get standard completion
  155. (string=
  156. "g"
  157. (with-simulated-input "g RET"
  158. (completing-read "Prompt: " '("blue" "yellow" "green"))))
  159. :tag tag)
  160. (should-with-tag
  161. (string=
  162. "green"
  163. (with-simulated-input "g RET"
  164. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  165. :tag tag)
  166. ;; Standard completion should refuse to finish with incomplete
  167. ;; input if match is required
  168. (should-error-with-tag
  169. (with-simulated-input "b RET"
  170. (completing-read "Prompt: " '("brown" "blue" "yellow" "green") nil t))
  171. :type 'error
  172. :tag tag))
  173. ;; Common tests whenever ido-ubiquitous is enabled in any way
  174. (should-with-tag
  175. ;; Verify that ido completion is active
  176. (string=
  177. "green"
  178. (with-simulated-input "g RET"
  179. (completing-read "Prompt: " '("blue" "yellow" "green"))))
  180. :tag tag)
  181. ;; Verify that C-j is working correctly
  182. (should-with-tag
  183. (string=
  184. "g"
  185. (with-simulated-input "g C-j"
  186. (completing-read "Prompt: " '("blue" "yellow" "green"))))
  187. :tag tag)
  188. (let ((collection '("brown" "blue" "yellow" "green")))
  189. (should-with-tag
  190. (member
  191. (with-simulated-input "b RET"
  192. (completing-read "Prompt: " collection))
  193. (all-completions "b" collection))
  194. :tag tag))
  195. (case override
  196. (enable
  197. ;; Test for new style
  198. (should-with-tag
  199. (string=
  200. "blue"
  201. (with-simulated-input "RET"
  202. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  203. :tag tag)
  204. (should-with-tag
  205. (string=
  206. ""
  207. (with-simulated-input "C-j"
  208. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  209. :tag tag))
  210. (enable-old
  211. (should-with-tag
  212. (string=
  213. ""
  214. (with-simulated-input "RET"
  215. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  216. :tag tag)
  217. (should-with-tag
  218. (string=
  219. "blue"
  220. (with-simulated-input "C-j"
  221. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  222. :tag tag)
  223. ;; Verify that doing other stuff reverts RET and C-j to standard
  224. ;; meanings
  225. (should-with-tag
  226. (string=
  227. "blue"
  228. (with-simulated-input "g DEL RET"
  229. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  230. :tag tag)
  231. (should-with-tag
  232. (string=
  233. "blue"
  234. (with-simulated-input "<right> <left> RET"
  235. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  236. :tag tag)
  237. (should-with-tag
  238. (string=
  239. ""
  240. (with-simulated-input "g DEL C-j"
  241. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  242. :tag tag)
  243. (should-with-tag
  244. (string=
  245. ""
  246. (with-simulated-input "<right> <left> C-j"
  247. (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
  248. :tag tag))
  249. (otherwise (error "Unknown override %S" override)))))
  250. (defvar original-completing-read (symbol-function #'completing-read))
  251. (defun test-ido-ubiquitous-expected-mode-on-functional-collection (override &optional tag)
  252. "Test whether observed ido-ubiquitous behavior on functional collection matches OVERRIDE."
  253. (declare (indent 1))
  254. ;; This just temporarily replaces `completing-read' with a wrapper
  255. ;; that always converts the collection argument to an equivalent
  256. ;; function. That way, any use of `completing-read' will always see
  257. ;; a functional collection.
  258. (cl-letf (((symbol-function 'completing-read)
  259. (lambda (prompt collection &rest args)
  260. (apply original-completing-read prompt
  261. (collection-as-function collection)
  262. args))))
  263. (test-ido-ubiquitous-expected-mode override tag)))
  264. (ert-deftest ido-ubiquitous-test-simple ()
  265. :tags '(ido ido-ubiquitous)
  266. "Test that basic ido-ubiquitous functionality is working."
  267. (with-ido-ubiquitous-standard-env
  268. (ido-ubiquitous-mode 1)
  269. (test-ido-ubiquitous-expected-mode 'enable
  270. :simple-enable)
  271. (ido-ubiquitous-mode 0)
  272. (test-ido-ubiquitous-expected-mode 'disable
  273. :simple-disable)))
  274. (ert-deftest ido-ubiquitous-test-oldstyle ()
  275. :tags '(ido ido-ubiquitous)
  276. "Test whether old-style completion works as expected."
  277. (with-ido-ubiquitous-standard-env
  278. (let ((ido-ubiquitous-default-state 'enable-old))
  279. (test-ido-ubiquitous-expected-mode 'enable-old
  280. :simple-oldstyle))))
  281. (ert-deftest ido-ubiquitous-test-maxitems ()
  282. :tags '(ido ido-ubiquitous)
  283. "Test whether the large-collection fallback works."
  284. (with-ido-ubiquitous-standard-env
  285. (let ((ido-cr+-max-items -1))
  286. (test-ido-ubiquitous-expected-mode 'disable
  287. :maxitems))))
  288. (ert-deftest ido-ubiquitous-test-override ()
  289. :tags '(ido ido-ubiquitous)
  290. "Test whether ido-ubiquitous overrides work."
  291. (with-ido-ubiquitous-standard-env
  292. (ido-ubiquitous-with-override 'enable
  293. (test-ido-ubiquitous-expected-mode 'enable
  294. :override-enable))
  295. (ido-ubiquitous-with-override 'enable-old
  296. (test-ido-ubiquitous-expected-mode 'enable-old
  297. :override-enable-old))
  298. (ido-ubiquitous-with-override 'disable
  299. (test-ido-ubiquitous-expected-mode 'disable
  300. :override-disable))))
  301. (ert-deftest ido-ubiquitous-test-functional-collection ()
  302. :tags '(ido ido-ubiquitous)
  303. "Test whether ido-ubiquitous overrides work when collection is a function."
  304. (with-ido-ubiquitous-standard-env
  305. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  306. :collfunc)
  307. (ido-ubiquitous-with-override 'enable
  308. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
  309. :override-enable-collfunc))
  310. (ido-ubiquitous-with-override 'enable-old
  311. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
  312. :override-enable-old-collfunc))))
  313. (ert-deftest ido-cr+-require-match ()
  314. :tags '(ido ido-cr+)
  315. "Test whether require-match works."
  316. ;; "C-j" should be allowed to return an empty string even if
  317. ;; require-match is non-nil, as long as default is nil
  318. (should
  319. (string=
  320. ""
  321. (with-simulated-input "C-j"
  322. (ido-completing-read+
  323. "Prompt: "
  324. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
  325. ;; "C-j" should NOT be allowed to return an empty string if
  326. ;; require-match and default are both non-nil.
  327. (should-error
  328. (with-simulated-input "C-j"
  329. (ido-completing-read+
  330. "Prompt: "
  331. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t nil nil "yellow")))
  332. ;; Multiple presses of C-j won't just select the first match
  333. (should-error
  334. (with-simulated-input "b C-j C-j C-j"
  335. (ido-completing-read+
  336. "Prompt: "
  337. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
  338. ;; First press of C-j should complete unique common prefix after the
  339. ;; first b, but then get stuck on the choice for the second b.
  340. (should-error
  341. (with-simulated-input "b C-j b C-j C-j"
  342. (ido-completing-read+
  343. "Prompt: "
  344. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
  345. ;; This should complete to "blueberry" via 2 rounds of unique common
  346. ;; prefix completion, and then return on the 3rd "C-j"
  347. (should
  348. (string=
  349. "blueberry"
  350. (with-simulated-input "b C-j b C-j e C-j C-j"
  351. (ido-completing-read+
  352. "Prompt: "
  353. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
  354. ;; The "C-j" should complete to "bluegrass" but should
  355. ;; not return.
  356. (should-error
  357. (with-simulated-input "b l u e g C-j"
  358. (ido-completing-read+
  359. "Prompt: "
  360. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
  361. ;; The first "C-j" should complete to "bluegrass", and the second
  362. ;; should return.
  363. (should
  364. (string=
  365. "bluegrass"
  366. (with-simulated-input "b l u e g C-j C-j"
  367. (ido-completing-read+
  368. "Prompt: "
  369. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
  370. ;; Finally, a few tests for the expected wrong behavior without
  371. ;; ido-cr+. If ido.el ever fixes this bug, it will cause this test
  372. ;; to fail as a signal that the workaround can be phased out.
  373. (should
  374. (string=
  375. ""
  376. (with-simulated-input "C-j"
  377. (ido-completing-read
  378. "Prompt: "
  379. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
  380. (should
  381. (string=
  382. "b"
  383. (with-simulated-input "b C-j"
  384. (ido-completing-read
  385. "Prompt: "
  386. '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))))
  387. ;; Functions to define overrides on for testing
  388. (defun idu-no-override-testfunc ()
  389. (test-ido-ubiquitous-expected-mode 'enable
  390. :func-override-none)
  391. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  392. :func-override-none-collfunc))
  393. (defun idu-enabled-testfunc (&rest args)
  394. (test-ido-ubiquitous-expected-mode 'enable
  395. :func-override-enable)
  396. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
  397. :func-override-enable-collfunc))
  398. (defun idu-disabled-testfunc (&rest args)
  399. (test-ido-ubiquitous-expected-mode 'disable
  400. :func-override-disable)
  401. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  402. :func-override-disable-collfunc))
  403. (defun idu-enabled-oldstyle-testfunc (&rest args)
  404. (test-ido-ubiquitous-expected-mode 'enable-old
  405. :func-override-enable-old)
  406. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
  407. :func-override-enable-old-collfunc))
  408. ;; commands to define overrides on for testing
  409. (defun idu-no-override-testcmd (&rest args)
  410. (interactive
  411. (list
  412. (test-ido-ubiquitous-expected-mode 'enable
  413. :cmd-override-none)
  414. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  415. :cmd-override-none-collfunc)))
  416. (test-ido-ubiquitous-expected-mode 'enable
  417. :cmd-override-none)
  418. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  419. :cmd-override-non-collfunc))
  420. (defun idu-enabled-testcmd (&rest args)
  421. (interactive
  422. (list
  423. (test-ido-ubiquitous-expected-mode 'enable
  424. :cmd-override-enable)
  425. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
  426. :cmd-override-enable-collfunc)))
  427. (test-ido-ubiquitous-expected-mode 'enable
  428. :cmd-override-enable)
  429. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
  430. :cmd-override-enable-collfunc))
  431. (defun idu-disabled-testcmd (&rest args)
  432. (interactive
  433. (list
  434. (test-ido-ubiquitous-expected-mode 'disable
  435. :cmd-override-disable)
  436. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  437. :cmd-override-disable-collfunc)))
  438. (test-ido-ubiquitous-expected-mode 'disable
  439. :cmd-override-disable)
  440. (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
  441. :cmd-override-disable-collfunc))
  442. (defun idu-enabled-oldstyle-testcmd (&rest args)
  443. (interactive
  444. (list
  445. (test-ido-ubiquitous-expected-mode 'enable-old
  446. :cmd-override-enable-old)
  447. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
  448. :cmd-override-enable-old-collfunc)))
  449. (test-ido-ubiquitous-expected-mode 'enable-old
  450. :cmd-override-enable-old)
  451. (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
  452. :cmd-override-enable-old-collfunc))
  453. (ert-deftest ido-ubiquitous-test-command-and-function-overrides ()
  454. :tags '(ido ido-ubiquitous)
  455. "Test whether command- and function-specific overrides work."
  456. (let ((orig-func-overrides ido-ubiquitous-function-overrides)
  457. (orig-cmd-overrides ido-ubiquitous-command-overrides))
  458. (unwind-protect
  459. (with-ido-ubiquitous-standard-env
  460. (customize-set-variable
  461. 'ido-ubiquitous-function-overrides
  462. (append ido-ubiquitous-function-overrides
  463. '((enable exact "idu-enabled-testfunc")
  464. (disable exact "idu-disabled-testfunc")
  465. (enable-old exact "idu-enabled-oldstyle-testfunc"))))
  466. (cl-loop for func in
  467. '(idu-no-override-testfunc
  468. idu-enabled-testfunc
  469. idu-disabled-testfunc
  470. idu-enabled-oldstyle-testfunc)
  471. do (funcall func))
  472. (customize-set-variable
  473. 'ido-ubiquitous-command-overrides
  474. (append ido-ubiquitous-command-overrides
  475. '((enable exact "idu-enabled-testcmd")
  476. (disable exact "idu-disabled-testcmd")
  477. (enable-old exact "idu-enabled-oldstyle-testcmd"))))
  478. (cl-loop for cmd in
  479. '(idu-no-override-testcmd
  480. idu-enabled-testcmd
  481. idu-disabled-testcmd
  482. idu-enabled-oldstyle-testcmd)
  483. do (call-interactively cmd)))
  484. (customize-set-variable 'ido-ubiquitous-function-overrides orig-func-overrides)
  485. (customize-set-variable 'ido-ubiquitous-command-overrides orig-cmd-overrides))))
  486. (ert-deftest ido-ubiquitous-test-fallback ()
  487. :tags '(ido ido-ubiquitous)
  488. "Test whether manually invoking fallback works."
  489. (with-ido-ubiquitous-standard-env
  490. (should
  491. ;; C-b/f not at beginning/end of input should not fall back
  492. (string=
  493. "green"
  494. (with-simulated-input "g C-b C-f RET"
  495. (completing-read "Prompt: " '("blue" "yellow" "green")))))
  496. (should
  497. ;; C-f at end of input should fall back
  498. (string=
  499. "g"
  500. (with-simulated-input "g C-f RET"
  501. (completing-read "Prompt: " '("blue" "yellow" "green")))))
  502. (should
  503. ;; Repeated C-b should not fall back
  504. (string=
  505. "green"
  506. (with-simulated-input "g C-b C-b C-b C-b RET"
  507. (completing-read "Prompt: " '("blue" "yellow" "green")))))
  508. (should
  509. ;; C-b at beginning of line should fall back (if previous action
  510. ;; was not also C-b)
  511. (string=
  512. "g"
  513. (with-simulated-input "g C-b x DEL C-b RET"
  514. (completing-read "Prompt: " '("blue" "yellow" "green")))))))
  515. (defun ido-ubiquitous-run-all-tests ()
  516. (interactive)
  517. (ert "^ido-\\(ubiquitous\\|cr\\+\\)-"))
  518. (provide 'ido-ubiquitous-test)
  519. ;;; ido-ubiquitous-test.el ends here