ido-ubiquitous-tests.el 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. ;;; ido-ubiquitous-tests.el --- -*- "lexical-binding": t -*-
  2. ;; Copyright (C) 2015 Ryan C. Thompson
  3. ;; Filename: ido-ubiquitous-tests.el
  4. ;; Author: Ryan C. Thompson
  5. ;; Created: Tue Oct 6 20:52:45 2015 (-0700)
  6. ;; Version:
  7. ;; Package-Requires: ()
  8. ;; URL:
  9. ;; Keywords:
  10. ;; This file is NOT part of GNU Emacs.
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12. ;;
  13. ;;; Commentary:
  14. ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16. ;;
  17. ;; This program is free software: you can redistribute it and/or modify
  18. ;; it under the terms of the GNU General Public License as published by
  19. ;; the Free Software Foundation, either version 3 of the License, or (at
  20. ;; your option) any later version.
  21. ;;
  22. ;; This program is distributed in the hope that it will be useful, but
  23. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  24. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. ;; General Public License for more details.
  26. ;;
  27. ;; You should have received a copy of the GNU General Public License
  28. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  29. ;;
  30. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  31. ;;
  32. ;;; Code:
  33. ;; This is a series of macros to facilitate the testing of completion
  34. ;; non-interactively by simulating input.
  35. (require 'ido-ubiquitous)
  36. (defmacro keyboard-quit-to-error (&rest body)
  37. "Evaluate BODY but signal an error on `keyboard-quit'."
  38. `(condition-case nil
  39. (progn ,@body)
  40. (quit
  41. (error "Caught `keyboard-quit'"))))
  42. (defmacro with-simulated-input (keys &rest body)
  43. "Eval body with KEYS as simulated input.
  44. This macro is intended for testing normally interactive functions
  45. by simulating input. If BODY tries to read more input events than
  46. KEYS provides, `keyboard-quit' is invoked (by means of appending
  47. multple C-g keys to KEYS). This is to ensure that BODY will never
  48. block waiting for input, since this macro is intended for
  49. noninteractive use. As such, BODY should not invoke
  50. `keyboard-quit' under normal operation, and KEYS should not
  51. include C-g, or this macro will interpret it as reading past the
  52. end of input."
  53. ;; It would be better to detect end-of-input by overriding
  54. ;; `read-event' to throw an error, since theoretically C-g could be
  55. ;; rebound to something other than `keyboard-quit'. But apparently
  56. ;; some functions read input directly in C code, and redefining
  57. ;; `read-event' has no effect on those. So the suboptimal solution
  58. ;; is to rely on C-g.
  59. (declare (indent 1))
  60. `(let* ((key-sequence (listify-key-sequence (kbd ,keys)))
  61. (C-g-key-sequence
  62. (listify-key-sequence
  63. ;; We *really* want to trigger `keyboard-quit' if we reach
  64. ;; the end of the input.
  65. (kbd "C-g C-g C-g C-g C-g C-g C-g")))
  66. (unread-command-events
  67. (append key-sequence C-g-key-sequence)))
  68. (when (member (car C-g-key-sequence) key-sequence)
  69. (error "KEYS must include C-g"))
  70. (condition-case nil
  71. ,@body
  72. (quit
  73. (error "Reached end of simulated input while evaluating body")))))
  74. (defmacro with-mode (mode arg &rest body)
  75. "Eval (MODE ARG), then body, then restore previous status of MODE.
  76. This will only work on modes that respect the normal conventions
  77. for activation and deactivation."
  78. (declare (indent 2))
  79. (let* ((orig-status (eval mode))
  80. (restore-arg (if orig-status 1 0)))
  81. `(unwind-protect
  82. (progn
  83. (,mode ,arg)
  84. ,@body)
  85. (,mode ,restore-arg))))
  86. (ert-deftest ido-ubiquitous-test ()
  87. "Do some ido-ubiquitous tests"
  88. (with-mode ido-ubiquitous-mode 1
  89. (should
  90. (string=
  91. "green"
  92. (with-simulated-input "g RET"
  93. (completing-read "Prompt: " '("blue" "yellow" "green")))))
  94. (should
  95. (string=
  96. "g"
  97. (with-simulated-input "g C-j"
  98. (completing-read "Prompt: " '("blue" "yellow" "green"))))))
  99. ;; Normal completing-read
  100. (with-mode ido-ubiquitous-mode 0
  101. ;; No match required
  102. (should
  103. (string=
  104. "g"
  105. (with-simulated-input "g RET"
  106. (completing-read "Prompt: " '("blue" "yellow" "green")))))
  107. ;; Match required, so input should be incomplete
  108. (should-error
  109. (with-simulated-input "g RET"
  110. (completing-read "Prompt: " '("blue" "yellow" "green") nil 'require-match))
  111. :type 'error))))
  112. (provide 'ido-ubiquitous-tests)
  113. ;;; ido-ubiquitous-tests.el ends here