diff options
| author | Gemini Lasswell | 2018-08-03 10:28:28 -0700 |
|---|---|---|
| committer | Gemini Lasswell | 2018-08-03 10:28:28 -0700 |
| commit | da0054c30729e58259c1e7251cb03c8ef13ff943 (patch) | |
| tree | f3fd4b5256aa6c6786d0ac4f80fb1d87dcc2e401 /test | |
| parent | e65ec81fc3e556719fae8d8b4b42f571c7e9f4fc (diff) | |
| parent | 95b2ab3dccdc756614b4c8f45a7b206d61753705 (diff) | |
| download | emacs-da0054c30729e58259c1e7251cb03c8ef13ff943.tar.gz emacs-da0054c30729e58259c1e7251cb03c8ef13ff943.zip | |
Merge branch 'scratch/backtrace-mode'
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/emacs-lisp/backtrace-tests.el | 436 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/cl-print-tests.el | 178 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el | 2 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/edebug-tests.el | 18 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/ert-tests.el | 2 |
5 files changed, 628 insertions, 8 deletions
diff --git a/test/lisp/emacs-lisp/backtrace-tests.el b/test/lisp/emacs-lisp/backtrace-tests.el new file mode 100644 index 00000000000..edd45c770c5 --- /dev/null +++ b/test/lisp/emacs-lisp/backtrace-tests.el | |||
| @@ -0,0 +1,436 @@ | |||
| 1 | ;;; backtrace-tests.el --- Tests for backtraces -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2018 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Gemini Lasswell | ||
| 6 | |||
| 7 | ;; This file is part of GNU Emacs. | ||
| 8 | |||
| 9 | ;; GNU Emacs 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 | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU 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 <https://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Code: | ||
| 23 | |||
| 24 | (require 'backtrace) | ||
| 25 | (require 'ert) | ||
| 26 | (require 'ert-x) | ||
| 27 | (require 'seq) | ||
| 28 | |||
| 29 | ;; Delay evaluation of the backtrace-creating functions until | ||
| 30 | ;; load so that the backtraces are the same whether this file | ||
| 31 | ;; is compiled or not. | ||
| 32 | |||
| 33 | (eval-and-compile | ||
| 34 | (defconst backtrace-tests--uncompiled-functions | ||
| 35 | '(progn | ||
| 36 | (defun backtrace-tests--make-backtrace (arg) | ||
| 37 | (backtrace-tests--setup-buffer)) | ||
| 38 | |||
| 39 | (defun backtrace-tests--setup-buffer () | ||
| 40 | "Set up the current buffer in backtrace mode." | ||
| 41 | (backtrace-mode) | ||
| 42 | (setq backtrace-frames (backtrace-get-frames)) | ||
| 43 | (let ((this-index)) | ||
| 44 | ;; Discard all past `backtrace-tests-make-backtrace'. | ||
| 45 | (dotimes (index (length backtrace-frames)) | ||
| 46 | (when (eq (backtrace-frame-fun (nth index backtrace-frames)) | ||
| 47 | 'backtrace-tests--make-backtrace) | ||
| 48 | (setq this-index index))) | ||
| 49 | (setq backtrace-frames (seq-subseq backtrace-frames 0 (1+ this-index)))) | ||
| 50 | (backtrace-print)))) | ||
| 51 | |||
| 52 | (eval backtrace-tests--uncompiled-functions)) | ||
| 53 | |||
| 54 | (defun backtrace-tests--backtrace-lines () | ||
| 55 | (if debugger-stack-frame-as-list | ||
| 56 | '(" (backtrace-get-frames)\n" | ||
| 57 | " (setq backtrace-frames (backtrace-get-frames))\n" | ||
| 58 | " (backtrace-tests--setup-buffer)\n" | ||
| 59 | " (backtrace-tests--make-backtrace %s)\n") | ||
| 60 | '(" backtrace-get-frames()\n" | ||
| 61 | " (setq backtrace-frames (backtrace-get-frames))\n" | ||
| 62 | " backtrace-tests--setup-buffer()\n" | ||
| 63 | " backtrace-tests--make-backtrace(%s)\n"))) | ||
| 64 | |||
| 65 | (defconst backtrace-tests--line-count (length (backtrace-tests--backtrace-lines))) | ||
| 66 | |||
| 67 | (defun backtrace-tests--backtrace-lines-with-locals () | ||
| 68 | (let ((lines (backtrace-tests--backtrace-lines)) | ||
| 69 | (locals '(" [no locals]\n" | ||
| 70 | " [no locals]\n" | ||
| 71 | " [no locals]\n" | ||
| 72 | " arg = %s\n"))) | ||
| 73 | (apply #'append (cl-mapcar #'list lines locals)))) | ||
| 74 | |||
| 75 | (defun backtrace-tests--result (value) | ||
| 76 | (format (apply #'concat (backtrace-tests--backtrace-lines)) | ||
| 77 | (cl-prin1-to-string value))) | ||
| 78 | |||
| 79 | (defun backtrace-tests--result-with-locals (value) | ||
| 80 | (let ((str (cl-prin1-to-string value))) | ||
| 81 | (format (apply #'concat (backtrace-tests--backtrace-lines-with-locals)) | ||
| 82 | str str))) | ||
| 83 | |||
| 84 | ;; TODO check that debugger-batch-max-lines still works | ||
| 85 | |||
| 86 | (defconst backtrace-tests--header "Test header\n") | ||
| 87 | (defun backtrace-tests--insert-header () | ||
| 88 | (insert backtrace-tests--header)) | ||
| 89 | |||
| 90 | ;;; Tests | ||
| 91 | |||
| 92 | (ert-deftest backtrace-tests--variables () | ||
| 93 | "Backtrace buffers can show and hide local variables." | ||
| 94 | (ert-with-test-buffer (:name "variables") | ||
| 95 | (let ((results (concat backtrace-tests--header | ||
| 96 | (backtrace-tests--result 'value))) | ||
| 97 | (last-frame (format (nth (1- backtrace-tests--line-count) | ||
| 98 | (backtrace-tests--backtrace-lines)) 'value)) | ||
| 99 | (last-frame-with-locals | ||
| 100 | (format (apply #'concat (nthcdr (* 2 (1- backtrace-tests--line-count)) | ||
| 101 | (backtrace-tests--backtrace-lines-with-locals))) | ||
| 102 | 'value 'value))) | ||
| 103 | (backtrace-tests--make-backtrace 'value) | ||
| 104 | (setq backtrace-insert-header-function #'backtrace-tests--insert-header) | ||
| 105 | (backtrace-print) | ||
| 106 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 107 | results)) | ||
| 108 | ;; Go to the last frame. | ||
| 109 | (goto-char (point-max)) | ||
| 110 | (forward-line -1) | ||
| 111 | ;; Turn on locals for that frame. | ||
| 112 | (backtrace-toggle-locals) | ||
| 113 | (should (string= (backtrace-tests--get-substring (point) (point-max)) | ||
| 114 | last-frame-with-locals)) | ||
| 115 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 116 | (concat results | ||
| 117 | (format (car (last (backtrace-tests--backtrace-lines-with-locals))) | ||
| 118 | 'value)))) | ||
| 119 | ;; Turn off locals for that frame. | ||
| 120 | (backtrace-toggle-locals) | ||
| 121 | (should (string= (backtrace-tests--get-substring (point) (point-max)) | ||
| 122 | last-frame)) | ||
| 123 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 124 | results)) | ||
| 125 | ;; Turn all locals on. | ||
| 126 | (backtrace-toggle-locals '(4)) | ||
| 127 | (should (string= (backtrace-tests--get-substring (point) (point-max)) | ||
| 128 | last-frame-with-locals)) | ||
| 129 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 130 | (concat backtrace-tests--header | ||
| 131 | (backtrace-tests--result-with-locals 'value)))) | ||
| 132 | ;; Turn all locals off. | ||
| 133 | (backtrace-toggle-locals '(4)) | ||
| 134 | (should (string= (backtrace-tests--get-substring | ||
| 135 | (point) (+ (point) (length last-frame))) | ||
| 136 | last-frame)) | ||
| 137 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 138 | results))))) | ||
| 139 | |||
| 140 | (ert-deftest backtrace-tests--backward-frame () | ||
| 141 | "`backtrace-backward-frame' moves backward to the start of a frame." | ||
| 142 | (ert-with-test-buffer (:name "backward") | ||
| 143 | (let ((results (concat backtrace-tests--header | ||
| 144 | (backtrace-tests--result nil)))) | ||
| 145 | (backtrace-tests--make-backtrace nil) | ||
| 146 | (setq backtrace-insert-header-function #'backtrace-tests--insert-header) | ||
| 147 | (backtrace-print) | ||
| 148 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 149 | results)) | ||
| 150 | |||
| 151 | ;; Try to move backward from header. | ||
| 152 | (goto-char (+ (point-min) (/ (length backtrace-tests--header) 2))) | ||
| 153 | (let ((pos (point))) | ||
| 154 | (should-error (backtrace-backward-frame)) | ||
| 155 | (should (= pos (point)))) | ||
| 156 | |||
| 157 | ;; Try to move backward from start of first line. | ||
| 158 | (forward-line) | ||
| 159 | (let ((pos (point))) | ||
| 160 | (should-error (backtrace-backward-frame)) | ||
| 161 | (should (= pos (point)))) | ||
| 162 | |||
| 163 | ;; Move backward from middle of line. | ||
| 164 | (let ((start (point))) | ||
| 165 | (forward-char (/ (length (nth 0 (backtrace-tests--backtrace-lines))) 2)) | ||
| 166 | (backtrace-backward-frame) | ||
| 167 | (should (= start (point)))) | ||
| 168 | |||
| 169 | ;; Move backward from end of buffer. | ||
| 170 | (goto-char (point-max)) | ||
| 171 | (backtrace-backward-frame) | ||
| 172 | (let* ((last (format (car (last (backtrace-tests--backtrace-lines))) nil)) | ||
| 173 | (len (length last))) | ||
| 174 | (should (string= (buffer-substring-no-properties (point) (+ (point) len)) | ||
| 175 | last))) | ||
| 176 | |||
| 177 | ;; Move backward from start of line. | ||
| 178 | (backtrace-backward-frame) | ||
| 179 | (let* ((line (car (last (backtrace-tests--backtrace-lines) 2))) | ||
| 180 | (len (length line))) | ||
| 181 | (should (string= (buffer-substring-no-properties (point) (+ (point) len)) | ||
| 182 | line)))))) | ||
| 183 | |||
| 184 | (ert-deftest backtrace-tests--forward-frame () | ||
| 185 | "`backtrace-forward-frame' moves forward to the start of a frame." | ||
| 186 | (ert-with-test-buffer (:name "forward") | ||
| 187 | (let* ((arg '(1 2 3)) | ||
| 188 | (results (concat backtrace-tests--header | ||
| 189 | (backtrace-tests--result arg))) | ||
| 190 | (first-line (nth 0 (backtrace-tests--backtrace-lines)))) | ||
| 191 | (backtrace-tests--make-backtrace arg) | ||
| 192 | (setq backtrace-insert-header-function #'backtrace-tests--insert-header) | ||
| 193 | (backtrace-print) | ||
| 194 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 195 | results)) | ||
| 196 | ;; Move forward from header. | ||
| 197 | (goto-char (+ (point-min) (/ (length backtrace-tests--header) 2))) | ||
| 198 | (backtrace-forward-frame) | ||
| 199 | (should (string= (backtrace-tests--get-substring | ||
| 200 | (point) (+ (point) (length first-line))) | ||
| 201 | first-line)) | ||
| 202 | |||
| 203 | (let ((start (point)) | ||
| 204 | (offset (/ (length first-line) 2)) | ||
| 205 | (second-line (nth 1 (backtrace-tests--backtrace-lines)))) | ||
| 206 | ;; Move forward from start of first frame. | ||
| 207 | (backtrace-forward-frame) | ||
| 208 | (should (string= (backtrace-tests--get-substring | ||
| 209 | (point) (+ (point) (length second-line))) | ||
| 210 | second-line)) | ||
| 211 | ;; Move forward from middle of first frame. | ||
| 212 | (goto-char (+ start offset)) | ||
| 213 | (backtrace-forward-frame) | ||
| 214 | (should (string= (backtrace-tests--get-substring | ||
| 215 | (point) (+ (point) (length second-line))) | ||
| 216 | second-line))) | ||
| 217 | ;; Try to move forward from middle of last frame. | ||
| 218 | (goto-char (- (point-max) | ||
| 219 | (/ 2 (length (car (last (backtrace-tests--backtrace-lines))))))) | ||
| 220 | (should-error (backtrace-forward-frame)) | ||
| 221 | ;; Try to move forward from end of buffer. | ||
| 222 | (goto-char (point-max)) | ||
| 223 | (should-error (backtrace-forward-frame))))) | ||
| 224 | |||
| 225 | (ert-deftest backtrace-tests--single-and-multi-line () | ||
| 226 | "Forms in backtrace frames can be on a single line or on multiple lines." | ||
| 227 | (ert-with-test-buffer (:name "single-multi-line") | ||
| 228 | (let* ((arg '(lambda (x) ; Quote this so it isn't made into a closure. | ||
| 229 | (let ((number (1+ x))) | ||
| 230 | (+ x number)))) | ||
| 231 | (header-string "Test header: ") | ||
| 232 | (header (format "%s%s\n" header-string arg)) | ||
| 233 | (insert-header-function (lambda () | ||
| 234 | (insert header-string) | ||
| 235 | (insert (backtrace-print-to-string arg)) | ||
| 236 | (insert "\n"))) | ||
| 237 | (results (concat header (backtrace-tests--result arg))) | ||
| 238 | (last-line (format (nth (1- backtrace-tests--line-count) | ||
| 239 | (backtrace-tests--backtrace-lines)) | ||
| 240 | arg)) | ||
| 241 | (last-line-locals (format (nth (1- (* 2 backtrace-tests--line-count)) | ||
| 242 | (backtrace-tests--backtrace-lines-with-locals)) | ||
| 243 | arg))) | ||
| 244 | |||
| 245 | (backtrace-tests--make-backtrace arg) | ||
| 246 | (setq backtrace-insert-header-function insert-header-function) | ||
| 247 | (backtrace-print) | ||
| 248 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 249 | results)) | ||
| 250 | ;; Check pp and collapse for the form in the header. | ||
| 251 | (goto-char (point-min)) | ||
| 252 | (backtrace-tests--verify-single-and-multi-line header) | ||
| 253 | ;; Check pp and collapse for the last frame. | ||
| 254 | (goto-char (point-max)) | ||
| 255 | (backtrace-backward-frame) | ||
| 256 | (backtrace-tests--verify-single-and-multi-line last-line) | ||
| 257 | ;; Check pp and collapse for local variables in the last line. | ||
| 258 | (goto-char (point-max)) | ||
| 259 | (backtrace-backward-frame) | ||
| 260 | (backtrace-toggle-locals) | ||
| 261 | (forward-line) | ||
| 262 | (backtrace-tests--verify-single-and-multi-line last-line-locals)))) | ||
| 263 | |||
| 264 | (defun backtrace-tests--verify-single-and-multi-line (line) | ||
| 265 | "Verify that `backtrace-single-line' and `backtrace-multi-line' work at point. | ||
| 266 | Point should be at the beginning of a line, and LINE should be a | ||
| 267 | string containing the text of the line at point. Assume that the | ||
| 268 | line contains the strings \"lambda\" and \"number\"." | ||
| 269 | (let ((pos (point))) | ||
| 270 | (backtrace-multi-line) | ||
| 271 | ;; Verify point is still at the start of the line. | ||
| 272 | (should (= pos (point)))) | ||
| 273 | |||
| 274 | ;; Verify the form now spans multiple lines. | ||
| 275 | (let ((pos (point))) | ||
| 276 | (search-forward "number") | ||
| 277 | (should-not (= pos (point-at-bol)))) | ||
| 278 | ;; Collapse the form. | ||
| 279 | (backtrace-single-line) | ||
| 280 | ;; Verify that the form is now back on one line, | ||
| 281 | ;; and that point is at the same place. | ||
| 282 | (should (string= (backtrace-tests--get-substring | ||
| 283 | (- (point) 6) (point)) "number")) | ||
| 284 | (should-not (= (point) (point-at-bol))) | ||
| 285 | (should (string= (backtrace-tests--get-substring | ||
| 286 | (point-at-bol) (1+ (point-at-eol))) | ||
| 287 | line))) | ||
| 288 | |||
| 289 | (ert-deftest backtrace-tests--print-circle () | ||
| 290 | "Backtrace buffers can toggle `print-circle' syntax." | ||
| 291 | (ert-with-test-buffer (:name "print-circle") | ||
| 292 | (let* ((print-circle nil) | ||
| 293 | (arg (let ((val (make-list 5 'a))) (nconc val val) val)) | ||
| 294 | (results (backtrace-tests--make-regexp | ||
| 295 | (backtrace-tests--result arg))) | ||
| 296 | (results-circle (regexp-quote (let ((print-circle t)) | ||
| 297 | (backtrace-tests--result arg)))) | ||
| 298 | (last-frame (backtrace-tests--make-regexp | ||
| 299 | (format (nth (1- backtrace-tests--line-count) | ||
| 300 | (backtrace-tests--backtrace-lines)) | ||
| 301 | arg))) | ||
| 302 | (last-frame-circle (regexp-quote | ||
| 303 | (let ((print-circle t)) | ||
| 304 | (format (nth (1- backtrace-tests--line-count) | ||
| 305 | (backtrace-tests--backtrace-lines)) | ||
| 306 | arg))))) | ||
| 307 | (backtrace-tests--make-backtrace arg) | ||
| 308 | (backtrace-print) | ||
| 309 | (should (string-match-p results | ||
| 310 | (backtrace-tests--get-substring (point-min) (point-max)))) | ||
| 311 | ;; Go to the last frame. | ||
| 312 | (goto-char (point-max)) | ||
| 313 | (forward-line -1) | ||
| 314 | ;; Turn on print-circle for that frame. | ||
| 315 | (backtrace-toggle-print-circle) | ||
| 316 | (should (string-match-p last-frame-circle | ||
| 317 | (backtrace-tests--get-substring (point) (point-max)))) | ||
| 318 | ;; Turn off print-circle for the frame. | ||
| 319 | (backtrace-toggle-print-circle) | ||
| 320 | (should (string-match-p last-frame | ||
| 321 | (backtrace-tests--get-substring (point) (point-max)))) | ||
| 322 | (should (string-match-p results | ||
| 323 | (backtrace-tests--get-substring (point-min) (point-max)))) | ||
| 324 | ;; Turn print-circle on for the buffer. | ||
| 325 | (backtrace-toggle-print-circle '(4)) | ||
| 326 | (should (string-match-p last-frame-circle | ||
| 327 | (backtrace-tests--get-substring (point) (point-max)))) | ||
| 328 | (should (string-match-p results-circle | ||
| 329 | (backtrace-tests--get-substring (point-min) (point-max)))) | ||
| 330 | ;; Turn print-circle off. | ||
| 331 | (backtrace-toggle-print-circle '(4)) | ||
| 332 | (should (string-match-p last-frame | ||
| 333 | (backtrace-tests--get-substring | ||
| 334 | (point) (+ (point) (length last-frame))))) | ||
| 335 | (should (string-match-p results | ||
| 336 | (backtrace-tests--get-substring (point-min) (point-max))))))) | ||
| 337 | |||
| 338 | (defun backtrace-tests--make-regexp (str) | ||
| 339 | "Make regexp from STR for `backtrace-tests--print-circle'. | ||
| 340 | Used for results of printing circular objects without | ||
| 341 | `print-circle' on. Look for #n in string STR where n is any | ||
| 342 | digit and replace with #[0-9]." | ||
| 343 | (let ((regexp (regexp-quote str))) | ||
| 344 | (with-temp-buffer | ||
| 345 | (insert regexp) | ||
| 346 | (goto-char (point-min)) | ||
| 347 | (while (re-search-forward "#[0-9]" nil t) | ||
| 348 | (replace-match "#[0-9]"))) | ||
| 349 | (buffer-string))) | ||
| 350 | |||
| 351 | (ert-deftest backtrace-tests--expand-ellipsis () | ||
| 352 | "Backtrace buffers ellipsify large forms as buttons which expand the ellipses." | ||
| 353 | ;; make a backtrace with an ellipsis | ||
| 354 | ;; expand the ellipsis | ||
| 355 | (ert-with-test-buffer (:name "variables") | ||
| 356 | (let* ((print-level nil) | ||
| 357 | (print-length nil) | ||
| 358 | (backtrace-line-length 300) | ||
| 359 | (arg (make-list 40 (make-string 10 ?a))) | ||
| 360 | (results (backtrace-tests--result arg))) | ||
| 361 | (backtrace-tests--make-backtrace arg) | ||
| 362 | (backtrace-print) | ||
| 363 | |||
| 364 | ;; There should be an ellipsis. Find and expand it. | ||
| 365 | (goto-char (point-min)) | ||
| 366 | (search-forward "...") | ||
| 367 | (backward-char) | ||
| 368 | (push-button) | ||
| 369 | |||
| 370 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 371 | results))))) | ||
| 372 | |||
| 373 | (ert-deftest backtrace-tests--expand-ellipses () | ||
| 374 | "Backtrace buffers ellipsify large forms and can expand the ellipses." | ||
| 375 | (ert-with-test-buffer (:name "variables") | ||
| 376 | (let* ((print-level nil) | ||
| 377 | (print-length nil) | ||
| 378 | (backtrace-line-length 300) | ||
| 379 | (arg (let ((outer (make-list 40 (make-string 10 ?a))) | ||
| 380 | (nested (make-list 40 (make-string 10 ?b)))) | ||
| 381 | (setf (nth 39 nested) (make-list 40 (make-string 10 ?c))) | ||
| 382 | (setf (nth 39 outer) nested) | ||
| 383 | outer)) | ||
| 384 | (results (backtrace-tests--result-with-locals arg))) | ||
| 385 | |||
| 386 | ;; Make a backtrace with local variables visible. | ||
| 387 | (backtrace-tests--make-backtrace arg) | ||
| 388 | (backtrace-print) | ||
| 389 | (backtrace-toggle-locals '(4)) | ||
| 390 | |||
| 391 | ;; There should be two ellipses. | ||
| 392 | (goto-char (point-min)) | ||
| 393 | (should (search-forward "...")) | ||
| 394 | (should (search-forward "...")) | ||
| 395 | (should-error (search-forward "...")) | ||
| 396 | |||
| 397 | ;; Expanding the last frame without argument should expand both | ||
| 398 | ;; ellipses, but the expansions will contain one ellipsis each. | ||
| 399 | (let ((buffer-len (- (point-max) (point-min)))) | ||
| 400 | (goto-char (point-max)) | ||
| 401 | (backtrace-backward-frame) | ||
| 402 | (backtrace-expand-ellipses) | ||
| 403 | (should (> (- (point-max) (point-min)) buffer-len)) | ||
| 404 | (goto-char (point-min)) | ||
| 405 | (should (search-forward "...")) | ||
| 406 | (should (search-forward "...")) | ||
| 407 | (should-error (search-forward "..."))) | ||
| 408 | |||
| 409 | ;; Expanding with argument should remove all ellipses. | ||
| 410 | (goto-char (point-max)) | ||
| 411 | (backtrace-backward-frame) | ||
| 412 | (backtrace-expand-ellipses '(4)) | ||
| 413 | (goto-char (point-min)) | ||
| 414 | |||
| 415 | (should-error (search-forward "...")) | ||
| 416 | (should (string= (backtrace-tests--get-substring (point-min) (point-max)) | ||
| 417 | results))))) | ||
| 418 | |||
| 419 | |||
| 420 | (ert-deftest backtrace-tests--to-string () | ||
| 421 | "Backtraces can be produced as strings." | ||
| 422 | (let ((frames (ert-with-test-buffer (:name nil) | ||
| 423 | (backtrace-tests--make-backtrace "string") | ||
| 424 | backtrace-frames))) | ||
| 425 | (should (string= (backtrace-to-string frames) | ||
| 426 | (backtrace-tests--result "string"))))) | ||
| 427 | |||
| 428 | (defun backtrace-tests--get-substring (beg end) | ||
| 429 | "Return the visible text between BEG and END. | ||
| 430 | Strip the string properties because it makes failed test results | ||
| 431 | easier to read." | ||
| 432 | (substring-no-properties (filter-buffer-substring beg end))) | ||
| 433 | |||
| 434 | (provide 'backtrace-tests) | ||
| 435 | |||
| 436 | ;;; backtrace-tests.el ends here | ||
diff --git a/test/lisp/emacs-lisp/cl-print-tests.el b/test/lisp/emacs-lisp/cl-print-tests.el index 404d323d0c1..a469b5526c0 100644 --- a/test/lisp/emacs-lisp/cl-print-tests.el +++ b/test/lisp/emacs-lisp/cl-print-tests.el | |||
| @@ -56,19 +56,30 @@ | |||
| 56 | (let ((long-list (make-list 5 'a)) | 56 | (let ((long-list (make-list 5 'a)) |
| 57 | (long-vec (make-vector 5 'b)) | 57 | (long-vec (make-vector 5 'b)) |
| 58 | (long-struct (cl-print-tests-con)) | 58 | (long-struct (cl-print-tests-con)) |
| 59 | (long-string (make-string 5 ?a)) | ||
| 59 | (print-length 4)) | 60 | (print-length 4)) |
| 60 | (should (equal "(a a a a ...)" (cl-prin1-to-string long-list))) | 61 | (should (equal "(a a a a ...)" (cl-prin1-to-string long-list))) |
| 61 | (should (equal "[b b b b ...]" (cl-prin1-to-string long-vec))) | 62 | (should (equal "[b b b b ...]" (cl-prin1-to-string long-vec))) |
| 62 | (should (equal "#s(cl-print-tests-struct :a nil :b nil :c nil :d nil ...)" | 63 | (should (equal "#s(cl-print-tests-struct :a nil :b nil :c nil :d nil ...)" |
| 63 | (cl-prin1-to-string long-struct))))) | 64 | (cl-prin1-to-string long-struct))) |
| 65 | (should (equal "\"aaaa...\"" (cl-prin1-to-string long-string))))) | ||
| 64 | 66 | ||
| 65 | (ert-deftest cl-print-tests-4 () | 67 | (ert-deftest cl-print-tests-4 () |
| 66 | "CL printing observes `print-level'." | 68 | "CL printing observes `print-level'." |
| 67 | (let ((deep-list '(a (b (c (d (e)))))) | 69 | (let* ((deep-list '(a (b (c (d (e)))))) |
| 68 | (deep-struct (cl-print-tests-con)) | 70 | (buried-vector '(a (b (c (d [e]))))) |
| 69 | (print-level 4)) | 71 | (deep-struct (cl-print-tests-con)) |
| 72 | (buried-struct `(a (b (c (d ,deep-struct))))) | ||
| 73 | (buried-string '(a (b (c (d #("hello" 0 5 (cl-print-test t))))))) | ||
| 74 | (buried-simple-string '(a (b (c (d "hello"))))) | ||
| 75 | (print-level 4)) | ||
| 70 | (setf (cl-print-tests-struct-a deep-struct) deep-list) | 76 | (setf (cl-print-tests-struct-a deep-struct) deep-list) |
| 71 | (should (equal "(a (b (c (d ...))))" (cl-prin1-to-string deep-list))) | 77 | (should (equal "(a (b (c (d ...))))" (cl-prin1-to-string deep-list))) |
| 78 | (should (equal "(a (b (c (d ...))))" (cl-prin1-to-string buried-vector))) | ||
| 79 | (should (equal "(a (b (c (d ...))))" (cl-prin1-to-string buried-struct))) | ||
| 80 | (should (equal "(a (b (c (d ...))))" (cl-prin1-to-string buried-string))) | ||
| 81 | (should (equal "(a (b (c (d \"hello\"))))" | ||
| 82 | (cl-prin1-to-string buried-simple-string))) | ||
| 72 | (should (equal "#s(cl-print-tests-struct :a (a (b (c ...))) :b nil :c nil :d nil :e nil)" | 83 | (should (equal "#s(cl-print-tests-struct :a (a (b (c ...))) :b nil :c nil :d nil :e nil)" |
| 73 | (cl-prin1-to-string deep-struct))))) | 84 | (cl-prin1-to-string deep-struct))))) |
| 74 | 85 | ||
| @@ -82,6 +93,129 @@ | |||
| 82 | (should (equal "((quote a) (function b) (\\` ((\\, c) (\\,@ d))))" | 93 | (should (equal "((quote a) (function b) (\\` ((\\, c) (\\,@ d))))" |
| 83 | (cl-prin1-to-string quoted-stuff)))))) | 94 | (cl-prin1-to-string quoted-stuff)))))) |
| 84 | 95 | ||
| 96 | (ert-deftest cl-print-tests-strings () | ||
| 97 | "CL printing prints strings and propertized strings." | ||
| 98 | (let* ((str1 "abcdefghij") | ||
| 99 | (str2 #("abcdefghij" 3 6 (bold t) 7 9 (italic t))) | ||
| 100 | (str3 #("abcdefghij" 0 10 (test t))) | ||
| 101 | (obj '(a b)) | ||
| 102 | ;; Since the byte compiler reuses string literals, | ||
| 103 | ;; and the put-text-property call is destructive, use | ||
| 104 | ;; copy-sequence to make a new string. | ||
| 105 | (str4 (copy-sequence "abcdefghij"))) | ||
| 106 | (put-text-property 0 5 'test obj str4) | ||
| 107 | (put-text-property 7 10 'test obj str4) | ||
| 108 | |||
| 109 | (should (equal "\"abcdefghij\"" (cl-prin1-to-string str1))) | ||
| 110 | (should (equal "#(\"abcdefghij\" 3 6 (bold t) 7 9 (italic t))" | ||
| 111 | (cl-prin1-to-string str2))) | ||
| 112 | (should (equal "#(\"abcdefghij\" 0 10 (test t))" | ||
| 113 | (cl-prin1-to-string str3))) | ||
| 114 | (let ((print-circle nil)) | ||
| 115 | (should | ||
| 116 | (equal | ||
| 117 | "#(\"abcdefghij\" 0 5 (test (a b)) 7 10 (test (a b)))" | ||
| 118 | (cl-prin1-to-string str4)))) | ||
| 119 | (let ((print-circle t)) | ||
| 120 | (should | ||
| 121 | (equal | ||
| 122 | "#(\"abcdefghij\" 0 5 (test #1=(a b)) 7 10 (test #1#))" | ||
| 123 | (cl-prin1-to-string str4)))))) | ||
| 124 | |||
| 125 | (ert-deftest cl-print-tests-ellipsis-cons () | ||
| 126 | "Ellipsis expansion works in conses." | ||
| 127 | (let ((print-length 4) | ||
| 128 | (print-level 3)) | ||
| 129 | (cl-print-tests-check-ellipsis-expansion | ||
| 130 | '(0 1 2 3 4 5) "(0 1 2 3 ...)" "4 5") | ||
| 131 | (cl-print-tests-check-ellipsis-expansion | ||
| 132 | '(0 1 2 3 4 5 6 7 8 9) "(0 1 2 3 ...)" "4 5 6 7 ...") | ||
| 133 | (cl-print-tests-check-ellipsis-expansion | ||
| 134 | '(a (b (c (d (e))))) "(a (b (c ...)))" "(d (e))") | ||
| 135 | (cl-print-tests-check-ellipsis-expansion | ||
| 136 | (let ((x (make-list 6 'b))) | ||
| 137 | (setf (nthcdr 6 x) 'c) | ||
| 138 | x) | ||
| 139 | "(b b b b ...)" "b b . c"))) | ||
| 140 | |||
| 141 | (ert-deftest cl-print-tests-ellipsis-vector () | ||
| 142 | "Ellipsis expansion works in vectors." | ||
| 143 | (let ((print-length 4) | ||
| 144 | (print-level 3)) | ||
| 145 | (cl-print-tests-check-ellipsis-expansion | ||
| 146 | [0 1 2 3 4 5] "[0 1 2 3 ...]" "4 5") | ||
| 147 | (cl-print-tests-check-ellipsis-expansion | ||
| 148 | [0 1 2 3 4 5 6 7 8 9] "[0 1 2 3 ...]" "4 5 6 7 ...") | ||
| 149 | (cl-print-tests-check-ellipsis-expansion | ||
| 150 | [a [b [c [d [e]]]]] "[a [b [c ...]]]" "[d [e]]"))) | ||
| 151 | |||
| 152 | (ert-deftest cl-print-tests-ellipsis-string () | ||
| 153 | "Ellipsis expansion works in strings." | ||
| 154 | (let ((print-length 4) | ||
| 155 | (print-level 3)) | ||
| 156 | (cl-print-tests-check-ellipsis-expansion | ||
| 157 | "abcdefg" "\"abcd...\"" "efg") | ||
| 158 | (cl-print-tests-check-ellipsis-expansion | ||
| 159 | "abcdefghijk" "\"abcd...\"" "efgh...") | ||
| 160 | (cl-print-tests-check-ellipsis-expansion | ||
| 161 | '(1 (2 (3 #("abcde" 0 5 (test t))))) | ||
| 162 | "(1 (2 (3 ...)))" "#(\"abcd...\" 0 5 (test t))") | ||
| 163 | (cl-print-tests-check-ellipsis-expansion | ||
| 164 | #("abcd" 0 1 (bold t) 1 2 (invisible t) 3 4 (italic t)) | ||
| 165 | "#(\"abcd\" 0 1 (bold t) ...)" "1 2 (invisible t) ..."))) | ||
| 166 | |||
| 167 | (ert-deftest cl-print-tests-ellipsis-struct () | ||
| 168 | "Ellipsis expansion works in structures." | ||
| 169 | (let ((print-length 4) | ||
| 170 | (print-level 3) | ||
| 171 | (struct (cl-print-tests-con))) | ||
| 172 | (cl-print-tests-check-ellipsis-expansion | ||
| 173 | struct "#s(cl-print-tests-struct :a nil :b nil :c nil :d nil ...)" ":e nil") | ||
| 174 | (let ((print-length 2)) | ||
| 175 | (cl-print-tests-check-ellipsis-expansion | ||
| 176 | struct "#s(cl-print-tests-struct :a nil :b nil ...)" ":c nil :d nil ...")) | ||
| 177 | (cl-print-tests-check-ellipsis-expansion | ||
| 178 | `(a (b (c ,struct))) | ||
| 179 | "(a (b (c ...)))" | ||
| 180 | "#s(cl-print-tests-struct :a nil :b nil :c nil :d nil ...)"))) | ||
| 181 | |||
| 182 | (ert-deftest cl-print-tests-ellipsis-circular () | ||
| 183 | "Ellipsis expansion works with circular objects." | ||
| 184 | (let ((wide-obj (list 0 1 2 3 4)) | ||
| 185 | (deep-obj `(0 (1 (2 (3 (4)))))) | ||
| 186 | (print-length 4) | ||
| 187 | (print-level 3)) | ||
| 188 | (setf (nth 4 wide-obj) wide-obj) | ||
| 189 | (setf (car (cadadr (cadadr deep-obj))) deep-obj) | ||
| 190 | (let ((print-circle nil)) | ||
| 191 | (cl-print-tests-check-ellipsis-expansion-rx | ||
| 192 | wide-obj (regexp-quote "(0 1 2 3 ...)") "\\`#[0-9]\\'") | ||
| 193 | (cl-print-tests-check-ellipsis-expansion-rx | ||
| 194 | deep-obj (regexp-quote "(0 (1 (2 ...)))") "\\`(3 (#[0-9]))\\'")) | ||
| 195 | (let ((print-circle t)) | ||
| 196 | (cl-print-tests-check-ellipsis-expansion | ||
| 197 | wide-obj "#1=(0 1 2 3 ...)" "#1#") | ||
| 198 | (cl-print-tests-check-ellipsis-expansion | ||
| 199 | deep-obj "#1=(0 (1 (2 ...)))" "(3 (#1#))")))) | ||
| 200 | |||
| 201 | (defun cl-print-tests-check-ellipsis-expansion (obj expected expanded) | ||
| 202 | (let* ((result (cl-prin1-to-string obj)) | ||
| 203 | (pos (next-single-property-change 0 'cl-print-ellipsis result)) | ||
| 204 | value) | ||
| 205 | (should pos) | ||
| 206 | (setq value (get-text-property pos 'cl-print-ellipsis result)) | ||
| 207 | (should (equal expected result)) | ||
| 208 | (should (equal expanded (with-output-to-string (cl-print-expand-ellipsis | ||
| 209 | value nil)))))) | ||
| 210 | |||
| 211 | (defun cl-print-tests-check-ellipsis-expansion-rx (obj expected expanded) | ||
| 212 | (let* ((result (cl-prin1-to-string obj)) | ||
| 213 | (pos (next-single-property-change 0 'cl-print-ellipsis result)) | ||
| 214 | (value (get-text-property pos 'cl-print-ellipsis result))) | ||
| 215 | (should (string-match expected result)) | ||
| 216 | (should (string-match expanded (with-output-to-string | ||
| 217 | (cl-print-expand-ellipsis value nil)))))) | ||
| 218 | |||
| 85 | (ert-deftest cl-print-circle () | 219 | (ert-deftest cl-print-circle () |
| 86 | (let ((x '(#1=(a . #1#) #1#))) | 220 | (let ((x '(#1=(a . #1#) #1#))) |
| 87 | (let ((print-circle nil)) | 221 | (let ((print-circle nil)) |
| @@ -99,5 +233,41 @@ | |||
| 99 | (let ((print-circle t)) | 233 | (let ((print-circle t)) |
| 100 | (should (equal "(0 . #1=(0 . #1#))" (cl-prin1-to-string x)))))) | 234 | (should (equal "(0 . #1=(0 . #1#))" (cl-prin1-to-string x)))))) |
| 101 | 235 | ||
| 236 | (ert-deftest cl-print-tests-print-to-string-with-limit () | ||
| 237 | (let* ((thing10 (make-list 10 'a)) | ||
| 238 | (thing100 (make-list 100 'a)) | ||
| 239 | (thing10x10 (make-list 10 thing10)) | ||
| 240 | (nested-thing (let ((val 'a)) | ||
| 241 | (dotimes (_i 20) | ||
| 242 | (setq val (list val))) | ||
| 243 | val)) | ||
| 244 | ;; Make a consistent environment for this test. | ||
| 245 | (print-circle nil) | ||
| 246 | (print-level nil) | ||
| 247 | (print-length nil)) | ||
| 248 | |||
| 249 | ;; Print something that fits in the space given. | ||
| 250 | (should (string= (cl-prin1-to-string thing10) | ||
| 251 | (cl-print-to-string-with-limit #'cl-prin1 thing10 100))) | ||
| 252 | |||
| 253 | ;; Print something which needs to be abbreviated and which can be. | ||
| 254 | (should (< (length (cl-print-to-string-with-limit #'cl-prin1 thing100 100)) | ||
| 255 | 100 | ||
| 256 | (length (cl-prin1-to-string thing100)))) | ||
| 257 | |||
| 258 | ;; Print something resistant to easy abbreviation. | ||
| 259 | (should (string= (cl-prin1-to-string thing10x10) | ||
| 260 | (cl-print-to-string-with-limit #'cl-prin1 thing10x10 100))) | ||
| 261 | |||
| 262 | ;; Print something which should be abbreviated even if the limit is large. | ||
| 263 | (should (< (length (cl-print-to-string-with-limit #'cl-prin1 nested-thing 1000)) | ||
| 264 | (length (cl-prin1-to-string nested-thing)))) | ||
| 265 | |||
| 266 | ;; Print with no limits. | ||
| 267 | (dolist (thing (list thing10 thing100 thing10x10 nested-thing)) | ||
| 268 | (let ((rep (cl-prin1-to-string thing))) | ||
| 269 | (should (string= rep (cl-print-to-string-with-limit #'cl-prin1 thing 0))) | ||
| 270 | (should (string= rep (cl-print-to-string-with-limit #'cl-prin1 thing nil))))))) | ||
| 271 | |||
| 102 | 272 | ||
| 103 | ;;; cl-print-tests.el ends here. | 273 | ;;; cl-print-tests.el ends here. |
diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index f3fc78d4e12..97dead057a9 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | (defun edebug-test-code-range (num) | 41 | (defun edebug-test-code-range (num) |
| 42 | !start!(let ((index 0) | 42 | !start!(let ((index 0) |
| 43 | (result nil)) | 43 | (result nil)) |
| 44 | (while (< index num)!test! | 44 | (while !lt!(< index num)!test! |
| 45 | (push index result)!loop! | 45 | (push index result)!loop! |
| 46 | (cl-incf index))!end-loop! | 46 | (cl-incf index))!end-loop! |
| 47 | (nreverse result))) | 47 | (nreverse result))) |
diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index 7d780edf285..7880aaf95bc 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el | |||
| @@ -432,9 +432,11 @@ test and possibly others should be updated." | |||
| 432 | (verify-keybinding "P" 'edebug-view-outside) ;; same as v | 432 | (verify-keybinding "P" 'edebug-view-outside) ;; same as v |
| 433 | (verify-keybinding "W" 'edebug-toggle-save-windows) | 433 | (verify-keybinding "W" 'edebug-toggle-save-windows) |
| 434 | (verify-keybinding "?" 'edebug-help) | 434 | (verify-keybinding "?" 'edebug-help) |
| 435 | (verify-keybinding "d" 'edebug-backtrace) | 435 | (verify-keybinding "d" 'edebug-pop-to-backtrace) |
| 436 | (verify-keybinding "-" 'negative-argument) | 436 | (verify-keybinding "-" 'negative-argument) |
| 437 | (verify-keybinding "=" 'edebug-temp-display-freq-count))) | 437 | (verify-keybinding "=" 'edebug-temp-display-freq-count) |
| 438 | (should (eq (lookup-key backtrace-mode-map "n") 'backtrace-forward-frame)) | ||
| 439 | (should (eq (lookup-key backtrace-mode-map "s") 'backtrace-goto-source)))) | ||
| 438 | 440 | ||
| 439 | (ert-deftest edebug-tests-stop-point-at-start-of-first-instrumented-function () | 441 | (ert-deftest edebug-tests-stop-point-at-start-of-first-instrumented-function () |
| 440 | "Edebug stops at the beginning of an instrumented function." | 442 | "Edebug stops at the beginning of an instrumented function." |
| @@ -924,5 +926,17 @@ test and possibly others should be updated." | |||
| 924 | "g" | 926 | "g" |
| 925 | (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11"))))) | 927 | (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11"))))) |
| 926 | 928 | ||
| 929 | (ert-deftest edebug-tests-backtrace-goto-source () | ||
| 930 | "Edebug can jump to instrumented source from its *Edebug-Backtrace* buffer." | ||
| 931 | (edebug-tests-with-normal-env | ||
| 932 | (edebug-tests-setup-@ "range" '(2) t) | ||
| 933 | (edebug-tests-run-kbd-macro | ||
| 934 | "@ SPC SPC" | ||
| 935 | (edebug-tests-should-be-at "range" "lt") | ||
| 936 | "dns" ; Pop to backtrace, next frame, goto source. | ||
| 937 | (edebug-tests-should-be-at "range" "start") | ||
| 938 | "g" | ||
| 939 | (should (equal edebug-tests-@-result '(0 1)))))) | ||
| 940 | |||
| 927 | (provide 'edebug-tests) | 941 | (provide 'edebug-tests) |
| 928 | ;;; edebug-tests.el ends here | 942 | ;;; edebug-tests.el ends here |
diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el index cb957bd9fd6..1fe5b79ef36 100644 --- a/test/lisp/emacs-lisp/ert-tests.el +++ b/test/lisp/emacs-lisp/ert-tests.el | |||
| @@ -376,7 +376,7 @@ This macro is used to test if macroexpansion in `should' works." | |||
| 376 | (test (make-ert-test :body test-body)) | 376 | (test (make-ert-test :body test-body)) |
| 377 | (result (ert-run-test test))) | 377 | (result (ert-run-test test))) |
| 378 | (should (ert-test-failed-p result)) | 378 | (should (ert-test-failed-p result)) |
| 379 | (should (eq (nth 1 (car (ert-test-failed-backtrace result))) | 379 | (should (eq (backtrace-frame-fun (car (ert-test-failed-backtrace result))) |
| 380 | 'signal)))) | 380 | 'signal)))) |
| 381 | 381 | ||
| 382 | (ert-deftest ert-test-messages () | 382 | (ert-deftest ert-test-messages () |