aboutsummaryrefslogtreecommitdiffstats
path: root/test/src/syntax-tests.el
diff options
context:
space:
mode:
Diffstat (limited to 'test/src/syntax-tests.el')
-rw-r--r--test/src/syntax-tests.el441
1 files changed, 440 insertions, 1 deletions
diff --git a/test/src/syntax-tests.el b/test/src/syntax-tests.el
index 67e7ec32517..751a900a23e 100644
--- a/test/src/syntax-tests.el
+++ b/test/src/syntax-tests.el
@@ -1,6 +1,6 @@
1;;; syntax-tests.el --- tests for syntax.c functions -*- lexical-binding: t -*- 1;;; syntax-tests.el --- tests for syntax.c functions -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 2017 Free Software Foundation, Inc. 3;; Copyright (C) 2017-2022 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -20,6 +20,8 @@
20;;; Code: 20;;; Code:
21 21
22(require 'ert) 22(require 'ert)
23(require 'ert-x)
24(require 'cl-lib)
23 25
24(ert-deftest parse-partial-sexp-continue-over-comment-marker () 26(ert-deftest parse-partial-sexp-continue-over-comment-marker ()
25 "Continue a parse that stopped in the middle of a comment marker." 27 "Continue a parse that stopped in the middle of a comment marker."
@@ -55,6 +57,16 @@
55 (should (equal (parse-partial-sexp aftC pointX nil nil pps-aftC) 57 (should (equal (parse-partial-sexp aftC pointX nil nil pps-aftC)
56 ppsX))))) 58 ppsX)))))
57 59
60(ert-deftest syntax-class-character-test ()
61 (cl-loop for char across " .w_()'\"$\\/<>@!|"
62 for i from 0
63 do (should (= char (syntax-class-to-char i)))
64 when (string-to-syntax (string char))
65 do (should (= char (syntax-class-to-char
66 (car (string-to-syntax (string char)))))))
67 (should-error (syntax-class-to-char -1))
68 (should-error (syntax-class-to-char 200)))
69
58(ert-deftest parse-partial-sexp-paren-comments () 70(ert-deftest parse-partial-sexp-paren-comments ()
59 "Test syntax parsing with paren comment markers. 71 "Test syntax parsing with paren comment markers.
60Specifically, where the first character of the comment marker is 72Specifically, where the first character of the comment marker is
@@ -82,4 +94,431 @@ also has open paren syntax (see Bug#24870)."
82 (should (equal (parse-partial-sexp pointC pointX nil nil ppsC) 94 (should (equal (parse-partial-sexp pointC pointX nil nil ppsC)
83 ppsX))))) 95 ppsX)))))
84 96
97
98;;; Commentary:
99;; The next bit tests the handling of comments in syntax.c, in
100;; particular the functions `forward-comment' and `scan-lists' and
101;; `parse-partial-sexp' (in so far as they relate to comments).
102
103;; It is intended to enhance this bit to test nested comments
104;; (2020-10-01).
105
106;; This bit uses the data file syntax-resources/syntax-comments.txt.
107
108(defun syntax-comments-point (n forw)
109 "Return the buffer offset corresponding to the \"label\" N.
110N is a decimal number which appears in the data file, usually
111twice, as \"labels\". It can also be a negative number or zero.
112FORW is t when we're using the label at BOL, nil for the one at EOL.
113
114If the label N doesn't exist in the current buffer, an exception
115is thrown.
116
117When FORW is t and N positive, we return the position after the
118first occurrence of label N at BOL in the data file. With FORW
119nil, we return the position before the last occurrence of the
120label at EOL in the data file.
121
122When N is negative, we return instead the position of the end of
123line that the -N label is on. When it is zero, we return POINT."
124 (if (zerop n)
125 (point)
126 (let ((str (format "%d" (abs n))))
127 (save-excursion
128 (if forw
129 (progn
130 (goto-char (point-min))
131 (re-search-forward
132 (concat "^\\(" str "\\)\\([^0-9\n]\\|$\\)"))
133 (if (< n 0)
134 (progn (end-of-line) (point))
135 (match-end 1)))
136 (goto-char (point-max))
137 (re-search-backward
138 (concat "\\(^\\|[^0-9]\\)\\(" str "\\)$"))
139 (if (< n 0)
140 (progn (end-of-line) (point))
141 (match-beginning 2)))))))
142
143(defun syntax-comments-midpoint (n)
144 "Return the buffer offset corresponding to the \"label\" N.
145N is a positive decimal number which should appear in the buffer
146exactly once. The label need not be at the beginning or end of a
147line.
148
149The return value is the position just before the label.
150
151If the label N doesn't exist in the current buffer, an exception
152is thrown."
153 (let ((str (format "%d" n)))
154 (save-excursion
155 (goto-char (point-min))
156 (re-search-forward
157 (concat "\\(^\\|[^0-9]\\)\\(" str "\\)\\([^0-9\n]\\|$\\)"))
158 (match-beginning 2))))
159
160(eval-and-compile
161 (defvar syntax-comments-section))
162
163(defmacro syntax-comments (-type- -dir- res start &optional stop)
164 "Create an ERT test to test (forward-comment 1/-1).
165The test uses a fixed name data file, which it visits. It calls
166entry and exit functions to set up and tear down syntax entries
167for comment characters. The test is given a name based on the
168global variable `syntax-comments-section', the direction of
169movement and the value of START.
170
171-TYPE- (unquoted) is a symbol from whose name the entry and exit
172function names are derived by appending \"-in\" and \"-out\".
173
174-DIR- (unquoted) is `forward' or `backward', the direction
175`forward-comment' is attempted.
176
177RES, t or nil, is the expected result from `forward-comment'.
178
179START and STOP are decimal numbers corresponding to labels in the
180data file marking the start and expected stop positions. See
181`syntax-comments-point' for a precise specification. If STOP is
182missing or nil, the value of START is assumed for it."
183 (declare (debug t))
184 (let ((forw
185 (cond
186 ((eq -dir- 'forward) t)
187 ((eq -dir- 'backward) nil)
188 (t (error "Invalid -dir- argument \"%s\" to `syntax-comments'" -dir-))))
189 (start-str (format "%d" (abs start)))
190 (type -type-))
191 `(ert-deftest ,(intern (concat "syntax-comments-"
192 syntax-comments-section
193 (if forw "-f" "-b") start-str))
194 ()
195 (with-current-buffer
196 (find-file
197 ,(ert-resource-file "syntax-comments.txt"))
198 (,(intern (concat (symbol-name type) "-in")))
199 (goto-char (syntax-comments-point ,start ,forw))
200 (let ((stop (syntax-comments-point ,(or stop start) ,(not forw))))
201 (should (eq (forward-comment ,(if forw 1 -1)) ,res))
202 (should (eq (point) stop)))
203 (,(intern (concat (symbol-name type) "-out")))))))
204
205(defmacro syntax-br-comments (-type- -dir- res -start- &optional stop)
206 "Create an ERT test to test (scan-lists <position> 1/-1 0).
207This is to test the interface between scan-lists and the internal
208comment routines in syntax.c.
209
210The test uses a fixed name data file, which it visits. It calls
211entry and exit functions to set up and tear down syntax entries
212for comment and paren characters. The test is given a name based
213on the global variable `syntax-comments-section', the direction
214of movement and the value of -START-.
215
216-TYPE- (unquoted) is a symbol from whose name the entry and exit
217function names are derived by appending \"-in\" and \"-out\".
218
219-DIR- (unquoted) is `forward' or `backward', the direction
220`scan-lists' is attempted.
221
222RES is t if `scan-lists' is expected to return, nil if it is
223expected to raise a `scan-error' exception.
224
225-START- and STOP are decimal numbers corresponding to labels in the
226data file marking the start and expected stop positions. See
227`syntax-comments-point' for a precise specification. If STOP is
228missing or nil, the value of -START- is assumed for it."
229 (declare (debug t))
230 (let* ((forw
231 (cond
232 ((eq -dir- 'forward) t)
233 ((eq -dir- 'backward) nil)
234 (t (error "Invalid -dir- argument \"%s\" to `syntax-br-comments'" -dir-))))
235 (start -start-)
236 (start-str (format "%d" (abs start)))
237 (type -type-))
238 `(ert-deftest ,(intern (concat "syntax-br-comments-"
239 syntax-comments-section
240 (if forw "-f" "-b") start-str))
241 ()
242 (with-current-buffer
243 (find-file
244 ,(ert-resource-file "syntax-comments.txt"))
245 (,(intern (concat (symbol-name type) "-in")))
246 (let ((start-pos (syntax-comments-point ,start ,forw))
247 ,@(if res
248 `((stop-pos (syntax-comments-point
249 ,(or stop start) ,(not forw))))))
250 ,(if res
251 `(should
252 (eq (scan-lists start-pos ,(if forw 1 -1) 0)
253 stop-pos))
254 `(should-error (scan-lists start-pos ,(if forw 1 -1) 0)
255 :type 'scan-error)))
256 (,(intern (concat (symbol-name type) "-out")))))))
257
258(defmacro syntax-pps-comments (-type- -start- open close &optional -stop-)
259 "Create an ERT test to test `parse-partial-sexp' with comments.
260This is to test the interface between `parse-partial-sexp' and
261the internal comment routines in syntax.c.
262
263The test uses a fixed name data file, which it visits. It calls
264entry and exit functions to set up and tear down syntax entries
265for comment and paren characters. The test is given a name based
266on the global variable `syntax-comments-section', and the value
267of -START-.
268
269The generated test calls `parse-partial-sexp' three times, the
270first two with COMMENTSTOP set to `syntax-table' so as to stop
271after the start and end of the comment. The third call is
272expected to stop at the brace/paren matching the one where the
273test started.
274
275-TYPE- (unquoted) is a symbol from whose name the entry and exit
276function names are derived by appending \"-in\" and \"-out\".
277
278-START- and -STOP- are decimal numbers corresponding to labels in
279the data file marking the start and expected stop positions. See
280`syntax-comments-point' for a precise specification. If -STOP-
281is missing or nil, the value of -START- is assumed for it.
282
283OPEN and CLOSE are decimal numbers corresponding to labels in the
284data file marking just after the comment opener and closer where
285the `parse-partial-sexp's are expected to stop. See
286`syntax-comments-midpoint' for a precise specification."
287 (declare (debug t))
288 (let* ((type -type-)
289 (start -start-)
290 (start-str (format "%d" start))
291 (stop (or -stop- start)))
292 `(ert-deftest ,(intern (concat "syntax-pps-comments-"
293 syntax-comments-section
294 "-" start-str))
295 ()
296 (with-current-buffer
297 (find-file
298 ,(ert-resource-file "syntax-comments.txt"))
299 (,(intern (concat (symbol-name type) "-in")))
300 (let ((start-pos (syntax-comments-point ,start t))
301 (open-pos (syntax-comments-midpoint ,open))
302 (close-pos (syntax-comments-midpoint ,close))
303 (stop-pos (syntax-comments-point ,stop nil))
304 s)
305 (setq s (parse-partial-sexp
306 start-pos (point-max) 0 nil nil 'syntax-table))
307 (should (eq (point) open-pos))
308 (setq s (parse-partial-sexp
309 (point) (point-max) 0 nil s 'syntax-table))
310 (should (eq (point) close-pos))
311 (setq s (parse-partial-sexp (point) (point-max) 0 nil s))
312 (should (eq (point) stop-pos)))
313 (,(intern (concat (symbol-name type) "-out")))))))
314
315;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
316;; "Pascal" style comments - single character delimiters, the closing
317;; delimiter not being newline.
318;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319(defun {-in ()
320 (setq parse-sexp-ignore-comments t)
321 (setq comment-end-can-be-escaped nil)
322 (modify-syntax-entry ?{ "<")
323 (modify-syntax-entry ?} ">"))
324(defun {-out ()
325 (modify-syntax-entry ?{ "(}")
326 (modify-syntax-entry ?} "){"))
327(eval-and-compile
328 (setq syntax-comments-section "pascal"))
329
330(syntax-comments { forward nil 20 0)
331(syntax-comments { backward nil 20 0)
332(syntax-comments { forward t 21)
333(syntax-comments { backward t 21)
334(syntax-comments { forward t 22)
335(syntax-comments { backward t 22)
336
337(syntax-comments { forward t 23)
338(syntax-comments { backward t 23)
339(syntax-comments { forward t 24)
340(syntax-comments { backward t 24)
341(syntax-comments { forward t 26)
342(syntax-comments { backward t 26)
343
344;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
345;; "Lisp" style comments - single character opening delimiters on line
346;; comments.
347;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
348(defun \;-in ()
349 (setq parse-sexp-ignore-comments t)
350 (setq comment-end-can-be-escaped nil)
351 (modify-syntax-entry ?\n ">")
352 (modify-syntax-entry ?\; "<")
353 (modify-syntax-entry ?{ ".")
354 (modify-syntax-entry ?} "."))
355(defun \;-out ()
356 (modify-syntax-entry ?\n " ")
357 (modify-syntax-entry ?\; ".")
358 (modify-syntax-entry ?{ "(}")
359 (modify-syntax-entry ?} "){"))
360(eval-and-compile
361 (setq syntax-comments-section "lisp"))
362
363(syntax-comments \; backward nil 30 30)
364(syntax-comments \; forward t 31)
365(syntax-comments \; backward t 31)
366(syntax-comments \; forward t 32)
367(syntax-comments \; backward t 32)
368(syntax-comments \; forward t 33)
369(syntax-comments \; backward t 33)
370
371;; "Lisp" style comments inside lists.
372(syntax-br-comments \; backward nil 40)
373(syntax-br-comments \; forward t 41)
374(syntax-br-comments \; backward t 41)
375(syntax-br-comments \; forward t 42)
376(syntax-br-comments \; backward t 42)
377(syntax-br-comments \; forward nil 43)
378
379;; "Lisp" style comments parsed by `parse-partial-sexp'.
380(syntax-pps-comments \; 41 90 91)
381(syntax-pps-comments \; 42 92 93)
382(syntax-pps-comments \; 43 94 95 -999)
383
384;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
385;; "Lisp" style nested comments: between delimiters #| |#.
386;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
387(defun \#|-in ()
388 (setq parse-sexp-ignore-comments t)
389 (modify-syntax-entry ?# ". 14")
390 (modify-syntax-entry ?| ". 23n")
391 (modify-syntax-entry ?\; "< b")
392 (modify-syntax-entry ?\n "> b"))
393(defun \#|-out ()
394 (modify-syntax-entry ?# ".")
395 (modify-syntax-entry ?| ".")
396 (modify-syntax-entry ?\; ".")
397 (modify-syntax-entry ?\n " "))
398(eval-and-compile
399 (setq syntax-comments-section "lisp-n"))
400
401(syntax-comments \#| forward nil 100 0)
402(syntax-comments \#| backward nil 100 0)
403(syntax-comments \#| forward nil 101 -999)
404(syntax-comments \#| forward t 102)
405(syntax-comments \#| backward t 102)
406
407(syntax-comments \#| forward t 103)
408(syntax-comments \#| backward t 103)
409(syntax-comments \#| forward t 104)
410(syntax-comments \#| backward t 104)
411
412(syntax-comments \#| forward nil 105 -999)
413(syntax-comments \#| backward t 105)
414(syntax-comments \#| forward t 106)
415(syntax-comments \#| backward t 106)
416(syntax-comments \#| forward t 107)
417(syntax-comments \#| backward t 107)
418
419;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
420;; Mixed "Lisp" style (nested and unnested) comments.
421;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
422(syntax-comments \#| forward t 110)
423(syntax-comments \#| backward t 110)
424(syntax-comments \#| forward t 111)
425(syntax-comments \#| backward t 111)
426
427;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
428;; Emacs 27 "C" style comments - `comment-end-can-be-escaped' is non-nil.
429;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
430(defun /*-in ()
431 (setq parse-sexp-ignore-comments t)
432 (setq comment-end-can-be-escaped t)
433 (modify-syntax-entry ?/ ". 124b")
434 (modify-syntax-entry ?* ". 23")
435 (modify-syntax-entry ?\n "> b"))
436(defun /*-out ()
437 (setq comment-end-can-be-escaped nil)
438 (modify-syntax-entry ?/ ".")
439 (modify-syntax-entry ?* ".")
440 (modify-syntax-entry ?\n " "))
441(eval-and-compile
442 (setq syntax-comments-section "c"))
443
444(syntax-comments /* forward t 1)
445(syntax-comments /* backward t 1)
446(syntax-comments /* forward t 2)
447(syntax-comments /* backward t 2)
448(syntax-comments /* forward t 3)
449(syntax-comments /* backward t 3)
450
451(syntax-comments /* forward t 4)
452(syntax-comments /* backward t 4)
453(syntax-comments /* forward t 5 6)
454(syntax-comments /* backward nil 5 0)
455(syntax-comments /* forward nil 6 0)
456(syntax-comments /* backward t 6 5)
457
458(syntax-comments /* forward t 7 8)
459(syntax-comments /* backward nil 7 0)
460(syntax-comments /* forward nil 8 0)
461(syntax-comments /* backward t 8 7)
462(syntax-comments /* forward t 9)
463(syntax-comments /* backward t 9)
464
465(syntax-comments /* forward nil 10 0)
466(syntax-comments /* backward nil 10 0)
467(syntax-comments /* forward t 11)
468(syntax-comments /* backward t 11)
469
470(syntax-comments /* forward t 13 14)
471(syntax-comments /* backward nil 13 -14)
472(syntax-comments /* forward t 15)
473(syntax-comments /* backward t 15)
474
475;; Emacs 27 "C" style comments inside brace lists.
476(syntax-br-comments /* forward t 50)
477(syntax-br-comments /* backward t 50)
478(syntax-br-comments /* forward t 51)
479(syntax-br-comments /* backward t 51)
480(syntax-br-comments /* forward t 52)
481(syntax-br-comments /* backward t 52)
482
483(syntax-br-comments /* forward t 53)
484(syntax-br-comments /* backward t 53)
485(syntax-br-comments /* forward t 54 20)
486(syntax-br-comments /* backward t 54)
487(syntax-br-comments /* forward t 55)
488(syntax-br-comments /* backward t 55)
489
490(syntax-br-comments /* forward t 56 58)
491(syntax-br-comments /* backward t 58 56)
492(syntax-br-comments /* backward nil 59)
493(syntax-br-comments /* forward t 60)
494(syntax-br-comments /* backward t 60)
495
496;; Emacs 27 "C" style comments parsed by `parse-partial-sexp'.
497(syntax-pps-comments /* 50 70 71)
498(syntax-pps-comments /* 52 72 73)
499(syntax-pps-comments /* 54 74 55 20)
500(syntax-pps-comments /* 56 76 77 58)
501(syntax-pps-comments /* 60 78 79)
502
503(ert-deftest test-from-to-parse-partial-sexp ()
504 (with-temp-buffer
505 (insert "foo")
506 (should (parse-partial-sexp 1 1))
507 (should-error (parse-partial-sexp 2 1))))
508
509(ert-deftest syntax-char-syntax ()
510 ;; Verify that char-syntax behaves identically in interpreted and
511 ;; byte-compiled code (bug#53260).
512 (let ((cs (byte-compile (lambda (x) (char-syntax x)))))
513 ;; Use a unibyte buffer with a syntax table using symbol syntax
514 ;; for raw byte 128.
515 (with-temp-buffer
516 (set-buffer-multibyte nil)
517 (let ((st (make-syntax-table)))
518 (modify-syntax-entry (unibyte-char-to-multibyte 128) "_" st)
519 (set-syntax-table st)
520 (should (equal (eval '(char-syntax 128) t) ?_))
521 (should (equal (funcall cs 128) ?_))))
522 (list (char-syntax 128) (funcall cs 128))))
523
85;;; syntax-tests.el ends here 524;;; syntax-tests.el ends here