aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMattias Engdegård2024-05-13 10:44:05 +0200
committerMattias Engdegård2024-05-13 12:39:41 +0200
commit49e243c0c85d18fc775970d9ebd846eba3a6866e (patch)
tree2ee32a6f81bfe93b7d0f3f84d83ee82f655808d1 /test
parent334fb0ddfe603097c3493297c3e78a185b22d1af (diff)
downloademacs-49e243c0c85d18fc775970d9ebd846eba3a6866e.tar.gz
emacs-49e243c0c85d18fc775970d9ebd846eba3a6866e.zip
Avoid resizing mutation in subst-char-in-string, take two
This time we take care to preserve properties, and add a test. * lisp/subr.el (subst-char-in-string): Use string-replace to avoid resizing mutation and O(n^2) time. * test/lisp/subr-tests.el (subr--subst-char-in-string): New test.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/subr-tests.el48
1 files changed, 48 insertions, 0 deletions
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 119c124f3a5..6f28e057342 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -1330,5 +1330,53 @@ final or penultimate step during initialization."))
1330 (t x) (:success (1+ x))) 1330 (t x) (:success (1+ x)))
1331 '(error ""))))) 1331 '(error "")))))
1332 1332
1333(ert-deftest subr--subst-char-in-string ()
1334 ;; Cross-validate `subst-char-in-string' with `string-replace',
1335 ;; which should produce the same results when there are no properties.
1336 (dolist (str '("ananas" "na\x80ma\x80s" "hétérogénéité"
1337 "Ω, Ω, Ω" "é-\x80-\x80"))
1338 (dolist (mb '(nil t))
1339 (unless (and (not mb) (multibyte-string-p str))
1340 (let ((str (if (and mb (not (multibyte-string-p str)))
1341 (string-to-multibyte str)
1342 str)))
1343 (dolist (inplace '(nil t))
1344 (dolist (from '(?a ?é ?Ω #x80 #x3fff80))
1345 (dolist (to '(?o ?á ?ƒ ?☃ #x1313f #xff #x3fffc9))
1346 ;; Can't put a non-byte value in a non-ASCII unibyte string.
1347 (unless (and (not mb) (> to #xff)
1348 (not (string-match-p (rx bos (* ascii) eos) str)))
1349 (let* ((in (copy-sequence str))
1350 (ref (if (and (not mb) (> from #xff))
1351 in ; nothing to replace
1352 (string-replace
1353 (if (and (not mb) (<= from #xff))
1354 (unibyte-string from)
1355 (string from))
1356 (if (and (not mb) (<= to #xff))
1357 (unibyte-string to)
1358 (string to))
1359 in)))
1360 (out (subst-char-in-string from to in inplace)))
1361 (should (equal out ref))
1362 (if inplace
1363 (should (eq out in))
1364 (should (equal in str))))))))))))
1365
1366 ;; Verify that properties are preserved.
1367 (dolist (str (list "cocoa" (string-to-multibyte "cocoa") "écalé"))
1368 (dolist (from '(?a ?o ?c ?é))
1369 (dolist (to '(?i ?à ?☃))
1370 (let ((in (copy-sequence str)))
1371 (put-text-property 0 5 'alpha 1 in)
1372 (put-text-property 1 4 'beta 2 in)
1373 (put-text-property 0 2 'gamma 3 in)
1374 (put-text-property 1 4 'delta 4 in)
1375 (put-text-property 2 3 'epsilon 5 in)
1376 (let* ((props-in (copy-tree (object-intervals in)))
1377 (out (subst-char-in-string from to in))
1378 (props-out (object-intervals out)))
1379 (should (equal props-out props-in))))))))
1380
1333(provide 'subr-tests) 1381(provide 'subr-tests)
1334;;; subr-tests.el ends here 1382;;; subr-tests.el ends here