1;;; buffer-tests.el --- tests for buffer.c functions -*- lexical-binding: t -*-
2
3;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software: you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
19
20;;; Code:
21
22(require 'ert)
23(require 'ert-x)
24(require 'cl-lib)
25
26(ert-deftest overlay-modification-hooks-message-other-buf ()
27  "Test for bug#21824.
28After a modification-hook has been run and there is an overlay in
29the *Messages* buffer, the message coalescing [2 times] wrongly
30runs the modification-hook of the overlay in the 1st buffer, but
31with parameters from the *Messages* buffer modification."
32  (let ((buf nil)
33        (msg-ov nil))
34    (with-temp-buffer
35      (insert "123")
36      (overlay-put (make-overlay 1 3)
37                   'modification-hooks
38                   (list (lambda (&rest _)
39                           (setq buf (current-buffer)))))
40      (goto-char 2)
41      (insert "x")
42      (unwind-protect
43          (progn
44            (setq msg-ov (make-overlay 1 1 (get-buffer-create "*Messages*")))
45            (message "a message")
46            (message "a message")
47            (should (eq buf (current-buffer))))
48        (when msg-ov (delete-overlay msg-ov))))))
49
50(ert-deftest overlay-modification-hooks-deleted-overlay ()
51  "Test for bug#30823."
52  (let ((check-point nil)
53	(ov-delete nil)
54	(ov-set nil))
55    (with-temp-buffer
56      (insert "abc")
57      (setq ov-set (make-overlay 1 3))
58      (overlay-put ov-set 'modification-hooks
59		   (list (lambda (_o after &rest _args)
60			   (and after (setq check-point t)))))
61      (setq ov-delete (make-overlay 1 3))
62      (overlay-put ov-delete 'modification-hooks
63		   (list (lambda (o after &rest _args)
64			   (and (not after) (delete-overlay o)))))
65      (goto-char 2)
66      (insert "1")
67      (should (eq check-point t)))))
68
69(ert-deftest test-generate-new-buffer-name-bug27966 ()
70  (should-not (string-equal "nil"
71                            (progn (get-buffer-create "nil")
72                                   (generate-new-buffer-name "nil")))))
73
74(ert-deftest test-buffer-base-buffer-indirect ()
75  (with-temp-buffer
76    (let* ((ind-buf-name (generate-new-buffer-name "indbuf"))
77           (ind-buf (make-indirect-buffer (current-buffer) ind-buf-name)))
78      (should (eq (buffer-base-buffer ind-buf) (current-buffer))))))
79
80(ert-deftest test-buffer-base-buffer-non-indirect ()
81  (with-temp-buffer
82    (should (eq (buffer-base-buffer (current-buffer)) nil))))
83
84(ert-deftest overlay-evaporation-after-killed-buffer ()
85  (let* ((ols (with-temp-buffer
86                (insert "toto")
87                (list
88                 (make-overlay (point-min) (point-max))
89                 (make-overlay (point-min) (point-max))
90                 (make-overlay (point-min) (point-max)))))
91         (ol (nth 1 ols)))
92    (overlay-put ol 'evaporate t)
93    ;; Evaporation within move-overlay of an overlay that was deleted because
94    ;; of a kill-buffer, triggered an assertion failure in unchain_both.
95    (with-temp-buffer
96      (insert "toto")
97      (move-overlay ol (point-min) (point-min)))))
98
99
100;; +==========================================================================+
101;; | Overlay test setup
102;; +==========================================================================+
103
104(eval-when-compile
105  (defun buffer-tests--make-test-name (fn x y)
106    (intern (format "buffer-tests--%s-%s-%s" fn x y))))
107
108(defun buffer-tests--unmake-test-name (symbol)
109  (let ((name (if (stringp symbol) symbol (symbol-name symbol))))
110    (when (string-match "\\`buffer-tests--\\(.*\\)-\\(.*\\)-\\(.*\\)\\'" name)
111      (list (match-string 1 name)
112            (match-string 2 name)
113            (match-string 3 name)))))
114
115(defmacro deftest-make-overlay-1 (id args)
116  (declare (indent 1))
117  `(ert-deftest ,(buffer-tests--make-test-name 'make-overlay 1 id) ()
118     (with-temp-buffer
119       (should ,(cons 'make-overlay args)))))
120
121(defmacro deftest-make-overlay-2 (id args condition)
122  (declare (indent 1))
123  `(ert-deftest ,(buffer-tests--make-test-name 'make-overlay 2 id) ()
124     (with-temp-buffer
125       (should-error
126        ,(cons 'make-overlay args)
127        :type ',condition
128        :exclude-subtypes t))))
129
130(defmacro deftest-overlay-start/end-1 (id start-end-args start-end-should)
131  (declare (indent 1))
132  (cl-destructuring-bind (start end sstart send)
133      (append start-end-args start-end-should)
134    `(ert-deftest ,(buffer-tests--make-test-name 'overlay-start/end 1 id) ()
135       (with-temp-buffer
136         (insert (make-string 9 ?\n))
137         (let ((ov (make-overlay ,start ,end)))
138           (should (equal ,sstart (overlay-start ov)))
139           (should (equal ,send (overlay-end ov))))))))
140
141(defmacro deftest-overlay-buffer-1 (id arg-expr should-expr)
142  (declare (indent 1))
143  `(ert-deftest ,(buffer-tests--make-test-name 'overlay-buffer 1 id) ()
144     (with-temp-buffer
145       (should (equal (overlay-buffer (make-overlay 1 1 ,arg-expr))
146                      ,should-expr)))))
147
148(defmacro deftest-overlayp-1 (id arg-expr should-expr)
149  (declare (indent 1))
150  `(ert-deftest ,(buffer-tests--make-test-name 'overlayp 1 id) ()
151     (with-temp-buffer
152       (should (equal ,should-expr (overlayp ,arg-expr))))))
153
154(defmacro deftest-next-overlay-change-1 (id pos result &rest ov-tuple)
155  `(ert-deftest ,(buffer-tests--make-test-name 'next-overlay-change 1 id) ()
156     (let ((tuple (copy-sequence ',ov-tuple)))
157       (with-temp-buffer
158         (insert (make-string (max 100 (if tuple
159                                           (apply #'max
160                                                  (mapcar
161                                                   (lambda (m) (apply #'max m))
162                                                   tuple))
163                                         0))
164                              ?\n))
165         (dolist (tup tuple)
166           (make-overlay (car tup) (cadr tup)))
167         (should (equal (next-overlay-change ,pos)
168                        ,result))))))
169
170(defmacro deftest-previous-overlay-change-1 (id pos result &rest ov-tuple)
171  `(ert-deftest ,(buffer-tests--make-test-name 'previous-overlay-change 1 id) ()
172     (let ((tuple ',ov-tuple))
173       (with-temp-buffer
174         (insert (make-string (max 100 (if tuple
175                                           (apply #'max
176                                                  (mapcar
177                                                   (lambda (m) (apply #'max m))
178                                                   tuple))
179                                         0))
180                              ?\n))
181         (dolist (tup tuple)
182           (make-overlay (car tup) (cadr tup)))
183         (should (equal (previous-overlay-change ,pos)
184                        ,result))))))
185
186(defmacro deftest-overlays-at-1 (id pos result &rest ov-triple)
187  `(ert-deftest ,(buffer-tests--make-test-name 'overlays-at 1 id) ()
188     (let ((pos* ,pos))
189       (with-temp-buffer
190         (insert (make-string 100 ?\s))
191         (should-not (memq nil ',result))
192         (dolist (v ',ov-triple)
193           (cl-destructuring-bind (tag start end)
194               v
195             (overlay-put (make-overlay start end) 'tag tag)))
196         (let ((ovl (overlays-at pos*)))
197           (should (equal (length ovl) (length ',result)))
198           (dolist (ov ovl)
199             (should (memq (overlay-get ov 'tag) ',result))))))))
200
201(defmacro deftest-overlays-in-1 (id beg end result &rest ov-triple)
202  `(ert-deftest ,(buffer-tests--make-test-name 'overlays-in 1 id) ()
203     (let ((beg* ,beg)
204           (end* ,end))
205       (with-temp-buffer
206         (insert (make-string 100 ?\s))
207         (should-not (memq nil ',result))
208         (dolist (v ',ov-triple)
209           (cl-destructuring-bind (tag start end)
210               v
211             (overlay-put (make-overlay start end) 'tag tag)))
212         (let ((ovl (overlays-in beg* end*)))
213           (should (equal (length ovl) (length ',result)))
214           (dolist (ov ovl)
215             (should (memq (overlay-get ov 'tag) ',result))))))))
216
217(defmacro test-with-overlay-in-buffer (symbol-beg-end-fa-ra &rest body)
218  (declare (indent 1))
219  (cl-destructuring-bind (symbol beg end &optional fa ra)
220      symbol-beg-end-fa-ra
221    `(with-temp-buffer
222       (insert (make-string (max 1000 (1- ,end)) ?\s))
223       (goto-char 1)
224       (let ((,symbol (make-overlay ,beg ,end nil ,fa ,ra)))
225         ,@body))))
226
227(defmacro deftest-overlays-equal-1 (id result ov1-args ov2-args)
228  `(ert-deftest ,(buffer-tests--make-test-name 'overlays-equal 1 id) ()
229     (cl-flet ((create-overlay (args)
230                 (cl-destructuring-bind (start end &optional fa ra
231                                                   &rest properties)
232                     args
233                   (let ((ov (make-overlay start end nil fa ra)))
234                     (while properties
235                       (overlay-put ov (pop properties) (pop properties)))
236                     ov))))
237       (with-temp-buffer
238         (insert (make-string 1024 ?\s))
239         (should (,(if result 'identity 'not)
240                  (equal (create-overlay ',ov1-args)
241                         (create-overlay ',ov2-args))))))))
242
243
244(defun buffer-tests--find-ert-test (name)
245  (let ((test (buffer-tests--unmake-test-name name)))
246    (or (and test
247             (cl-destructuring-bind (fn x y)
248                 test
249               (let ((regexp (format "deftest-%s-%s +%s" fn x y)))
250                 (re-search-forward regexp nil t))))
251        (let ((find-function-regexp-alist
252               (cl-remove #'buffer-tests--find-ert-test
253                          find-function-regexp-alist :key #'cdr)))
254          (find-function-do-it name 'ert-deftest
255                               #'switch-to-buffer-other-window)))))
256
257(add-to-list 'find-function-regexp-alist
258             `(ert-deftest . ,#'buffer-tests--find-ert-test))
259
260
261;; +==========================================================================+
262;; | make-overlay
263;; +==========================================================================+
264
265;; Test if making an overlay succeeds.
266(deftest-make-overlay-1 A (1 1))
267(deftest-make-overlay-1 B (7 26))
268(deftest-make-overlay-1 C (29 7))
269(deftest-make-overlay-1 D (most-positive-fixnum 1))
270(deftest-make-overlay-1 E (most-negative-fixnum 1))
271(deftest-make-overlay-1 F (1 most-positive-fixnum))
272(deftest-make-overlay-1 G (1 most-negative-fixnum))
273(deftest-make-overlay-1 H (1 1 nil t))
274(deftest-make-overlay-1 I (1 1 nil nil))
275(deftest-make-overlay-1 J (1 1 nil nil nil))
276(deftest-make-overlay-1 K (1 1 nil nil t))
277(deftest-make-overlay-1 L (1 1 nil t t))
278(deftest-make-overlay-1 M (1 1 nil "yes" "yes"))
279
280;; Test if trying to make an overlay signals conditions.
281(deftest-make-overlay-2 A ()            wrong-number-of-arguments)
282(deftest-make-overlay-2 B (1)           wrong-number-of-arguments)
283(deftest-make-overlay-2 C (1 2 3 4 5 6) wrong-number-of-arguments)
284(deftest-make-overlay-2 D ("1")         wrong-number-of-arguments)
285(deftest-make-overlay-2 E ("1" "2")     wrong-type-argument)
286(deftest-make-overlay-2 F (1 2 "b")     wrong-type-argument)
287(deftest-make-overlay-2 G (1 2 3.14)    wrong-type-argument)
288(deftest-make-overlay-2 H (3.14 3)      wrong-type-argument)
289(deftest-make-overlay-2 I (1 [1])       wrong-type-argument)
290(deftest-make-overlay-2 J (1 1 (with-temp-buffer
291                                 (current-buffer)))
292  error)
293
294
295;; +==========================================================================+
296;; | overlay-start/end
297;; +==========================================================================+
298
299;; Test if the overlays return proper positions.  point-max of the
300;; buffer will equal 10.        ARG RESULT
301(deftest-overlay-start/end-1 A (1 1) (1 1))
302(deftest-overlay-start/end-1 B (2 7) (2 7))
303(deftest-overlay-start/end-1 C (7 2) (2 7))
304(deftest-overlay-start/end-1 D (1 10) (1 10))
305(deftest-overlay-start/end-1 E (1 11) (1 10))
306(deftest-overlay-start/end-1 F (1 most-positive-fixnum) (1 10))
307(deftest-overlay-start/end-1 G (most-positive-fixnum 1) (1 10))
308(deftest-overlay-start/end-1 H (most-positive-fixnum most-positive-fixnum)
309                               (10 10))
310(deftest-overlay-start/end-1 I (100 11) (10 10))
311(deftest-overlay-start/end-1 J (11 100) (10 10))
312(deftest-overlay-start/end-1 K (0 1) (1 1))
313(deftest-overlay-start/end-1 L (1 0) (1 1))
314(deftest-overlay-start/end-1 M (0 0) (1 1))
315
316(ert-deftest test-overlay-start/end-2 ()
317  (should-not (overlay-start (with-temp-buffer (make-overlay 1 1))))
318  (should-not (overlay-end (with-temp-buffer (make-overlay 1 1)))))
319
320
321;; +==========================================================================+
322;; | overlay-buffer
323;; +==========================================================================+
324
325;; Test if overlay-buffer returns appropriate values.
326(deftest-overlay-buffer-1 A (current-buffer) (current-buffer))
327(deftest-overlay-buffer-1 B nil (current-buffer))
328(ert-deftest test-overlay-buffer-1-C ()
329  (should-error (make-overlay
330                 1 1 (with-temp-buffer (current-buffer)))))
331
332
333;; +==========================================================================+
334;; | overlayp
335;; +==========================================================================+
336
337;; Check the overlay predicate.
338(deftest-overlayp-1 A (make-overlay 1 1) t)
339(deftest-overlayp-1 B (with-temp-buffer (make-overlay 1 1)) t)
340(deftest-overlayp-1 C nil                            nil)
341(deftest-overlayp-1 D 'symbol                        nil)
342(deftest-overlayp-1 E "string"                       nil)
343(deftest-overlayp-1 F 42                             nil)
344(deftest-overlayp-1 G [1 2]                          nil)
345(deftest-overlayp-1 H (symbol-function 'car)         nil)
346(deftest-overlayp-1 I float-pi                       nil)
347(deftest-overlayp-1 J (cons 1 2)                     nil)
348(deftest-overlayp-1 K (make-hash-table)              nil)
349(deftest-overlayp-1 L (symbol-function 'ert-deftest) nil)
350(deftest-overlayp-1 M (current-buffer)               nil)
351(deftest-overlayp-1 N (selected-window)              nil)
352(deftest-overlayp-1 O (selected-frame)               nil)
353
354
355;; +==========================================================================+
356;; | overlay equality
357;; +==========================================================================+
358
359(deftest-overlays-equal-1 A t (1 1) (1 1))
360(deftest-overlays-equal-1 B t (5 10) (5 10))
361(deftest-overlays-equal-1 C nil (5 11) (5 10))
362(deftest-overlays-equal-1 D t (10 20 t) (10 20))
363(deftest-overlays-equal-1 E t (10 20 nil t) (10 20))
364(deftest-overlays-equal-1 F t (10 20 t t) (10 20 nil t))
365(deftest-overlays-equal-1 G t (10 20 t t) (10 20 t nil))
366(deftest-overlays-equal-1 H t (10 20 nil nil foo 42) (10 20 nil nil foo 42))
367(deftest-overlays-equal-1 I nil (10 20 nil nil foo 42) (10 20 nil nil foo 43))
368
369
370;; +==========================================================================+
371;; | overlay-lists
372;; +==========================================================================+
373
374;; Check whether overlay-lists returns something sensible.
375(ert-deftest test-overlay-lists-1 ()
376  (with-temp-buffer
377    (should (equal (cons nil nil) (overlay-lists)))
378    (dotimes (i 10) (make-overlay 1 i))
379    (should (listp (car (overlay-lists))))
380    (should (listp (cdr (overlay-lists))))
381    (let ((list (append (car (overlay-lists))
382                        (cdr (overlay-lists)))))
383      (should (= 10 (length list)))
384      (should (seq-every-p #'overlayp list)))))
385
386
387;; +==========================================================================+
388;; | overlay-put/get/properties
389;; +==========================================================================+
390
391;; Test if overlay-put properties can be retrieved by overlay-get and
392;; overlay-properties.
393(ert-deftest test-overlay-props-1 ()
394  (with-temp-buffer
395    (let* ((keys '(:k1 :k2 :k3))
396           (values '(1 "v2" v3))
397           (ov (make-overlay 1 1))
398           (n (length keys)))
399      (should (equal (length keys) (length values)))
400      (should (null (overlay-properties ov)))
401      ;; Insert keys and values.
402      (dotimes (i n)
403        (should (equal (overlay-put ov (nth i keys) (nth i values))
404                       (nth i values))))
405      ;; Compare with what overlay-get says.
406      (dotimes (i n)
407        (should (equal (overlay-get ov (nth i keys))
408                       (nth i values))))
409      ;; Test if overlay-properties is a superset.
410      (dotimes (i n)
411        (should (equal (plist-get (overlay-properties ov)
412                                  (nth i keys))
413                       (nth i values))))
414      ;; Check if overlay-properties is a subset.
415      (should (= (length (overlay-properties ov)) (* n 2))))))
416
417
418;; +==========================================================================+
419;; | next-overlay-change
420;; +==========================================================================+
421
422;; Test if next-overlay-change returns RESULT if called with POS in a
423;; buffer with overlays corresponding to OVS and point-max >= 100.
424;;                               (POS RESULT &rest OVS)
425;; 0 overlays
426(deftest-next-overlay-change-1 A (point-min) (point-max))
427(deftest-next-overlay-change-1 B (point-max) (point-max))
428;; 1 non-empty overlay
429(deftest-next-overlay-change-1 C 1 10 (10 20))
430(deftest-next-overlay-change-1 D 10 20 (10 20))
431(deftest-next-overlay-change-1 E 15 20 (10 20))
432(deftest-next-overlay-change-1 F 20 (point-max) (10 20))
433(deftest-next-overlay-change-1 G 30 (point-max) (10 20))
434;; 1 empty overlay
435(deftest-next-overlay-change-1 H 1 10 (10 10))
436(deftest-next-overlay-change-1 I 10 (point-max) (10 10))
437(deftest-next-overlay-change-1 J 20 (point-max) (10 10))
438;; 2 non-empty, non-intersecting
439(deftest-next-overlay-change-1 D2 10 20 (20 30) (40 50))
440(deftest-next-overlay-change-1 E2 35 40 (20 30) (40 50))
441(deftest-next-overlay-change-1 F2 60 (point-max) (20 30) (40 50))
442(deftest-next-overlay-change-1 G2 30 40 (20 30) (40 50))
443(deftest-next-overlay-change-1 H2 50 (point-max) (20 30) (40 50))
444;; 2 non-empty, intersecting
445(deftest-next-overlay-change-1 I2 10 20 (20 30) (25 35))
446(deftest-next-overlay-change-1 J2 20 25 (20 30) (25 35))
447(deftest-next-overlay-change-1 K 23 25 (20 30) (25 35))
448(deftest-next-overlay-change-1 L 25 30 (20 30) (25 35))
449(deftest-next-overlay-change-1 M 28 30 (20 30) (25 35))
450(deftest-next-overlay-change-1 N 30 35 (20 30) (25 35))
451(deftest-next-overlay-change-1 O 35 (point-max) (20 30) (25 35))
452(deftest-next-overlay-change-1 P 50 (point-max) (20 30) (25 35))
453;; 2 non-empty, continuous
454(deftest-next-overlay-change-1 Q 10 20 (20 30) (30 40))
455(deftest-next-overlay-change-1 R 20 30 (20 30) (30 40))
456(deftest-next-overlay-change-1 S 25 30 (20 30) (30 40))
457(deftest-next-overlay-change-1 T 30 40 (20 30) (30 40))
458(deftest-next-overlay-change-1 U 35 40 (20 30) (30 40))
459(deftest-next-overlay-change-1 V 40 (point-max) (20 30) (30 40))
460(deftest-next-overlay-change-1 W 50 (point-max) (20 30) (30 40))
461;; 1 empty, 1 non-empty, non-in
462(deftest-next-overlay-change-1 a 10 20 (20 20) (30 40))
463(deftest-next-overlay-change-1 b 20 30 (20 30) (30 40))
464(deftest-next-overlay-change-1 c 25 30 (20 30) (30 40))
465(deftest-next-overlay-change-1 d 30 40 (20 30) (30 40))
466(deftest-next-overlay-change-1 e 35 40 (20 30) (30 40))
467(deftest-next-overlay-change-1 f 40 (point-max) (20 30) (30 40))
468(deftest-next-overlay-change-1 g 50 (point-max) (20 30) (30 40))
469;; 1 empty, 1 non-empty, intersecting at begin
470(deftest-next-overlay-change-1 h 10 20 (20 20) (20 30))
471(deftest-next-overlay-change-1 i 20 30 (20 20) (20 30))
472(deftest-next-overlay-change-1 j 25 30 (20 20) (20 30))
473(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30))
474(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30))
475;; 1 empty, 1 non-empty, intersecting at end
476(deftest-next-overlay-change-1 h2 10 20 (30 30) (20 30))
477(deftest-next-overlay-change-1 i2 20 30 (30 30) (20 30))
478(deftest-next-overlay-change-1 j2 25 30 (30 30) (20 30))
479(deftest-next-overlay-change-1 k2 30 (point-max) (20 20) (20 30))
480(deftest-next-overlay-change-1 l2 40 (point-max) (20 20) (20 30))
481;; 1 empty, 1 non-empty, intersecting in the middle
482(deftest-next-overlay-change-1 m 10 20 (25 25) (20 30))
483(deftest-next-overlay-change-1 n 20 25 (25 25) (20 30))
484(deftest-next-overlay-change-1 o 25 30 (25 25) (20 30))
485(deftest-next-overlay-change-1 p 30 (point-max) (25 25) (20 30))
486(deftest-next-overlay-change-1 q 40 (point-max) (25 25) (20 30))
487;; 2 empty, intersecting
488(deftest-next-overlay-change-1 r 10 20 (20 20) (20 20))
489(deftest-next-overlay-change-1 s 20 (point-max) (20 20) (20 20))
490(deftest-next-overlay-change-1 t 30 (point-max) (20 20) (20 20))
491;; 2 empty, non-intersecting
492(deftest-next-overlay-change-1 u 10 20 (20 20) (30 30))
493(deftest-next-overlay-change-1 v 20 30 (20 20) (30 30))
494(deftest-next-overlay-change-1 w 25 30 (20 20) (30 30))
495(deftest-next-overlay-change-1 x 30 (point-max) (20 20) (30 30))
496(deftest-next-overlay-change-1 y 50 (point-max) (20 20) (30 30))
497;; 10 random
498(deftest-next-overlay-change-1 aa 1 5
499  (58 66) (41 10) (9 67) (28 88) (27 43)
500  (24 27) (48 36) (5 90) (61 9))
501(deftest-next-overlay-change-1 ab (point-max) (point-max)
502  (58 66) (41 10) (9 67) (28 88) (27 43)
503  (24 27) (48 36) (5 90) (61 9))
504(deftest-next-overlay-change-1 ac 67 88
505  (58 66) (41 10) (9 67) (28 88) (27 43)
506  (24 27) (48 36) (5 90) (61 9))
507
508
509;; +==========================================================================+
510;; | previous-overlay-change.
511;; +==========================================================================+
512
513;; Same for previous-overlay-change.
514;; 1 non-empty overlay
515(deftest-previous-overlay-change-1 A (point-max) 1)
516(deftest-previous-overlay-change-1 B 1 1)
517(deftest-previous-overlay-change-1 C 1 1 (10 20))
518(deftest-previous-overlay-change-1 D 10 1 (10 20))
519(deftest-previous-overlay-change-1 E 15 10 (10 20))
520(deftest-previous-overlay-change-1 F 20 10 (10 20))
521(deftest-previous-overlay-change-1 G 30 20 (10 20))
522;; 1 empty overlay
523(deftest-previous-overlay-change-1 H 1 1 (10 10))
524(deftest-previous-overlay-change-1 I 10 1 (10 10))
525(deftest-previous-overlay-change-1 J 20 10 (10 10))
526;; 2 non-empty, non-intersecting
527(deftest-previous-overlay-change-1 D2 10 1 (20 30) (40 50))
528(deftest-previous-overlay-change-1 E2 35 30 (20 30) (40 50))
529(deftest-previous-overlay-change-1 F2 60 50 (20 30) (40 50))
530(deftest-previous-overlay-change-1 G2 30 20 (20 30) (40 50))
531(deftest-previous-overlay-change-1 H2 50 40 (20 30) (40 50))
532;; 2 non-empty, intersecting
533(deftest-previous-overlay-change-1 I2 10 1 (20 30) (25 35))
534(deftest-previous-overlay-change-1 J2 20 1 (20 30) (25 35))
535(deftest-previous-overlay-change-1 K 23 20 (20 30) (25 35))
536(deftest-previous-overlay-change-1 L 25 20 (20 30) (25 35))
537(deftest-previous-overlay-change-1 M 28 25 (20 30) (25 35))
538(deftest-previous-overlay-change-1 N 30 25 (20 30) (25 35))
539(deftest-previous-overlay-change-1 O 35 30 (20 30) (25 35))
540(deftest-previous-overlay-change-1 P 50 35 (20 30) (25 35))
541;; 2 non-empty, continuous
542(deftest-previous-overlay-change-1 Q 10 1 (20 30) (30 40))
543(deftest-previous-overlay-change-1 R 20 1 (20 30) (30 40))
544(deftest-previous-overlay-change-1 S 25 20 (20 30) (30 40))
545(deftest-previous-overlay-change-1 T 30 20 (20 30) (30 40))
546(deftest-previous-overlay-change-1 U 35 30 (20 30) (30 40))
547(deftest-previous-overlay-change-1 V 40 30 (20 30) (30 40))
548(deftest-previous-overlay-change-1 W 50 40 (20 30) (30 40))
549;; 1 empty, 1 non-empty, non-intersecting
550(deftest-previous-overlay-change-1 a 10 1 (20 20) (30 40))
551(deftest-previous-overlay-change-1 b 20 1 (20 30) (30 40))
552(deftest-previous-overlay-change-1 c 25 20 (20 30) (30 40))
553(deftest-previous-overlay-change-1 d 30 20 (20 30) (30 40))
554(deftest-previous-overlay-change-1 e 35 30 (20 30) (30 40))
555(deftest-previous-overlay-change-1 f 40 30 (20 30) (30 40))
556(deftest-previous-overlay-change-1 g 50 40 (20 30) (30 40))
557;; 1 empty, 1 non-empty, intersecting at begin
558(deftest-previous-overlay-change-1 h 10 1 (20 20) (20 30))
559(deftest-previous-overlay-change-1 i 20 1 (20 20) (20 30))
560(deftest-previous-overlay-change-1 j 25 20 (20 20) (20 30))
561(deftest-previous-overlay-change-1 k 30 20 (20 20) (20 30))
562(deftest-previous-overlay-change-1 l 40 30 (20 20) (20 30))
563;; 1 empty, 1 non-empty, intersecting at end
564(deftest-previous-overlay-change-1 m 10 1 (30 30) (20 30))
565(deftest-previous-overlay-change-1 n 20 1 (30 30) (20 30))
566(deftest-previous-overlay-change-1 o 25 20 (30 30) (20 30))
567(deftest-previous-overlay-change-1 p 30 20 (20 20) (20 30))
568(deftest-previous-overlay-change-1 q 40 30 (20 20) (20 30))
569;; 1 empty, 1 non-empty, intersecting in the middle
570(deftest-previous-overlay-change-1 r 10 1 (25 25) (20 30))
571(deftest-previous-overlay-change-1 s 20 1 (25 25) (20 30))
572(deftest-previous-overlay-change-1 t 25 20 (25 25) (20 30))
573(deftest-previous-overlay-change-1 u 30 25 (25 25) (20 30))
574(deftest-previous-overlay-change-1 v 40 30 (25 25) (20 30))
575;; 2 empty, intersecting
576(deftest-previous-overlay-change-1 w 10 1 (20 20) (20 20))
577(deftest-previous-overlay-change-1 x 20 1 (20 20) (20 20))
578(deftest-previous-overlay-change-1 y 30 20 (20 20) (20 20))
579;; 2 empty, non-intersecting
580(deftest-previous-overlay-change-1 z 10 1 (20 20) (30 30))
581(deftest-previous-overlay-change-1 aa 20 1 (20 20) (30 30))
582(deftest-previous-overlay-change-1 ab 25 20 (20 20) (30 30))
583(deftest-previous-overlay-change-1 ac 30 20 (20 20) (30 30))
584(deftest-previous-overlay-change-1 ad 50 30 (20 20) (30 30))
585;; 10 random
586(deftest-previous-overlay-change-1 ae 100 90
587  (58 66) (41 10) (9 67) (28 88) (27 43)
588  (24 27) (48 36) (5 90) (61 9))
589(deftest-previous-overlay-change-1 af (point-min) (point-min)
590  (58 66) (41 10) (9 67) (28 88) (27 43)
591  (24 27) (48 36) (5 90) (61 9))
592(deftest-previous-overlay-change-1 ag 29 28
593  (58 66) (41 10) (9 67) (28 88) (27 43)
594  (24 27) (48 36) (5 90) (61 9))
595
596
597;; +==========================================================================+
598;; | overlays-at
599;; +==========================================================================+
600
601
602;; Test whether overlay-at returns RESULT at POS after overlays OVL were
603;; created in a buffer.         POS RES OVL
604(deftest-overlays-at-1 A 1 ())
605;; 1 overlay
606(deftest-overlays-at-1 B 10 (a) (a 10 20))
607(deftest-overlays-at-1 C 15 (a) (a 10 20))
608(deftest-overlays-at-1 D 19 (a) (a 10 20))
609(deftest-overlays-at-1 E 20 ()  (a 10 20))
610(deftest-overlays-at-1 F 1 () (a 10 20))
611
612;; 2 non-empty overlays non-intersecting
613(deftest-overlays-at-1 G 1 () (a 10 20) (b 30 40))
614(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 30 40))
615(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 30 40))
616(deftest-overlays-at-1 K 20 () (a 10 20) (b 30 40))
617(deftest-overlays-at-1 L 25 () (a 10 20) (b 30 40))
618(deftest-overlays-at-1 M 30 (b) (a 10 20) (b 30 40))
619(deftest-overlays-at-1 N 35 (b) (a 10 20) (b 30 40))
620(deftest-overlays-at-1 O 40 () (a 10 20) (b 30 40))
621(deftest-overlays-at-1 P 50 () (a 10 20) (b 30 40))
622
623;; 2 non-empty overlays intersecting
624(deftest-overlays-at-1 G2 1 () (a 10 30) (b 20 40))
625(deftest-overlays-at-1 H2 10 (a) (a 10 30) (b 20 40))
626(deftest-overlays-at-1 I2 15 (a) (a 10 30) (b 20 40))
627(deftest-overlays-at-1 K2 20 (a b) (a 10 30) (b 20 40))
628(deftest-overlays-at-1 L2 25 (a b) (a 10 30) (b 20 40))
629(deftest-overlays-at-1 M2 30 (b) (a 10 30) (b 20 40))
630(deftest-overlays-at-1 N2 35 (b) (a 10 30) (b 20 40))
631(deftest-overlays-at-1 O2 40 () (a 10 30) (b 20 40))
632(deftest-overlays-at-1 P2 50 () (a 10 30) (b 20 40))
633
634;; 2 non-empty overlays continuous
635(deftest-overlays-at-1 G3 1 () (a 10 20) (b 20 30))
636(deftest-overlays-at-1 H3 10 (a) (a 10 20) (b 20 30))
637(deftest-overlays-at-1 I3 15 (a) (a 10 20) (b 20 30))
638(deftest-overlays-at-1 K3 20 (b) (a 10 20) (b 20 30))
639(deftest-overlays-at-1 L3 25 (b) (a 10 20) (b 20 30))
640(deftest-overlays-at-1 M3 30 () (a 10 20) (b 20 30))
641
642;; overlays-at never returns empty overlays.
643(deftest-overlays-at-1 N3 1 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
644(deftest-overlays-at-1 O3 20 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
645(deftest-overlays-at-1 P3 30 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
646(deftest-overlays-at-1 Q 40 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
647(deftest-overlays-at-1 R 50 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
648(deftest-overlays-at-1 S 60 () (a 1 60) (c 1 1) (b 30 30) (d 50 50))
649
650;; behavior at point-min and point-max
651(ert-deftest test-overlays-at-2 ()
652  (cl-macrolet ((should-length (n list)
653                               `(should (= ,n (length ,list)))))
654    (with-temp-buffer
655      (insert (make-string 100 ?\s))
656      (make-overlay 1 (point-max))
657      (make-overlay 10 10)
658      (make-overlay 20 20)
659      (make-overlay (point-max) (point-max))
660      (should-length 1 (overlays-at 1))
661      (should-length 1 (overlays-at 10))
662      (should-length 1 (overlays-at 20))
663      (should-length 0 (overlays-at (point-max)))
664      (narrow-to-region 10 20)
665      (should-length 1 (overlays-at (point-min)))
666      (should-length 1 (overlays-at 15))
667      (should-length 1 (overlays-at (point-max))))))
668
669
670;; +==========================================================================+
671;; | overlay-in
672;; +==========================================================================+
673
674
675;; Test whether overlays-in returns RES in BEG,END after overlays OVL were
676;; created in a buffer.
677
678(deftest-overlays-in-1 A 1 (point-max) ());;POS RES OVL
679;; 1 overlay
680(deftest-overlays-in-1 B 1 10 () (a 10 20))
681(deftest-overlays-in-1 C 5 10 () (a 10 20))
682(deftest-overlays-in-1 D 5 15 (a) (a 10 20))
683(deftest-overlays-in-1 E 10 15 (a)  (a 10 20))
684(deftest-overlays-in-1 F 10 20 (a) (a 10 20))
685(deftest-overlays-in-1 G 15 20 (a) (a 10 20))
686(deftest-overlays-in-1 H 15 25 (a) (a 10 20))
687(deftest-overlays-in-1 I 20 25 () (a 10 20))
688(deftest-overlays-in-1 J 30 50 () (a 10 20))
689
690;; 2 non-empty overlays non-intersecting
691(deftest-overlays-in-1 K 1 5 () (a 10 20) (b 30 40))
692(deftest-overlays-in-1 L 5 10 () (a 10 20) (b 30 40))
693(deftest-overlays-in-1 M 5 15 (a) (a 10 20) (b 30 40))
694(deftest-overlays-in-1 N 10 15 (a) (a 10 20) (b 30 40))
695(deftest-overlays-in-1 O 15 20 (a) (a 10 20) (b 30 40))
696(deftest-overlays-in-1 P 15 25 (a) (a 10 20) (b 30 40))
697(deftest-overlays-in-1 Q 20 25 () (a 10 20) (b 30 40))
698(deftest-overlays-in-1 R 20 30 () (a 10 20) (b 30 40))
699(deftest-overlays-in-1 S 25 30 () (a 10 20) (b 30 40))
700(deftest-overlays-in-1 T 25 35 (b) (a 10 20) (b 30 40))
701(deftest-overlays-in-1 U 30 35 (b) (a 10 20) (b 30 40))
702(deftest-overlays-in-1 V 40 50  () (a 10 20) (b 30 40))
703(deftest-overlays-in-1 W 50 60  () (a 10 20) (b 30 40))
704(deftest-overlays-in-1 X 1 50  (a b) (a 10 20) (b 30 40))
705(deftest-overlays-in-1 Y 10 40  (a b) (a 10 20) (b 30 40))
706(deftest-overlays-in-1 Z 10 41  (a b) (a 10 20) (b 30 40))
707
708;; 2 non-empty overlays intersecting
709(deftest-overlays-in-1 a 1 5 () (a 10 30) (b 20 40))
710(deftest-overlays-in-1 b 5 10 () (a 10 30) (b 20 40))
711(deftest-overlays-in-1 c 5 15 (a) (a 10 30) (b 20 40))
712(deftest-overlays-in-1 d 10 15 (a) (a 10 30) (b 20 40))
713(deftest-overlays-in-1 e 10 20 (a) (a 10 30) (b 20 40))
714(deftest-overlays-in-1 f 15 20 (a) (a 10 30) (b 20 40))
715(deftest-overlays-in-1 g 20 30 (a b) (a 10 30) (b 20 40))
716(deftest-overlays-in-1 h 20 40 (a b) (a 10 30) (b 20 40))
717(deftest-overlays-in-1 i 25 30 (a b) (a 10 30) (b 20 40))
718(deftest-overlays-in-1 j 30 30 (b) (a 10 30) (b 20 40))
719(deftest-overlays-in-1 k 30 35 (b) (a 10 30) (b 20 40))
720(deftest-overlays-in-1 l 35 40 (b) (a 10 30) (b 20 40))
721(deftest-overlays-in-1 m 40 45 () (a 10 30) (b 20 40))
722(deftest-overlays-in-1 n 41 45 () (a 10 30) (b 20 40))
723(deftest-overlays-in-1 o 50 60 () (a 10 30) (b 20 40))
724
725;; 2 non-empty overlays continuous
726(deftest-overlays-in-1 p 1 5 () (a 10 20) (b 20 30))
727(deftest-overlays-in-1 q 5 10 () (a 10 20) (b 20 30))
728(deftest-overlays-in-1 r 15 20 (a) (a 10 20) (b 20 30))
729(deftest-overlays-in-1 s 15 25 (a b) (a 10 20) (b 20 30))
730(deftest-overlays-in-1 t 20 25 (b) (a 10 20) (b 20 30))
731(deftest-overlays-in-1 u 25 30 (b) (a 10 20) (b 20 30))
732(deftest-overlays-in-1 v 29 35 (b) (a 10 20) (b 20 30))
733(deftest-overlays-in-1 w 30 35 () (a 10 20) (b 20 30))
734(deftest-overlays-in-1 x 35 50 () (a 10 20) (b 20 30))
735(deftest-overlays-in-1 y 1 50 (a b) (a 10 20) (b 20 30))
736(deftest-overlays-in-1 z 15 50 (a b) (a 10 20) (b 20 30))
737(deftest-overlays-in-1 aa 1 25 (a b) (a 10 20) (b 20 30))
738
739;; 1 empty overlay
740(deftest-overlays-in-1 ab 1 10 () (a 10 10))
741(deftest-overlays-in-1 ac 10 10 (a) (a 10 10))
742(deftest-overlays-in-1 ad 9 10 () (a 10 10))
743(deftest-overlays-in-1 ae 9 11 (a) (a 10 10))
744(deftest-overlays-in-1 af 10 11 (a) (a 10 10))
745
746
747;; behavior at point-max
748(ert-deftest test-overlays-in-2 ()
749  (cl-macrolet ((should-length (n list)
750                               `(should (= ,n (length ,list)))))
751    (with-temp-buffer
752      (insert (make-string 100 ?\s))
753      (make-overlay (point-max) (point-max))
754      (make-overlay 50 50)
755      (should-length 1 (overlays-in 50 50))
756      (should-length 2 (overlays-in 1 (point-max)))
757      (should-length 1 (overlays-in (point-max) (point-max)))
758      (narrow-to-region 1 50)
759      (should-length 1 (overlays-in 1 (point-max)))
760      (should-length 1 (overlays-in (point-max) (point-max))))))
761
762
763;; +==========================================================================+
764;; | overlay-recenter
765;; +==========================================================================+
766
767;; This function is a noop in the overlay tree branch.
768(ert-deftest test-overlay-recenter ()
769  (with-temp-buffer
770    (should-not (overlay-recenter 1))
771    (insert (make-string 100 ?\s))
772    (dotimes (i 10)
773      (make-overlay i (1+ i))
774      (should-not (overlay-recenter i)))))
775
776
777;; +==========================================================================+
778;; | move-overlay
779;; +==========================================================================+
780
781;; buffer nil with live overlay
782(ert-deftest test-move-overlay-1 ()
783  (test-with-overlay-in-buffer (ov 1 100)
784    (move-overlay ov 50 60)
785    (should (= 50 (overlay-start ov)))
786    (should (= 60 (overlay-end ov)))
787    (should (eq (current-buffer) (overlay-buffer ov)))))
788
789;; buffer nil, dead overlay
790(ert-deftest test-move-overlay-2 ()
791  (with-temp-buffer
792    (let ((ov (test-with-overlay-in-buffer (ov 1 100) ov)))
793      (insert (make-string 100 ?\s))
794      (move-overlay ov 50 60)
795      (should (= 50 (overlay-start ov)))
796      (should (= 60 (overlay-end ov)))
797      (should (eq (current-buffer) (overlay-buffer ov))))))
798
799;; buffer non-nil, live overlay
800(ert-deftest test-move-overlay-3 ()
801  (test-with-overlay-in-buffer (ov 10 100)
802    (with-temp-buffer
803      (move-overlay ov 1 1 (current-buffer))
804      (should (= 1 (overlay-start ov)))
805      (should (= 1 (overlay-end ov)))
806      (should (eq (current-buffer) (overlay-buffer ov))))
807    (should-not (overlay-start ov))
808    (should-not (overlay-end ov))
809    (should-not (overlay-buffer ov))))
810
811;; buffer non-nil, dead overlay
812(ert-deftest test-move-overlay-4 ()
813  (let ((ov (test-with-overlay-in-buffer (ov 1 1) ov)))
814    (with-temp-buffer
815      (move-overlay ov 1 1 (current-buffer))
816      (should (= 1 (overlay-start ov)))
817      (should (= 1 (overlay-end ov)))
818      (should (eq (current-buffer) (overlay-buffer ov))))
819    (should-not (overlay-start ov))
820    (should-not (overlay-end ov))
821    (should-not (overlay-buffer ov))))
822
823;; +==========================================================================+
824;; | delete-(all-)overlay
825;; +==========================================================================+
826
827;; delete live overlay
828(ert-deftest test-delete-overlay-1 ()
829  (test-with-overlay-in-buffer (ov 10 100)
830    (should (buffer-live-p (overlay-buffer ov)))
831    (delete-overlay ov)
832    (should-not (overlay-start ov))
833    (should-not (overlay-end ov))
834    (should-not (overlay-buffer ov))))
835
836;; delete dead overlay
837(ert-deftest test-delete-overlay-2 ()
838  (let ((ov (test-with-overlay-in-buffer (ov 10 100) ov)))
839    (should-not (overlay-start ov))
840    (should-not (overlay-end ov))
841    (should-not (overlay-buffer ov))
842    (should-not (delete-overlay ov))
843    (should-not (overlay-start ov))
844    (should-not (overlay-end ov))
845    (should-not (overlay-buffer ov))))
846
847(ert-deftest test-delete-all-overlay-1 ()
848  (with-temp-buffer
849    (should-not (delete-all-overlays))
850    (should-not (delete-all-overlays (current-buffer)))
851    (insert (make-string 100 ?\s))
852    (dotimes (i 10) (make-overlay i (1+ i)))
853    (should-not (delete-all-overlays (current-buffer)))
854    (should-not (delete-all-overlays))))
855
856
857;; +==========================================================================+
858;; | get-char-property(-and-overlay)
859;; +==========================================================================+
860
861;; FIXME: TBD
862
863
864;; +==========================================================================+
865;; | Moving by insertions
866;; +==========================================================================+
867
868(defmacro deftest-moving-insert-1 (id beg-end insert sbeg-send fa ra)
869  (cl-destructuring-bind (beg end ipos ilen sbeg send fa ra)
870      (append beg-end insert sbeg-send (list fa ra) nil)
871    `(ert-deftest ,(buffer-tests--make-test-name 'moving-insert 1 id) ()
872       (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra)
873         (should (= ,beg (overlay-start ov)))
874         (should (= ,end (overlay-end ov)))
875         (goto-char ,ipos)
876         (insert (make-string ,ilen ?x))
877         (should (= ,sbeg (overlay-start ov)))
878         (should (= ,send (overlay-end ov)))))))
879
880;; non-empty, no fa, no ra
881;; --------------------  OV      INS    RESULT
882(deftest-moving-insert-1 A (10 20) (15 3) (10 23) nil nil)
883(deftest-moving-insert-1 B (10 20) (20 4) (10 20) nil nil)
884(deftest-moving-insert-1 C (10 20) (5 5) (15 25) nil nil)
885(deftest-moving-insert-1 D (10 20) (10 3) (10 23) nil nil)
886(deftest-moving-insert-1 E (10 20) (20 4) (10 20) nil nil)
887
888;; non-empty no fa, ra
889(deftest-moving-insert-1 F (10 20) (15 3) (10 23) nil t)
890(deftest-moving-insert-1 G (10 20) (20 4) (10 24) nil t)
891(deftest-moving-insert-1 H (10 20) (5 5) (15 25) nil t)
892(deftest-moving-insert-1 I (10 20) (10 3) (10 23) nil t)
893(deftest-moving-insert-1 J (10 20) (20 4) (10 24) nil t)
894
895;; non-empty, fa, no r
896(deftest-moving-insert-1 K (10 20) (15 3) (10 23) t nil)
897(deftest-moving-insert-1 L (10 20) (20 4) (10 20) t nil)
898(deftest-moving-insert-1 M (10 20) (5 5) (15 25) t nil)
899(deftest-moving-insert-1 N (10 20) (10 3) (13 23) t nil)
900(deftest-moving-insert-1 O (10 20) (20 4) (10 20) t nil)
901
902;; This used to fail.
903(ert-deftest test-moving-insert-2-a ()
904  (with-temp-buffer
905    (insert (make-string 1 ?.))
906    (let ((ov (make-overlay 1 1 nil t nil)))
907      (insert "()")
908      (should (= 1 (overlay-end ov))))))
909
910;; non-empty, fa, ra
911(deftest-moving-insert-1 P (10 20) (15 3) (10 23) t t)
912(deftest-moving-insert-1 Q (10 20) (20 4) (10 24) t t)
913(deftest-moving-insert-1 R (10 20) (5 5) (15 25) t t)
914(deftest-moving-insert-1 S (10 20) (10 3) (13 23) t t)
915(deftest-moving-insert-1 T (10 20) (20 4) (10 24) t t)
916
917;; empty, no fa, no ra
918(deftest-moving-insert-1 U (15 15) (20 4) (15 15) nil nil)
919(deftest-moving-insert-1 V (15 15) (5 5) (20 20) nil nil)
920(deftest-moving-insert-1 W (15 15) (15 3) (15 15) nil nil)
921
922;; empty no fa, ra
923(deftest-moving-insert-1 X (15 15) (20 4) (15 15) nil t)
924(deftest-moving-insert-1 Y (15 15) (5 5) (20 20) nil t)
925(deftest-moving-insert-1 Z (15 15) (15 3) (15 18) nil t)
926
927;; empty, fa, no ra
928(deftest-moving-insert-1 a (15 15) (20 4) (15 15) t nil)
929(deftest-moving-insert-1 b (15 15) (5 5) (20 20) t nil)
930(deftest-moving-insert-1 c (15 15) (15 3) (15 15) t nil)
931
932;; empty, fa, ra
933(deftest-moving-insert-1 d (15 15) (20 4) (15 15) t t)
934(deftest-moving-insert-1 e (15 15) (5 5) (20 20) t t)
935(deftest-moving-insert-1 f (15 15) (15 3) (18 18) t t)
936
937;; Try to trigger a pathological case where the tree could become
938;; unordered due to an insert operation.
939
940(ert-deftest test-moving-insert-2 ()
941  (with-temp-buffer
942    (insert (make-string 1000 ?x))
943    (let ((root (make-overlay 50 75 nil    nil             'rear-advance))
944          (left (make-overlay 25 50 nil    'front-advance  'rear-advance))
945          (right (make-overlay 75 100 nil  nil             nil)))
946      ;;     [50] <--- start
947      ;;    /    \
948      ;; (25)    (75)
949      (delete-region 25 75)
950      ;;     [25]
951      ;;    /    \
952      ;; (25)    (25)
953      (should (= 25 (overlay-start root)))
954      (should (= 25 (overlay-end root)))
955      (should (= 25 (overlay-start left)))
956      (should (= 25 (overlay-end left)))
957      (should (= 25 (overlay-start right)))
958      (should (= 50 (overlay-end right)))
959      ;; Inserting at start should make left advance while right and
960      ;; root stay, thus we would have left > right .
961      (goto-char 25)
962      (insert (make-string 25 ?x))
963      ;;     [25]
964      ;;    /    \
965      ;; (50)    (25)
966      (should (= 25 (overlay-start root)))
967      (should (= 50 (overlay-end root)))
968      (should (= 50 (overlay-start left)))
969      (should (= 50 (overlay-end left)))
970      (should (= 25 (overlay-start right)))
971      (should (= 75 (overlay-end right)))
972      ;; Try to detect the error, by removing left.  The should fail
973      ;; an eassert, since it won't be found by a regular tree
974      ;; traversal - in theory.
975      (delete-overlay left)
976      (should (= 2 (length (overlays-in 1 (point-max))))))))
977
978
979
980;; +==========================================================================+
981;; | Moving by deletions
982;; +==========================================================================+
983
984(defmacro deftest-moving-delete-1 (id beg-end delete sbeg-send fa ra)
985  (cl-destructuring-bind (beg end dpos dlen sbeg send fa ra)
986      (append beg-end delete sbeg-send (list fa ra) nil)
987    `(ert-deftest ,(buffer-tests--make-test-name 'moving-delete 1 id) ()
988       (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra)
989         (should (= ,beg (overlay-start ov)))
990         (should (= ,end (overlay-end ov)))
991         (delete-region ,dpos (+ ,dpos ,dlen))
992         (should (= ,sbeg (overlay-start ov)))
993         (should (= ,send (overlay-end ov)))))))
994
995;; non-empty, no fa, no ra
996;; --------------------  OV      DEL    RESULT
997(deftest-moving-delete-1 A (10 20) (15 3) (10 17) nil nil)
998(deftest-moving-delete-1 B (10 20) (20 4) (10 20) nil nil)
999(deftest-moving-delete-1 C (10 20) (5 5) (5 15) nil nil)
1000(deftest-moving-delete-1 D (10 20) (10 3) (10 17) nil nil)
1001(deftest-moving-delete-1 E (10 20) (20 4) (10 20) nil nil)
1002
1003;; non-empty no fa, ra
1004(deftest-moving-delete-1 F (10 20) (15 3) (10 17) nil t)
1005(deftest-moving-delete-1 G (10 20) (20 4) (10 20) nil t)
1006(deftest-moving-delete-1 H (10 20) (5 5) (5 15) nil t)
1007(deftest-moving-delete-1 I (10 20) (10 3) (10 17) nil t)
1008(deftest-moving-delete-1 J (10 20) (20 4) (10 20) nil t)
1009
1010;; non-empty, fa, no ra
1011(deftest-moving-delete-1 K (10 20) (15 3) (10 17) t nil)
1012(deftest-moving-delete-1 L (10 20) (20 4) (10 20) t nil)
1013(deftest-moving-delete-1 M (10 20) (5 5) (5 15) t nil)
1014(deftest-moving-delete-1 N (10 20) (10 3) (10 17) t nil)
1015(deftest-moving-delete-1 O (10 20) (20 4) (10 20) t nil)
1016
1017;; non-empty, fa, ra
1018(deftest-moving-delete-1 P (10 20) (15 3) (10 17) t t)
1019(deftest-moving-delete-1 Q (10 20) (20 4) (10 20) t t)
1020(deftest-moving-delete-1 R (10 20) (5 5) (5 15) t t)
1021(deftest-moving-delete-1 S (10 20) (10 3) (10 17) t t)
1022(deftest-moving-delete-1 T (10 20) (20 4) (10 20) t t)
1023
1024;; empty, no fa, no ra
1025(deftest-moving-delete-1 U (15 15) (20 4) (15 15) nil nil)
1026(deftest-moving-delete-1 V (15 15) (5 5) (10 10) nil nil)
1027(deftest-moving-delete-1 W (15 15) (15 3) (15 15) nil nil)
1028
1029;; empty no fa, ra
1030(deftest-moving-delete-1 X (15 15) (20 4) (15 15) nil t)
1031(deftest-moving-delete-1 Y (15 15) (5 5) (10 10) nil t)
1032(deftest-moving-delete-1 Z (15 15) (15 3) (15 15) nil t)
1033
1034;; empty, fa, no ra
1035(deftest-moving-delete-1 a (15 15) (20 4) (15 15) t nil)
1036(deftest-moving-delete-1 b (15 15) (5 5) (10 10) t nil)
1037(deftest-moving-delete-1 c (15 15) (15 3) (15 15) t nil)
1038
1039;; empty, fa, ra
1040(deftest-moving-delete-1 d (15 15) (20 4) (15 15) t t)
1041(deftest-moving-delete-1 e (15 15) (5 5) (10 10) t t)
1042(deftest-moving-delete-1 f (15 15) (15 3) (15 15) t t)
1043
1044
1045;; +==========================================================================+
1046;; | make-indirect-buffer
1047;; +==========================================================================+
1048
1049;; Check if overlays are cloned/separate from indirect buffer.
1050(ert-deftest test-make-indirect-buffer-1 ()
1051  (with-temp-buffer
1052    (dotimes (_ 10) (make-overlay 1 1))
1053    (let (indirect clone)
1054      (unwind-protect
1055          (progn
1056            (setq indirect (make-indirect-buffer
1057                            (current-buffer) "indirect"))
1058            (with-current-buffer indirect
1059              (should-not (overlays-in (point-min) (point-max)))
1060              (dotimes (_ 20) (make-overlay 1 1))
1061              (should (= 20 (length (overlays-in (point-min) (point-max)))))
1062              (delete-all-overlays)
1063              (should-not (overlays-in (point-min) (point-max))))
1064            (should (= 10 (length (overlays-in (point-min) (point-max)))))
1065            (setq clone (make-indirect-buffer
1066                         (current-buffer) "clone" 'clone))
1067            (with-current-buffer clone
1068              (should (= 10 (length (overlays-in (point-min) (point-max)))))
1069              (dotimes (_ 30) (make-overlay 1 1))
1070              (should (= 40 (length (overlays-in (point-min) (point-max))))))
1071            ;; back in temp buffer
1072            (should (= 10 (length (overlays-in (point-min) (point-max)))))
1073            (with-current-buffer clone
1074              (mapc #'delete-overlay
1075                    (seq-take (overlays-in (point-min) (point-max)) 10))
1076              (should (= 30 (length (overlays-in (point-min) (point-max))))))
1077            (should (= 10 (length (overlays-in (point-min) (point-max)))))
1078            (delete-all-overlays)
1079            (with-current-buffer clone
1080              (should (= 30 (length (overlays-in (point-min) (point-max)))))))
1081        (when (buffer-live-p clone)
1082          (kill-buffer clone))
1083        (when (buffer-live-p indirect)
1084          (kill-buffer indirect))))))
1085
1086
1087
1088;; +==========================================================================+
1089;; | buffer-swap-text
1090;; +==========================================================================+
1091
1092(defmacro buffer-tests--with-temp-buffers (vars &rest body)
1093  (declare (indent 1) (debug (sexp &rest form)))
1094  (if (null vars)
1095      `(progn ,@body)
1096    `(with-temp-buffer
1097       (let ((,(car vars) (current-buffer)))
1098         (buffer-tests--with-temp-buffers ,(cdr vars) ,@body)))))
1099
1100;; basic
1101(ert-deftest test-buffer-swap-text-1 ()
1102  (buffer-tests--with-temp-buffers (buffer other)
1103    (with-current-buffer buffer
1104      (let ((ov (make-overlay 1 1)))
1105        (buffer-swap-text other)
1106        (should-not (overlays-in 1 1))
1107        (with-current-buffer other
1108          (should (overlays-in 1 1))
1109          (should (eq ov (car (overlays-in 1 1)))))))))
1110
1111;; properties
1112(ert-deftest test-buffer-swap-text-2 ()
1113  (buffer-tests--with-temp-buffers (buffer other)
1114    (with-current-buffer other
1115      (overlay-put (make-overlay 1 1) 'buffer 'other))
1116    (with-current-buffer buffer
1117      (overlay-put (make-overlay 1 1) 'buffer 'buffer)
1118      (buffer-swap-text other)
1119      (should (= 1 (length (overlays-in 1 1))))
1120      (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'other)))
1121    (with-current-buffer other
1122      (should (= 1 (length (overlays-in 1 1))))
1123      (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'buffer)))))
1124
1125
1126;; +==========================================================================+
1127;; | priorities
1128;; +==========================================================================+
1129
1130(ert-deftest test-overlay-priorities-1 ()
1131  (with-temp-buffer
1132    (insert " ")
1133    (dotimes (i 10)
1134      (let ((ov (make-overlay 1 2)))
1135        (overlay-put ov 'priority i)
1136        (overlay-put ov 'value i)))
1137    (should (eq 9 (get-char-property 1 'value)))))
1138
1139(ert-deftest test-overlay-priorities-2 ()
1140  (with-temp-buffer
1141    (insert " ")
1142    (dotimes (j 10)
1143      (let* ((i (- 9 j))
1144             (ov (make-overlay 1 2)))
1145        (overlay-put ov 'priority i)
1146        (overlay-put ov 'value i)))
1147    (should (eq 9 (get-char-property 1 'value)))))
1148
1149
1150;; +==========================================================================+
1151;; | Other
1152;; +==========================================================================+
1153
1154(defun test-overlay-regions ()
1155  (sort (mapcar (lambda (ov)
1156                  (cons (overlay-start ov)
1157                        (overlay-end ov)))
1158                (overlays-in (point-min)
1159                             (point-max)))
1160        (lambda (o1 o2)
1161          (or (< (car o1) (car o2))
1162              (and (= (car o1) (car o2))
1163                   (< (cdr o1) (cdr o2)))))))
1164
1165;; This test used to fail.
1166(ert-deftest overlay-complex-delete-with-offset ()
1167  (with-temp-buffer
1168    (let (todelete)
1169      (insert (make-string 1000 ?\s))
1170      (make-overlay 1 2 nil t nil)
1171      (make-overlay 2 3 nil t nil)
1172      (make-overlay 3 4 nil t nil)
1173      (make-overlay 4 5 nil t nil)
1174      (setq todelete (make-overlay 280 287 nil t nil))
1175      (make-overlay 265 275 nil t nil)
1176      (make-overlay 329 386 nil t nil)
1177      (make-overlay 386 390 nil t nil)
1178      (goto-char 50)
1179      (delete-char 50)
1180      (goto-char 1)
1181      (delete-char 2)
1182      (delete-overlay todelete)
1183      (should (equal (test-overlay-regions)
1184                     '((1 . 1) (1 . 1) (1 . 2) (2 . 3) (213 . 223) (277 . 334) (334 . 338)))))))
1185
1186;; This test used to fail.
1187(ert-deftest overlay-complex-insert-1 ()
1188  (with-temp-buffer
1189    (insert "          ")
1190    (make-overlay 8 11 nil nil t)
1191    (make-overlay 2 7 nil nil nil)
1192    (make-overlay 2 4 nil t nil)
1193    (goto-char 1)
1194    (insert "     ")
1195    (should (equal (test-overlay-regions)
1196                   '((7 . 9)
1197                     (7 . 12)
1198                     (13 . 16))))))
1199
1200;; This test used to fail.
1201(ert-deftest overlay-complex-insert-2 ()
1202  (with-temp-buffer
1203    (insert (make-string 100 ?\s))
1204    (make-overlay 77 7 nil nil t)
1205    (make-overlay 21 53 nil t t)
1206    (make-overlay 84 14 nil nil nil)
1207    (make-overlay 38 69 nil t nil)
1208    (make-overlay 93 15 nil nil t)
1209    (make-overlay 73 48 nil t t)
1210    (make-overlay 96 51 nil t t)
1211    (make-overlay 6 43 nil t t)
1212    (make-overlay 15 100 nil t t)
1213    (make-overlay 22 17 nil nil nil)
1214    (make-overlay 72 45 nil t nil)
1215    (make-overlay 2 74 nil nil t)
1216    (make-overlay 15 29 nil t t)
1217    (make-overlay 17 34 nil t t)
1218    (make-overlay 101 66 nil t nil)
1219    (make-overlay 94 24 nil nil nil)
1220    (goto-char 78)
1221    (insert "           ")
1222    (narrow-to-region 47 19)
1223    (goto-char 46)
1224    (widen)
1225    (narrow-to-region 13 3)
1226    (goto-char 9)
1227    (delete-char 0)
1228    (goto-char 11)
1229    (insert "           ")
1230    (goto-char 3)
1231    (insert "          ")
1232    (goto-char 8)
1233    (insert "       ")
1234    (goto-char 26)
1235    (insert "  ")
1236    (goto-char 14)
1237    (widen)
1238    (narrow-to-region 71 35)
1239    (should
1240     (equal (test-overlay-regions)
1241            '((2 . 104)
1242              (23 . 73)
1243              (24 . 107)
1244              (44 . 125)
1245              (45 . 59)
1246              (45 . 134)
1247              (45 . 141)
1248              (47 . 52)
1249              (47 . 64)
1250              (51 . 83)
1251              (54 . 135)
1252              (68 . 99))))))
1253
1254(ert-deftest test-overlay-multibyte-transition-1 ()
1255  (with-temp-buffer
1256    (set-buffer-multibyte t)
1257    (insert "ääää")
1258    ;; aeaeaeae
1259    ;; 1 2 3 4 5
1260    ;; 123456789
1261    (let ((nonempty-bob (make-overlay 1 2))
1262          (empty-bob    (make-overlay 1 1))
1263          (empty        (make-overlay 2 2))
1264          (nonempty     (make-overlay 2 4))
1265          (nonempty-eob (make-overlay 4 5))
1266          (empty-eob    (make-overlay 5 5)))
1267      (set-buffer-multibyte nil)
1268      (cl-macrolet
1269          ((ovshould (ov begin end)
1270             `(should (equal (list (overlay-start ,ov) (overlay-end ,ov))
1271                             (list ,begin ,end)))))
1272        (ovshould nonempty-bob 1 3)
1273        (ovshould empty-bob    1 1)
1274        (ovshould empty        3 3)
1275        (ovshould nonempty     3 7)
1276        (ovshould nonempty-eob 7 9)
1277        (ovshould empty-eob    9 9)))))
1278
1279(ert-deftest test-overlay-multibyte-transition-2 ()
1280  (with-temp-buffer
1281    (set-buffer-multibyte t)
1282    (insert "ääää")
1283    (set-buffer-multibyte nil)
1284    ;; aeaeaeae
1285    ;; 1 2 3 4 5
1286    ;; 123456789
1287    (let ((nonempty-bob-end (make-overlay 1 2))
1288          (nonempty-bob-beg (make-overlay 1 3))
1289          (empty-bob        (make-overlay 1 1))
1290          (empty-beg        (make-overlay 3 3))
1291          (empty-end        (make-overlay 2 2))
1292          (nonempty-beg-beg (make-overlay 3 7))
1293          (nonempty-beg-end (make-overlay 3 8))
1294          (nonempty-end-beg (make-overlay 4 7))
1295          (nonempty-end-end (make-overlay 4 8))
1296          (nonempty-eob-beg (make-overlay 5 9))
1297          (nonempty-eob-end (make-overlay 6 9))
1298          (empty-eob        (make-overlay 9 9)))
1299      (set-buffer-multibyte t)
1300      (cl-macrolet
1301          ((ovshould (ov begin end)
1302             `(should (equal (list (overlay-start ,ov) (overlay-end ,ov))
1303                             (list ,begin ,end)))))
1304        (ovshould nonempty-bob-end 1 2)
1305        (ovshould nonempty-bob-beg 1 2)
1306        (ovshould empty-bob        1 1)
1307        (ovshould empty-beg        2 2)
1308        (ovshould empty-end        2 2)
1309        (ovshould nonempty-beg-beg 2 4)
1310        (ovshould nonempty-beg-end 2 5)
1311        (ovshould nonempty-end-beg 3 4)
1312        (ovshould nonempty-end-end 3 5)
1313        (ovshould nonempty-eob-beg 3 5)
1314        (ovshould nonempty-eob-end 4 5)
1315        (ovshould empty-eob        5 5)))))
1316
1317(ert-deftest buffer-multibyte-overlong-sequences ()
1318  (dolist (uni '("\xE0\x80\x80"
1319                 "\xF0\x80\x80\x80"
1320                 "\xF8\x8F\xBF\xBF\x80"))
1321    (let ((multi (string-to-multibyte uni)))
1322      (should
1323       (string-equal
1324        multi
1325        (with-temp-buffer
1326          (set-buffer-multibyte nil)
1327          (insert uni)
1328          (set-buffer-multibyte t)
1329          (buffer-string)))))))
1330
1331;; https://debbugs.gnu.org/33492
1332(ert-deftest buffer-tests-buffer-local-variables-undo ()
1333  "Test that `buffer-undo-list' appears in `buffer-local-variables'."
1334  (with-temp-buffer
1335    (should (assq 'buffer-undo-list (buffer-local-variables)))))
1336
1337(ert-deftest buffer-tests-inhibit-buffer-hooks ()
1338  "Test `get-buffer-create' argument INHIBIT-BUFFER-HOOKS."
1339  (let* (run-bluh (bluh (lambda () (setq run-bluh t))))
1340    (unwind-protect
1341        (let* ( run-kbh  (kbh  (lambda () (setq run-kbh  t)))
1342                run-kbqf (kbqf (lambda () (setq run-kbqf t))) )
1343
1344          ;; Inhibited.
1345          (add-hook 'buffer-list-update-hook bluh)
1346          (with-current-buffer (generate-new-buffer " foo" t)
1347            (add-hook 'kill-buffer-hook kbh nil t)
1348            (add-hook 'kill-buffer-query-functions kbqf nil t)
1349            (kill-buffer))
1350          (with-temp-buffer (ignore))
1351          (with-output-to-string (ignore))
1352          (should-not run-bluh)
1353          (should-not run-kbh)
1354          (should-not run-kbqf)
1355
1356          ;; Not inhibited.
1357          (with-current-buffer (generate-new-buffer " foo")
1358            (should run-bluh)
1359            (add-hook 'kill-buffer-hook kbh nil t)
1360            (add-hook 'kill-buffer-query-functions kbqf nil t)
1361            (kill-buffer))
1362          (should run-kbh)
1363          (should run-kbqf))
1364      (remove-hook 'buffer-list-update-hook bluh))))
1365
1366(ert-deftest buffer-tests-inhibit-buffer-hooks-indirect ()
1367  "Indirect buffers do not call `get-buffer-create'."
1368  (dolist (inhibit '(nil t))
1369    (let ((base (get-buffer-create "foo" inhibit)))
1370      (unwind-protect
1371          (dotimes (_i 11)
1372            (let* (flag*
1373                   (flag (lambda () (prog1 t (setq flag* t))))
1374                   (indirect (make-indirect-buffer base "foo[indirect]" nil
1375                                                   inhibit)))
1376              (unwind-protect
1377                  (progn
1378                    (with-current-buffer indirect
1379                      (add-hook 'kill-buffer-query-functions flag nil t))
1380                    (kill-buffer indirect)
1381                    (if inhibit
1382                        (should-not flag*)
1383                      (should flag*)))
1384                (let (kill-buffer-query-functions)
1385                  (when (buffer-live-p indirect)
1386                    (kill-buffer indirect))))))
1387        (let (kill-buffer-query-functions)
1388          (when (buffer-live-p base)
1389            (kill-buffer base)))))))
1390
1391(ert-deftest zero-length-overlays-and-not ()
1392  (with-temp-buffer
1393    (insert "hello")
1394    (let ((long-overlay (make-overlay 2 4))
1395          (zero-overlay (make-overlay 3 3)))
1396      ;; Exclude.
1397      (should (= (length (overlays-at 3)) 1))
1398      (should (eq (car (overlays-at 3)) long-overlay))
1399      ;; Include.
1400      (should (= (length (overlays-in 3 3)) 2))
1401      (should (memq long-overlay (overlays-in 3 3)))
1402      (should (memq zero-overlay (overlays-in 3 3))))))
1403
1404(ert-deftest test-remove-overlays ()
1405  (with-temp-buffer
1406    (insert "foo")
1407    (make-overlay (point) (point))
1408    (should (= (length (overlays-in (point-min) (point-max))) 1))
1409    (remove-overlays)
1410    (should (= (length (overlays-in (point-min) (point-max))) 0)))
1411
1412  (with-temp-buffer
1413    (insert "foo")
1414    (goto-char 2)
1415    (make-overlay (point) (point))
1416    ;; We only count zero-length overlays at the end of the buffer.
1417    (should (= (length (overlays-in 1 2)) 0))
1418    (narrow-to-region 1 2)
1419    ;; We've now narrowed, so the zero-length overlay is at the end of
1420    ;; the (accessible part of the) buffer.
1421    (should (= (length (overlays-in 1 2)) 1))
1422    (remove-overlays)
1423    (should (= (length (overlays-in (point-min) (point-max))) 0))))
1424
1425(ert-deftest test-kill-buffer-auto-save-default ()
1426  (ert-with-temp-file file
1427    (let (auto-save)
1428      ;; Always answer yes.
1429      (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
1430        (unwind-protect
1431            (progn
1432              (find-file file)
1433              (auto-save-mode t)
1434              (insert "foo\n")
1435              (should buffer-auto-save-file-name)
1436              (setq auto-save buffer-auto-save-file-name)
1437              (do-auto-save)
1438              (should (file-exists-p auto-save))
1439              (kill-buffer (current-buffer))
1440              (should (file-exists-p auto-save)))
1441          (when auto-save
1442            (ignore-errors (delete-file auto-save))))))))
1443
1444(ert-deftest test-kill-buffer-auto-save-delete ()
1445  (ert-with-temp-file file
1446    (let (auto-save)
1447      (should (file-exists-p file))
1448      (setq kill-buffer-delete-auto-save-files t)
1449      ;; Always answer yes.
1450      (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
1451        (unwind-protect
1452            (progn
1453              (find-file file)
1454              (auto-save-mode t)
1455              (insert "foo\n")
1456              (should buffer-auto-save-file-name)
1457              (setq auto-save buffer-auto-save-file-name)
1458              (do-auto-save)
1459              (should (file-exists-p auto-save))
1460              ;; This should delete the auto-save file.
1461              (kill-buffer (current-buffer))
1462              (should-not (file-exists-p auto-save)))
1463          (ignore-errors (delete-file file))
1464          (when auto-save
1465            (ignore-errors (delete-file auto-save)))))
1466      ;; Answer no to deletion.
1467      (cl-letf (((symbol-function #'yes-or-no-p)
1468                 (lambda (prompt)
1469                   (not (string-search "Delete auto-save file" prompt)))))
1470        (unwind-protect
1471            (progn
1472              (find-file file)
1473              (auto-save-mode t)
1474              (insert "foo\n")
1475              (should buffer-auto-save-file-name)
1476              (setq auto-save buffer-auto-save-file-name)
1477              (do-auto-save)
1478              (should (file-exists-p auto-save))
1479              ;; This should not delete the auto-save file.
1480              (kill-buffer (current-buffer))
1481              (should (file-exists-p auto-save)))
1482          (when auto-save
1483            (ignore-errors (delete-file auto-save))))))))
1484
1485;;; buffer-tests.el ends here
1486