diff options
Diffstat (limited to 'test/src')
29 files changed, 7941 insertions, 0 deletions
diff --git a/test/src/alloc-tests.el b/test/src/alloc-tests.el new file mode 100644 index 00000000000..97c6b4f8070 --- /dev/null +++ b/test/src/alloc-tests.el @@ -0,0 +1,33 @@ +;;; alloc-tests.el --- alloc tests -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; Author: Daniel Colascione <dancol@dancol.org> +;; Keywords: + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(ert-deftest finalizer-object-type () + (should (equal (type-of (make-finalizer nil)) 'finalizer))) diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el new file mode 100644 index 00000000000..62875216a31 --- /dev/null +++ b/test/src/buffer-tests.el @@ -0,0 +1,48 @@ +;;; buffer-tests.el --- tests for buffer.c functions -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest overlay-modification-hooks-message-other-buf () + "Test for bug#21824. +After a modification-hook has been run and there is an overlay in +the *Messages* buffer, the message coalescing [2 times] wrongly +runs the modification-hook of the overlay in the 1st buffer, but +with parameters from the *Messages* buffer modification." + (let ((buf nil) + (msg-ov nil)) + (with-temp-buffer + (insert "123") + (overlay-put (make-overlay 1 3) + 'modification-hooks + (list (lambda (&rest _) + (setq buf (current-buffer))))) + (goto-char 2) + (insert "x") + (unwind-protect + (progn + (setq msg-ov (make-overlay 1 1 (get-buffer-create "*Messages*"))) + (message "a message") + (message "a message") + (should (eq buf (current-buffer)))) + (when msg-ov (delete-overlay msg-ov)))))) + +;;; buffer-tests.el ends here diff --git a/test/src/callproc-tests.el b/test/src/callproc-tests.el new file mode 100644 index 00000000000..46541aba78c --- /dev/null +++ b/test/src/callproc-tests.el @@ -0,0 +1,39 @@ +;;; callproc-tests.el --- callproc.c tests -*- lexical-binding: t -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) +(eval-when-compile (require 'cl-lib)) + +(ert-deftest initial-environment-preserved () + "Check that `initial-environment' is not modified by Emacs (Bug #10980)." + (skip-unless (eq system-type 'windows-nt)) + (cl-destructuring-bind (initial-shell shell) + (with-temp-buffer + (let ((process-environment (cons "SHELL" process-environment))) + (call-process (expand-file-name invocation-name invocation-directory) + nil t nil + "--batch" "-Q" "--eval" + (prin1-to-string + '(progn (prin1 (getenv-internal "SHELL" initial-environment)) + (prin1 (getenv-internal "SHELL")))))) + (split-string-and-unquote (buffer-string))) + (should (equal initial-shell "nil")) + (should-not (equal initial-shell shell)))) diff --git a/test/src/chartab-tests.el b/test/src/chartab-tests.el new file mode 100644 index 00000000000..016ddcdde61 --- /dev/null +++ b/test/src/chartab-tests.el @@ -0,0 +1,51 @@ +;;; chartab-tests.el --- Tests for char-tab.c + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Eli Zaretskii <eliz@gnu.org> + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(defun chartab-set-and-test (rng) + (let ((tbl (make-char-table nil nil)) + (from (car rng)) + (to (cdr rng))) + (set-char-table-range tbl rng t) + (should (eq (aref tbl from) t)) + (should (eq (aref tbl to) t)) + (should (eq (aref tbl (/ (+ from to) 2)) t)) + (when (< to (max-char)) + (should-not (eq (aref tbl (1+ to)) t))) + (when (> from 0) + (should-not (eq (aref tbl (1- from)) t))))) + +(ert-deftest chartab-test-range-setting () + (mapc (lambda (elt) + (chartab-set-and-test elt)) + '((0 . 127) + (128 . 256) + (#x1000 . #x1fff) + (#x1001 . #x2000) + (#x10000 . #x20000) + (#x10001 . #x1ffff) + (#x20000 . #x30000) + (#xe0e00 . #xe0ef6) + ))) + +(provide 'chartab-tests) +;;; chartab-tests.el ends here diff --git a/test/src/cmds-tests.el b/test/src/cmds-tests.el new file mode 100644 index 00000000000..4a30d9872a1 --- /dev/null +++ b/test/src/cmds-tests.el @@ -0,0 +1,34 @@ +;;; cmds-tests.el --- Testing some Emacs commands + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Nicolas Richard <youngfrog@members.fsf.org> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; + +;;; Code: + + +(ert-deftest self-insert-command-with-negative-argument () + "Test `self-insert-command' with a negative argument." + (let ((last-command-event ?a)) + (should-error (self-insert-command -1)))) + +(provide 'cmds-tests) +;;; cmds-tests.el ends here diff --git a/test/src/coding-tests.el b/test/src/coding-tests.el new file mode 100644 index 00000000000..bd494bc26f8 --- /dev/null +++ b/test/src/coding-tests.el @@ -0,0 +1,383 @@ +;;; coding-tests.el --- tests for text encoding and decoding + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Eli Zaretskii <eliz@gnu.org> +;; Author: Kenichi Handa <handa@gnu.org> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +;; Directory to hold test data files. +(defvar coding-tests-workdir + (expand-file-name "coding-tests" temporary-file-directory)) + +;; Remove all generated test files. +(defun coding-tests-remove-files () + (delete-directory coding-tests-workdir t)) + +(ert-deftest ert-test-coding-bogus-coding-systems () + (unwind-protect + (let (test-file) + (or (file-directory-p coding-tests-workdir) + (mkdir coding-tests-workdir t)) + (setq test-file (expand-file-name "nonexistent" coding-tests-workdir)) + (if (file-exists-p test-file) + (delete-file test-file)) + (should-error + (let ((coding-system-for-read 'bogus)) + (insert-file-contents test-file))) + ;; See bug #21602. + (setq test-file (expand-file-name "writing" coding-tests-workdir)) + (should-error + (let ((coding-system-for-write (intern "\"us-ascii\""))) + (write-region "some text" nil test-file)))) + (coding-tests-remove-files))) + +;; See issue #5251. +(ert-deftest ert-test-unibyte-buffer-dos-eol-decode () + (with-temp-buffer + (set-buffer-multibyte nil) + (insert (encode-coding-string "あ" 'euc-jp) "\xd" "\n") + (decode-coding-region (point-min) (point-max) 'euc-jp-dos) + (should-not (string-match-p "\^M" (buffer-string))))) + +;; Return the contents (specified by CONTENT-TYPE; ascii, latin, or +;; binary) of a test file. +(defun coding-tests-file-contents (content-type) + (let* ((ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n") + (latin (concat ascii "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ\n")) + (binary (string-to-multibyte + (concat (string-as-unibyte latin) + (unibyte-string #xC0 #xC1 ?\n))))) + (cond ((eq content-type 'ascii) ascii) + ((eq content-type 'latin) latin) + ((eq content-type 'binary) binary) + (t + (error "Invalid file content type: %s" content-type))))) + +;; Generate FILE with CONTENTS encoded by CODING-SYSTEM. +;; whose encoding specified by CODING-SYSTEM. +(defun coding-tests-gen-file (file contents coding-system) + (or (file-directory-p coding-tests-workdir) + (mkdir coding-tests-workdir t)) + (setq file (expand-file-name file coding-tests-workdir)) + (with-temp-file file + (set-buffer-file-coding-system coding-system) + (insert contents)) + file) + +;;; The following three functions are filters for contents of a test +;;; file. + +;; Convert all LFs to CR LF sequences in the string STR. +(defun coding-tests-lf-to-crlf (str) + (with-temp-buffer + (insert str) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (delete-char -1) + (insert "\r\n")) + (buffer-string))) + +;; Convert all LFs to CRs in the string STR. +(defun coding-tests-lf-to-cr (str) + (with-temp-buffer + (insert str) + (subst-char-in-region (point-min) (point-max) ?\n ?\r) + (buffer-string))) + +;; Convert all LFs to LF LF sequences in the string STR. +(defun coding-tests-lf-to-lflf (str) + (with-temp-buffer + (insert str) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (insert "\n")) + (buffer-string))) + +;; Prepend the UTF-8 BOM to STR. +(defun coding-tests-add-bom (str) + (concat "\xfeff" str)) + +;; Return the name of test file whose contents specified by +;; CONTENT-TYPE and whose encoding specified by CODING-SYSTEM. +(defun coding-tests-filename (content-type coding-system &optional ext) + (if ext + (expand-file-name (format "%s-%s.%s" content-type coding-system ext) + coding-tests-workdir) + (expand-file-name (format "%s-%s" content-type coding-system) + coding-tests-workdir))) + + +;;; Check ASCII optimizing decoder + +;; Generate a test file whose contents specified by CONTENT-TYPE and +;; whose encoding specified by CODING-SYSTEM. +(defun coding-tests-ao-gen-file (content-type coding-system) + (let ((file (coding-tests-filename content-type coding-system))) + (coding-tests-gen-file file + (coding-tests-file-contents content-type) + coding-system))) + +;; Test the decoding of a file whose contents and encoding are +;; specified by CONTENT-TYPE and WRITE-CODING. The test passes if the +;; file is read by READ-CODING and detected as DETECTED-CODING and the +;; contents is correctly decoded. +;; Optional 5th arg TRANSLATOR is a function to translate the original +;; file contents to match with the expected result of decoding. For +;; instance, when a file of dos eol-type is read by unix eol-type, +;; `decode-test-lf-to-crlf' must be specified. + +(defun coding-tests (content-type write-coding read-coding detected-coding + &optional translator) + (prefer-coding-system 'utf-8-auto) + (let ((filename (coding-tests-filename content-type write-coding))) + (with-temp-buffer + (let ((coding-system-for-read read-coding) + (contents (coding-tests-file-contents content-type)) + (disable-ascii-optimization nil)) + (if translator + (setq contents (funcall translator contents))) + (insert-file-contents filename) + (if (and (coding-system-equal buffer-file-coding-system detected-coding) + (string= (buffer-string) contents)) + nil + (list buffer-file-coding-system + (string-to-list (buffer-string)) + (string-to-list contents))))))) + +(ert-deftest ert-test-coding-ascii () + (unwind-protect + (progn + (dolist (eol-type '(unix dos mac)) + (coding-tests-ao-gen-file 'ascii eol-type)) + (should-not (coding-tests 'ascii 'unix 'undecided 'unix)) + (should-not (coding-tests 'ascii 'dos 'undecided 'dos)) + (should-not (coding-tests 'ascii 'dos 'dos 'dos)) + (should-not (coding-tests 'ascii 'mac 'undecided 'mac)) + (should-not (coding-tests 'ascii 'mac 'mac 'mac)) + (should-not (coding-tests 'ascii 'dos 'utf-8 'utf-8-dos)) + (should-not (coding-tests 'ascii 'dos 'unix 'unix + 'coding-tests-lf-to-crlf)) + (should-not (coding-tests 'ascii 'mac 'dos 'dos + 'coding-tests-lf-to-cr)) + (should-not (coding-tests 'ascii 'dos 'mac 'mac + 'coding-tests-lf-to-lflf))) + (coding-tests-remove-files))) + +(ert-deftest ert-test-coding-latin () + (unwind-protect + (progn + (dolist (coding '("utf-8" "utf-8-with-signature")) + (dolist (eol-type '("unix" "dos" "mac")) + (coding-tests-ao-gen-file 'latin + (intern (concat coding "-" eol-type))))) + (should-not (coding-tests 'latin 'utf-8-unix 'undecided 'utf-8-unix)) + (should-not (coding-tests 'latin 'utf-8-unix 'utf-8-unix 'utf-8-unix)) + (should-not (coding-tests 'latin 'utf-8-dos 'undecided 'utf-8-dos)) + (should-not (coding-tests 'latin 'utf-8-dos 'utf-8-dos 'utf-8-dos)) + (should-not (coding-tests 'latin 'utf-8-mac 'undecided 'utf-8-mac)) + (should-not (coding-tests 'latin 'utf-8-mac 'utf-8-mac 'utf-8-mac)) + (should-not (coding-tests 'latin 'utf-8-dos 'unix 'utf-8-unix + 'coding-tests-lf-to-crlf)) + (should-not (coding-tests 'latin 'utf-8-mac 'dos 'utf-8-dos + 'coding-tests-lf-to-cr)) + (should-not (coding-tests 'latin 'utf-8-dos 'mac 'utf-8-mac + 'coding-tests-lf-to-lflf)) + (should-not (coding-tests 'latin 'utf-8-with-signature-unix 'undecided + 'utf-8-with-signature-unix)) + (should-not (coding-tests 'latin 'utf-8-with-signature-unix 'utf-8-auto + 'utf-8-with-signature-unix)) + (should-not (coding-tests 'latin 'utf-8-with-signature-dos 'undecided + 'utf-8-with-signature-dos)) + (should-not (coding-tests 'latin 'utf-8-with-signature-unix 'utf-8 + 'utf-8-unix 'coding-tests-add-bom)) + (should-not (coding-tests 'latin 'utf-8-with-signature-unix 'utf-8 + 'utf-8-unix 'coding-tests-add-bom))) + (coding-tests-remove-files))) + +(ert-deftest ert-test-coding-binary () + (unwind-protect + (progn + (dolist (eol-type '("unix" "dos" "mac")) + (coding-tests-ao-gen-file 'binary + (intern (concat "raw-text" "-" eol-type)))) + (should-not (coding-tests 'binary 'raw-text-unix 'undecided + 'raw-text-unix)) + (should-not (coding-tests 'binary 'raw-text-dos 'undecided + 'raw-text-dos)) + (should-not (coding-tests 'binary 'raw-text-mac 'undecided + 'raw-text-mac)) + (should-not (coding-tests 'binary 'raw-text-dos 'unix + 'raw-text-unix 'coding-tests-lf-to-crlf)) + (should-not (coding-tests 'binary 'raw-text-mac 'dos + 'raw-text-dos 'coding-tests-lf-to-cr)) + (should-not (coding-tests 'binary 'raw-text-dos 'mac + 'raw-text-mac 'coding-tests-lf-to-lflf))) + (coding-tests-remove-files))) + + +;;; Check the coding system `prefer-utf-8'. + +;; Read FILE. Check if the encoding was detected as DETECT. If +;; PREFER is non-nil, prefer that coding system before reading. + +(defun coding-tests-prefer-utf-8-read (file detect prefer) + (with-temp-buffer + (with-coding-priority (if prefer (list prefer)) + (insert-file-contents file)) + (if (eq buffer-file-coding-system detect) + nil + (format "Invalid detection: %s" buffer-file-coding-system)))) + +;; Read FILE, modify it, and write it. Check if the coding system +;; used for writing was CODING. If CODING-TAG is non-nil, insert +;; coding tag with it before writing. If STR is non-nil, insert it +;; before writing. + +(defun coding-tests-prefer-utf-8-write (file coding-tag coding + &optional str) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (if coding-tag + (insert (format ";; -*- coding: %s; -*-\n" coding-tag)) + (insert ";;\n")) + (if str + (insert str)) + (write-file (coding-tests-filename 'test 'test "el")) + (if (coding-system-equal buffer-file-coding-system coding) + nil + (format "Incorrect encoding: %s" last-coding-system-used)))) + +(ert-deftest ert-test-coding-prefer-utf-8 () + (unwind-protect + (let ((ascii (coding-tests-gen-file "ascii.el" + (coding-tests-file-contents 'ascii) + 'unix)) + (latin (coding-tests-gen-file "utf-8.el" + (coding-tests-file-contents 'latin) + 'utf-8-unix))) + (should-not (coding-tests-prefer-utf-8-read + ascii 'prefer-utf-8-unix nil)) + (should-not (coding-tests-prefer-utf-8-read + latin 'utf-8-unix nil)) + (should-not (coding-tests-prefer-utf-8-read + latin 'utf-8-unix 'iso-8859-1)) + (should-not (coding-tests-prefer-utf-8-read + latin 'utf-8-unix 'sjis)) + (should-not (coding-tests-prefer-utf-8-write + ascii nil 'prefer-utf-8-unix)) + (should-not (coding-tests-prefer-utf-8-write + ascii 'iso-8859-1 'iso-8859-1-unix)) + (should-not (coding-tests-prefer-utf-8-write + ascii nil 'utf-8-unix "À"))) + (coding-tests-remove-files))) + + +;;; The following is for benchmark testing of the new optimized +;;; decoder, not for regression testing. + +(defun generate-ascii-file () + (dotimes (i 100000) + (insert-char ?a 80) + (insert "\n"))) + +(defun generate-rarely-nonascii-file () + (dotimes (i 100000) + (if (/= i 50000) + (insert-char ?a 80) + (insert ?À) + (insert-char ?a 79)) + (insert "\n"))) + +(defun generate-mostly-nonascii-file () + (dotimes (i 30000) + (insert-char ?a 80) + (insert "\n")) + (dotimes (i 20000) + (insert-char ?À 80) + (insert "\n")) + (dotimes (i 10000) + (insert-char ?あ 80) + (insert "\n"))) + + +(defvar test-file-list + '((generate-ascii-file + ("~/ascii-tag-utf-8-unix.unix" ";; -*- coding: utf-8-unix; -*-" unix) + ("~/ascii-tag-utf-8.unix" ";; -*- coding: utf-8; -*-" unix) + ("~/ascii-tag-none.unix" "" unix) + ("~/ascii-tag-utf-8-dos.dos" ";; -*- coding: utf-8-dos; -*-" dos) + ("~/ascii-tag-utf-8.dos" ";; -*- coding: utf-8; -*-" dos) + ("~/ascii-tag-none.dos" "" dos)) + (generate-rarely-nonascii-file + ("~/utf-8-r-tag-utf-8-unix.unix" ";; -*- coding: utf-8-unix; -*-" utf-8-unix) + ("~/utf-8-r-tag-utf-8.unix" ";; -*- coding: utf-8; -*-" utf-8-unix) + ("~/utf-8-r-tag-none.unix" "" utf-8-unix) + ("~/utf-8-r-tag-utf-8-dos.dos" ";; -*- coding: utf-8-dos; -*-" utf-8-dos) + ("~/utf-8-r-tag-utf-8.dos" ";; -*- coding: utf-8; -*-" utf-8-dos) + ("~/utf-8-r-tag-none.dos" "" utf-8-dos)) + (generate-mostly-nonascii-file + ("~/utf-8-m-tag-utf-8-unix.unix" ";; -*- coding: utf-8-unix; -*-" utf-8-unix) + ("~/utf-8-m-tag-utf-8.unix" ";; -*- coding: utf-8; -*-" utf-8-unix) + ("~/utf-8-m-tag-none.unix" "" utf-8-unix) + ("~/utf-8-m-tag-utf-8-dos.dos" ";; -*- coding: utf-8-dos; -*-" utf-8-dos) + ("~/utf-8-m-tag-utf-8.dos" ";; -*- coding: utf-8; -*-" utf-8-dos) + ("~/utf-8-m-tag-none.dos" "" utf-8-dos)))) + +(defun generate-benchmark-test-file () + (interactive) + (with-temp-buffer + (message "Generating data...") + (dolist (files test-file-list) + (delete-region (point-min) (point-max)) + (funcall (car files)) + (dolist (file (cdr files)) + (message "Writing %s..." (car file)) + (goto-char (point-min)) + (insert (nth 1 file) "\n") + (let ((coding-system-for-write (nth 2 file))) + (write-region (point-min) (point-max) (car file))) + (delete-region (point-min) (point)))))) + +(defun benchmark-decoder () + (let ((gc-cons-threshold 4000000)) + (insert "Without optimization:\n") + (dolist (files test-file-list) + (dolist (file (cdr files)) + (let* ((disable-ascii-optimization t) + (result (benchmark-run 10 + (with-temp-buffer (insert-file-contents (car file)))))) + (insert (format "%s: %s\n" (car file) result))))) + (insert "With optimization:\n") + (dolist (files test-file-list) + (dolist (file (cdr files)) + (let* ((disable-ascii-optimization nil) + (result (benchmark-run 10 + (with-temp-buffer (insert-file-contents (car file)))))) + (insert (format "%s: %s\n" (car file) result))))))) + +;; Local Variables: +;; byte-compile-warnings: (not obsolete) +;; End: + +(provide 'coding-tests) +;; coding-tests.el ends here diff --git a/test/src/data-tests.el b/test/src/data-tests.el new file mode 100644 index 00000000000..757522e399b --- /dev/null +++ b/test/src/data-tests.el @@ -0,0 +1,452 @@ +;;; data-tests.el --- tests for src/data.c + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'cl-lib) +(eval-when-compile (require 'cl)) + +(ert-deftest data-tests-= () + (should-error (=)) + (should (= 1)) + (should (= 2 2)) + (should (= 9 9 9 9 9 9 9 9 9)) + (should-not (apply #'= '(3 8 3))) + (should-error (= 9 9 'foo)) + ;; Short circuits before getting to bad arg + (should-not (= 9 8 'foo))) + +(ert-deftest data-tests-< () + (should-error (<)) + (should (< 1)) + (should (< 2 3)) + (should (< -6 -1 0 2 3 4 8 9 999)) + (should-not (apply #'< '(3 8 3))) + (should-error (< 9 10 'foo)) + ;; Short circuits before getting to bad arg + (should-not (< 9 8 'foo))) + +(ert-deftest data-tests-> () + (should-error (>)) + (should (> 1)) + (should (> 3 2)) + (should (> 6 1 0 -2 -3 -4 -8 -9 -999)) + (should-not (apply #'> '(3 8 3))) + (should-error (> 9 8 'foo)) + ;; Short circuits before getting to bad arg + (should-not (> 8 9 'foo))) + +(ert-deftest data-tests-<= () + (should-error (<=)) + (should (<= 1)) + (should (<= 2 3)) + (should (<= -6 -1 -1 0 0 0 2 3 4 8 999)) + (should-not (apply #'<= '(3 8 3 3))) + (should-error (<= 9 10 'foo)) + ;; Short circuits before getting to bad arg + (should-not (<= 9 8 'foo))) + +(ert-deftest data-tests->= () + (should-error (>=)) + (should (>= 1)) + (should (>= 3 2)) + (should (>= 666 1 0 0 -2 -3 -3 -3 -4 -8 -8 -9 -999)) + (should-not (apply #'>= '(3 8 3))) + (should-error (>= 9 8 'foo)) + ;; Short circuits before getting to bad arg + (should-not (>= 8 9 'foo))) + +;; Bool vector tests. Compactly represent bool vectors as hex +;; strings. + +(ert-deftest bool-vector-count-population-all-0-nil () + (cl-loop for sz in '(0 45 1 64 9 344) + do (let* ((bv (make-bool-vector sz nil))) + (should + (zerop + (bool-vector-count-population bv)))))) + +(ert-deftest bool-vector-count-population-all-1-t () + (cl-loop for sz in '(0 45 1 64 9 344) + do (let* ((bv (make-bool-vector sz t))) + (should + (eql + (bool-vector-count-population bv) + sz))))) + +(ert-deftest bool-vector-count-population-1-nil () + (let* ((bv (make-bool-vector 45 nil))) + (aset bv 40 t) + (aset bv 0 t) + (should + (eql + (bool-vector-count-population bv) + 2)))) + +(ert-deftest bool-vector-count-population-1-t () + (let* ((bv (make-bool-vector 45 t))) + (aset bv 40 nil) + (aset bv 0 nil) + (should + (eql + (bool-vector-count-population bv) + 43)))) + +(defun mock-bool-vector-count-consecutive (a b i) + (loop for i from i below (length a) + while (eq (aref a i) b) + sum 1)) + +(defun test-bool-vector-bv-from-hex-string (desc) + (let (bv nchars nibbles) + (dolist (c (string-to-list desc)) + (push (string-to-number + (char-to-string c) + 16) + nibbles)) + (setf bv (make-bool-vector (* 4 (length nibbles)) nil)) + (let ((i 0)) + (dolist (n (nreverse nibbles)) + (dotimes (_ 4) + (aset bv i (> (logand 1 n) 0)) + (incf i) + (setf n (lsh n -1))))) + bv)) + +(defun test-bool-vector-to-hex-string (bv) + (let (nibbles (v (cl-coerce bv 'list))) + (while v + (push (logior + (lsh (if (nth 0 v) 1 0) 0) + (lsh (if (nth 1 v) 1 0) 1) + (lsh (if (nth 2 v) 1 0) 2) + (lsh (if (nth 3 v) 1 0) 3)) + nibbles) + (setf v (nthcdr 4 v))) + (mapconcat (lambda (n) (format "%X" n)) + (nreverse nibbles) + ""))) + +(defun test-bool-vector-count-consecutive-tc (desc) + "Run a test case for bool-vector-count-consecutive. +DESC is a string describing the test. It is a sequence of +hexadecimal digits describing the bool vector. We exhaustively +test all counts at all possible positions in the vector by +comparing the subr with a much slower lisp implementation." + (let ((bv (test-bool-vector-bv-from-hex-string desc))) + (loop + for lf in '(nil t) + do (loop + for pos from 0 upto (length bv) + for cnt = (mock-bool-vector-count-consecutive bv lf pos) + for rcnt = (bool-vector-count-consecutive bv lf pos) + unless (eql cnt rcnt) + do (error "FAILED testcase %S %3S %3S %3S" + pos lf cnt rcnt))))) + +(defconst bool-vector-test-vectors +'("" + "0" + "F" + "0F" + "F0" + "00000000000000000000000000000FFFFF0000000" + "44a50234053fba3340000023444a50234053fba33400000234" + "12341234123456123412346001234123412345612341234600" + "44a50234053fba33400000234" + "1234123412345612341234600" + "44a50234053fba33400000234" + "1234123412345612341234600" + "44a502340" + "123412341" + "0000000000000000000000000" + "FFFFFFFFFFFFFFFF1")) + +(ert-deftest bool-vector-count-consecutive () + (mapc #'test-bool-vector-count-consecutive-tc + bool-vector-test-vectors)) + +(defun test-bool-vector-apply-mock-op (mock a b c) + "Compute (slowly) the correct result of a bool-vector set operation." + (let (changed nv) + (assert (eql (length b) (length c))) + (if a (setf nv a) + (setf a (make-bool-vector (length b) nil)) + (setf changed t)) + + (loop for i below (length b) + for mockr = (funcall mock + (if (aref b i) 1 0) + (if (aref c i) 1 0)) + for r = (not (= 0 mockr)) + do (progn + (unless (eq (aref a i) r) + (setf changed t)) + (setf (aref a i) r))) + (if changed a))) + +(defun test-bool-vector-binop (mock real) + "Test a binary set operation." + (loop for s1 in bool-vector-test-vectors + for bv1 = (test-bool-vector-bv-from-hex-string s1) + for vecs2 = (cl-remove-if-not + (lambda (x) (eql (length x) (length s1))) + bool-vector-test-vectors) + do (loop for s2 in vecs2 + for bv2 = (test-bool-vector-bv-from-hex-string s2) + for mock-result = (test-bool-vector-apply-mock-op + mock nil bv1 bv2) + for real-result = (funcall real bv1 bv2) + do (progn + (should (equal mock-result real-result)))))) + +(ert-deftest bool-vector-intersection-op () + (test-bool-vector-binop + #'logand + #'bool-vector-intersection)) + +(ert-deftest bool-vector-union-op () + (test-bool-vector-binop + #'logior + #'bool-vector-union)) + +(ert-deftest bool-vector-xor-op () + (test-bool-vector-binop + #'logxor + #'bool-vector-exclusive-or)) + +(ert-deftest bool-vector-set-difference-op () + (test-bool-vector-binop + (lambda (a b) (logand a (lognot b))) + #'bool-vector-set-difference)) + +(ert-deftest bool-vector-change-detection () + (let* ((vc1 (test-bool-vector-bv-from-hex-string "abcdef")) + (vc2 (test-bool-vector-bv-from-hex-string "012345")) + (vc3 (make-bool-vector (length vc1) nil)) + (c1 (bool-vector-union vc1 vc2 vc3)) + (c2 (bool-vector-union vc1 vc2 vc3))) + (should (equal c1 (test-bool-vector-apply-mock-op + #'logior + nil + vc1 vc2))) + (should (not c2)))) + +(ert-deftest bool-vector-not () + (let* ((v1 (test-bool-vector-bv-from-hex-string "FFFF3")) + (v2 (test-bool-vector-bv-from-hex-string "0000C")) + (v3 (bool-vector-not v1))) + (should (equal v2 v3)))) + +;; Tests for variable bindings + +(defvar binding-test-buffer-A (get-buffer-create "A")) +(defvar binding-test-buffer-B (get-buffer-create "B")) + +(defvar binding-test-always-local 'always) +(make-variable-buffer-local 'binding-test-always-local) + +(defvar binding-test-some-local 'some) +(with-current-buffer binding-test-buffer-A + (set (make-local-variable 'binding-test-some-local) 'local)) + +(ert-deftest binding-test-manual () + "A test case from the elisp manual." + (save-excursion + (set-buffer binding-test-buffer-A) + (let ((binding-test-some-local 'something-else)) + (should (eq binding-test-some-local 'something-else)) + (set-buffer binding-test-buffer-B) + (should (eq binding-test-some-local 'some))) + (should (eq binding-test-some-local 'some)) + (set-buffer binding-test-buffer-A) + (should (eq binding-test-some-local 'local)))) + +(ert-deftest binding-test-setq-default () + "Test that a setq-default has no effect when there is a local binding." + (save-excursion + (set-buffer binding-test-buffer-B) + ;; This variable is not local in this buffer. + (let ((binding-test-some-local 'something-else)) + (setq-default binding-test-some-local 'new-default)) + (should (eq binding-test-some-local 'some)))) + +(ert-deftest binding-test-makunbound () + "Tests of makunbound, from the manual." + (save-excursion + (set-buffer binding-test-buffer-B) + (should (boundp 'binding-test-some-local)) + (let ((binding-test-some-local 'outer)) + (let ((binding-test-some-local 'inner)) + (makunbound 'binding-test-some-local) + (should (not (boundp 'binding-test-some-local)))) + (should (and (boundp 'binding-test-some-local) + (eq binding-test-some-local 'outer)))))) + +(ert-deftest binding-test-defvar-bool () + "Test DEFVAR_BOOL" + (let ((display-hourglass 5)) + (should (eq display-hourglass t)))) + +(ert-deftest binding-test-defvar-int () + "Test DEFVAR_INT" + (should-error (setq gc-cons-threshold 5.0) :type 'wrong-type-argument)) + +(ert-deftest binding-test-set-constant-t () + "Test setting the constant t" + (should-error (setq t 'bob) :type 'setting-constant)) + +(ert-deftest binding-test-set-constant-nil () + "Test setting the constant nil" + (should-error (setq nil 'bob) :type 'setting-constant)) + +(ert-deftest binding-test-set-constant-keyword () + "Test setting a keyword constant" + (should-error (setq :keyword 'bob) :type 'setting-constant)) + +(ert-deftest binding-test-set-constant-nil () + "Test setting a keyword to itself" + (should (setq :keyword :keyword))) + +;; More tests to write - +;; kill-local-variable +;; defconst; can modify +;; defvar and defconst modify the local binding [ doesn't matter for us ] +;; various kinds of special internal forwarding objects +;; a couple examples in manual, not enough +;; variable aliases + +;; Tests for watchpoints + +(ert-deftest data-tests-variable-watchers () + (defvar data-tests-var 0) + (let* ((watch-data nil) + (collect-watch-data + (lambda (&rest args) (push args watch-data)))) + (cl-flet ((should-have-watch-data (data) + (should (equal (pop watch-data) data)) + (should (null watch-data)))) + (add-variable-watcher 'data-tests-var collect-watch-data) + (setq data-tests-var 1) + (should-have-watch-data '(data-tests-var 1 set nil)) + (let ((data-tests-var 2)) + (should-have-watch-data '(data-tests-var 2 let nil)) + (setq data-tests-var 3) + (should-have-watch-data '(data-tests-var 3 set nil))) + (should-have-watch-data '(data-tests-var 1 unlet nil)) + ;; `setq-default' on non-local variable is same as `setq'. + (setq-default data-tests-var 4) + (should-have-watch-data '(data-tests-var 4 set nil)) + (makunbound 'data-tests-var) + (should-have-watch-data '(data-tests-var nil makunbound nil)) + (setq data-tests-var 5) + (should-have-watch-data '(data-tests-var 5 set nil)) + (remove-variable-watcher 'data-tests-var collect-watch-data) + (setq data-tests-var 6) + (should (null watch-data))))) + +(ert-deftest data-tests-varalias-watchers () + (defvar data-tests-var0 0) + (defvar data-tests-var1 0) + (defvar data-tests-var2 0) + (defvar data-tests-var3 0) + (let* ((watch-data nil) + (collect-watch-data + (lambda (&rest args) (push args watch-data)))) + (cl-flet ((should-have-watch-data (data) + (should (equal (pop watch-data) data)) + (should (null watch-data)))) + ;; Watch var0, then alias it. + (add-variable-watcher 'data-tests-var0 collect-watch-data) + (defvaralias 'data-tests-var0-alias 'data-tests-var0) + (setq data-tests-var0 1) + (should-have-watch-data '(data-tests-var0 1 set nil)) + (setq data-tests-var0-alias 2) + (should-have-watch-data '(data-tests-var0 2 set nil)) + ;; Alias var1, then watch var1-alias. + (defvaralias 'data-tests-var1-alias 'data-tests-var1) + (add-variable-watcher 'data-tests-var1-alias collect-watch-data) + (setq data-tests-var1 1) + (should-have-watch-data '(data-tests-var1 1 set nil)) + (setq data-tests-var1-alias 2) + (should-have-watch-data '(data-tests-var1 2 set nil)) + ;; Alias var2, then watch it. + (defvaralias 'data-tests-var2-alias 'data-tests-var2) + (add-variable-watcher 'data-tests-var2 collect-watch-data) + (setq data-tests-var2 1) + (should-have-watch-data '(data-tests-var2 1 set nil)) + (setq data-tests-var2-alias 2) + (should-have-watch-data '(data-tests-var2 2 set nil)) + ;; Watch var3-alias, then make it alias var3 (this removes the + ;; watcher flag). + (defvar data-tests-var3-alias 0) + (add-variable-watcher 'data-tests-var3-alias collect-watch-data) + (defvaralias 'data-tests-var3-alias 'data-tests-var3) + (should-have-watch-data '(data-tests-var3-alias + data-tests-var3 defvaralias nil)) + (setq data-tests-var3 1) + (setq data-tests-var3-alias 2) + (should (null watch-data))))) + +(ert-deftest data-tests-local-variable-watchers () + (defvar-local data-tests-lvar 0) + (let* ((buf1 (current-buffer)) + (buf2 nil) + (watch-data nil) + (collect-watch-data + (lambda (&rest args) (push args watch-data)))) + (cl-flet ((should-have-watch-data (data) + (should (equal (pop watch-data) data)) + (should (null watch-data)))) + (add-variable-watcher 'data-tests-lvar collect-watch-data) + (setq data-tests-lvar 1) + (should-have-watch-data `(data-tests-lvar 1 set ,buf1)) + (let ((data-tests-lvar 2)) + (should-have-watch-data `(data-tests-lvar 2 let ,buf1)) + (setq data-tests-lvar 3) + (should-have-watch-data `(data-tests-lvar 3 set ,buf1))) + (should-have-watch-data `(data-tests-lvar 1 unlet ,buf1)) + (setq-default data-tests-lvar 4) + (should-have-watch-data `(data-tests-lvar 4 set nil)) + (with-temp-buffer + (setq buf2 (current-buffer)) + (setq data-tests-lvar 1) + (should-have-watch-data `(data-tests-lvar 1 set ,buf2)) + (let ((data-tests-lvar 2)) + (should-have-watch-data `(data-tests-lvar 2 let ,buf2)) + (setq data-tests-lvar 3) + (should-have-watch-data `(data-tests-lvar 3 set ,buf2))) + (should-have-watch-data `(data-tests-lvar 1 unlet ,buf2)) + (kill-local-variable 'data-tests-lvar) + (should-have-watch-data `(data-tests-lvar nil makunbound ,buf2)) + (setq data-tests-lvar 3.5) + (should-have-watch-data `(data-tests-lvar 3.5 set ,buf2)) + (kill-all-local-variables) + (should-have-watch-data `(data-tests-lvar nil makunbound ,buf2))) + (setq-default data-tests-lvar 4) + (should-have-watch-data `(data-tests-lvar 4 set nil)) + (makunbound 'data-tests-lvar) + (should-have-watch-data '(data-tests-lvar nil makunbound nil)) + (setq data-tests-lvar 5) + (should-have-watch-data `(data-tests-lvar 5 set ,buf1)) + (remove-variable-watcher 'data-tests-lvar collect-watch-data) + (setq data-tests-lvar 6) + (should (null watch-data))))) diff --git a/test/src/decompress-tests.el b/test/src/decompress-tests.el new file mode 100644 index 00000000000..f0264ec548d --- /dev/null +++ b/test/src/decompress-tests.el @@ -0,0 +1,45 @@ +;;; decompress-tests.el --- Test suite for decompress. + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Lars Ingebrigtsen <larsi@gnus.org> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(defvar zlib-tests-data-directory + (expand-file-name "data/decompress" (getenv "EMACS_TEST_DIRECTORY")) + "Directory containing zlib test data.") + +(ert-deftest zlib--decompress () + "Test decompressing a gzipped file." + (when (and (fboundp 'zlib-available-p) + (zlib-available-p)) + (should (string= + (with-temp-buffer + (set-buffer-multibyte nil) + (insert-file-contents-literally + (expand-file-name "foo.gz" zlib-tests-data-directory)) + (zlib-decompress-region (point-min) (point-max)) + (buffer-string)) + "foo\n")))) + +(provide 'decompress-tests) + +;;; decompress-tests.el ends here. diff --git a/test/src/doc-tests.el b/test/src/doc-tests.el new file mode 100644 index 00000000000..be490545747 --- /dev/null +++ b/test/src/doc-tests.el @@ -0,0 +1,92 @@ +;;; doc-tests.el --- Tests for doc.c + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Eli Zaretskii <eliz@gnu.org> + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest doc-test-substitute-command-keys () + ;; Bindings. + (should (string= (substitute-command-keys "foo \\[goto-char]") "foo M-g c")) + ;; Cannot use string= here, as that compares unibyte and multibyte + ;; strings not equal. + (should (compare-strings + (substitute-command-keys "\200 \\[goto-char]") nil nil + "\200 M-g c" nil nil)) + ;; Literals. + (should (string= (substitute-command-keys "foo \\=\\[goto-char]") + "foo \\[goto-char]")) + (should (string= (substitute-command-keys "foo \\=\\=") + "foo \\=")) + ;; Keymaps. + (should (string= (substitute-command-keys + "\\{minibuffer-local-must-match-map}") + "\ +key binding +--- ------- + +C-g abort-recursive-edit +TAB minibuffer-complete +C-j minibuffer-complete-and-exit +RET minibuffer-complete-and-exit +ESC Prefix Command +SPC minibuffer-complete-word +? minibuffer-completion-help +<C-tab> file-cache-minibuffer-complete +<XF86Back> previous-history-element +<XF86Forward> next-history-element +<down> next-line-or-history-element +<next> next-history-element +<prior> switch-to-completions +<up> previous-line-or-history-element + +M-v switch-to-completions + +M-n next-history-element +M-p previous-history-element +M-r previous-matching-history-element +M-s next-matching-history-element + +")) + (should (string= + (substitute-command-keys + "\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]") + "C-g")) + ;; Allow any style of quotes, since the terminal might not support + ;; UTF-8. + (should (string-match + "\nUses keymap [`‘']foobar-map['’], which is not currently defined.\n" + (substitute-command-keys "\\{foobar-map}"))) + ;; Quotes. + (should (let ((text-quoting-style 'grave)) + (string= (substitute-command-keys "quotes `like this'") + "quotes `like this'"))) + (should (let ((text-quoting-style 'grave)) + (string= (substitute-command-keys "quotes ‘like this’") + "quotes ‘like this’"))) + (should (let ((text-quoting-style 'straight)) + (string= (substitute-command-keys "quotes `like this'") + "quotes 'like this'"))) + ;; Bugs. + (should (string= (substitute-command-keys "\\[foobar") "\\[foobar")) + (should (string= (substitute-command-keys "\\=") "\\=")) + ) + +(provide 'doc-tests) +;;; doc-tests.el ends here diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el new file mode 100644 index 00000000000..2f90d1e7495 --- /dev/null +++ b/test/src/editfns-tests.el @@ -0,0 +1,136 @@ +;;; editfns-tests.el -- tests for editfns.c + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest format-properties () + ;; Bug #23730 + (should (ert-equal-including-properties + (format (propertize "%d" 'face '(:background "red")) 1) + #("1" 0 1 (face (:background "red"))))) + (should (ert-equal-including-properties + (format (propertize "%2d" 'face '(:background "red")) 1) + #(" 1" 0 2 (face (:background "red"))))) + (should (ert-equal-including-properties + (format (propertize "%02d" 'face '(:background "red")) 1) + #("01" 0 2 (face (:background "red"))))) + (should (ert-equal-including-properties + (format (concat (propertize "%2d" 'x 'X) + (propertize "a" 'a 'A) + (propertize "b" 'b 'B)) + 1) + #(" 1ab" 0 2 (x X) 2 3 (a A) 3 4 (b B)))) + + ;; Bug #5306 + (should (ert-equal-including-properties + (format "%.10s" + (concat "1234567890aaaa" + (propertize "12345678901234567890" 'xxx 25))) + "1234567890")) + (should (ert-equal-including-properties + (format "%.10s" + (concat "123456789" + (propertize "12345678901234567890" 'xxx 25))) + #("1234567891" 9 10 (xxx 25)))) + + ;; Bug #23859 + (should (ert-equal-including-properties + (format "%4s" (propertize "hi" 'face 'bold)) + #(" hi" 2 4 (face bold)))) + + ;; Bug #23897 + (should (ert-equal-including-properties + (format "%s" (concat (propertize "01234" 'face 'bold) "56789")) + #("0123456789" 0 5 (face bold)))) + (should (ert-equal-including-properties + (format "%s" (concat (propertize "01" 'face 'bold) + (propertize "23" 'face 'underline) + "45")) + #("012345" 0 2 (face bold) 2 4 (face underline)))) + ;; The last property range is extended to include padding on the + ;; right, but the first range is not extended to the left to include + ;; padding on the left! + (should (ert-equal-including-properties + (format "%12s" (concat (propertize "01234" 'face 'bold) "56789")) + #(" 0123456789" 2 7 (face bold)))) + (should (ert-equal-including-properties + (format "%-12s" (concat (propertize "01234" 'face 'bold) "56789")) + #("0123456789 " 0 5 (face bold)))) + (should (ert-equal-including-properties + (format "%10s" (concat (propertize "01" 'face 'bold) + (propertize "23" 'face 'underline) + "45")) + #(" 012345" 4 6 (face bold) 6 8 (face underline)))) + (should (ert-equal-including-properties + (format "%-10s" (concat (propertize "01" 'face 'bold) + (propertize "23" 'face 'underline) + "45")) + #("012345 " 0 2 (face bold) 2 4 (face underline)))) + (should (ert-equal-including-properties + (format "%-10s" (concat (propertize "01" 'face 'bold) + (propertize "23" 'face 'underline) + (propertize "45" 'face 'italic))) + #("012345 " 0 2 (face bold) 2 4 (face underline) 4 10 (face italic))))) + +;; Tests for bug#5131. +(defun transpose-test-reverse-word (start end) + "Reverse characters in a word by transposing pairs of characters." + (let ((begm (make-marker)) + (endm (make-marker))) + (set-marker begm start) + (set-marker endm end) + (while (> endm begm) + (progn (transpose-regions begm (1+ begm) endm (1+ endm) t) + (set-marker begm (1+ begm)) + (set-marker endm (1- endm)))))) + +(defun transpose-test-get-byte-positions (len) + "Validate character position to byte position translation." + (let ((bytes '())) + (dotimes (pos len) + (setq bytes (add-to-list 'bytes (position-bytes (1+ pos)) t))) + bytes)) + +(ert-deftest transpose-ascii-regions-test () + (with-temp-buffer + (erase-buffer) + (insert "abcd") + (transpose-test-reverse-word 1 4) + (should (string= (buffer-string) "dcba")) + (should (equal (transpose-test-get-byte-positions 5) '(1 2 3 4 5))))) + +(ert-deftest transpose-nonascii-regions-test-1 () + (with-temp-buffer + (erase-buffer) + (insert "÷bcd") + (transpose-test-reverse-word 1 4) + (should (string= (buffer-string) "dcb÷")) + (should (equal (transpose-test-get-byte-positions 5) '(1 2 3 4 6))))) + +(ert-deftest transpose-nonascii-regions-test-2 () + (with-temp-buffer + (erase-buffer) + (insert "÷ab\"äé") + (transpose-test-reverse-word 1 6) + (should (string= (buffer-string) "éä\"ba÷")) + (should (equal (transpose-test-get-byte-positions 7) '(1 3 5 6 7 8 10))))) + +;;; editfns-tests.el ends here diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el new file mode 100644 index 00000000000..fe08506ed25 --- /dev/null +++ b/test/src/eval-tests.el @@ -0,0 +1,50 @@ +;;; eval-tests.el --- unit tests for src/eval.c -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Philipp Stephani <phst@google.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Unit tests for src/eval.c. + +;;; Code: + +(require 'ert) + +(ert-deftest eval-tests--bug24673 () + "Checks that Bug#24673 has been fixed." + ;; This should not crash. + (should-error (funcall '(closure)) :type 'invalid-function)) + +(ert-deftest eval-tests--bugs-24912-and-24913 () + "Checks that Emacs doesn’t accept weird argument lists. +Bug#24912 and Bug#24913." + (dolist (args '((&optional) (&rest) (&optional &rest) (&rest &optional) + (&optional &rest a) (&optional a &rest) + (&rest a &optional) (&rest &optional a) + (&optional &optional) (&optional &optional a) + (&optional a &optional b) + (&rest &rest) (&rest &rest a) + (&rest a &rest b))) + (should-error (eval `(funcall (lambda ,args)) t) :type 'invalid-function) + (should-error (byte-compile-check-lambda-list args)) + (let ((byte-compile-debug t)) + (should-error (eval `(byte-compile (lambda ,args)) t))))) + +;;; eval-tests.el ends here diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el new file mode 100644 index 00000000000..c533bad3cdc --- /dev/null +++ b/test/src/fns-tests.el @@ -0,0 +1,247 @@ +;;; fns-tests.el --- tests for src/fns.c + +;; Copyright (C) 2014-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation, either version 3 of the +;; License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see `http://www.gnu.org/licenses/'. + +;;; Commentary: + +;;; Code: + +(require 'cl-lib) +(eval-when-compile (require 'cl)) + +(ert-deftest fns-tests-reverse () + (should-error (reverse)) + (should-error (reverse 1)) + (should-error (reverse (make-char-table 'foo))) + (should (equal [] (reverse []))) + (should (equal [0] (reverse [0]))) + (should (equal [1 2 3 4] (reverse (reverse [1 2 3 4])))) + (should (equal '(a b c d) (reverse (reverse '(a b c d))))) + (should (equal "xyzzy" (reverse (reverse "xyzzy")))) + (should (equal "こんにちは / コンニチハ" (reverse (reverse "こんにちは / コンニチハ"))))) + +(ert-deftest fns-tests-nreverse () + (should-error (nreverse)) + (should-error (nreverse 1)) + (should-error (nreverse (make-char-table 'foo))) + (should (equal (nreverse "xyzzy") "yzzyx")) + (let ((A [])) + (nreverse A) + (should (equal A []))) + (let ((A [0])) + (nreverse A) + (should (equal A [0]))) + (let ((A [1 2 3 4])) + (nreverse A) + (should (equal A [4 3 2 1]))) + (let ((A [1 2 3 4])) + (nreverse A) + (nreverse A) + (should (equal A [1 2 3 4]))) + (let* ((A [1 2 3 4]) + (B (nreverse (nreverse A)))) + (should (equal A B)))) + +(ert-deftest fns-tests-reverse-bool-vector () + (let ((A (make-bool-vector 10 nil))) + (dotimes (i 5) (aset A i t)) + (should (equal [nil nil nil nil nil t t t t t] (vconcat (reverse A)))) + (should (equal A (reverse (reverse A)))))) + +(ert-deftest fns-tests-nreverse-bool-vector () + (let ((A (make-bool-vector 10 nil))) + (dotimes (i 5) (aset A i t)) + (nreverse A) + (should (equal [nil nil nil nil nil t t t t t] (vconcat A))) + (should (equal [t t t t t nil nil nil nil nil] (vconcat (nreverse A)))))) + +(ert-deftest fns-tests-compare-strings () + (should-error (compare-strings)) + (should-error (compare-strings "xyzzy" "xyzzy")) + (should (= (compare-strings "xyzzy" 0 10 "zyxxy" 0 5) -1)) + (should-error (compare-strings "xyzzy" 0 5 "zyxxy" -1 2)) + (should-error (compare-strings "xyzzy" 'foo nil "zyxxy" 0 1)) + (should-error (compare-strings "xyzzy" 0 'foo "zyxxy" 2 3)) + (should-error (compare-strings "xyzzy" 0 2 "zyxxy" 'foo 3)) + (should-error (compare-strings "xyzzy" nil 3 "zyxxy" 4 'foo)) + (should (eq (compare-strings "" nil nil "" nil nil) t)) + (should (eq (compare-strings "" 0 0 "" 0 0) t)) + (should (eq (compare-strings "test" nil nil "test" nil nil) t)) + (should (eq (compare-strings "test" nil nil "test" nil nil t) t)) + (should (eq (compare-strings "test" nil nil "test" nil nil nil) t)) + (should (eq (compare-strings "Test" nil nil "test" nil nil t) t)) + (should (= (compare-strings "Test" nil nil "test" nil nil) -1)) + (should (= (compare-strings "Test" nil nil "test" nil nil) -1)) + (should (= (compare-strings "test" nil nil "Test" nil nil) 1)) + (should (= (compare-strings "foobaz" nil nil "barbaz" nil nil) 1)) + (should (= (compare-strings "barbaz" nil nil "foobar" nil nil) -1)) + (should (= (compare-strings "foobaz" nil nil "farbaz" nil nil) 2)) + (should (= (compare-strings "farbaz" nil nil "foobar" nil nil) -2)) + (should (eq (compare-strings "abcxyz" 0 2 "abcprq" 0 2) t)) + (should (eq (compare-strings "abcxyz" 0 -3 "abcprq" 0 -3) t)) + (should (= (compare-strings "abcxyz" 0 6 "abcprq" 0 6) 4)) + (should (= (compare-strings "abcprq" 0 6 "abcxyz" 0 6) -4)) + (should (eq (compare-strings "xyzzy" -3 4 "azza" -3 3) t)) + (should (eq (compare-strings "こんにちはコンニチハ" nil nil "こんにちはコンニチハ" nil nil) t)) + (should (= (compare-strings "んにちはコンニチハこ" nil nil "こんにちはコンニチハ" nil nil) 1)) + (should (= (compare-strings "こんにちはコンニチハ" nil nil "んにちはコンニチハこ" nil nil) -1))) + +(defun fns-tests--collate-enabled-p () + "Check whether collation functions are enabled." + (and + ;; When there is no collation library, collation functions fall back + ;; to their lexicographic counterparts. We don't need to test then. + (not (ignore-errors (string-collate-equalp "" "" t))) + ;; We use a locale, which might not be installed. Check it. + (ignore-errors + (string-collate-equalp + "" "" (if (eq system-type 'windows-nt) "enu_USA" "en_US.UTF-8"))))) + +(ert-deftest fns-tests-collate-strings () + (skip-unless (fns-tests--collate-enabled-p)) + + (should (string-collate-equalp "xyzzy" "xyzzy")) + (should-not (string-collate-equalp "xyzzy" "XYZZY")) + + ;; In POSIX or C locales, collation order is lexicographic. + (should (string-collate-lessp "XYZZY" "xyzzy" "POSIX")) + ;; In a language specific locale, collation order is different. + (should (string-collate-lessp + "xyzzy" "XYZZY" + (if (eq system-type 'windows-nt) "enu_USA" "en_US.UTF-8"))) + + ;; Ignore case. + (should (string-collate-equalp "xyzzy" "XYZZY" nil t)) + + ;; Locale must be valid. + (should-error (string-collate-equalp "xyzzy" "xyzzy" "en_DE.UTF-8"))) + +;; There must be a check for valid codepoints. (Check not implemented yet) +; (should-error +; (string-collate-equalp (string ?\x00110000) (string ?\x00110000))) +;; Invalid UTF-8 sequences shall be indicated. How to create such strings? + +(ert-deftest fns-tests-sort () + (should (equal (sort '(9 5 2 -1 5 3 8 7 4) (lambda (x y) (< x y))) + '(-1 2 3 4 5 5 7 8 9))) + (should (equal (sort '(9 5 2 -1 5 3 8 7 4) (lambda (x y) (> x y))) + '(9 8 7 5 5 4 3 2 -1))) + (should (equal (sort '[9 5 2 -1 5 3 8 7 4] (lambda (x y) (< x y))) + [-1 2 3 4 5 5 7 8 9])) + (should (equal (sort '[9 5 2 -1 5 3 8 7 4] (lambda (x y) (> x y))) + [9 8 7 5 5 4 3 2 -1])) + (should (equal + (sort + (vector + '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") + '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff")) + (lambda (x y) (< (car x) (car y)))) + [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") + (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")]))) + +(ert-deftest fns-tests-collate-sort () + ;; See https://lists.gnu.org/archive/html/emacs-devel/2015-10/msg02505.html. + :expected-result (if (eq system-type 'cygwin) :failed :passed) + (skip-unless (fns-tests--collate-enabled-p)) + + ;; Punctuation and whitespace characters are relevant for POSIX. + (should + (equal + (sort '("11" "12" "1 1" "1 2" "1.1" "1.2") + (lambda (a b) (string-collate-lessp a b "POSIX"))) + '("1 1" "1 2" "1.1" "1.2" "11" "12"))) + ;; Punctuation and whitespace characters are not taken into account + ;; for collation in other locales. + (should + (equal + (sort '("11" "12" "1 1" "1 2" "1.1" "1.2") + (lambda (a b) + (let ((w32-collate-ignore-punctuation t)) + (string-collate-lessp + a b (if (eq system-type 'windows-nt) "enu_USA" "en_US.UTF-8"))))) + '("11" "1 1" "1.1" "12" "1 2" "1.2"))) + + ;; Diacritics are different letters for POSIX, they sort lexicographical. + (should + (equal + (sort '("Ævar" "Agustín" "Adrian" "Eli") + (lambda (a b) (string-collate-lessp a b "POSIX"))) + '("Adrian" "Agustín" "Eli" "Ævar"))) + ;; Diacritics are sorted between similar letters for other locales. + (should + (equal + (sort '("Ævar" "Agustín" "Adrian" "Eli") + (lambda (a b) + (let ((w32-collate-ignore-punctuation t)) + (string-collate-lessp + a b (if (eq system-type 'windows-nt) "enu_USA" "en_US.UTF-8"))))) + '("Adrian" "Ævar" "Agustín" "Eli")))) + +(ert-deftest fns-tests-string-version-lessp () + (should (string-version-lessp "foo2.png" "foo12.png")) + (should (not (string-version-lessp "foo12.png" "foo2.png"))) + (should (string-version-lessp "foo12.png" "foo20000.png")) + (should (not (string-version-lessp "foo20000.png" "foo12.png"))) + (should (string-version-lessp "foo.png" "foo2.png")) + (should (not (string-version-lessp "foo2.png" "foo.png"))) + (should (equal (sort '("foo12.png" "foo2.png" "foo1.png") + 'string-version-lessp) + '("foo1.png" "foo2.png" "foo12.png"))) + (should (string-version-lessp "foo2" "foo1234")) + (should (not (string-version-lessp "foo1234" "foo2"))) + (should (string-version-lessp "foo.png" "foo2")) + (should (string-version-lessp "foo1.25.5.png" "foo1.125.5")) + (should (string-version-lessp "2" "1245")) + (should (not (string-version-lessp "1245" "2")))) + +(ert-deftest fns-tests-func-arity () + (should (equal (func-arity 'car) '(1 . 1))) + (should (equal (func-arity 'caar) '(1 . 1))) + (should (equal (func-arity 'format) '(1 . many))) + (require 'info) + (should (equal (func-arity 'Info-goto-node) '(1 . 3))) + (should (equal (func-arity (lambda (&rest x))) '(0 . many))) + (should (equal (func-arity (eval (lambda (x &optional y)) nil)) '(1 . 2))) + (should (equal (func-arity (eval (lambda (x &optional y)) t)) '(1 . 2))) + (should (equal (func-arity 'let) '(1 . unevalled)))) + +(ert-deftest fns-tests-hash-buffer () + (should (equal (sha1 "foo") "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")) + (should (equal (with-temp-buffer + (insert "foo") + (buffer-hash)) + (sha1 "foo"))) + ;; This tests whether the presence of a gap in the middle of the + ;; buffer is handled correctly. + (should (equal (with-temp-buffer + (insert "foo") + (goto-char 2) + (insert " ") + (backward-delete-char 1) + (buffer-hash)) + (sha1 "foo")))) + +(ert-deftest fns-tests-mapcan () + (should-error (mapcan)) + (should-error (mapcan #'identity)) + (should-error (mapcan #'identity (make-char-table 'foo))) + (should (equal (mapcan #'list '(1 2 3)) '(1 2 3))) + ;; `mapcan' is destructive + (let ((data '((foo) (bar)))) + (should (equal (mapcan #'identity data) '(foo bar))) + (should (equal data '((foo bar) (bar)))))) diff --git a/test/src/font-tests.el b/test/src/font-tests.el new file mode 100644 index 00000000000..f0f0d31efc7 --- /dev/null +++ b/test/src/font-tests.el @@ -0,0 +1,167 @@ +;;; font-tests.el --- Test suite for font-related functions. + +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. + +;; Author: Chong Yidong <cyd@stupidchicken.com> +;; Keywords: internal +;; Human-Keywords: internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Type M-x test-font-parse RET to generate the test buffer. + +;;; Code: + +(require 'ert) + +(defvar font-parse-tests--data + `((" " ,(intern " ") nil nil nil nil) + ("Monospace" Monospace nil nil nil nil) + ("Monospace Serif" ,(intern "Monospace Serif") nil nil nil nil) + ("Foo1" Foo1 nil nil nil nil) + ("12" nil 12.0 nil nil nil) + ("12 " ,(intern "12 ") nil nil nil nil) + ;; Fontconfig format + ("Foo:" Foo nil nil nil nil) + ("Foo-8" Foo 8.0 nil nil nil) + ("Foo-18:" Foo 18.0 nil nil nil) + ("Foo-18:light" Foo 18.0 light nil nil) + ("Foo 10:weight=bold" ,(intern "Foo 10") nil bold nil nil) + ("Foo-12:weight=bold" Foo 12.0 bold nil nil) + ("Foo 8-20:slant=oblique" ,(intern "Foo 8") 20.0 nil oblique nil) + ("Foo:light:roman" Foo nil light roman nil) + ("Foo:italic:roman" Foo nil nil roman nil) + ("Foo 12:light:oblique" ,(intern "Foo 12") nil light oblique nil) + ("Foo-12:demibold:oblique" Foo 12.0 demibold oblique nil) + ("Foo:black:proportional" Foo nil black nil 0) + ("Foo-10:black:proportional" Foo 10.0 black nil 0) + ("Foo:weight=normal" Foo nil normal nil nil) + ("Foo:weight=bold" Foo nil bold nil nil) + ("Foo:weight=bold:slant=italic" Foo nil bold italic) + ("Foo:weight=bold:slant=italic:mono" Foo nil bold italic 100) + ("Foo-10:demibold:slant=normal" Foo 10.0 demibold normal nil) + ("Foo 11-16:oblique:weight=bold" ,(intern "Foo 11") 16.0 bold oblique nil) + ("Foo:oblique:randomprop=randomtag:weight=bold" Foo nil bold oblique nil) + ("Foo:randomprop=randomtag:bar=baz" Foo nil nil nil nil) + ("Foo Book Light:bar=baz" ,(intern "Foo Book Light") nil nil nil nil) + ("Foo Book Light 10:bar=baz" ,(intern "Foo Book Light 10") nil nil nil nil) + ("Foo Book Light-10:bar=baz" ,(intern "Foo Book Light") 10.0 nil nil nil) + ;; GTK format + ("Oblique" nil nil nil oblique nil) + ("Bold 17" nil 17.0 bold nil nil) + ("17 Bold" ,(intern "17") nil bold nil nil) + ("Book Oblique 2" nil 2.0 book oblique nil) + ("Bar 7" Bar 7.0 nil nil nil) + ("Bar Ultra-Light" Bar nil ultra-light nil nil) + ("Bar Light 8" Bar 8.0 light nil nil) + ("Bar Book Medium 9" Bar 9.0 medium nil nil) + ("Bar Semi-Bold Italic 10" Bar 10.0 semi-bold italic nil) + ("Bar Semi-Condensed Bold Italic 11" Bar 11.0 bold italic nil) + ("Foo 10 11" ,(intern "Foo 10") 11.0 nil nil nil) + ("Foo 1985 Book" ,(intern "Foo 1985") nil book nil nil) + ("Foo 1985 A Book" ,(intern "Foo 1985 A") nil book nil nil) + ("Foo 1 Book 12" ,(intern "Foo 1") 12.0 book nil nil) + ("Foo A Book 12 A" ,(intern "Foo A Book 12 A") nil nil nil nil) + ("Foo 1985 Book 12 Oblique" ,(intern "Foo 1985 Book 12") nil nil oblique nil) + ("Foo 1985 Book 12 Italic 10" ,(intern "Foo 1985 Book 12") 10.0 nil italic nil) + ("Foo Book Bar 6 Italic" ,(intern "Foo Book Bar 6") nil nil italic nil) + ("Foo Book Bar Bold" ,(intern "Foo Book Bar") nil bold nil nil)) + "List of font names parse data. +Each element should have the form + (NAME FAMILY SIZE WEIGHT SLANT SPACING) +where NAME is the name to parse, and the remainder are the +expected font properties from parsing NAME.") + +(defun font-parse-check (name prop expected) + (let ((result (font-get (font-spec :name name) prop))) + (if (and (symbolp result) (symbolp expected)) + (eq result expected) + (equal result expected)))) + +(put 'font-parse-check 'ert-explainer 'font-parse-explain) + +(defun font-parse-explain (name prop expected) + (let ((result (font-get (font-spec :name name) prop)) + (propname (symbol-name prop))) + (format "Parsing `%s': expected %s `%s', got `%s'." + name (substring propname 1) expected + (font-get (font-spec :name name) prop)))) + +(ert-deftest font-parse-tests () + "Test parsing of Fontconfig-style and GTK-style font names." + (dolist (test font-parse-tests--data) + (let* ((name (nth 0 test))) + (should (font-parse-check name :family (nth 1 test))) + (should (font-parse-check name :size (nth 2 test))) + (should (font-parse-check name :weight (nth 3 test))) + (should (font-parse-check name :slant (nth 4 test))) + (should (font-parse-check name :spacing (nth 5 test)))))) + + +(defun test-font-parse () + "Test font name parsing." + (interactive) + (switch-to-buffer (generate-new-buffer "*Font Pase Test*")) + (setq show-trailing-whitespace nil) + (let ((pass-face '((t :foreground "green"))) + (fail-face '((t :foreground "red")))) + (dolist (test font-parse-tests--data) + (let* ((name (nth 0 test)) + (fs (font-spec :name name)) + (family (font-get fs :family)) + (size (font-get fs :size)) + (weight (font-get fs :weight)) + (slant (font-get fs :slant)) + (spacing (font-get fs :spacing))) + (insert name) + (if (> (current-column) 20) + (insert "\n")) + (indent-to-column 21) + (insert (propertize (symbol-name family) + 'face (if (eq family (nth 1 test)) + pass-face + fail-face))) + (indent-to-column 40) + (insert (propertize (format "%s" size) + 'face (if (equal size (nth 2 test)) + pass-face + fail-face))) + (indent-to-column 48) + (insert (propertize (format "%s" weight) + 'face (if (eq weight (nth 3 test)) + pass-face + fail-face))) + (indent-to-column 60) + (insert (propertize (format "%s" slant) + 'face (if (eq slant (nth 4 test)) + pass-face + fail-face))) + (indent-to-column 69) + (insert (propertize (format "%s" spacing) + 'face (if (eq spacing (nth 5 test)) + pass-face + fail-face))) + (insert "\n")))) + (goto-char (point-min))) + +;; Local Variables: +;; no-byte-compile: t +;; End: + +(provide 'font-tests) +;;; font-tests.el ends here. diff --git a/test/src/inotify-tests.el b/test/src/inotify-tests.el new file mode 100644 index 00000000000..54977925f86 --- /dev/null +++ b/test/src/inotify-tests.el @@ -0,0 +1,64 @@ +;;; inotify-tests.el --- Test suite for inotify. -*- lexical-binding: t -*- + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: Rüdiger Sonderfeld <ruediger@c-plusplus.de> +;; Keywords: internal +;; Human-Keywords: internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(declare-function inotify-add-watch "inotify.c" (file-name aspect callback)) +(declare-function inotify-rm-watch "inotify.c" (watch-descriptor)) + +;; (ert-deftest filewatch-file-watch-aspects-check () +;; "Test whether `file-watch' properly checks the aspects." +;; (let ((temp-file (make-temp-file "filewatch-aspects"))) +;; (should (stringp temp-file)) +;; (should-error (file-watch temp-file 'wrong nil) +;; :type 'error) +;; (should-error (file-watch temp-file '(modify t) nil) +;; :type 'error) +;; (should-error (file-watch temp-file '(modify all-modify) nil) +;; :type 'error) +;; (should-error (file-watch temp-file '(access wrong modify) nil) +;; :type 'error))) + +(ert-deftest inotify-file-watch-simple () + "Test if watching a normal file works." + + (skip-unless (featurep 'inotify)) + (let ((temp-file (make-temp-file "inotify-simple")) + (events 0)) + (let ((wd + (inotify-add-watch temp-file t (lambda (_ev) + (setq events (1+ events)))))) + (unwind-protect + (progn + (with-temp-file temp-file + (insert "Foo\n")) + (read-event nil nil 5) + (should (> events 0))) + (inotify-rm-watch wd) + (delete-file temp-file))))) + +(provide 'inotify-tests) + +;;; inotify-tests.el ends here. diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el new file mode 100644 index 00000000000..26d34858703 --- /dev/null +++ b/test/src/keymap-tests.el @@ -0,0 +1,50 @@ +;;; keymap-tests.el --- Test suite for src/keymap.c + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; Author: Juanma Barranquero <lekktu@gmail.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest keymap-store_in_keymap-XFASTINT-on-non-characters () + "Check for bug fixed in \"Fix assertion violation in define-key\", +commit 86c19714b097aa477d339ed99ffb5136c755a046." + (let ((def (lookup-key Buffer-menu-mode-map [32]))) + (unwind-protect + (progn + (should-not (eq def 'undefined)) + ;; This will cause an assertion violation if the bug is present. + ;; We could run an inferior Emacs process and check for the return + ;; status, but in some environments an assertion failure triggers + ;; an abort dialog that requires user intervention anyway. + (define-key Buffer-menu-mode-map [(32 . 32)] 'undefined) + (should (eq (lookup-key Buffer-menu-mode-map [32]) 'undefined))) + (define-key Buffer-menu-mode-map [32] def)))) + +(ert-deftest keymap-where-is-internal-test () + "Make sure we don't crash when `where-is-preferred-modifier' is not a symbol." + (should + (equal (let ((where-is-preferred-modifier "alt")) + (where-is-internal 'execute-extended-command global-map t)) + [#x8000078]))) + +(provide 'keymap-tests) + +;;; keymap-tests.el ends here diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el new file mode 100644 index 00000000000..609f82ec20b --- /dev/null +++ b/test/src/lread-tests.el @@ -0,0 +1,115 @@ +;;; lread-tests.el --- tests for lread.c -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Philipp Stephani <phst@google.com> + +;; This file is part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Unit tests for code in src/lread.c. + +;;; Code: + +(ert-deftest lread-char-number () + (should (equal (read "?\\N{U+A817}") #xA817))) + +(ert-deftest lread-char-name-1 () + (should (equal (read "?\\N{SYLOTI NAGRI LETTER \n DHO}") + #xA817))) +(ert-deftest lread-char-name-2 () + (should (equal (read "?\\N{BED}") #x1F6CF))) +(ert-deftest lread-char-name-3 () + (should (equal (read "?\\N{U+BED}") #xBED))) +(ert-deftest lread-char-name-4 () + (should (equal (read "?\\N{VARIATION SELECTOR-1}") #xFE00))) +(ert-deftest lread-char-name-5 () + (should (equal (read "?\\N{VARIATION SELECTOR-16}") #xFE0F))) +(ert-deftest lread-char-name-6 () + (should (equal (read "?\\N{VARIATION SELECTOR-17}") #xE0100))) +(ert-deftest lread-char-name-7 () + (should (equal (read "?\\N{VARIATION SELECTOR-256}") #xE01EF))) +(ert-deftest lread-char-name-8 () + (should (equal (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-F900}") #xF900))) +(ert-deftest lread-char-name-9 () + (should (equal (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-FAD9}") #xFAD9))) +(ert-deftest lread-char-name-10 () + (should (equal (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-2F800}") #x2F800))) +(ert-deftest lread-char-name-11 () + (should (equal (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-2FA1D}") #x2FA1D))) + +(ert-deftest lread-char-invalid-number () + (should-error (read "?\\N{U+110000}") :type 'invalid-read-syntax)) + +(ert-deftest lread-char-invalid-name-1 () + (should-error (read "?\\N{DOES NOT EXIST}")) :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-2 () + (should-error (read "?\\N{VARIATION SELECTOR-0}")) :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-3 () + (should-error (read "?\\N{VARIATION SELECTOR-257}")) + :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-4 () + (should-error (read "?\\N{VARIATION SELECTOR--0}")) + :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-5 () + (should-error (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-F8FF}")) + :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-6 () + (should-error (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-FADA}")) + :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-7 () + (should-error (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-2F7FF}")) + :type 'invalid-read-syntax) +(ert-deftest lread-char-invalid-name-8 () + (should-error (read "?\\N{CJK COMPATIBILITY IDEOGRAPH-2FA1E}")) + :type 'invalid-read-syntax) + +(ert-deftest lread-char-non-ascii-name () + (should-error (read "?\\N{LATIN CAPITAL LETTER Ø}") + :type 'invalid-read-syntax)) + +(ert-deftest lread-char-empty-name () + (should-error (read "?\\N{}") :type 'invalid-read-syntax)) + +(ert-deftest lread-char-surrogate-1 () + (should-error (read "?\\N{U+D800}") :type 'invalid-read-syntax)) +(ert-deftest lread-char-surrogate-2 () + (should-error (read "?\\N{U+D801}") :type 'invalid-read-syntax)) +(ert-deftest lread-char-surrogate-3 () + (should-error (read "?\\N{U+Dffe}") :type 'invalid-read-syntax)) +(ert-deftest lread-char-surrogate-4 () + (should-error (read "?\\N{U+DFFF}") :type 'invalid-read-syntax)) + +(ert-deftest lread-string-char-number-1 () + (should (equal (read "\"a\\N{U+A817}b\"") "a\uA817b"))) +(ert-deftest lread-string-char-number-2 () + (should-error (read "?\\N{0.5}") :type 'invalid-read-syntax)) +(ert-deftest lread-string-char-number-3 () + (should-error (read "?\\N{U+-0}") :type 'invalid-read-syntax)) + +(ert-deftest lread-string-char-name () + (should (equal (read "\"a\\N{SYLOTI NAGRI LETTER DHO}b\"") "a\uA817b"))) + +(ert-deftest lread-empty-int-literal () + "Check that Bug#25120 is fixed." + (should-error (read "#b") :type 'invalid-read-syntax) + (should-error (read "#o") :type 'invalid-read-syntax) + (should-error (read "#x") :type 'invalid-read-syntax) + (should-error (read "#24r") :type 'invalid-read-syntax) + (should-error (read "#") :type 'invalid-read-syntax)) + +;;; lread-tests.el ends here diff --git a/test/src/marker-tests.el b/test/src/marker-tests.el new file mode 100644 index 00000000000..18d49addb2f --- /dev/null +++ b/test/src/marker-tests.el @@ -0,0 +1,60 @@ +;;; marker-tests.el --- tests for marker.c functions -*- lexical-binding: t -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +;; The following three tests assert that Emacs survives operations +;; copying a marker whose character position differs from its byte +;; position into a buffer whose character size equals its byte size +;; (Bug#24368). + +(ert-deftest marker-set-window-start-from-other-buffer () + "`set-window-start' from other buffer's marker." + (let ((text-quoting-style 'curve)) + (describe-function 'describe-function)) + (let* ((help (get-buffer "*Help*")) + (marker (with-current-buffer help + (copy-marker (point-max))))) + (should (set-window-start (selected-window) marker)))) + +(ert-deftest marker-set-window-point-from-other-buffer () + "`set-window-point' from another buffer's marker." + (let ((text-quoting-style 'curve)) + (describe-function 'describe-function)) + (let* ((help (get-buffer "*Help*")) + (marker (with-current-buffer help + (copy-marker (point-max))))) + (with-selected-window (get-buffer-window help) + (should (set-window-point (get-buffer-window "*scratch*") marker))))) + +(ert-deftest marker-goto-char-from-other-buffer () + "`goto-char' from another buffer's marker." + (let ((text-quoting-style 'curve)) + (describe-function 'describe-function)) + (let ((marker-1 (make-marker)) + (marker-2 (make-marker))) + (describe-function 'describe-function) + (with-current-buffer "*Help*" + (set-marker marker-1 (point-max))) + (set-marker marker-2 marker-1) + (should (goto-char marker-2)))) + +;;; marker-tests.el ends here. diff --git a/test/src/minibuf-tests.el b/test/src/minibuf-tests.el new file mode 100644 index 00000000000..82ac0373cb4 --- /dev/null +++ b/test/src/minibuf-tests.el @@ -0,0 +1,403 @@ +;;; minibuf-tests.el --- tests for minibuf.c functions -*- lexical-binding: t -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + + +;;; Support functions for `try-completion', `all-completion', and +;;; `test-completion' tests. + +(defun minibuf-tests--strings-to-symbol-list (list) + (mapcar #'intern list)) +(defun minibuf-tests--strings-to-symbol-alist (list) + (let ((num 0)) + (mapcar (lambda (str) (cons (intern str) (cl-incf num))) list))) +(defun minibuf-tests--strings-to-string-alist (list) + (let ((num 0)) + (mapcar (lambda (str) (cons str (cl-incf num))) list))) +(defun minibuf-tests--strings-to-obarray (list) + (let ((ob (make-vector 7 0))) + (mapc (lambda (str) (intern str ob)) list) + ob)) +(defun minibuf-tests--strings-to-string-hashtable (list) + (let ((ht (make-hash-table :test #'equal)) + (num 0)) + (mapc (lambda (str) (puthash str (cl-incf num) ht)) list) + ht)) +(defun minibuf-tests--strings-to-symbol-hashtable (list) + (let ((ht (make-hash-table :test #'equal)) + (num 0)) + (mapc (lambda (str) (puthash (intern str) (cl-incf num) ht)) list) + ht)) + +;;; Functions that produce a predicate (for *-completion functions) +;;; which always returns non-nil for a given collection. + +(defun minibuf-tests--memq-of-collection (collection) + (lambda (elt) (memq elt collection))) +(defun minibuf-tests--part-of-obarray (ob) + (lambda (sym) (eq (intern-soft (symbol-name sym) ob) sym))) +(defun minibuf-tests--part-of-hashtable (table) + (lambda (k v) (equal (gethash k table) v))) + + +;;; Testing functions that are agnostic to type of COLLECTION. + +(defun minibuf-tests--try-completion (xform-collection) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (should (equal (try-completion "a" abcdef) "abc")) + (should (equal (try-completion "a" +abba) "ab")) + (should (equal (try-completion "abc" +abba) t)) + (should (equal (try-completion "abcd" +abba) nil)))) + +(defun minibuf-tests--try-completion-pred (xform-collection collection-member) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (abcdef-member (funcall collection-member abcdef)) + (+abba (funcall xform-collection '("abc" "abba" "def"))) + (+abba-member (funcall collection-member +abba))) + (should (equal (try-completion "a" abcdef abcdef-member) "abc")) + (should (equal (try-completion "a" +abba +abba-member) "ab")) + (should (equal (try-completion "abc" +abba +abba-member) t)) + (should (equal (try-completion "abcd" +abba +abba-member) nil)) + (should-not (try-completion "a" abcdef #'ignore)) + (should-not (try-completion "a" +abba #'ignore)) + (should-not (try-completion "abc" +abba #'ignore)) + (should-not (try-completion "abcd" +abba #'ignore)))) + +(defun minibuf-tests--try-completion-regexp (xform-collection) + (let ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (let ((completion-regexp-list '("."))) + (should (equal (try-completion "a" abcdef) "abc")) + (should (equal (try-completion "a" +abba) "ab")) + (should (equal (try-completion "abc" +abba) t)) + (should (equal (try-completion "abcd" +abba) nil))) + (let ((completion-regexp-list '("X"))) + (should-not (try-completion "a" abcdef)) + (should-not (try-completion "a" +abba)) + (should-not (try-completion "abc" +abba)) + (should-not (try-completion "abcd" +abba))))) + +(defun minibuf-tests--all-completions (xform-collection) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (should (equal (all-completions "a" abcdef) '("abc"))) + (should (equal (all-completions "a" +abba) '("abc" "abba"))) + (should (equal (all-completions "abc" +abba) '("abc"))) + (should (equal (all-completions "abcd" +abba) nil)))) + +(defun minibuf-tests--all-completions-pred (xform-collection collection-member) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (abcdef-member (funcall collection-member abcdef)) + (+abba (funcall xform-collection '("abc" "abba" "def"))) + (+abba-member (funcall collection-member +abba))) + (should (equal (all-completions "a" abcdef abcdef-member) '("abc"))) + (should (equal (all-completions "a" +abba +abba-member) '("abc" "abba"))) + (should (equal (all-completions "abc" +abba +abba-member) '("abc"))) + (should (equal (all-completions "abcd" +abba +abba-member) nil)) + (should-not (all-completions "a" abcdef #'ignore)) + (should-not (all-completions "a" +abba #'ignore)) + (should-not (all-completions "abc" +abba #'ignore)) + (should-not (all-completions "abcd" +abba #'ignore)))) + +(defun minibuf-tests--all-completions-regexp (xform-collection) + (let ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (let ((completion-regexp-list '("."))) + (should (equal (all-completions "a" abcdef) '("abc"))) + (should (equal (all-completions "a" +abba) '("abc" "abba"))) + (should (equal (all-completions "abc" +abba) '("abc"))) + (should (equal (all-completions "abcd" +abba) nil))) + (let ((completion-regexp-list '("X"))) + (should-not (all-completions "a" abcdef)) + (should-not (all-completions "a" +abba)) + (should-not (all-completions "abc" +abba)) + (should-not (all-completions "abcd" +abba))))) + +(defun minibuf-tests--test-completion (xform-collection) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (should (test-completion "abc" abcdef)) + (should (test-completion "def" +abba)) + (should (test-completion "abba" +abba)) + (should-not (test-completion "abcd" +abba)))) + +(defun minibuf-tests--test-completion-pred (xform-collection collection-member) + (let* ((abcdef (funcall xform-collection '("abc" "def"))) + (abcdef-member (funcall collection-member abcdef)) + (+abba (funcall xform-collection '("abc" "abba" "def"))) + (+abba-member (funcall collection-member +abba))) + (should (test-completion "abc" abcdef abcdef-member)) + (should (test-completion "def" +abba +abba-member)) + (should (test-completion "abba" +abba +abba-member)) + (should-not (test-completion "abcd" +abba +abba-member)) + (should-not (test-completion "abc" abcdef #'ignore)) + (should-not (test-completion "def" +abba #'ignore)) + (should-not (test-completion "abba" +abba #'ignore)) + (should-not (test-completion "abcd" +abba #'ignore)))) + +(defun minibuf-tests--test-completion-regexp (xform-collection) + (let ((abcdef (funcall xform-collection '("abc" "def"))) + (+abba (funcall xform-collection '("abc" "abba" "def")))) + (let ((completion-regexp-list '("."))) + (should (test-completion "abc" abcdef)) + (should (test-completion "def" +abba)) + (should (test-completion "abba" +abba)) + (should-not (test-completion "abcd" +abba))) + (let ((completion-regexp-list '("X"))) + (should-not (test-completion "abc" abcdef)) + (should-not (test-completion "def" +abba)) + (should-not (test-completion "abba" +abba)) + (should-not (test-completion "abcd" +abba))))) + + +;;; Tests for `try-completion'. +(ert-deftest try-completion-string-list () + (minibuf-tests--try-completion #'identity)) +(ert-deftest try-completion-string-list-predicate () + (minibuf-tests--try-completion-pred + #'identity #'minibuf-tests--memq-of-collection)) +(ert-deftest try-completion-string-list-completion-regexp () + (minibuf-tests--try-completion-regexp #'identity)) + +(ert-deftest try-completion-symbol-list () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-symbol-list)) +(ert-deftest try-completion-symbol-list-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-symbol-list + #'minibuf-tests--memq-of-collection)) +(ert-deftest try-completion-symbol-list-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-symbol-list)) + +(ert-deftest try-completion-symbol-alist () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-symbol-alist)) +(ert-deftest try-completion-symbol-alist-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-symbol-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest try-completion-symbol-alist-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-symbol-alist)) + +(ert-deftest try-completion-string-alist () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-string-alist)) +(ert-deftest try-completion-string-alist-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-string-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest try-completion-string-alist-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-string-alist)) + +(ert-deftest try-completion-obarray () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-obarray)) +(ert-deftest try-completion-obarray-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-obarray + #'minibuf-tests--part-of-obarray)) +(ert-deftest try-completion-obarray-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-obarray)) + +(ert-deftest try-completion-string-hashtable () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-string-hashtable)) +(ert-deftest try-completion-string-hashtable-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-string-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest try-completion-string-hashtable-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-string-hashtable)) + +(ert-deftest try-completion-symbol-hashtable () + (minibuf-tests--try-completion + #'minibuf-tests--strings-to-symbol-hashtable)) +(ert-deftest try-completion-symbol-hashtable-predicate () + (minibuf-tests--try-completion-pred + #'minibuf-tests--strings-to-symbol-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest try-completion-symbol-hashtable-completion-regexp () + (minibuf-tests--try-completion-regexp + #'minibuf-tests--strings-to-symbol-hashtable)) + + +;;; Tests for `all-completions'. + +(ert-deftest all-completions-string-list () + (minibuf-tests--all-completions #'identity)) +(ert-deftest all-completions-string-list-predicate () + (minibuf-tests--all-completions-pred + #'identity #'minibuf-tests--memq-of-collection)) +(ert-deftest all-completions-string-list-completion-regexp () + (minibuf-tests--all-completions-regexp #'identity)) + +(ert-deftest all-completions-symbol-list () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-symbol-list)) +(ert-deftest all-completions-symbol-list-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-symbol-list + #'minibuf-tests--memq-of-collection)) +(ert-deftest all-completions-symbol-list-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-symbol-list)) + +(ert-deftest all-completions-symbol-alist () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-symbol-alist)) +(ert-deftest all-completions-symbol-alist-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-symbol-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest all-completions-symbol-alist-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-symbol-alist)) + +(ert-deftest all-completions-string-alist () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-string-alist)) +(ert-deftest all-completions-string-alist-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-string-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest all-completions-string-alist-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-string-alist)) + +(ert-deftest all-completions-obarray () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-obarray)) +(ert-deftest all-completions-obarray-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-obarray + #'minibuf-tests--part-of-obarray)) +(ert-deftest all-completions-obarray-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-obarray)) + +(ert-deftest all-completions-string-hashtable () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-string-hashtable)) +(ert-deftest all-completions-string-hashtable-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-string-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest all-completions-string-hashtable-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-string-hashtable)) + +(ert-deftest all-completions-symbol-hashtable () + (minibuf-tests--all-completions + #'minibuf-tests--strings-to-symbol-hashtable)) +(ert-deftest all-completions-symbol-hashtable-predicate () + (minibuf-tests--all-completions-pred + #'minibuf-tests--strings-to-symbol-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest all-completions-symbol-hashtable-completion-regexp () + (minibuf-tests--all-completions-regexp + #'minibuf-tests--strings-to-symbol-hashtable)) + + +;;; Tests for `test-completion'. + +(ert-deftest test-completion-string-list () + (minibuf-tests--test-completion #'identity)) +(ert-deftest test-completion-string-list-predicate () + (minibuf-tests--test-completion-pred + #'identity #'minibuf-tests--memq-of-collection)) +(ert-deftest test-completion-string-list-completion-regexp () + (minibuf-tests--test-completion-regexp #'identity)) + +(ert-deftest test-completion-symbol-list () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-symbol-list)) +(ert-deftest test-completion-symbol-list-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-symbol-list + #'minibuf-tests--memq-of-collection)) +(ert-deftest test-completion-symbol-list-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-symbol-list)) + +(ert-deftest test-completion-symbol-alist () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-symbol-alist)) +(ert-deftest test-completion-symbol-alist-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-symbol-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest test-completion-symbol-alist-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-symbol-alist)) + +(ert-deftest test-completion-string-alist () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-string-alist)) +(ert-deftest test-completion-string-alist-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-string-alist + #'minibuf-tests--memq-of-collection)) +(ert-deftest test-completion-string-alist-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-string-alist)) + +(ert-deftest test-completion-obarray () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-obarray)) +(ert-deftest test-completion-obarray-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-obarray + #'minibuf-tests--part-of-obarray)) +(ert-deftest test-completion-obarray-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-obarray)) + +(ert-deftest test-completion-string-hashtable () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-string-hashtable)) +(ert-deftest test-completion-string-hashtable-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-string-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest test-completion-string-hashtable-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-string-hashtable)) + +(ert-deftest test-completion-symbol-hashtable () + (minibuf-tests--test-completion + #'minibuf-tests--strings-to-symbol-hashtable)) +(ert-deftest test-completion-symbol-hashtable-predicate () + (minibuf-tests--test-completion-pred + #'minibuf-tests--strings-to-symbol-hashtable + #'minibuf-tests--part-of-hashtable)) +(ert-deftest test-completion-symbol-hashtable-completion-regexp () + (minibuf-tests--test-completion-regexp + #'minibuf-tests--strings-to-symbol-hashtable)) + + +;;; minibuf-tests.el ends here diff --git a/test/src/print-tests.el b/test/src/print-tests.el new file mode 100644 index 00000000000..1abfa53581c --- /dev/null +++ b/test/src/print-tests.el @@ -0,0 +1,62 @@ +;;; print-tests.el --- tests for src/print.c -*- lexical-binding: t; -*- + +;; Copyright (C) 2014-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest print-hex-backslash () + (should (string= (let ((print-escape-multibyte t) + (print-escape-newlines t)) + (prin1-to-string "\u00A2\ff")) + "\"\\x00a2\\ff\""))) + +(ert-deftest terpri () + (should (string= (with-output-to-string + (princ 'abc) + (should (terpri nil t))) + "abc\n")) + (should (string= (with-output-to-string + (should-not (terpri nil t)) + (princ 'xyz)) + "xyz")) + (message nil) + (if noninteractive + (progn (should (terpri nil t)) + (should-not (terpri nil t)) + (princ 'abc) + (should (terpri nil t)) + (should-not (terpri nil t))) + (should (string= (progn (should-not (terpri nil t)) + (princ 'abc) + (should (terpri nil t)) + (current-message)) + "abc\n"))) + (let ((standard-output + (with-current-buffer (get-buffer-create "*terpri-test*") + (insert "--------") + (point-max-marker)))) + (should (terpri nil t)) + (should-not (terpri nil t)) + (should (string= (with-current-buffer (marker-buffer standard-output) + (buffer-string)) + "--------\n")))) + +(provide 'print-tests) +;;; print-tests.el ends here diff --git a/test/src/process-tests.el b/test/src/process-tests.el new file mode 100644 index 00000000000..8cc59bf9feb --- /dev/null +++ b/test/src/process-tests.el @@ -0,0 +1,166 @@ +;;; process-tests.el --- Testing the process facilities + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; + +;;; Code: + +(require 'ert) + +;; Timeout in seconds; the test fails if the timeout is reached. +(defvar process-test-sentinel-wait-timeout 2.0) + +;; Start a process that exits immediately. Call WAIT-FUNCTION, +;; possibly multiple times, to wait for the process to complete. +(defun process-test-sentinel-wait-function-working-p (wait-function) + (let ((proc (start-process "test" nil "bash" "-c" "exit 20")) + (sentinel-called nil) + (start-time (float-time))) + (set-process-sentinel proc (lambda (proc msg) + (setq sentinel-called t))) + (while (not (or sentinel-called + (> (- (float-time) start-time) + process-test-sentinel-wait-timeout))) + (funcall wait-function)) + (cl-assert (eq (process-status proc) 'exit)) + (cl-assert (= (process-exit-status proc) 20)) + sentinel-called)) + +(ert-deftest process-test-sentinel-accept-process-output () + (skip-unless (executable-find "bash")) + (should (process-test-sentinel-wait-function-working-p + #'accept-process-output))) + +(ert-deftest process-test-sentinel-sit-for () + (skip-unless (executable-find "bash")) + (should + (process-test-sentinel-wait-function-working-p (lambda () (sit-for 0.01 t))))) + +(when (eq system-type 'windows-nt) + (ert-deftest process-test-quoted-batfile () + "Check that Emacs hides CreateProcess deficiency (bug#18745)." + (let (batfile) + (unwind-protect + (progn + ;; CreateProcess will fail when both the bat file and 1st + ;; argument are quoted, so include spaces in both of those + ;; to force quoting. + (setq batfile (make-temp-file "echo args" nil ".bat")) + (with-temp-file batfile + (insert "@echo arg1=%1, arg2=%2\n")) + (with-temp-buffer + (call-process batfile nil '(t t) t "x &y") + (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n"))) + (with-temp-buffer + (call-process-shell-command + (mapconcat #'shell-quote-argument (list batfile "x &y") " ") + nil '(t t) t) + (should (string= (buffer-string) "arg1=\"x &y\", arg2=\n")))) + (when batfile (delete-file batfile)))))) + +(ert-deftest process-test-stderr-buffer () + (skip-unless (executable-find "bash")) + (let* ((stdout-buffer (generate-new-buffer "*stdout*")) + (stderr-buffer (generate-new-buffer "*stderr*")) + (proc (make-process :name "test" + :command (list "bash" "-c" + (concat "echo hello stdout!; " + "echo hello stderr! >&2; " + "exit 20")) + :buffer stdout-buffer + :stderr stderr-buffer)) + (sentinel-called nil) + (start-time (float-time))) + (set-process-sentinel proc (lambda (proc msg) + (setq sentinel-called t))) + (while (not (or sentinel-called + (> (- (float-time) start-time) + process-test-sentinel-wait-timeout))) + (accept-process-output)) + (cl-assert (eq (process-status proc) 'exit)) + (cl-assert (= (process-exit-status proc) 20)) + (should (with-current-buffer stdout-buffer + (goto-char (point-min)) + (looking-at "hello stdout!"))) + (should (with-current-buffer stderr-buffer + (goto-char (point-min)) + (looking-at "hello stderr!"))))) + +(ert-deftest process-test-stderr-filter () + (skip-unless (executable-find "bash")) + (let* ((sentinel-called nil) + (stderr-sentinel-called nil) + (stdout-output nil) + (stderr-output nil) + (stdout-buffer (generate-new-buffer "*stdout*")) + (stderr-buffer (generate-new-buffer "*stderr*")) + (stderr-proc (make-pipe-process :name "stderr" + :buffer stderr-buffer)) + (proc (make-process :name "test" :buffer stdout-buffer + :command (list "bash" "-c" + (concat "echo hello stdout!; " + "echo hello stderr! >&2; " + "exit 20")) + :stderr stderr-proc)) + (start-time (float-time))) + (set-process-filter proc (lambda (proc input) + (push input stdout-output))) + (set-process-sentinel proc (lambda (proc msg) + (setq sentinel-called t))) + (set-process-filter stderr-proc (lambda (proc input) + (push input stderr-output))) + (set-process-sentinel stderr-proc (lambda (proc input) + (setq stderr-sentinel-called t))) + (while (not (or sentinel-called + (> (- (float-time) start-time) + process-test-sentinel-wait-timeout))) + (accept-process-output)) + (cl-assert (eq (process-status proc) 'exit)) + (cl-assert (= (process-exit-status proc) 20)) + (should sentinel-called) + (should (equal 1 (with-current-buffer stdout-buffer + (point-max)))) + (should (equal "hello stdout!\n" + (mapconcat #'identity (nreverse stdout-output) ""))) + (should stderr-sentinel-called) + (should (equal 1 (with-current-buffer stderr-buffer + (point-max)))) + (should (equal "hello stderr!\n" + (mapconcat #'identity (nreverse stderr-output) ""))))) + +(ert-deftest start-process-should-not-modify-arguments () + "`start-process' must not modify its arguments in-place." + ;; See bug#21831. + (let* ((path (pcase system-type + ((or 'windows-nt 'ms-dos) + ;; Make sure the file name uses forward slashes. + ;; The original bug was that 'start-process' would + ;; convert forward slashes to backslashes. + (expand-file-name (executable-find "attrib.exe"))) + (_ "/bin//sh"))) + (samepath (copy-sequence path))) + ;; Make sure 'start-process' actually goes all the way and invokes + ;; the program. + (should (process-live-p (condition-case nil + (start-process "" nil path) + (error nil)))) + (should (equal path samepath)))) + +(provide 'process-tests) +;; process-tests.el ends here. diff --git a/test/src/regex-resources/BOOST.tests b/test/src/regex-resources/BOOST.tests new file mode 100644 index 00000000000..98fd3b6abf3 --- /dev/null +++ b/test/src/regex-resources/BOOST.tests @@ -0,0 +1,829 @@ +; +; +; this file contains a script of tests to run through regress.exe +; +; comments start with a semicolon and proceed to the end of the line +; +; changes to regular expression compile flags start with a "-" as the first +; non-whitespace character and consist of a list of the printable names +; of the flags, for example "match_default" +; +; Other lines contain a test to perform using the current flag status +; the first token contains the expression to compile, the second the string +; to match it against. If the second string is "!" then the expression should +; not compile, that is the first string is an invalid regular expression. +; This is then followed by a list of integers that specify what should match, +; each pair represents the starting and ending positions of a subexpression +; starting with the zeroth subexpression (the whole match). +; A value of -1 indicates that the subexpression should not take part in the +; match at all, if the first value is -1 then no part of the expression should +; match the string. +; +; Tests taken from BOOST testsuite and adapted to glibc regex. +; +; Boost Software License - Version 1.0 - August 17th, 2003 +; +; Permission is hereby granted, free of charge, to any person or organization +; obtaining a copy of the software and accompanying documentation covered by +; this license (the "Software") to use, reproduce, display, distribute, +; execute, and transmit the Software, and to prepare derivative works of the +; Software, and to permit third-parties to whom the Software is furnished to +; do so, all subject to the following: +; +; The copyright notices in the Software and this entire statement, including +; the above license grant, this restriction and the following disclaimer, +; must be included in all copies of the Software, in whole or in part, and +; all derivative works of the Software, unless such copies or derivative +; works are solely in the form of machine-executable object code generated by +; a source language processor. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +; SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +; FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +; DEALINGS IN THE SOFTWARE. +; + +- match_default normal REG_EXTENDED + +; +; try some really simple literals: +a a 0 1 +Z Z 0 1 +Z aaa -1 -1 +Z xxxxZZxxx 4 5 + +; and some simple brackets: +(a) zzzaazz 3 4 3 4 +() zzz 0 0 0 0 +() "" 0 0 0 0 +( ! +) ) 0 1 +(aa ! +aa) baa)b 1 4 +a b -1 -1 +\(\) () 0 2 +\(a\) (a) 0 3 +\() () 0 2 +(\) ! +p(a)rameter ABCparameterXYZ 3 12 4 5 +[pq](a)rameter ABCparameterXYZ 3 12 4 5 + +; now try escaped brackets: +- match_default bk_parens REG_BASIC +\(a\) zzzaazz 3 4 3 4 +\(\) zzz 0 0 0 0 +\(\) "" 0 0 0 0 +\( ! +\) ! +\(aa ! +aa\) ! +() () 0 2 +(a) (a) 0 3 +(\) ! +\() ! + +; now move on to "." wildcards +- match_default normal REG_EXTENDED REG_STARTEND +. a 0 1 +. \n 0 1 +. \r 0 1 +. \0 0 1 + +; +; now move on to the repetion ops, +; starting with operator * +- match_default normal REG_EXTENDED +a* b 0 0 +ab* a 0 1 +ab* ab 0 2 +ab* sssabbbbbbsss 3 10 +ab*c* a 0 1 +ab*c* abbb 0 4 +ab*c* accc 0 4 +ab*c* abbcc 0 5 +*a ! +\<* ! +\>* ! +\n* \n\n 0 2 +\** ** 0 2 +\* * 0 1 + +; now try operator + +ab+ a -1 -1 +ab+ ab 0 2 +ab+ sssabbbbbbsss 3 10 +ab+c+ a -1 -1 +ab+c+ abbb -1 -1 +ab+c+ accc -1 -1 +ab+c+ abbcc 0 5 ++a ! +\<+ ! +\>+ ! +\n+ \n\n 0 2 +\+ + 0 1 +\+ ++ 0 1 +\++ ++ 0 2 + +; now try operator ? +- match_default normal REG_EXTENDED +a? b 0 0 +ab? a 0 1 +ab? ab 0 2 +ab? sssabbbbbbsss 3 5 +ab?c? a 0 1 +ab?c? abbb 0 2 +ab?c? accc 0 2 +ab?c? abcc 0 3 +?a ! +\<? ! +\>? ! +\n? \n\n 0 1 +\? ? 0 1 +\? ?? 0 1 +\?? ?? 0 1 + +; now try operator {} +- match_default normal REG_EXTENDED +a{2} a -1 -1 +a{2} aa 0 2 +a{2} aaa 0 2 +a{2,} a -1 -1 +a{2,} aa 0 2 +a{2,} aaaaa 0 5 +a{2,4} a -1 -1 +a{2,4} aa 0 2 +a{2,4} aaa 0 3 +a{2,4} aaaa 0 4 +a{2,4} aaaaa 0 4 +a{} ! +a{2 ! +a} a} 0 2 +\{\} {} 0 2 + +- match_default normal REG_BASIC +a\{2\} a -1 -1 +a\{2\} aa 0 2 +a\{2\} aaa 0 2 +a\{2,\} a -1 -1 +a\{2,\} aa 0 2 +a\{2,\} aaaaa 0 5 +a\{2,4\} a -1 -1 +a\{2,4\} aa 0 2 +a\{2,4\} aaa 0 3 +a\{2,4\} aaaa 0 4 +a\{2,4\} aaaaa 0 4 +{} {} 0 2 + +; now test the alternation operator | +- match_default normal REG_EXTENDED +a|b a 0 1 +a|b b 0 1 +a(b|c) ab 0 2 1 2 +a(b|c) ac 0 2 1 2 +a(b|c) ad -1 -1 -1 -1 +a\| a| 0 2 + +; now test the set operator [] +- match_default normal REG_EXTENDED +; try some literals first +[abc] a 0 1 +[abc] b 0 1 +[abc] c 0 1 +[abc] d -1 -1 +[^bcd] a 0 1 +[^bcd] b -1 -1 +[^bcd] d -1 -1 +[^bcd] e 0 1 +a[b]c abc 0 3 +a[ab]c abc 0 3 +a[^ab]c adc 0 3 +a[]b]c a]c 0 3 +a[[b]c a[c 0 3 +a[-b]c a-c 0 3 +a[^]b]c adc 0 3 +a[^-b]c adc 0 3 +a[b-]c a-c 0 3 +a[b ! +a[] ! + +; then some ranges +[b-e] a -1 -1 +[b-e] b 0 1 +[b-e] e 0 1 +[b-e] f -1 -1 +[^b-e] a 0 1 +[^b-e] b -1 -1 +[^b-e] e -1 -1 +[^b-e] f 0 1 +a[1-3]c a2c 0 3 +a[3-1]c ! +a[1-3-5]c ! +a[1- ! + +; and some classes +a[[:alpha:]]c abc 0 3 +a[[:unknown:]]c ! +a[[: ! +a[[:alpha ! +a[[:alpha:] ! +a[[:alpha,:] ! +a[[:]:]]b ! +a[[:-:]]b ! +a[[:alph:]] ! +a[[:alphabet:]] ! +[[:alnum:]]+ -%@a0X_- 3 6 +[[:alpha:]]+ -%@aX_0- 3 5 +[[:blank:]]+ "a \tb" 1 4 +[[:cntrl:]]+ a\n\tb 1 3 +[[:digit:]]+ a019b 1 4 +[[:graph:]]+ " a%b " 1 4 +[[:lower:]]+ AabC 1 3 +; This test fails with STLPort, disable for now as this is a corner case anyway... +;[[:print:]]+ "\na b\n" 1 4 +[[:punct:]]+ " %-&\t" 1 4 +[[:space:]]+ "a \n\t\rb" 1 5 +[[:upper:]]+ aBCd 1 3 +[[:xdigit:]]+ p0f3Cx 1 5 + +; now test flag settings: +- escape_in_lists REG_NO_POSIX_TEST +[\n] \n 0 1 +- REG_NO_POSIX_TEST + +; line anchors +- match_default normal REG_EXTENDED +^ab ab 0 2 +^ab xxabxx -1 -1 +ab$ ab 0 2 +ab$ abxx -1 -1 +- match_default match_not_bol match_not_eol normal REG_EXTENDED REG_NOTBOL REG_NOTEOL +^ab ab -1 -1 +^ab xxabxx -1 -1 +ab$ ab -1 -1 +ab$ abxx -1 -1 + +; back references +- match_default normal REG_PERL +a(b)\2c ! +a(b\1)c ! +a(b*)c\1d abbcbbd 0 7 1 3 +a(b*)c\1d abbcbd -1 -1 +a(b*)c\1d abbcbbbd -1 -1 +^(.)\1 abc -1 -1 +a([bc])\1d abcdabbd 4 8 5 6 +; strictly speaking this is at best ambiguous, at worst wrong, this is what most +; re implimentations will match though. +a(([bc])\2)*d abbccd 0 6 3 5 3 4 + +a(([bc])\2)*d abbcbd -1 -1 +a((b)*\2)*d abbbd 0 5 1 4 2 3 +; perl only: +(ab*)[ab]*\1 ababaaa 0 7 0 1 +(a)\1bcd aabcd 0 5 0 1 +(a)\1bc*d aabcd 0 5 0 1 +(a)\1bc*d aabd 0 4 0 1 +(a)\1bc*d aabcccd 0 7 0 1 +(a)\1bc*[ce]d aabcccd 0 7 0 1 +^(a)\1b(c)*cd$ aabcccd 0 7 0 1 4 5 + +; posix only: +- match_default extended REG_EXTENDED +(ab*)[ab]*\1 ababaaa 0 7 0 1 + +; +; word operators: +\w a 0 1 +\w z 0 1 +\w A 0 1 +\w Z 0 1 +\w _ 0 1 +\w } -1 -1 +\w ` -1 -1 +\w [ -1 -1 +\w @ -1 -1 +; non-word: +\W a -1 -1 +\W z -1 -1 +\W A -1 -1 +\W Z -1 -1 +\W _ -1 -1 +\W } 0 1 +\W ` 0 1 +\W [ 0 1 +\W @ 0 1 +; word start: +\<abcd " abcd" 2 6 +\<ab cab -1 -1 +\<ab "\nab" 1 3 +\<tag ::tag 2 5 +;word end: +abc\> abc 0 3 +abc\> abcd -1 -1 +abc\> abc\n 0 3 +abc\> abc:: 0 3 +; word boundary: +\babcd " abcd" 2 6 +\bab cab -1 -1 +\bab "\nab" 1 3 +\btag ::tag 2 5 +abc\b abc 0 3 +abc\b abcd -1 -1 +abc\b abc\n 0 3 +abc\b abc:: 0 3 +; within word: +\B ab 1 1 +a\Bb ab 0 2 +a\B ab 0 1 +a\B a -1 -1 +a\B "a " -1 -1 + +; +; buffer operators: +\`abc abc 0 3 +\`abc \nabc -1 -1 +\`abc " abc" -1 -1 +abc\' abc 0 3 +abc\' abc\n -1 -1 +abc\' "abc " -1 -1 + +; +; now follows various complex expressions designed to try and bust the matcher: +a(((b)))c abc 0 3 1 2 1 2 1 2 +a(b|(c))d abd 0 3 1 2 -1 -1 +a(b|(c))d acd 0 3 1 2 1 2 +a(b*|c)d abbd 0 4 1 3 +; just gotta have one DFA-buster, of course +a[ab]{20} aaaaabaaaabaaaabaaaab 0 21 +; and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] aaaaabaaaabaaaabaaaab 0 21 +; and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) aaaaabaaaabaaaabaaaabweeknights 0 31 21 24 24 31 +; one really big one +1234567890123456789012345678901234567890123456789012345678901234567890 a1234567890123456789012345678901234567890123456789012345678901234567890b 1 71 +; fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] xacegikmoq 1 8 +[ab][cd][ef][gh][ij][kl][mn][op] xacegikmoq 1 9 +[ab][cd][ef][gh][ij][kl][mn][op][qr] xacegikmoqy 1 10 +[ab][cd][ef][gh][ij][kl][mn][op][q] xacegikmoqy 1 10 +; and as parenthesis go past 9: +(a)(b)(c)(d)(e)(f)(g)(h) zabcdefghi 1 9 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 +(a)(b)(c)(d)(e)(f)(g)(h)(i) zabcdefghij 1 10 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 +(a)(b)(c)(d)(e)(f)(g)(h)(i)(j) zabcdefghijk 1 11 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 +(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k) zabcdefghijkl 1 12 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 +(a)d|(b)c abc 1 3 -1 -1 1 2 +_+((www)|(ftp)|(mailto)):_* "_wwwnocolon _mailto:" 12 20 13 19 -1 -1 -1 -1 13 19 + +; subtleties of matching +;a(b)?c\1d acd 0 3 -1 -1 +; POSIX is about the following test: +a(b)?c\1d acd -1 -1 -1 -1 +a(b?c)+d accd 0 4 2 3 +(wee|week)(knights|night) weeknights 0 10 0 3 3 10 +.* abc 0 3 +a(b|(c))d abd 0 3 1 2 -1 -1 +a(b|(c))d acd 0 3 1 2 1 2 +a(b*|c|e)d abbd 0 4 1 3 +a(b*|c|e)d acd 0 3 1 2 +a(b*|c|e)d ad 0 2 1 1 +a(b?)c abc 0 3 1 2 +a(b?)c ac 0 2 1 1 +a(b+)c abc 0 3 1 2 +a(b+)c abbbc 0 5 1 4 +a(b*)c ac 0 2 1 1 +(a|ab)(bc([de]+)f|cde) abcdef 0 6 0 1 1 6 3 5 +a([bc]?)c abc 0 3 1 2 +a([bc]?)c ac 0 2 1 1 +a([bc]+)c abc 0 3 1 2 +a([bc]+)c abcc 0 4 1 3 +a([bc]+)bc abcbc 0 5 1 3 +a(bb+|b)b abb 0 3 1 2 +a(bbb+|bb+|b)b abb 0 3 1 2 +a(bbb+|bb+|b)b abbb 0 4 1 3 +a(bbb+|bb+|b)bb abbb 0 4 1 2 +(.*).* abcdef 0 6 0 6 +(a*)* bc 0 0 0 0 +xyx*xz xyxxxxyxxxz 5 11 + +; do we get the right subexpression when it is used more than once? +a(b|c)*d ad 0 2 -1 -1 +a(b|c)*d abcd 0 4 2 3 +a(b|c)+d abd 0 3 1 2 +a(b|c)+d abcd 0 4 2 3 +a(b|c?)+d ad 0 2 1 1 +a(b|c){0,0}d ad 0 2 -1 -1 +a(b|c){0,1}d ad 0 2 -1 -1 +a(b|c){0,1}d abd 0 3 1 2 +a(b|c){0,2}d ad 0 2 -1 -1 +a(b|c){0,2}d abcd 0 4 2 3 +a(b|c){0,}d ad 0 2 -1 -1 +a(b|c){0,}d abcd 0 4 2 3 +a(b|c){1,1}d abd 0 3 1 2 +a(b|c){1,2}d abd 0 3 1 2 +a(b|c){1,2}d abcd 0 4 2 3 +a(b|c){1,}d abd 0 3 1 2 +a(b|c){1,}d abcd 0 4 2 3 +a(b|c){2,2}d acbd 0 4 2 3 +a(b|c){2,2}d abcd 0 4 2 3 +a(b|c){2,4}d abcd 0 4 2 3 +a(b|c){2,4}d abcbd 0 5 3 4 +a(b|c){2,4}d abcbcd 0 6 4 5 +a(b|c){2,}d abcd 0 4 2 3 +a(b|c){2,}d abcbd 0 5 3 4 +; perl only: these conflict with the POSIX test below +;a(b|c?)+d abcd 0 4 3 3 +;a(b+|((c)*))+d abd 0 3 2 2 2 2 -1 -1 +;a(b+|((c)*))+d abcd 0 4 3 3 3 3 2 3 + +; posix only: +- match_default extended REG_EXTENDED REG_STARTEND + +a(b|c?)+d abcd 0 4 2 3 +a(b|((c)*))+d abcd 0 4 2 3 2 3 2 3 +a(b+|((c)*))+d abd 0 3 1 2 -1 -1 -1 -1 +a(b+|((c)*))+d abcd 0 4 2 3 2 3 2 3 +a(b|((c)*))+d ad 0 2 1 1 1 1 -1 -1 +a(b|((c)*))*d abcd 0 4 2 3 2 3 2 3 +a(b+|((c)*))*d abd 0 3 1 2 -1 -1 -1 -1 +a(b+|((c)*))*d abcd 0 4 2 3 2 3 2 3 +a(b|((c)*))*d ad 0 2 1 1 1 1 -1 -1 + +- match_default normal REG_PERL +; try to match C++ syntax elements: +; line comment: +//[^\n]* "++i //here is a line comment\n" 4 28 +; block comment: +/\*([^*]|\*+[^*/])*\*+/ "/* here is a block comment */" 0 29 26 27 +/\*([^*]|\*+[^*/])*\*+/ "/**/" 0 4 -1 -1 +/\*([^*]|\*+[^*/])*\*+/ "/***/" 0 5 -1 -1 +/\*([^*]|\*+[^*/])*\*+/ "/****/" 0 6 -1 -1 +/\*([^*]|\*+[^*/])*\*+/ "/*****/" 0 7 -1 -1 +/\*([^*]|\*+[^*/])*\*+/ "/*****/*/" 0 7 -1 -1 +; preprossor directives: +^[[:blank:]]*#([^\n]*\\[[:space:]]+)*[^\n]* "#define some_symbol" 0 19 -1 -1 +^[[:blank:]]*#([^\n]*\\[[:space:]]+)*[^\n]* "#define some_symbol(x) #x" 0 25 -1 -1 +; perl only: +^[[:blank:]]*#([^\n]*\\[[:space:]]+)*[^\n]* "#define some_symbol(x) \\ \r\n foo();\\\r\n printf(#x);" 0 53 30 42 +; literals: +((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)? 0xFF 0 4 0 4 0 4 -1 -1 -1 -1 -1 -1 -1 -1 +((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)? 35 0 2 0 2 -1 -1 0 2 -1 -1 -1 -1 -1 -1 +((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)? 0xFFu 0 5 0 4 0 4 -1 -1 -1 -1 -1 -1 -1 -1 +((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)? 0xFFL 0 5 0 4 0 4 -1 -1 4 5 -1 -1 -1 -1 +((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)? 0xFFFFFFFFFFFFFFFFuint64 0 24 0 18 0 18 -1 -1 19 24 19 24 22 24 +; strings: +'([^\\']|\\.)*' '\\x3A' 0 6 4 5 +'([^\\']|\\.)*' '\\'' 0 4 1 3 +'([^\\']|\\.)*' '\\n' 0 4 1 3 + +; finally try some case insensitive matches: +- match_default normal REG_EXTENDED REG_ICASE +; upper and lower have no meaning here so they fail, however these +; may compile with other libraries... +;[[:lower:]] ! +;[[:upper:]] ! +0123456789@abcdefghijklmnopqrstuvwxyz\[\\\]\^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ\{\|\} 0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\} 0 72 + +; known and suspected bugs: +- match_default normal REG_EXTENDED +\( ( 0 1 +\) ) 0 1 +\$ $ 0 1 +\^ ^ 0 1 +\. . 0 1 +\* * 0 1 +\+ + 0 1 +\? ? 0 1 +\[ [ 0 1 +\] ] 0 1 +\| | 0 1 +\\ \\ 0 1 +# # 0 1 +\# # 0 1 +a- a- 0 2 +\- - 0 1 +\{ { 0 1 +\} } 0 1 +0 0 0 1 +1 1 0 1 +9 9 0 1 +b b 0 1 +B B 0 1 +< < 0 1 +> > 0 1 +w w 0 1 +W W 0 1 +` ` 0 1 +' ' 0 1 +\n \n 0 1 +, , 0 1 +a a 0 1 +f f 0 1 +n n 0 1 +r r 0 1 +t t 0 1 +v v 0 1 +c c 0 1 +x x 0 1 +: : 0 1 +(\.[[:alnum:]]+){2} "w.a.b " 1 5 3 5 + +- match_default normal REG_EXTENDED REG_ICASE +a A 0 1 +A a 0 1 +[abc]+ abcABC 0 6 +[ABC]+ abcABC 0 6 +[a-z]+ abcABC 0 6 +[A-Z]+ abzANZ 0 6 +[a-Z]+ abzABZ 0 6 +[A-z]+ abzABZ 0 6 +[[:lower:]]+ abyzABYZ 0 8 +[[:upper:]]+ abzABZ 0 6 +[[:alpha:]]+ abyzABYZ 0 8 +[[:alnum:]]+ 09abyzABYZ 0 10 + +; word start: +\<abcd " abcd" 2 6 +\<ab cab -1 -1 +\<ab "\nab" 1 3 +\<tag ::tag 2 5 +;word end: +abc\> abc 0 3 +abc\> abcd -1 -1 +abc\> abc\n 0 3 +abc\> abc:: 0 3 + +; collating elements and rewritten set code: +- match_default normal REG_EXTENDED REG_STARTEND +;[[.zero.]] 0 0 1 +;[[.one.]] 1 0 1 +;[[.two.]] 2 0 1 +;[[.three.]] 3 0 1 +[[.a.]] baa 1 2 +;[[.right-curly-bracket.]] } 0 1 +;[[.NUL.]] \0 0 1 +[[:<:]z] ! +[a[:>:]] ! +[[=a=]] a 0 1 +;[[=right-curly-bracket=]] } 0 1 +- match_default normal REG_EXTENDED REG_STARTEND REG_ICASE +[[.A.]] A 0 1 +[[.A.]] a 0 1 +[[.A.]-b]+ AaBb 0 4 +[A-[.b.]]+ AaBb 0 4 +[[.a.]-B]+ AaBb 0 4 +[a-[.B.]]+ AaBb 0 4 +- match_default normal REG_EXTENDED REG_STARTEND +[[.a.]-c]+ abcd 0 3 +[a-[.c.]]+ abcd 0 3 +[[:alpha:]-a] ! +[a-[:alpha:]] ! + +; try mutli-character ligatures: +;[[.ae.]] ae 0 2 +;[[.ae.]] aE -1 -1 +;[[.AE.]] AE 0 2 +;[[.Ae.]] Ae 0 2 +;[[.ae.]-b] a -1 -1 +;[[.ae.]-b] b 0 1 +;[[.ae.]-b] ae 0 2 +;[a-[.ae.]] a 0 1 +;[a-[.ae.]] b -1 -1 +;[a-[.ae.]] ae 0 2 +- match_default normal REG_EXTENDED REG_STARTEND REG_ICASE +;[[.ae.]] AE 0 2 +;[[.ae.]] Ae 0 2 +;[[.AE.]] Ae 0 2 +;[[.Ae.]] aE 0 2 +;[[.AE.]-B] a -1 -1 +;[[.Ae.]-b] b 0 1 +;[[.Ae.]-b] B 0 1 +;[[.ae.]-b] AE 0 2 + +- match_default normal REG_EXTENDED REG_STARTEND REG_NO_POSIX_TEST +\s+ "ab ab" 2 5 +\S+ " abc " 2 5 + +- match_default normal REG_EXTENDED REG_STARTEND +\`abc abc 0 3 +\`abc aabc -1 -1 +abc\' abc 0 3 +abc\' abcd -1 -1 +abc\' abc\n\n -1 -1 +abc\' abc 0 3 + +; extended repeat checking to exercise new algorithms: +ab.*xy abxy_ 0 4 +ab.*xy ab_xy_ 0 5 +ab.*xy abxy 0 4 +ab.*xy ab_xy 0 5 +ab.* ab 0 2 +ab.* ab__ 0 4 + +ab.{2,5}xy ab__xy_ 0 6 +ab.{2,5}xy ab____xy_ 0 8 +ab.{2,5}xy ab_____xy_ 0 9 +ab.{2,5}xy ab__xy 0 6 +ab.{2,5}xy ab_____xy 0 9 +ab.{2,5} ab__ 0 4 +ab.{2,5} ab_______ 0 7 +ab.{2,5}xy ab______xy -1 -1 +ab.{2,5}xy ab_xy -1 -1 + +ab.*?xy abxy_ 0 4 +ab.*?xy ab_xy_ 0 5 +ab.*?xy abxy 0 4 +ab.*?xy ab_xy 0 5 +ab.*? ab 0 2 +ab.*? ab__ 0 4 + +ab.{2,5}?xy ab__xy_ 0 6 +ab.{2,5}?xy ab____xy_ 0 8 +ab.{2,5}?xy ab_____xy_ 0 9 +ab.{2,5}?xy ab__xy 0 6 +ab.{2,5}?xy ab_____xy 0 9 +ab.{2,5}? ab__ 0 4 +ab.{2,5}? ab_______ 0 7 +ab.{2,5}?xy ab______xy -1 -1 +ab.{2,5}xy ab_xy -1 -1 + +; again but with slower algorithm variant: +- match_default REG_EXTENDED +; now again for single character repeats: + +ab_*xy abxy_ 0 4 +ab_*xy ab_xy_ 0 5 +ab_*xy abxy 0 4 +ab_*xy ab_xy 0 5 +ab_* ab 0 2 +ab_* ab__ 0 4 + +ab_{2,5}xy ab__xy_ 0 6 +ab_{2,5}xy ab____xy_ 0 8 +ab_{2,5}xy ab_____xy_ 0 9 +ab_{2,5}xy ab__xy 0 6 +ab_{2,5}xy ab_____xy 0 9 +ab_{2,5} ab__ 0 4 +ab_{2,5} ab_______ 0 7 +ab_{2,5}xy ab______xy -1 -1 +ab_{2,5}xy ab_xy -1 -1 + +ab_*?xy abxy_ 0 4 +ab_*?xy ab_xy_ 0 5 +ab_*?xy abxy 0 4 +ab_*?xy ab_xy 0 5 +ab_*? ab 0 2 +ab_*? ab__ 0 4 + +ab_{2,5}?xy ab__xy_ 0 6 +ab_{2,5}?xy ab____xy_ 0 8 +ab_{2,5}?xy ab_____xy_ 0 9 +ab_{2,5}?xy ab__xy 0 6 +ab_{2,5}?xy ab_____xy 0 9 +ab_{2,5}? ab__ 0 4 +ab_{2,5}? ab_______ 0 7 +ab_{2,5}?xy ab______xy -1 -1 +ab_{2,5}xy ab_xy -1 -1 + +; and again for sets: +ab[_,;]*xy abxy_ 0 4 +ab[_,;]*xy ab_xy_ 0 5 +ab[_,;]*xy abxy 0 4 +ab[_,;]*xy ab_xy 0 5 +ab[_,;]* ab 0 2 +ab[_,;]* ab__ 0 4 + +ab[_,;]{2,5}xy ab__xy_ 0 6 +ab[_,;]{2,5}xy ab____xy_ 0 8 +ab[_,;]{2,5}xy ab_____xy_ 0 9 +ab[_,;]{2,5}xy ab__xy 0 6 +ab[_,;]{2,5}xy ab_____xy 0 9 +ab[_,;]{2,5} ab__ 0 4 +ab[_,;]{2,5} ab_______ 0 7 +ab[_,;]{2,5}xy ab______xy -1 -1 +ab[_,;]{2,5}xy ab_xy -1 -1 + +ab[_,;]*?xy abxy_ 0 4 +ab[_,;]*?xy ab_xy_ 0 5 +ab[_,;]*?xy abxy 0 4 +ab[_,;]*?xy ab_xy 0 5 +ab[_,;]*? ab 0 2 +ab[_,;]*? ab__ 0 4 + +ab[_,;]{2,5}?xy ab__xy_ 0 6 +ab[_,;]{2,5}?xy ab____xy_ 0 8 +ab[_,;]{2,5}?xy ab_____xy_ 0 9 +ab[_,;]{2,5}?xy ab__xy 0 6 +ab[_,;]{2,5}?xy ab_____xy 0 9 +ab[_,;]{2,5}? ab__ 0 4 +ab[_,;]{2,5}? ab_______ 0 7 +ab[_,;]{2,5}?xy ab______xy -1 -1 +ab[_,;]{2,5}xy ab_xy -1 -1 + +; and again for tricky sets with digraphs: +;ab[_[.ae.]]*xy abxy_ 0 4 +;ab[_[.ae.]]*xy ab_xy_ 0 5 +;ab[_[.ae.]]*xy abxy 0 4 +;ab[_[.ae.]]*xy ab_xy 0 5 +;ab[_[.ae.]]* ab 0 2 +;ab[_[.ae.]]* ab__ 0 4 + +;ab[_[.ae.]]{2,5}xy ab__xy_ 0 6 +;ab[_[.ae.]]{2,5}xy ab____xy_ 0 8 +;ab[_[.ae.]]{2,5}xy ab_____xy_ 0 9 +;ab[_[.ae.]]{2,5}xy ab__xy 0 6 +;ab[_[.ae.]]{2,5}xy ab_____xy 0 9 +;ab[_[.ae.]]{2,5} ab__ 0 4 +;ab[_[.ae.]]{2,5} ab_______ 0 7 +;ab[_[.ae.]]{2,5}xy ab______xy -1 -1 +;ab[_[.ae.]]{2,5}xy ab_xy -1 -1 + +;ab[_[.ae.]]*?xy abxy_ 0 4 +;ab[_[.ae.]]*?xy ab_xy_ 0 5 +;ab[_[.ae.]]*?xy abxy 0 4 +;ab[_[.ae.]]*?xy ab_xy 0 5 +;ab[_[.ae.]]*? ab 0 2 +;ab[_[.ae.]]*? ab__ 0 2 + +;ab[_[.ae.]]{2,5}?xy ab__xy_ 0 6 +;ab[_[.ae.]]{2,5}?xy ab____xy_ 0 8 +;ab[_[.ae.]]{2,5}?xy ab_____xy_ 0 9 +;ab[_[.ae.]]{2,5}?xy ab__xy 0 6 +;ab[_[.ae.]]{2,5}?xy ab_____xy 0 9 +;ab[_[.ae.]]{2,5}? ab__ 0 4 +;ab[_[.ae.]]{2,5}? ab_______ 0 4 +;ab[_[.ae.]]{2,5}?xy ab______xy -1 -1 +;ab[_[.ae.]]{2,5}xy ab_xy -1 -1 + +; new bugs detected in spring 2003: +- normal match_continuous REG_NO_POSIX_TEST +b abc 1 2 + +() abc 0 0 0 0 +^() abc 0 0 0 0 +^()+ abc 0 0 0 0 +^(){1} abc 0 0 0 0 +^(){2} abc 0 0 0 0 +^((){2}) abc 0 0 0 0 0 0 +() "" 0 0 0 0 +()\1 "" 0 0 0 0 +()\1 a 0 0 0 0 +a()\1b ab 0 2 1 1 +a()b\1 ab 0 2 1 1 + +; subtleties of matching with no sub-expressions marked +- normal match_nosubs REG_NO_POSIX_TEST +a(b?c)+d accd 0 4 +(wee|week)(knights|night) weeknights 0 10 +.* abc 0 3 +a(b|(c))d abd 0 3 +a(b|(c))d acd 0 3 +a(b*|c|e)d abbd 0 4 +a(b*|c|e)d acd 0 3 +a(b*|c|e)d ad 0 2 +a(b?)c abc 0 3 +a(b?)c ac 0 2 +a(b+)c abc 0 3 +a(b+)c abbbc 0 5 +a(b*)c ac 0 2 +(a|ab)(bc([de]+)f|cde) abcdef 0 6 +a([bc]?)c abc 0 3 +a([bc]?)c ac 0 2 +a([bc]+)c abc 0 3 +a([bc]+)c abcc 0 4 +a([bc]+)bc abcbc 0 5 +a(bb+|b)b abb 0 3 +a(bbb+|bb+|b)b abb 0 3 +a(bbb+|bb+|b)b abbb 0 4 +a(bbb+|bb+|b)bb abbb 0 4 +(.*).* abcdef 0 6 +(a*)* bc 0 0 + +- normal nosubs REG_NO_POSIX_TEST +a(b?c)+d accd 0 4 +(wee|week)(knights|night) weeknights 0 10 +.* abc 0 3 +a(b|(c))d abd 0 3 +a(b|(c))d acd 0 3 +a(b*|c|e)d abbd 0 4 +a(b*|c|e)d acd 0 3 +a(b*|c|e)d ad 0 2 +a(b?)c abc 0 3 +a(b?)c ac 0 2 +a(b+)c abc 0 3 +a(b+)c abbbc 0 5 +a(b*)c ac 0 2 +(a|ab)(bc([de]+)f|cde) abcdef 0 6 +a([bc]?)c abc 0 3 +a([bc]?)c ac 0 2 +a([bc]+)c abc 0 3 +a([bc]+)c abcc 0 4 +a([bc]+)bc abcbc 0 5 +a(bb+|b)b abb 0 3 +a(bbb+|bb+|b)b abb 0 3 +a(bbb+|bb+|b)b abbb 0 4 +a(bbb+|bb+|b)bb abbb 0 4 +(.*).* abcdef 0 6 +(a*)* bc 0 0 + diff --git a/test/src/regex-resources/PCRE.tests b/test/src/regex-resources/PCRE.tests new file mode 100644 index 00000000000..0fb9cadafc9 --- /dev/null +++ b/test/src/regex-resources/PCRE.tests @@ -0,0 +1,2386 @@ +# PCRE version 4.4 21-August-2003 + +# Tests taken from PCRE and modified to suit glibc regex. +# +# PCRE LICENCE +# ------------ +# +# PCRE is a library of functions to support regular expressions whose syntax +# and semantics are as close as possible to those of the Perl 5 language. +# +# Written by: Philip Hazel <ph10@cam.ac.uk> +# +# University of Cambridge Computing Service, +# Cambridge, England. Phone: +44 1223 334714. +# +# Copyright (c) 1997-2003 University of Cambridge +# +# Permission is granted to anyone to use this software for any purpose on any +# computer system, and to redistribute it freely, subject to the following +# restrictions: +# +# 1. This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# 2. The origin of this software must not be misrepresented, either by +# explicit claim or by omission. In practice, this means that if you use +# PCRE in software that you distribute to others, commercially or +# otherwise, you must put a sentence like this +# +# Regular expression support is provided by the PCRE library package, +# which is open source software, written by Philip Hazel, and copyright +# by the University of Cambridge, England. +# +# somewhere reasonably visible in your documentation and in any relevant +# files or online help data or similar. A reference to the ftp site for +# the source, that is, to +# +# ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ +# +# should also be given in the documentation. However, this condition is not +# intended to apply to whole chains of software. If package A includes PCRE, +# it must acknowledge it, but if package B is software that includes package +# A, the condition is not imposed on package B (unless it uses PCRE +# independently). +# +# 3. Altered versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# +# 4. If PCRE is embedded in any software that is released under the GNU +# General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL), +# then the terms of that licence shall supersede any condition above with +# which it is incompatible. +# +# The documentation for PCRE, supplied in the "doc" directory, is distributed +# under the same terms as the software itself. +# +# End +# + +/the quick brown fox/ + the quick brown fox + 0: the quick brown fox + The quick brown FOX +No match + What do you know about the quick brown fox? + 0: the quick brown fox + What do you know about THE QUICK BROWN FOX? +No match + +/The quick brown fox/i + the quick brown fox + 0: the quick brown fox + The quick brown FOX + 0: The quick brown FOX + What do you know about the quick brown fox? + 0: the quick brown fox + What do you know about THE QUICK BROWN FOX? + 0: THE QUICK BROWN FOX + +/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ + abxyzpqrrrabbxyyyypqAzz + 0: abxyzpqrrrabbxyyyypqAzz + abxyzpqrrrabbxyyyypqAzz + 0: abxyzpqrrrabbxyyyypqAzz + aabxyzpqrrrabbxyyyypqAzz + 0: aabxyzpqrrrabbxyyyypqAzz + aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz + aabcxyzpqrrrabbxyyyypqAzz + 0: aabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypAzz + 0: aaabcxyzpqrrrabbxyyyypAzz + aaabcxyzpqrrrabbxyyyypqAzz + 0: aaabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqAzz + aaabcxyzpqrrrabbxyyyypqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz + aaaabcxyzpqrrrabbxyyyypqAzz + 0: aaaabcxyzpqrrrabbxyyyypqAzz + abxyzzpqrrrabbxyyyypqAzz + 0: abxyzzpqrrrabbxyyyypqAzz + aabxyzzzpqrrrabbxyyyypqAzz + 0: aabxyzzzpqrrrabbxyyyypqAzz + aaabxyzzzzpqrrrabbxyyyypqAzz + 0: aaabxyzzzzpqrrrabbxyyyypqAzz + aaaabxyzzzzpqrrrabbxyyyypqAzz + 0: aaaabxyzzzzpqrrrabbxyyyypqAzz + abcxyzzpqrrrabbxyyyypqAzz + 0: abcxyzzpqrrrabbxyyyypqAzz + aabcxyzzzpqrrrabbxyyyypqAzz + 0: aabcxyzzzpqrrrabbxyyyypqAzz + aaabcxyzzzzpqrrrabbxyyyypqAzz + 0: aaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbxyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + aaabcxyzpqrrrabbxyyyypABzz + 0: aaabcxyzpqrrrabbxyyyypABzz + aaabcxyzpqrrrabbxyyyypABBzz + 0: aaabcxyzpqrrrabbxyyyypABBzz + >>>aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz + *** Failers +No match + abxyzpqrrabbxyyyypqAzz +No match + abxyzpqrrrrabbxyyyypqAzz +No match + abxyzpqrrrabxyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyypqAzz +No match + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz +No match + +/^(abc){1,2}zz/ + abczz + 0: abczz + 1: abc + abcabczz + 0: abcabczz + 1: abc + *** Failers +No match + zz +No match + abcabcabczz +No match + >>abczz +No match + +/^(b+|a){1,2}c/ + bc + 0: bc + 1: b + bbc + 0: bbc + 1: bb + bbbc + 0: bbbc + 1: bbb + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + aac + 0: aac + 1: a + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + 1: bbbbbbbbbbb + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + 1: a + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^[]cde]/ + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + athing +No match + fthing +No match + +/^[^]cde]/ + athing + 0: a + fthing + 0: f + *** Failers + 0: * + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^[0-9]+$/ + 0 + 0: 0 + 1 + 0: 1 + 2 + 0: 2 + 3 + 0: 3 + 4 + 0: 4 + 5 + 0: 5 + 6 + 0: 6 + 7 + 0: 7 + 8 + 0: 8 + 9 + 0: 9 + 10 + 0: 10 + 100 + 0: 100 + *** Failers +No match + abc +No match + +/^.*nter/ + enter + 0: enter + inter + 0: inter + uponter + 0: uponter + +/^xxx[0-9]+$/ + xxx0 + 0: xxx0 + xxx1234 + 0: xxx1234 + *** Failers +No match + xxx +No match + +/^.+[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + 0: abc!pqr=apquxz.ixr.zzz.ac.uk + 1: abc + 2: pqr + *** Failers +No match + !pqr=apquxz.ixr.zzz.ac.uk +No match + abc!=apquxz.ixr.zzz.ac.uk +No match + abc!pqr=apquxz:ixr.zzz.ac.uk +No match + abc!pqr=apquxz.ixr.zzz.ac.ukk +No match + +/:/ + Well, we need a colon: somewhere + 0: : + *** Fail if we don't +No match + +/([0-9a-f:]+)$/i + 0abc + 0: 0abc + 1: 0abc + abc + 0: abc + 1: abc + fed + 0: fed + 1: fed + E + 0: E + 1: E + :: + 0: :: + 1: :: + 5f03:12C0::932e + 0: 5f03:12C0::932e + 1: 5f03:12C0::932e + fed def + 0: def + 1: def + Any old stuff + 0: ff + 1: ff + *** Failers +No match + 0zzz +No match + gzzz +No match + Any old rubbish +No match + +/^.*\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/ + .1.2.3 + 0: .1.2.3 + 1: 1 + 2: 2 + 3: 3 + A.12.123.0 + 0: A.12.123.0 + 1: 12 + 2: 123 + 3: 0 + *** Failers +No match + .1.2.3333 +No match + 1.2.3 +No match + 1234.2.3 +No match + +/^([0-9]+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 0: 1 IN SOA non-sp1 non-sp2( + 1: 1 + 2: non-sp1 + 3: non-sp2 + 1 IN SOA non-sp1 non-sp2 ( + 0: 1 IN SOA non-sp1 non-sp2 ( + 1: 1 + 2: non-sp1 + 3: non-sp2 + *** Failers +No match + 1IN SOA non-sp1 non-sp2( +No match + +/^[a-zA-Z0-9][a-zA-Z0-9-]*(\.[a-zA-Z0-9][a-zA-z0-9-]*)*\.$/ + a. + 0: a. + Z. + 0: Z. + 2. + 0: 2. + ab-c.pq-r. + 0: ab-c.pq-r. + 1: .pq-r + sxk.zzz.ac.uk. + 0: sxk.zzz.ac.uk. + 1: .uk + x-.y-. + 0: x-.y-. + 1: .y- + *** Failers +No match + -abc.peq. +No match + +/^\*\.[a-z]([a-z0-9-]*[a-z0-9]+)?(\.[a-z]([a-z0-9-]*[a-z0-9]+)?)*$/ + *.a + 0: *.a + *.b0-a + 0: *.b0-a + 1: 0-a + *.c3-b.c + 0: *.c3-b.c + 1: 3-b + 2: .c + *.c-a.b-c + 0: *.c-a.b-c + 1: -a + 2: .b-c + 3: -c + *** Failers +No match + *.0 +No match + *.a- +No match + *.a-b.c- +No match + *.c-a.0-c +No match + +/^[0-9a-f](\.[0-9a-f])*$/i + a.b.c.d + 0: a.b.c.d + 1: .d + A.B.C.D + 0: A.B.C.D + 1: .D + a.b.c.1.2.3.C + 0: a.b.c.1.2.3.C + 1: .C + +/^".*"\s*(;.*)?$/ + "1234" + 0: "1234" + "abcd" ; + 0: "abcd" ; + 1: ; + "" ; rhubarb + 0: "" ; rhubarb + 1: ; rhubarb + *** Failers +No match + "1234" : things +No match + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + 1: abc + 2: bc + 3: c + 4: def + 5: ef + 6: f + 7: hij + 8: ij + 9: j +10: klm +11: lm +12: m + +/^a*\w/ + z + 0: z + az + 0: az + aaaz + 0: aaaz + a + 0: a + aa + 0: aa + aaaa + 0: aaaa + a+ + 0: a + aa+ + 0: aa + +/^a+\w/ + az + 0: az + aaaz + 0: aaaz + aa + 0: aa + aaaa + 0: aaaa + aa+ + 0: aa + +/^[0-9]{8}\w{2,}/ + 1234567890 + 0: 1234567890 + 12345678ab + 0: 12345678ab + 12345678__ + 0: 12345678__ + *** Failers +No match + 1234567 +No match + +/^[aeiou0-9]{4,5}$/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + aaaaa + 0: aaaaa + *** Failers +No match + 123456 +No match + +/\`(abc|def)=(\1){2,3}\'/ + abc=abcabc + 0: abc=abcabc + 1: abc + 2: abc + def=defdefdef + 0: def=defdefdef + 1: def + 2: def + *** Failers +No match + abc=defdef +No match + +/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ + cataract cataract23 + 0: cataract cataract23 + 1: cataract + 2: aract + 3: ract + 4: + 5: 3 + catatonic catatonic23 + 0: catatonic catatonic23 + 1: catatonic + 2: atonic + 3: tonic + 4: + 5: 3 + caterpillar caterpillar23 + 0: caterpillar caterpillar23 + 1: caterpillar + 2: erpillar + 3: <unset> + 4: + 5: 3 + + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + 1: abcd + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}[0-9]{1,2}\s+[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + 1: Sep + From abcd Mon Sep 1 12:33:02 1997 + 0: From abcd Mon Sep 1 12:33 + 1: Sep + *** Failers +No match + From abcd Sep 01 12:33:02 1997 +No match + +/^(a)\1{2,3}(.)/ + aaab + 0: aaab + 1: a + 2: b + aaaab + 0: aaaab + 1: a + 2: b + aaaaab + 0: aaaaa + 1: a + 2: a + aaaaaab + 0: aaaaa + 1: a + 2: a + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: abbbbb + +/^(cow|)\1(bell)/ + cowcowbell + 0: cowcowbell + 1: cow + 2: bell + bell + 0: bell + 1: + 2: bell + *** Failers +No match + cowbell +No match + +/^(a|)\1+b/ + aab + 0: aab + 1: a + aaaab + 0: aaaab + 1: a + b + 0: b + 1: + *** Failers +No match + ab +No match + +/^(a|)\1{2}b/ + aaab + 0: aaab + 1: a + b + 0: b + 1: + *** Failers +No match + ab +No match + aab +No match + aaaab +No match + +/^(a|)\1{2,3}b/ + aaab + 0: aaab + 1: a + aaaab + 0: aaaab + 1: a + b + 0: b + 1: + *** Failers +No match + ab +No match + aab +No match + aaaaab +No match + +/ab{1,3}bc/ + abbbbc + 0: abbbbc + abbbc + 0: abbbc + abbc + 0: abbc + *** Failers +No match + abc +No match + abbbbbc +No match + +/([^.]*)\.([^:]*):[T ]+(.*)/ + track1.title:TBlah blah blah + 0: track1.title:TBlah blah blah + 1: track1 + 2: title + 3: Blah blah blah + +/([^.]*)\.([^:]*):[T ]+(.*)/i + track1.title:TBlah blah blah + 0: track1.title:TBlah blah blah + 1: track1 + 2: title + 3: Blah blah blah + +/([^.]*)\.([^:]*):[t ]+(.*)/i + track1.title:TBlah blah blah + 0: track1.title:TBlah blah blah + 1: track1 + 2: title + 3: Blah blah blah + +/^abc$/ + abc + 0: abc + *** Failers +No match + +/[-az]+/ + az- + 0: az- + *** Failers + 0: a + b +No match + +/[az-]+/ + za- + 0: za- + *** Failers + 0: a + b +No match + +/[a-z]+/ + abcdxyz + 0: abcdxyz + +/[0-9-]+/ + 12-34 + 0: 12-34 + *** Failers +No match + aaa +No match + +/(abc)\1/i + abcabc + 0: abcabc + 1: abc + ABCabc + 0: ABCabc + 1: ABC + abcABC + 0: abcABC + 1: abc + +/a{0}bc/ + bc + 0: bc + +/^([^a])([^b])([^c]*)([^d]{3,4})/ + baNOTccccd + 0: baNOTcccc + 1: b + 2: a + 3: NOT + 4: cccc + baNOTcccd + 0: baNOTccc + 1: b + 2: a + 3: NOT + 4: ccc + baNOTccd + 0: baNOTcc + 1: b + 2: a + 3: NO + 4: Tcc + bacccd + 0: baccc + 1: b + 2: a + 3: + 4: ccc + *** Failers + 0: *** Failers + 1: * + 2: * + 3: * Fail + 4: ers + anything +No match + baccd +No match + +/[^a]/ + Abc + 0: A + +/[^a]/i + Abc + 0: b + +/[^a]+/ + AAAaAbc + 0: AAA + +/[^a]+/i + AAAaAbc + 0: bc + +/[^k]$/ + abc + 0: c + *** Failers + 0: s + abk +No match + +/[^k]{2,3}$/ + abc + 0: abc + kbc + 0: bc + kabc + 0: abc + *** Failers + 0: ers + abk +No match + akb +No match + akk +No match + +/^[0-9]{8,}@.+[^k]$/ + 12345678@a.b.c.d + 0: 12345678@a.b.c.d + 123456789@x.y.z + 0: 123456789@x.y.z + *** Failers +No match + 12345678@x.y.uk +No match + 1234567@a.b.c.d +No match + +/(a)\1{8,}/ + aaaaaaaaa + 0: aaaaaaaaa + 1: a + aaaaaaaaaa + 0: aaaaaaaaaa + 1: a + *** Failers +No match + aaaaaaa +No match + +/[^a]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^a]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/[^az]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^az]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/P[^*]TAIRE[^*]{1,6}LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/P[^*]TAIRE[^*]{1,}LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/(\.[0-9][0-9][1-9]?)[0-9]+/ + 1.230003938 + 0: .230003938 + 1: .23 + 1.875000282 + 0: .875000282 + 1: .875 + 1.235 + 0: .235 + 1: .23 + +/\b(foo)\s+(\w+)/i + Food is on the foo table + 0: foo table + 1: foo + 2: table + +/foo(.*)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: d is under the bar in the + +/(.*)([0-9]*)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 53147 + 2: + +/(.*)([0-9]+)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*)([0-9]+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*)\b([0-9]+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/(.*[^0-9])([0-9]+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/[[:digit:]][[:digit:]]\/[[:digit:]][[:digit:]]\/[[:digit:]][[:digit:]][[:digit:]][[:digit:]]/ + 01/01/2000 + 0: 01/01/2000 + +/^(a){0,0}/ + bcd + 0: + abc + 0: + aab + 0: + +/^(a){0,1}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: a + 1: a + +/^(a){0,2}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){0,3}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){0,}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: a + +/^(a){1,1}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: a + 1: a + +/^(a){1,2}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){1,3}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){1,}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: a + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + 0: 123456654321 + +/^[[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]]/ + 123456654321 + 0: 123456654321 + +/^[abc]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + 0: abcabcabcabc + 1: c + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + 0: n + *** Failers +No match + z +No match + +/abcde{0,0}/ + abcd + 0: abcd + *** Failers +No match + abce +No match + +/ab[cd]{0,0}e/ + abe + 0: abe + *** Failers +No match + abcde +No match + +/ab(c){0,0}d/ + abd + 0: abd + *** Failers +No match + abcd +No match + +/a(b*)/ + a + 0: a + 1: + ab + 0: ab + 1: b + abbbb + 0: abbbb + 1: bbbb + *** Failers + 0: a + 1: + bbbbb +No match + +/ab[0-9]{0}e/ + abe + 0: abe + *** Failers +No match + ab1e +No match + +/(A|B)*CD/ + CD + 0: CD + +/(AB)*\1/ + ABABAB + 0: ABABAB + 1: AB + +/([0-9]+)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: a + 12345+ + 0: 12345 + 1: 1234 + 2: 5 + +/(abc|)+/ + abc + 0: abc + 1: abc + abcabc + 0: abcabc + 1: abc + abcabcabc + 0: abcabcabc + 1: abc + xyz + 0: + 1: + +/([a]*)*/ + a + 0: a + 1: a + aaaaa + 0: aaaaa + 1: aaaaa + +/([ab]*)*/ + a + 0: a + 1: a + b + 0: b + 1: b + ababab + 0: ababab + 1: ababab + aaaabcde + 0: aaaab + 1: aaaab + bbbb + 0: bbbb + 1: bbbb + +/([^a]*)*/ + b + 0: b + 1: b + bbbb + 0: bbbb + 1: bbbb + aaa + 0: + +/([^ab]*)*/ + cccc + 0: cccc + 1: cccc + abab + 0: + +/abc/ + abc + 0: abc + xabcy + 0: abc + ababc + 0: abc + *** Failers +No match + xbc +No match + axc +No match + abx +No match + +/ab*c/ + abc + 0: abc + +/ab*bc/ + abc + 0: abc + abbc + 0: abbc + abbbbc + 0: abbbbc + +/.{1}/ + abbbbc + 0: a + +/.{3,4}/ + abbbbc + 0: abbb + +/ab{0,}bc/ + abbbbc + 0: abbbbc + +/ab+bc/ + abbc + 0: abbc + *** Failers +No match + abc +No match + abq +No match + +/ab+bc/ + abbbbc + 0: abbbbc + +/ab{1,}bc/ + abbbbc + 0: abbbbc + +/ab{1,3}bc/ + abbbbc + 0: abbbbc + +/ab{3,4}bc/ + abbbbc + 0: abbbbc + +/ab{4,5}bc/ + *** Failers +No match + abq +No match + abbbbc +No match + +/ab?bc/ + abbc + 0: abbc + abc + 0: abc + +/ab{0,1}bc/ + abc + 0: abc + +/ab?c/ + abc + 0: abc + +/ab{0,1}c/ + abc + 0: abc + +/^abc$/ + abc + 0: abc + *** Failers +No match + abbbbc +No match + abcc +No match + +/^abc/ + abcc + 0: abc + +/abc$/ + aabc + 0: abc + *** Failers +No match + aabc + 0: abc + aabcd +No match + +/^/ + abc + 0: + +/$/ + abc + 0: + +/a.c/ + abc + 0: abc + axc + 0: axc + +/a.*c/ + axyzc + 0: axyzc + +/a[bc]d/ + abd + 0: abd + *** Failers +No match + axyzd +No match + abc +No match + +/a[b-d]e/ + ace + 0: ace + +/a[b-d]/ + aac + 0: ac + +/a[-b]/ + a- + 0: a- + +/a[b-]/ + a- + 0: a- + +/a[]]b/ + a]b + 0: a]b + +/a[^bc]d/ + aed + 0: aed + *** Failers +No match + abd +No match + abd +No match + +/a[^-b]c/ + adc + 0: adc + +/a[^]b]c/ + adc + 0: adc + *** Failers +No match + a-c + 0: a-c + a]c +No match + +/\ba\b/ + a- + 0: a + -a + 0: a + -a- + 0: a + +/\by\b/ + *** Failers +No match + xy +No match + yz +No match + xyz +No match + +/\Ba\B/ + *** Failers + 0: a + a- +No match + -a +No match + -a- +No match + +/\By\b/ + xy + 0: y + +/\by\B/ + yz + 0: y + +/\By\B/ + xyz + 0: y + +/\w/ + a + 0: a + +/\W/ + - + 0: - + *** Failers + 0: * + - + 0: - + a +No match + +/a\sb/ + a b + 0: a b + +/a\Sb/ + a-b + 0: a-b + *** Failers +No match + a-b + 0: a-b + a b +No match + +/[0-9]/ + 1 + 0: 1 + +/[^0-9]/ + - + 0: - + *** Failers + 0: * + - + 0: - + 1 +No match + +/ab|cd/ + abc + 0: ab + abcd + 0: ab + +/()ef/ + def + 0: ef + 1: + +/a\(b/ + a(b + 0: a(b + +/a\(*b/ + ab + 0: ab + a((b + 0: a((b + +/((a))/ + abc + 0: a + 1: a + 2: a + +/(a)b(c)/ + abc + 0: abc + 1: a + 2: c + +/a+b+c/ + aabbabc + 0: abc + +/a{1,}b{1,}c/ + aabbabc + 0: abc + +/(a+|b)*/ + ab + 0: ab + 1: b + +/(a+|b){0,}/ + ab + 0: ab + 1: b + +/(a+|b)+/ + ab + 0: ab + 1: b + +/(a+|b){1,}/ + ab + 0: ab + 1: b + +/(a+|b)?/ + ab + 0: a + 1: a + +/(a+|b){0,1}/ + ab + 0: a + 1: a + +/[^ab]*/ + cde + 0: cde + +/abc/ + *** Failers +No match + b +No match + + +/a*/ + + +/([abc])*d/ + abbbcd + 0: abbbcd + 1: c + +/([abc])*bcd/ + abcd + 0: abcd + 1: a + +/a|b|c|d|e/ + e + 0: e + +/(a|b|c|d|e)f/ + ef + 0: ef + 1: e + +/abcd*efg/ + abcdefg + 0: abcdefg + +/ab*/ + xabyabbbz + 0: ab + xayabbbz + 0: a + +/(ab|cd)e/ + abcde + 0: cde + 1: cd + +/[abhgefdc]ij/ + hij + 0: hij + +/(abc|)ef/ + abcdef + 0: ef + 1: + +/(a|b)c*d/ + abcd + 0: bcd + 1: b + +/(ab|ab*)bc/ + abc + 0: abc + 1: a + +/a([bc]*)c*/ + abc + 0: abc + 1: bc + +/a([bc]*)(c*d)/ + abcd + 0: abcd + 1: bc + 2: d + +/a([bc]+)(c*d)/ + abcd + 0: abcd + 1: bc + 2: d + +/a([bc]*)(c+d)/ + abcd + 0: abcd + 1: b + 2: cd + +/a[bcd]*dcdcde/ + adcdcde + 0: adcdcde + +/a[bcd]+dcdcde/ + *** Failers +No match + abcde +No match + adcdcde +No match + +/(ab|a)b*c/ + abc + 0: abc + 1: ab + +/((a)(b)c)(d)/ + abcd + 0: abcd + 1: abc + 2: a + 3: b + 4: d + +/[a-zA-Z_][a-zA-Z0-9_]*/ + alpha + 0: alpha + +/^a(bc+|b[eh])g|.h$/ + abh + 0: bh + +/(bc+d$|ef*g.|h?i(j|k))/ + effgz + 0: effgz + 1: effgz + ij + 0: ij + 1: ij + 2: j + reffgz + 0: effgz + 1: effgz + *** Failers +No match + effg +No match + bcdd +No match + +/((((((((((a))))))))))/ + a + 0: a + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a +10: a + +/((((((((((a))))))))))\9/ + aa + 0: aa + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a +10: a + +/(((((((((a)))))))))/ + a + 0: a + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a + +/multiple words of text/ + *** Failers +No match + aa +No match + uh-uh +No match + +/multiple words/ + multiple words, yeah + 0: multiple words + +/(.*)c(.*)/ + abcde + 0: abcde + 1: ab + 2: de + +/\((.*), (.*)\)/ + (a, b) + 0: (a, b) + 1: a + 2: b + +/abcd/ + abcd + 0: abcd + +/a(bc)d/ + abcd + 0: abcd + 1: bc + +/a[-]?c/ + ac + 0: ac + +/(abc)\1/ + abcabc + 0: abcabc + 1: abc + +/([a-c]*)\1/ + abcabc + 0: abcabc + 1: abc + +/(a)|\1/ + a + 0: a + 1: a + *** Failers + 0: a + 1: a + ab + 0: a + 1: a + x +No match + +/abc/i + ABC + 0: ABC + XABCY + 0: ABC + ABABC + 0: ABC + *** Failers +No match + aaxabxbaxbbx +No match + XBC +No match + AXC +No match + ABX +No match + +/ab*c/i + ABC + 0: ABC + +/ab*bc/i + ABC + 0: ABC + ABBC + 0: ABBC + +/ab+bc/i + *** Failers +No match + ABC +No match + ABQ +No match + +/ab+bc/i + ABBBBC + 0: ABBBBC + +/^abc$/i + ABC + 0: ABC + *** Failers +No match + ABBBBC +No match + ABCC +No match + +/^abc/i + ABCC + 0: ABC + +/abc$/i + AABC + 0: ABC + +/^/i + ABC + 0: + +/$/i + ABC + 0: + +/a.c/i + ABC + 0: ABC + AXC + 0: AXC + +/a.*c/i + *** Failers +No match + AABC + 0: AABC + AXYZD +No match + +/a[bc]d/i + ABD + 0: ABD + +/a[b-d]e/i + ACE + 0: ACE + *** Failers +No match + ABC +No match + ABD +No match + +/a[b-d]/i + AAC + 0: AC + +/a[-b]/i + A- + 0: A- + +/a[b-]/i + A- + 0: A- + +/a[]]b/i + A]B + 0: A]B + +/a[^bc]d/i + AED + 0: AED + +/a[^-b]c/i + ADC + 0: ADC + *** Failers +No match + ABD +No match + A-C +No match + +/a[^]b]c/i + ADC + 0: ADC + +/ab|cd/i + ABC + 0: AB + ABCD + 0: AB + +/()ef/i + DEF + 0: EF + 1: + +/$b/i + *** Failers +No match + A]C +No match + B +No match + +/a\(b/i + A(B + 0: A(B + +/a\(*b/i + AB + 0: AB + A((B + 0: A((B + +/((a))/i + ABC + 0: A + 1: A + 2: A + +/(a)b(c)/i + ABC + 0: ABC + 1: A + 2: C + +/a+b+c/i + AABBABC + 0: ABC + +/a{1,}b{1,}c/i + AABBABC + 0: ABC + +/(a+|b)*/i + AB + 0: AB + 1: B + +/(a+|b){0,}/i + AB + 0: AB + 1: B + +/(a+|b)+/i + AB + 0: AB + 1: B + +/(a+|b){1,}/i + AB + 0: AB + 1: B + +/(a+|b)?/i + AB + 0: A + 1: A + +/(a+|b){0,1}/i + AB + 0: A + 1: A + +/[^ab]*/i + CDE + 0: CDE + +/([abc])*d/i + ABBBCD + 0: ABBBCD + 1: C + +/([abc])*bcd/i + ABCD + 0: ABCD + 1: A + +/a|b|c|d|e/i + E + 0: E + +/(a|b|c|d|e)f/i + EF + 0: EF + 1: E + +/abcd*efg/i + ABCDEFG + 0: ABCDEFG + +/ab*/i + XABYABBBZ + 0: AB + XAYABBBZ + 0: A + +/(ab|cd)e/i + ABCDE + 0: CDE + 1: CD + +/[abhgefdc]ij/i + HIJ + 0: HIJ + +/^(ab|cd)e/i + ABCDE +No match + +/(abc|)ef/i + ABCDEF + 0: EF + 1: + +/(a|b)c*d/i + ABCD + 0: BCD + 1: B + +/(ab|ab*)bc/i + ABC + 0: ABC + 1: A + +/a([bc]*)c*/i + ABC + 0: ABC + 1: BC + +/a([bc]*)(c*d)/i + ABCD + 0: ABCD + 1: BC + 2: D + +/a([bc]+)(c*d)/i + ABCD + 0: ABCD + 1: BC + 2: D + +/a([bc]*)(c+d)/i + ABCD + 0: ABCD + 1: B + 2: CD + +/a[bcd]*dcdcde/i + ADCDCDE + 0: ADCDCDE + +/a[bcd]+dcdcde/i + +/(ab|a)b*c/i + ABC + 0: ABC + 1: AB + +/((a)(b)c)(d)/i + ABCD + 0: ABCD + 1: ABC + 2: A + 3: B + 4: D + +/[a-zA-Z_][a-zA-Z0-9_]*/i + ALPHA + 0: ALPHA + +/^a(bc+|b[eh])g|.h$/i + ABH + 0: BH + +/(bc+d$|ef*g.|h?i(j|k))/i + EFFGZ + 0: EFFGZ + 1: EFFGZ + IJ + 0: IJ + 1: IJ + 2: J + REFFGZ + 0: EFFGZ + 1: EFFGZ + *** Failers +No match + ADCDCDE +No match + EFFG +No match + BCDD +No match + +/((((((((((a))))))))))/i + A + 0: A + 1: A + 2: A + 3: A + 4: A + 5: A + 6: A + 7: A + 8: A + 9: A +10: A + +/((((((((((a))))))))))\9/i + AA + 0: AA + 1: A + 2: A + 3: A + 4: A + 5: A + 6: A + 7: A + 8: A + 9: A +10: A + +/(((((((((a)))))))))/i + A + 0: A + 1: A + 2: A + 3: A + 4: A + 5: A + 6: A + 7: A + 8: A + 9: A + +/multiple words of text/i + *** Failers +No match + AA +No match + UH-UH +No match + +/multiple words/i + MULTIPLE WORDS, YEAH + 0: MULTIPLE WORDS + +/(.*)c(.*)/i + ABCDE + 0: ABCDE + 1: AB + 2: DE + +/\((.*), (.*)\)/i + (A, B) + 0: (A, B) + 1: A + 2: B + +/abcd/i + ABCD + 0: ABCD + +/a(bc)d/i + ABCD + 0: ABCD + 1: BC + +/a[-]?c/i + AC + 0: AC + +/(abc)\1/i + ABCABC + 0: ABCABC + 1: ABC + +/([a-c]*)\1/i + ABCABC + 0: ABCABC + 1: ABC + +/((foo)|(bar))*/ + foobar + 0: foobar + 1: bar + 2: foo + 3: bar + +/^(.+)?B/ + AB + 0: AB + 1: A + +/^([^a-z])|(\^)$/ + . + 0: . + 1: . + +/^[<>]&/ + <&OUT + 0: <& + +/^(){3,5}/ + abc + 0: + 1: + +/^(a+)*ax/ + aax + 0: aax + 1: a + +/^((a|b)+)*ax/ + aax + 0: aax + 1: a + 2: a + +/^((a|bc)+)*ax/ + aax + 0: aax + 1: a + 2: a + +/(a|x)*ab/ + cab + 0: ab + +/(a)*ab/ + cab + 0: ab + +/(ab)[0-9]\1/i + Ab4ab + 0: Ab4ab + 1: Ab + ab4Ab + 0: ab4Ab + 1: ab + +/foo\w*[0-9]{4}baz/ + foobar1234baz + 0: foobar1234baz + +/(\w+:)+/ + one: + 0: one: + 1: one: + +/((\w|:)+::)?(\w+)$/ + abcd + 0: abcd + 1: <unset> + 2: <unset> + 3: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: : + 3: abcd + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/(a*)b+/ + caab + 0: aab + 1: aa + +/((\w|:)+::)?(\w+)$/ + abcd + 0: abcd + 1: <unset> + 2: <unset> + 3: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: : + 3: abcd + *** Failers + 0: Failers + 1: <unset> + 2: <unset> + 3: Failers + abcd: +No match + abcd: +No match + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/((Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: A + 2: Z + +/(Z()|A)*/ + ZABCDEFG + 0: ZA + 1: A + 2: + +/(Z(())|A)*/ + ZABCDEFG + 0: ZA + 1: A + 2: + 3: + +/(.*)[0-9]+\1/ + abc123abc + 0: abc123abc + 1: abc + abc123bc + 0: bc123bc + 1: bc + +/((.*))[0-9]+\1/ + abc123abc + 0: abc123abc + 1: abc + 2: abc + abc123bc + 0: bc123bc + 1: bc + 2: bc + +/^a{2,5}$/ + aa + 0: aa + aaa + 0: aaa + aaaa + 0: aaaa + aaaaa + 0: aaaaa + *** Failers +No match + a +No match + b +No match + aaaaab +No match + aaaaaa diff --git a/test/src/regex-resources/PTESTS b/test/src/regex-resources/PTESTS new file mode 100644 index 00000000000..68acc314d37 --- /dev/null +++ b/test/src/regex-resources/PTESTS @@ -0,0 +1,341 @@ +# 2.8.2 Regular Expression General Requirement +2¦4¦bb*¦abbbc¦ +2¦2¦bb*¦ababbbc¦ +7¦9¦A#*::¦A:A#:qA::qA#::qA##::q¦ +1¦5¦A#*::¦A##::A#::qA::qA#:q¦ +# 2.8.3.1.2 BRE Special Characters +# GA108 +2¦2¦\.¦a.c¦ +2¦2¦\[¦a[c¦ +2¦2¦\\¦a\c¦ +2¦2¦\*¦a*c¦ +2¦2¦\^¦a^c¦ +2¦2¦\$¦a$c¦ +7¦11¦X\*Y\*8¦Y*8X*8X*Y*8¦ +# GA109 +2¦2¦[.]¦a.c¦ +2¦2¦[[]¦a[c¦ +-1¦-1¦[[]¦ac¦ +2¦2¦[\]¦a\c¦ +1¦1¦[\a]¦abc¦ +2¦2¦[\.]¦a\.c¦ +2¦2¦[\.]¦a.\c¦ +2¦2¦[*]¦a*c¦ +2¦2¦[$]¦a$c¦ +2¦2¦[X*Y8]¦7*8YX¦ +# GA110 +2¦2¦*¦a*c¦ +3¦4¦*a¦*b*a*c¦ +1¦5¦**9=¦***9=9¦ +# GA111 +1¦1¦^*¦*bc¦ +-1¦-1¦^*¦a*c¦ +-1¦-1¦^*¦^*ab¦ +1¦5¦^**9=¦***9=¦ +-1¦-1¦^*5<*9¦5<9*5<*9¦ +# GA112 +2¦3¦\(*b\)¦a*b¦ +-1¦-1¦\(*b\)¦ac¦ +1¦6¦A\(**9\)=¦A***9=79¦ +# GA113(1) +1¦3¦\(^*ab\)¦*ab¦ +-1¦-1¦\(^*ab\)¦^*ab¦ +-1¦-1¦\(^*b\)¦a*b¦ +-1¦-1¦\(^*b\)¦^*b¦ +### GA113(2) GNU regex implements GA113(1) +##-1¦-1¦\(^*ab\)¦*ab¦ +##-1¦-1¦\(^*ab\)¦^*ab¦ +##1¦1¦\(^*b\)¦b¦ +##1¦3¦\(^*b\)¦^^b¦ +# GA114 +1¦3¦a^b¦a^b¦ +1¦3¦a\^b¦a^b¦ +1¦1¦^^¦^bc¦ +2¦2¦\^¦a^c¦ +1¦1¦[c^b]¦^abc¦ +1¦1¦[\^ab]¦^ab¦ +2¦2¦[\^ab]¦c\d¦ +-1¦-1¦[^^]¦^¦ +1¦3¦\(a^b\)¦a^b¦ +1¦3¦\(a\^b\)¦a^b¦ +2¦2¦\(\^\)¦a^b¦ +# GA115 +3¦3¦$$¦ab$¦ +-1¦-1¦$$¦$ab¦ +2¦3¦$c¦a$c¦ +2¦2¦[$]¦a$c¦ +1¦2¦\$a¦$a¦ +3¦3¦\$$¦ab$¦ +2¦6¦A\([34]$[34]\)B¦XA4$3BY¦ +# 2.8.3.1.3 Periods in BREs +# GA116 +1¦1¦.¦abc¦ +-1¦-1¦.ab¦abc¦ +1¦3¦ab.¦abc¦ +1¦3¦a.b¦a,b¦ +-1¦-1¦.......¦PqRs6¦ +1¦7¦.......¦PqRs6T8¦ +# 2.8.3.2 RE Bracket Expression +# GA118 +2¦2¦[abc]¦xbyz¦ +-1¦-1¦[abc]¦xyz¦ +2¦2¦[abc]¦xbay¦ +# GA119 +2¦2¦[^a]¦abc¦ +4¦4¦[^]cd]¦cd]ef¦ +2¦2¦[^abc]¦axyz¦ +-1¦-1¦[^abc]¦abc¦ +3¦3¦[^[.a.]b]¦abc¦ +3¦3¦[^[=a=]b]¦abc¦ +2¦2¦[^-ac]¦abcde-¦ +2¦2¦[^ac-]¦abcde-¦ +3¦3¦[^a-b]¦abcde¦ +3¦3¦[^a-bd-e]¦dec¦ +2¦2¦[^---]¦-ab¦ +16¦16¦[^a-zA-Z0-9]¦pqrstVWXYZ23579#¦ +# GA120(1) +3¦3¦[]a]¦cd]ef¦ +1¦1¦[]-a]¦a_b¦ +3¦3¦[][.-.]-0]¦ab0-]¦ +1¦1¦[]^a-z]¦string¦ +# GA120(2) +4¦4¦[^]cd]¦cd]ef¦ +0¦0¦[^]]*¦]]]]]]]]X¦ +0¦0¦[^]]*¦]]]]]]]]¦ +9¦9¦[^]]\{1,\}¦]]]]]]]]X¦ +-1¦-1¦[^]]\{1,\}¦]]]]]]]]¦ +# GA120(3) +3¦3¦[c[.].]d]¦ab]cd¦ +2¦8¦[a-z]*[[.].]][A-Z]*¦Abcd]DEFg¦ +# GA121 +2¦2¦[[.a.]b]¦Abc¦ +1¦1¦[[.a.]b]¦aBc¦ +-1¦-1¦[[.a.]b]¦ABc¦ +3¦3¦[^[.a.]b]¦abc¦ +3¦3¦[][.-.]-0]¦ab0-]¦ +3¦3¦[A-[.].]c]¦ab]!¦ +# GA122 +-2¦-2¦[[.ch.]]¦abc¦ +-2¦-2¦[[.ab.][.CD.][.EF.]]¦yZabCDEFQ9¦ +# GA125 +2¦2¦[[=a=]b]¦Abc¦ +1¦1¦[[=a=]b]¦aBc¦ +-1¦-1¦[[=a=]b]¦ABc¦ +3¦3¦[^[=a=]b]¦abc¦ +# GA126 +#W the expected result for [[:alnum:]]* is 2-7 which is wrong +0¦0¦[[:alnum:]]*¦ aB28gH¦ +2¦7¦[[:alnum:]][[:alnum:]]*¦ aB28gH¦ +#W the expected result for [^[:alnum:]]* is 2-5 which is wrong +0¦0¦[^[:alnum:]]*¦2 ,a¦ +2¦5¦[^[:alnum:]][^[:alnum:]]*¦2 ,a¦ +#W the expected result for [[:alpha:]]* is 2-5 which is wrong +0¦0¦[[:alpha:]]*¦ aBgH2¦ +2¦5¦[[:alpha:]][[:alpha:]]*¦ aBgH2¦ +1¦6¦[^[:alpha:]]*¦2 8,a¦ +1¦2¦[[:blank:]]*¦
¦ +1¦8¦[^[:blank:]]*¦aB28gH, ¦ +1¦2¦[[:cntrl:]]*¦ ¦ +1¦8¦[^[:cntrl:]]*¦aB2 8gh,¦ +#W the expected result for [[:digit:]]* is 2-3 which is wrong +0¦0¦[[:digit:]]*¦a28¦ +2¦3¦[[:digit:]][[:digit:]]*¦a28¦ +1¦8¦[^[:digit:]]*¦aB gH,¦ +1¦7¦[[:graph:]]*¦aB28gH, ¦ +1¦3¦[^[:graph:]]*¦ ,¦ +1¦2¦[[:lower:]]*¦agB¦ +1¦8¦[^[:lower:]]*¦B2 8H,a¦ +1¦8¦[[:print:]]*¦aB2 8gH, ¦ +1¦2¦[^[:print:]]*¦ ¦ +#W the expected result for [[:punct:]]* is 2-2 which is wrong +0¦0¦[[:punct:]]*¦a,2¦ +2¦3¦[[:punct:]][[:punct:]]*¦a,,2¦ +1¦9¦[^[:punct:]]*¦aB2 8gH¦ +1¦3¦[[:space:]]*¦
¦ +#W the expected result for [^[:space:]]* is 2-9 which is wrong +0¦0¦[^[:space:]]*¦ aB28gH, ¦ +2¦9¦[^[:space:]][^[:space:]]*¦ aB28gH, ¦ +#W the expected result for [[:upper:]]* is 2-3 which is wrong +0¦0¦[[:upper:]]*¦aBH2¦ +2¦3¦[[:upper:]][[:upper:]]*¦aBH2¦ +1¦8¦[^[:upper:]]*¦a2 8g,B¦ +#W the expected result for [[:xdigit:]]* is 2-5 which is wrong +0¦0¦[[:xdigit:]]*¦gaB28h¦ +2¦5¦[[:xdigit:]][[:xdigit:]]*¦gaB28h¦ +#W the expected result for [^[:xdigit:]]* is 2-7 which is wrong +2¦7¦[^[:xdigit:]][^[:xdigit:]]*¦a gH,2¦ +# GA127 +-2¦-2¦[b-a]¦abc¦ +1¦1¦[a-c]¦bbccde¦ +2¦2¦[a-b]¦-bc¦ +3¦3¦[a-z0-9]¦AB0¦ +3¦3¦[^a-b]¦abcde¦ +3¦3¦[^a-bd-e]¦dec¦ +1¦1¦[]-a]¦a_b¦ +2¦2¦[+--]¦a,b¦ +2¦2¦[--/]¦a.b¦ +2¦2¦[^---]¦-ab¦ +3¦3¦[][.-.]-0]¦ab0-]¦ +3¦3¦[A-[.].]c]¦ab]!¦ +2¦6¦bc[d-w]xy¦abchxyz¦ +# GA129 +1¦1¦[a-cd-f]¦dbccde¦ +-1¦-1¦[a-ce-f]¦dBCCdE¦ +2¦4¦b[n-zA-M]Y¦absY9Z¦ +2¦4¦b[n-zA-M]Y¦abGY9Z¦ +# GA130 +3¦3¦[-xy]¦ac-¦ +2¦4¦c[-xy]D¦ac-D+¦ +2¦2¦[--/]¦a.b¦ +2¦4¦c[--/]D¦ac.D+b¦ +2¦2¦[^-ac]¦abcde-¦ +1¦3¦a[^-ac]c¦abcde-¦ +3¦3¦[xy-]¦zc-¦ +2¦4¦c[xy-]7¦zc-786¦ +2¦2¦[^ac-]¦abcde-¦ +2¦4¦a[^ac-]c¦5abcde-¦ +2¦2¦[+--]¦a,b¦ +2¦4¦a[+--]B¦Xa,By¦ +2¦2¦[^---]¦-ab¦ +4¦6¦X[^---]Y¦X-YXaYXbY¦ +# 2.8.3.3 BREs Matching Multiple Characters +# GA131 +3¦4¦cd¦abcdeabcde¦ +1¦2¦ag*b¦abcde¦ +-1¦-1¦[a-c][e-f]¦abcdef¦ +3¦4¦[a-c][e-f]¦acbedf¦ +4¦8¦abc*XYZ¦890abXYZ#*¦ +4¦9¦abc*XYZ¦890abcXYZ#*¦ +4¦15¦abc*XYZ¦890abcccccccXYZ#*¦ +-1¦-1¦abc*XYZ¦890abc*XYZ#*¦ +# GA132 +2¦4¦\(*bc\)¦a*bc¦ +1¦2¦\(ab\)¦abcde¦ +1¦10¦\(a\(b\(c\(d\(e\(f\(g\)h\(i\(j\)\)\)\)\)\)\)\)¦abcdefghijk¦ +3¦8¦43\(2\(6\)*0\)AB¦654320ABCD¦ +3¦9¦43\(2\(7\)*0\)AB¦6543270ABCD¦ +3¦12¦43\(2\(7\)*0\)AB¦6543277770ABCD¦ +# GA133 +1¦10¦\(a\(b\(c\(d\(e\(f\(g\)h\(i\(j\)\)\)\)\)\)\)\)¦abcdefghijk¦ +-1¦-1¦\(a\(b\(c\(d\(e\(f\(g\)h\(i\(k\)\)\)\)\)\)\)\)¦abcdefghijk¦ +# GA134 +2¦4¦\(bb*\)¦abbbc¦ +2¦2¦\(bb*\)¦ababbbc¦ +1¦6¦a\(.*b\)¦ababbbc¦ +1¦2¦a\(b*\)¦ababbbc¦ +1¦20¦a\(.*b\)c¦axcaxbbbcsxbbbbbbbbc¦ +# GA135 +1¦7¦\(a\(b\(c\(d\(e\)\)\)\)\)\4¦abcdededede¦ +#W POSIX does not really specify whether a\(b\)*c\1 matches acb. +#W back references are supposed to expand to the last match, but what +#W if there never was a match as in this case? +-1¦-1¦a\(b\)*c\1¦acb¦ +1¦11¦\(a\(b\(c\(d\(e\(f\(g\)h\(i\(j\)\)\)\)\)\)\)\)\9¦abcdefghijjk¦ +# GA136 +#W These two tests have the same problem as the test in GA135. No match +#W of a subexpression, why should the back reference be usable? +#W 1 2 a\(b\)*c\1 acb +#W 4 7 a\(b\(c\(d\(f\)*\)\)\)\4¦xYzabcdePQRST +-1¦-1¦a\(b\)*c\1¦acb¦ +-1¦-1¦a\(b\(c\(d\(f\)*\)\)\)\4¦xYzabcdePQRST¦ +# GA137 +-2¦-2¦\(a\(b\)\)\3¦foo¦ +-2¦-2¦\(a\(b\)\)\(a\(b\)\)\5¦foo¦ +# GA138 +1¦2¦ag*b¦abcde¦ +1¦10¦a.*b¦abababvbabc¦ +2¦5¦b*c¦abbbcdeabbbbbbcde¦ +2¦5¦bbb*c¦abbbcdeabbbbbbcde¦ +1¦5¦a\(b\)*c\1¦abbcbbb¦ +-1¦-1¦a\(b\)*c\1¦abbdbd¦ +0¦0¦\([a-c]*\)\1¦abcacdef¦ +1¦6¦\([a-c]*\)\1¦abcabcabcd¦ +1¦2¦a^*b¦ab¦ +1¦5¦a^*b¦a^^^b¦ +# GA139 +1¦2¦a\{2\}¦aaaa¦ +1¦7¦\([a-c]*\)\{0,\}¦aabcaab¦ +1¦2¦\(a\)\1\{1,2\}¦aabc¦ +1¦3¦\(a\)\1\{1,2\}¦aaaabc¦ +#W the expression \(\(a\)\1\)\{1,2\} is ill-formed, using \2 +1¦4¦\(\(a\)\2\)\{1,2\}¦aaaabc¦ +# GA140 +1¦2¦a\{2\}¦aaaa¦ +-1¦-1¦a\{2\}¦abcd¦ +0¦0¦a\{0\}¦aaaa¦ +1¦64¦a\{64\}¦aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¦ +# GA141 +1¦7¦\([a-c]*\)\{0,\}¦aabcaab¦ +#W the expected result for \([a-c]*\)\{2,\} is failure which isn't correct +1¦3¦\([a-c]*\)\{2,\}¦abcdefg¦ +1¦3¦\([a-c]*\)\{1,\}¦abcdefg¦ +-1¦-1¦a\{64,\}¦aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¦ +# GA142 +1¦3¦a\{2,3\}¦aaaa¦ +-1¦-1¦a\{2,3\}¦abcd¦ +0¦0¦\([a-c]*\)\{0,0\}¦foo¦ +1¦63¦a\{1,63\}¦aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¦ +# 2.8.3.4 BRE Precedence +# GA143 +#W There are numerous bugs in the original version. +2¦19¦\^\[[[.].]]\\(\\1\\)\*\\{1,2\\}\$¦a^[]\(\1\)*\{1,2\}$b¦ +1¦6¦[[=*=]][[=\=]][[=]=]][[===]][[...]][[:punct:]]¦*\]=.;¦ +1¦6¦[$\(*\)^]*¦$\()*^¦ +1¦1¦[\1]¦1¦ +1¦1¦[\{1,2\}]¦{¦ +#W the expected result for \(*\)*\1* is 2-2 which isn't correct +0¦0¦\(*\)*\1*¦a*b*11¦ +2¦3¦\(*\)*\1*b¦a*b*11¦ +#W the expected result for \(a\(b\{1,2\}\)\{1,2\}\) is 1-5 which isn't correct +1¦3¦\(a\(b\{1,2\}\)\{1,2\}\)¦abbab¦ +1¦5¦\(a\(b\{1,2\}\)\)\{1,2\}¦abbab¦ +1¦1¦^\(^\(^a$\)$\)$¦a¦ +1¦2¦\(a\)\1$¦aa¦ +1¦3¦ab*¦abb¦ +1¦4¦ab\{2,4\}¦abbbc¦ +# 2.8.3.5 BRE Expression Anchoring +# GA144 +1¦1¦^a¦abc¦ +-1¦-1¦^b¦abc¦ +-1¦-1¦^[a-zA-Z]¦99Nine¦ +1¦4¦^[a-zA-Z]*¦Nine99¦ +# GA145(1) +1¦2¦\(^a\)\1¦aabc¦ +-1¦-1¦\(^a\)\1¦^a^abc¦ +1¦2¦\(^^a\)¦^a¦ +1¦1¦\(^^\)¦^^¦ +1¦3¦\(^abc\)¦abcdef¦ +-1¦-1¦\(^def\)¦abcdef¦ +### GA145(2) GNU regex implements GA145(1) +##-1¦-1¦\(^a\)\1¦aabc¦ +##1¦4¦\(^a\)\1¦^a^abc¦ +##-1¦-1¦\(^^a\)¦^a¦ +##1¦2¦\(^^\)¦^^¦ +# GA146 +3¦3¦a$¦cba¦ +-1¦-1¦a$¦abc¦ +5¦7¦[a-z]*$¦99ZZxyz¦ +#W the expected result for [a-z]*$ is failure which isn't correct +10¦9¦[a-z]*$¦99ZZxyz99¦ +3¦3¦$$¦ab$¦ +-1¦-1¦$$¦$ab¦ +3¦3¦\$$¦ab$¦ +# GA147(1) +-1¦-1¦\(a$\)\1¦bcaa¦ +-1¦-1¦\(a$\)\1¦ba$¦ +-1¦-1¦\(ab$\)¦ab$¦ +1¦2¦\(ab$\)¦ab¦ +4¦6¦\(def$\)¦abcdef¦ +-1¦-1¦\(abc$\)¦abcdef¦ +### GA147(2) GNU regex implements GA147(1) +##-1¦-1¦\(a$\)\1¦bcaa¦ +##2¦5¦\(a$\)\1¦ba$a$¦ +##-1¦-1¦\(ab$\)¦ab¦ +##1¦3¦\(ab$\)¦ab$¦ +# GA148 +0¦0¦^$¦¦ +1¦3¦^abc$¦abc¦ +-1¦-1¦^xyz$¦^xyz^¦ +-1¦-1¦^234$¦^234$¦ +1¦9¦^[a-zA-Z0-9]*$¦2aA3bB9zZ¦ +-1¦-1¦^[a-z0-9]*$¦2aA3b#B9zZ¦ diff --git a/test/src/regex-resources/TESTS b/test/src/regex-resources/TESTS new file mode 100644 index 00000000000..f2c98864058 --- /dev/null +++ b/test/src/regex-resources/TESTS @@ -0,0 +1,167 @@ +0:(.*)*\1:xx +0:^: +0:$: +0:^$: +0:^a$:a +0:abc:abc +1:abc:xbc +1:abc:axc +1:abc:abx +0:abc:xabcy +0:abc:ababc +0:ab*c:abc +0:ab*bc:abc +0:ab*bc:abbc +0:ab*bc:abbbbc +0:ab+bc:abbc +1:ab+bc:abc +1:ab+bc:abq +0:ab+bc:abbbbc +0:ab?bc:abbc +0:ab?bc:abc +1:ab?bc:abbbbc +0:ab?c:abc +0:^abc$:abc +1:^abc$:abcc +0:^abc:abcc +1:^abc$:aabc +0:abc$:aabc +0:^:abc +0:$:abc +0:a.c:abc +0:a.c:axc +0:a.*c:axyzc +1:a.*c:axyzd +1:a[bc]d:abc +0:a[bc]d:abd +1:a[b-d]e:abd +0:a[b-d]e:ace +0:a[b-d]:aac +0:a[-b]:a- +0:a[b-]:a- +2:a[b-a]:- +2:a[]b:- +2:a[:- +0:a]:a] +0:a[]]b:a]b +0:a[^bc]d:aed +1:a[^bc]d:abd +0:a[^-b]c:adc +1:a[^-b]c:a-c +1:a[^]b]c:a]c +0:a[^]b]c:adc +0:ab|cd:abc +0:ab|cd:abcd +0:()ef:def +0:()*:- +2:*a:- +2:^*:- +2:$*:- +2:(*)b:- +1:$b:b +2:a\:- +0:a\(b:a(b +0:a\(*b:ab +0:a\(*b:a((b +1:a\x:a\x +1:abc):- +2:(abc:- +0:((a)):abc +0:(a)b(c):abc +0:a+b+c:aabbabc +0:a**:- +0:a*?:- +0:(a*)*:- +0:(a*)+:- +0:(a|)*:- +0:(a*|b)*:- +0:(a+|b)*:ab +0:(a+|b)+:ab +0:(a+|b)?:ab +0:[^ab]*:cde +0:(^)*:- +0:(ab|)*:- +2:)(:- +1:abc: +1:abc: +0:a*: +0:([abc])*d:abbbcd +0:([abc])*bcd:abcd +0:a|b|c|d|e:e +0:(a|b|c|d|e)f:ef +0:((a*|b))*:- +0:abcd*efg:abcdefg +0:ab*:xabyabbbz +0:ab*:xayabbbz +0:(ab|cd)e:abcde +0:[abhgefdc]ij:hij +1:^(ab|cd)e:abcde +0:(abc|)ef:abcdef +0:(a|b)c*d:abcd +0:(ab|ab*)bc:abc +0:a([bc]*)c*:abc +0:a([bc]*)(c*d):abcd +0:a([bc]+)(c*d):abcd +0:a([bc]*)(c+d):abcd +0:a[bcd]*dcdcde:adcdcde +1:a[bcd]+dcdcde:adcdcde +0:(ab|a)b*c:abc +0:((a)(b)c)(d):abcd +0:[A-Za-z_][A-Za-z0-9_]*:alpha +0:^a(bc+|b[eh])g|.h$:abh +0:(bc+d$|ef*g.|h?i(j|k)):effgz +0:(bc+d$|ef*g.|h?i(j|k)):ij +1:(bc+d$|ef*g.|h?i(j|k)):effg +1:(bc+d$|ef*g.|h?i(j|k)):bcdd +0:(bc+d$|ef*g.|h?i(j|k)):reffgz +1:((((((((((a)))))))))):- +0:(((((((((a))))))))):a +1:multiple words of text:uh-uh +0:multiple words:multiple words, yeah +0:(.*)c(.*):abcde +1:\((.*),:(.*)\) +1:[k]:ab +0:abcd:abcd +0:a(bc)d:abcd +0:a[-]?c:ac +0:(....).*\1:beriberi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Qaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mo'ammar Gadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Kaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Qadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moammar El Kadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Gadafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar al-Qadafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moamer El Kazzafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moamar al-Gaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar Al Qathafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Al Qathafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mo'ammar el-Gadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moamar El Kadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar al-Qadhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar al-Qadhdhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar Qadafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moamar Gaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar Qadhdhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Khaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar al-Khaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'amar al-Kadafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Ghaddafy +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Ghadafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Ghaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muamar Kaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Quathafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muammar Gheddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Muamar Al-Kaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moammar Khadafy +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Moammar Qudhafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mu'ammar al-Qaddafi +0:M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]:Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi +0:[[:digit:]]+:01234 +1:[[:alpha:]]+:01234 +0:^[[:digit:]]*$:01234 +1:^[[:digit:]]*$:01234a +0:^[[:alnum:]]*$:01234a +0:^[[:xdigit:]]*$:01234a +1:^[[:xdigit:]]*$:01234g +0:^[[:alnum:][:space:]]*$:Hello world diff --git a/test/src/regex-tests.el b/test/src/regex-tests.el new file mode 100644 index 00000000000..c4844c7cdbc --- /dev/null +++ b/test/src/regex-tests.el @@ -0,0 +1,680 @@ +;;; regex-tests.el --- tests for regex.c functions -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(defvar regex-tests--resources-dir + (concat (concat (file-name-directory (or load-file-name buffer-file-name)) + "/regex-resources/")) + "Path to regex-resources directory next to the \"regex-tests.el\" file.") + +(ert-deftest regex-word-cc-fallback-test () + "Test that ‘[[:cc:]]*x’ matches ‘x’ (bug#24020). + +Test that a regex of the form \"[[:cc:]]*x\" where CC is +a character class which matches a multibyte character X, matches +string \"x\". + +For example, ‘[[:word:]]*\u2620’ regex (note: \u2620 is a word +character) must match a string \"\u2420\"." + (dolist (class '("[[:word:]]" "\\sw")) + (dolist (repeat '("*" "+")) + (dolist (suffix '("" "b" "bar" "\u2620")) + (dolist (string '("" "foo")) + (when (not (and (string-equal repeat "+") + (string-equal string ""))) + (should (string-match (concat "^" class repeat suffix "$") + (concat string suffix))))))))) + +(defun regex--test-cc (name matching not-matching) + (let (case-fold-search) + (should (string-match-p (concat "^[[:" name ":]]*$") matching)) + (should (string-match-p (concat "^[[:" name ":]]*?\u2622$") + (concat matching "\u2622"))) + (should (string-match-p (concat "^[^[:" name ":]]*$") not-matching)) + (should (string-match-p (concat "^[^[:" name ":]]*\u2622$") + (concat not-matching "\u2622"))) + (with-temp-buffer + (insert matching) + (let ((p (point))) + (insert not-matching) + (goto-char (point-min)) + (skip-chars-forward (concat "[:" name ":]")) + (should (equal (point) p)) + (skip-chars-forward (concat "^[:" name ":]")) + (should (equal (point) (point-max))) + (goto-char (point-min)) + (skip-chars-forward (concat "[:" name ":]\u2622")) + (should (or (equal (point) p) (equal (point) (1+ p)))))))) + +(dolist (test '(("alnum" "abcABC012łąka" "-, \t\n") + ("alpha" "abcABCłąka" "-,012 \t\n") + ("digit" "012" "abcABCłąka-, \t\n") + ("xdigit" "0123aBc" "łąk-, \t\n") + ("upper" "ABCŁĄKA" "abc012-, \t\n") + ("lower" "abcłąka" "ABC012-, \t\n") + + ("word" "abcABC012\u2620" "-, \t\n") + + ("punct" ".,-" "abcABC012\u2620 \t\n") + ("cntrl" "\1\2\t\n" ".,-abcABC012\u2620 ") + ("graph" "abcłąka\u2620-," " \t\n\1") + ("print" "abcłąka\u2620-, " "\t\n\1") + + ("space" " \t\n\u2001" "abcABCł0123") + ("blank" " \t" "\n\u2001") + + ("ascii" "abcABC012 \t\n\1" "łą\u2620") + ("nonascii" "łą\u2622" "abcABC012 \t\n\1") + ("unibyte" "abcABC012 \t\n\1" "łą\u2622") + ("multibyte" "łą\u2622" "abcABC012 \t\n\1"))) + (let ((name (intern (concat "regex-tests-" (car test) "-character-class"))) + (doc (concat "Perform sanity test of regexes using " (car test) + " character class. + +Go over all the supported character classes and test whether the +classes and their inversions match what they are supposed to +match. The test is done using `string-match-p' as well as +`skip-chars-forward'."))) + (eval `(ert-deftest ,name () ,doc ,(cons 'regex--test-cc test)) t))) + + +(defmacro regex-tests-generic-line (comment-char test-file whitelist &rest body) + "Reads a line of the test file TEST-FILE, skipping +comments (defined by COMMENT-CHAR), and evaluates the tests in +this line as defined in the BODY. Line numbers in the WHITELIST +are known failures, and are skipped." + + `(with-temp-buffer + (modify-syntax-entry ?_ "w;; ") ; tests expect _ to be a word + (insert-file-contents (concat regex-tests--resources-dir ,test-file)) + (let ((case-fold-search nil) + (line-number 1) + (whitelist-idx 0)) + + (goto-char (point-min)) + + (while (not (eobp)) + (let ((start (point))) + (end-of-line) + (narrow-to-region start (point)) + + (goto-char (point-min)) + + (when + (and + ;; ignore comments + (save-excursion + (re-search-forward ,(concat "^[^" (string comment-char) "]") nil t)) + + ;; skip lines in the whitelist + (let ((whitelist-next + (condition-case nil + (aref ,whitelist whitelist-idx) (args-out-of-range nil)))) + (cond + ;; whitelist exhausted. do process this line + ((null whitelist-next) t) + + ;; we're not yet at the next whitelist element. do + ;; process this line + ((< line-number whitelist-next) t) + + ;; we're past the next whitelist element. This + ;; shouldn't happen + ((> line-number whitelist-next) + (error + (format + "We somehow skipped the next whitelist element: line %d" whitelist-next))) + + ;; we're at the next whitelist element. Skip this + ;; line, and advance the whitelist index + (t + (setq whitelist-idx (1+ whitelist-idx)) nil)))) + ,@body) + + (widen) + (forward-line) + (beginning-of-line) + (setq line-number (1+ line-number))))))) + +(defun regex-tests-compare (string what-failed bounds-ref &optional substring-ref) + "I just ran a search, looking at STRING. WHAT-FAILED describes +what failed, if anything; valid values are 'search-failed, +'compilation-failed and nil. I compare the beginning/end of each +group with their expected values. This is done with either +BOUNDS-REF or SUBSTRING-REF; one of those should be non-nil. +BOUNDS-REF is a sequence \[start-ref0 end-ref0 start-ref1 +end-ref1 ....] while SUBSTRING-REF is the expected substring +obtained by indexing the input string by start/end-ref. + +If the search was supposed to fail then start-ref0/substring-ref0 +is 'search-failed. If the search wasn't even supposed to compile +successfully, then start-ref0/substring-ref0 is +'compilation-failed. If I only care about a match succeeding, +this can be set to t. + +This function returns a string that describes the failure, or nil +on success" + + (when (or + (and bounds-ref substring-ref) + (not (or bounds-ref substring-ref))) + (error "Exactly one of bounds-ref and bounds-ref should be non-nil")) + + (let ((what-failed-ref (car (or bounds-ref substring-ref)))) + + (cond + ((eq what-failed 'search-failed) + (cond + ((eq what-failed-ref 'search-failed) + nil) + ((eq what-failed-ref 'compilation-failed) + "Expected pattern failure; but no match") + (t + "Expected match; but no match"))) + + ((eq what-failed 'compilation-failed) + (cond + ((eq what-failed-ref 'search-failed) + "Expected no match; but pattern failure") + ((eq what-failed-ref 'compilation-failed) + nil) + (t + "Expected match; but pattern failure"))) + + ;; The regex match succeeded + ((eq what-failed-ref 'search-failed) + "Expected no match; but match") + ((eq what-failed-ref 'compilation-failed) + "Expected pattern failure; but match") + + ;; The regex match succeeded, as expected. I now check all the + ;; bounds + (t + (let ((idx 0) + msg + ref next-ref-function compare-ref-function mismatched-ref-function) + + (if bounds-ref + (setq ref bounds-ref + next-ref-function (lambda (x) (cddr x)) + compare-ref-function (lambda (ref start-pos end-pos) + (or (eq (car ref) t) + (and (eq start-pos (car ref)) + (eq end-pos (cadr ref))))) + mismatched-ref-function (lambda (ref start-pos end-pos) + (format + "beginning/end positions: %d/%s and %d/%s" + start-pos (car ref) end-pos (cadr ref)))) + (setq ref substring-ref + next-ref-function (lambda (x) (cdr x)) + compare-ref-function (lambda (ref start-pos end-pos) + (or (eq (car ref) t) + (string= (substring string start-pos end-pos) (car ref)))) + mismatched-ref-function (lambda (ref start-pos end-pos) + (format + "beginning/end positions: %d/%s and %d/%s" + start-pos (car ref) end-pos (cadr ref))))) + + (while (not (or (null ref) msg)) + + (let ((start (match-beginning idx)) + (end (match-end idx))) + + (when (not (funcall compare-ref-function ref start end)) + (setq msg + (format + "Have expected match, but mismatch in group %d: %s" idx (funcall mismatched-ref-function ref start end)))) + + (setq ref (funcall next-ref-function ref) + idx (1+ idx)))) + + (or msg + nil)))))) + + + +(defun regex-tests-match (pattern string bounds-ref &optional substring-ref) + "I match the given STRING against PATTERN. I compare the +beginning/end of each group with their expected values. +BOUNDS-REF is a sequence [start-ref0 end-ref0 start-ref1 end-ref1 +....]. + +If the search was supposed to fail then start-ref0 is +'search-failed. If the search wasn't even supposed to compile +successfully, then start-ref0 is 'compilation-failed. + +This function returns a string that describes the failure, or nil +on success" + + (if (string-match "\\[\\([\\.=]\\)..?\\1\\]" pattern) + ;; Skipping test: [.x.] and [=x=] forms not supported by emacs + nil + + (regex-tests-compare + string + (condition-case nil + (if (string-match pattern string) nil 'search-failed) + ('invalid-regexp 'compilation-failed)) + bounds-ref substring-ref))) + + +(defconst regex-tests-re-even-escapes + "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*" + "Regex that matches an even number of \\ characters") + +(defconst regex-tests-re-odd-escapes + (concat regex-tests-re-even-escapes "\\\\") + "Regex that matches an odd number of \\ characters") + + +(defun regex-tests-unextend (pattern) + "Basic conversion from extended regexes to emacs ones. This is +mostly a hack that adds \\ to () and | and {}, and removes it if +it already exists. We also change \\S (and \\s) to \\S- (and +\\s-) because extended regexes see the former as whitespace, but +emacs requires an extra symbol character" + + (with-temp-buffer + (insert pattern) + (goto-char (point-min)) + + (while (re-search-forward "[()|{}]" nil t) + ;; point is past special character. If it is escaped, unescape + ;; it + + (if (save-excursion + (re-search-backward (concat regex-tests-re-odd-escapes ".\\=") nil t)) + + ;; This special character is preceded by an odd number of \, + ;; so I unescape it by removing the last one + (progn + (forward-char -2) + (delete-char 1) + (forward-char 1)) + + ;; This special character is preceded by an even (possibly 0) + ;; number of \. I add an escape + (forward-char -1) + (insert "\\") + (forward-char 1))) + + ;; convert \s to \s- + (goto-char (point-min)) + (while (re-search-forward (concat regex-tests-re-odd-escapes "[Ss]") nil t) + (insert "-")) + + (buffer-string))) + +(defun regex-tests-BOOST-frob-escapes (s ispattern) + "Mangle \\ the way it is done in frob_escapes() in +regex-tests-BOOST.c in glibc: \\t, \\n, \\r are interpreted; +\\\\, \\^, \{, \\|, \} are unescaped for the string (not +pattern)" + + ;; this is all similar to (regex-tests-unextend) + (with-temp-buffer + (insert s) + + (let ((interpret-list (list "t" "n" "r"))) + (while interpret-list + (goto-char (point-min)) + (while (re-search-forward + (concat "\\(" regex-tests-re-even-escapes "\\)" + "\\\\" (car interpret-list)) + nil t) + (replace-match (concat "\\1" (car (read-from-string + (concat "\"\\" (car interpret-list) "\"")))))) + + (setq interpret-list (cdr interpret-list)))) + + (when (not ispattern) + ;; unescape \\, \^, \{, \|, \} + (let ((unescape-list (list "\\\\" "^" "{" "|" "}"))) + (while unescape-list + (goto-char (point-min)) + (while (re-search-forward + (concat "\\(" regex-tests-re-even-escapes "\\)" + "\\\\" (car unescape-list)) + nil t) + (replace-match (concat "\\1" (car unescape-list)))) + + (setq unescape-list (cdr unescape-list)))) + ) + (buffer-string))) + + + + +(defconst regex-tests-BOOST-whitelist + [ + ;; emacs is more stringent with regexes involving unbalanced ) + 63 65 69 + + ;; in emacs, regex . doesn't match \n + 91 + + ;; emacs is more forgiving with * and ? that don't apply to + ;; characters + 107 108 109 122 123 124 140 141 142 + + ;; emacs accepts regexes with {} + 161 + + ;; emacs doesn't fail on bogus ranges such as [3-1] or [1-3-5] + 222 223 + + ;; emacs doesn't match (ab*)[ab]*\1 greedily: only 4 chars of + ;; ababaaa match + 284 294 + + ;; ambiguous groupings are ambiguous + 443 444 445 446 448 449 450 + + ;; emacs doesn't know how to handle weird ranges such as [a-Z] and + ;; [[:alpha:]-a] + 539 580 581 + + ;; emacs matches non-greedy regex ab.*? non-greedily + 639 677 712 + ] + "Line numbers in the boost test that should be skipped. These +are false-positive test failures that represent known/benign +differences in behavior.") + +;; - Format +;; - Comments are lines starting with ; +;; - Lines starting with - set options passed to regcomp() and regexec(): +;; - if no "REG_BASIC" is found, with have an extended regex +;; - These set a flag: +;; - REG_ICASE +;; - REG_NEWLINE (ignored by this function) +;; - REG_NOTBOL +;; - REG_NOTEOL +;; +;; - Test lines are +;; pattern string start0 end0 start1 end1 ... +;; +;; - pattern, string can have escapes +;; - string can have whitespace if enclosed in "" +;; - if string is "!", then the pattern is supposed to fail compilation +;; - start/end are of group0, group1, etc. group 0 is the full match +;; - start<0 indicates "no match" +;; - start is the 0-based index of the first character +;; - end is the 0-based index of the first character past the group +(defun regex-tests-BOOST () + (let (failures + basic icase notbol noteol) + (regex-tests-generic-line + ?; "BOOST.tests" regex-tests-BOOST-whitelist + (if (save-excursion (re-search-forward "^-" nil t)) + (setq basic (save-excursion (re-search-forward "REG_BASIC" nil t)) + icase (save-excursion (re-search-forward "REG_ICASE" nil t)) + notbol (save-excursion (re-search-forward "REG_NOTBOL" nil t)) + noteol (save-excursion (re-search-forward "REG_NOTEOL" nil t))) + + (save-excursion + (or (re-search-forward "\\(\\S-+\\)\\s-+\"\\(.*\\)\"\\s-+?\\(.+\\)" nil t) + (re-search-forward "\\(\\S-+\\)\\s-+\\(\\S-+\\)\\s-+?\\(.+\\)" nil t) + (re-search-forward "\\(\\S-+\\)\\s-+\\(!\\)" nil t))) + + (let* ((pattern-raw (match-string 1)) + (string-raw (match-string 2)) + (positions-raw (match-string 3)) + (pattern (regex-tests-BOOST-frob-escapes pattern-raw t)) + (string (regex-tests-BOOST-frob-escapes string-raw nil)) + (positions + (if (string= string "!") + (list 'compilation-failed 0) + (mapcar + (lambda (x) + (let ((x (string-to-number x))) + (if (< x 0) nil x))) + (split-string positions-raw))))) + + (when (null (car positions)) + (setcar positions 'search-failed)) + + (when (not basic) + (setq pattern (regex-tests-unextend pattern))) + + ;; great. I now have all the data parsed. Let's use it to do + ;; stuff + (let* ((case-fold-search icase) + (msg (regex-tests-match pattern string positions))) + + (if (and + ;; Skipping test: notbol/noteol not supported + (not notbol) (not noteol) + + msg) + + ;; store failure + (setq failures + (cons (format "line number %d: Regex '%s': %s" + line-number pattern msg) + failures))))))) + + failures)) + +(defconst regex-tests-PCRE-whitelist + [ + ;; ambiguous groupings are ambiguous + 610 611 1154 1157 1160 1168 1171 1176 1179 1182 1185 1188 1193 1196 1203 + ] + "Line numbers in the PCRE test that should be skipped. These +are false-positive test failures that represent known/benign +differences in behavior.") + +;; - Format +;; +;; regex +;; input_string +;; group_num: group_match | "No match" +;; input_string +;; group_num: group_match | "No match" +;; input_string +;; group_num: group_match | "No match" +;; input_string +;; group_num: group_match | "No match" +;; ... +(defun regex-tests-PCRE () + (let (failures + pattern icase string what-failed matches-observed) + (regex-tests-generic-line + ?# "PCRE.tests" regex-tests-PCRE-whitelist + + (cond + + ;; pattern + ((save-excursion (re-search-forward "^/\\(.*\\)/\\(.*i?\\)$" nil t)) + (setq icase (string= "i" (match-string 2)) + pattern (regex-tests-unextend (match-string 1)))) + + ;; string. read it in, match against pattern, and save all the results + ((save-excursion (re-search-forward "^ \\(.*\\)" nil t)) + (let ((case-fold-search icase)) + (setq string (match-string 1) + + ;; the regex match under test + what-failed + (condition-case nil + (if (string-match pattern string) nil 'search-failed) + ('invalid-regexp 'compilation-failed)) + + matches-observed + (cl-loop for x from 0 to 20 + collect (and (not what-failed) + (or (match-string x string) "<unset>"))))) + nil) + + ;; verification line: failed match + ((save-excursion (re-search-forward "^No match" nil t)) + (unless what-failed + (setq failures + (cons (format "line number %d: Regex '%s': Expected no match; but match" + line-number pattern) + failures)))) + + ;; verification line: succeeded match + ((save-excursion (re-search-forward "^ *\\([0-9]+\\): \\(.*\\)" nil t)) + (let* ((match-ref (match-string 2)) + (idx (string-to-number (match-string 1)))) + + (if what-failed + "Expected match; but no match" + (unless (string= match-ref (elt matches-observed idx)) + (setq failures + (cons (format "line number %d: Regex '%s': Have expected match, but group %d is wrong: '%s'/'%s'" + line-number pattern + idx match-ref (elt matches-observed idx)) + failures)))))) + + ;; reset + (t (setq pattern nil) nil))) + + failures)) + +(defconst regex-tests-PTESTS-whitelist + [ + ;; emacs doesn't barf on weird ranges such as [b-a], but simply + ;; fails to match + 138 + + ;; emacs doesn't see DEL (0x78) as a [:cntrl:] character + 168 + ] + "Line numbers in the PTESTS test that should be skipped. These +are false-positive test failures that represent known/benign +differences in behavior.") + +;; - Format +;; - fields separated by ¦ (note: this is not a |) +;; - start¦end¦pattern¦string +;; - start is the 1-based index of the first character +;; - end is the 1-based index of the last character +(defun regex-tests-PTESTS () + (let (failures) + (regex-tests-generic-line + ?# "PTESTS" regex-tests-PTESTS-whitelist + (let* ((fields (split-string (buffer-string) "¦")) + + ;; string has 1-based index of first char in the + ;; match. -1 means "no match". -2 means "invalid + ;; regex". + ;; + ;; start-ref is 0-based index of first char in the + ;; match + ;; + ;; string==0 is a special case, and I have to treat + ;; it as start-ref = 0 + (start-ref (let ((raw (string-to-number (elt fields 0)))) + (cond + ((= raw -2) 'compilation-failed) + ((= raw -1) 'search-failed) + ((= raw 0) 0) + (t (1- raw))))) + + ;; string has 1-based index of last char in the + ;; match. end-ref is 0-based index of first char past + ;; the match + (end-ref (string-to-number (elt fields 1))) + (pattern (elt fields 2)) + (string (elt fields 3))) + + (let ((msg (regex-tests-match pattern string (list start-ref end-ref)))) + (when msg + (setq failures + (cons (format "line number %d: Regex '%s': %s" + line-number pattern msg) + failures)))))) + failures)) + +(defconst regex-tests-TESTS-whitelist + [ + ;; emacs doesn't barf on weird ranges such as [b-a], but simply + ;; fails to match + 42 + + ;; emacs is more forgiving with * and ? that don't apply to + ;; characters + 57 58 59 60 + + ;; emacs is more stringent with regexes involving unbalanced ) + 67 + ] + "Line numbers in the TESTS test that should be skipped. These +are false-positive test failures that represent known/benign +differences in behavior.") + +;; - Format +;; - fields separated by :. Watch for [\[:xxx:]] +;; - expected:pattern:string +;; +;; expected: +;; | 0 | successful match | +;; | 1 | failed match | +;; | 2 | regcomp() should fail | +(defun regex-tests-TESTS () + (let (failures) + (regex-tests-generic-line + ?# "TESTS" regex-tests-TESTS-whitelist + (if (save-excursion (re-search-forward "^\\([^:]+\\):\\(.*\\):\\([^:]*\\)$" nil t)) + (let* ((what-failed + (let ((raw (string-to-number (match-string 1)))) + (cond + ((= raw 2) 'compilation-failed) + ((= raw 1) 'search-failed) + (t t)))) + (string (match-string 3)) + (pattern (regex-tests-unextend (match-string 2)))) + + (let ((msg (regex-tests-match pattern string nil (list what-failed)))) + (when msg + (setq failures + (cons (format "line number %d: Regex '%s': %s" + line-number pattern msg) + failures))))) + + (error "Error parsing TESTS file line: '%s'" (buffer-string)))) + failures)) + +(ert-deftest regex-tests-BOOST () + "Tests of the regular expression engine. +This evaluates the BOOST test cases from glibc." + (should-not (regex-tests-BOOST))) + +(ert-deftest regex-tests-PCRE () + "Tests of the regular expression engine. +This evaluates the PCRE test cases from glibc." + (should-not (regex-tests-PCRE))) + +(ert-deftest regex-tests-PTESTS () + "Tests of the regular expression engine. +This evaluates the PTESTS test cases from glibc." + (should-not (regex-tests-PTESTS))) + +(ert-deftest regex-tests-TESTS () + "Tests of the regular expression engine. +This evaluates the TESTS test cases from glibc." + (should-not (regex-tests-TESTS))) + +;;; regex-tests.el ends here diff --git a/test/src/textprop-tests.el b/test/src/textprop-tests.el new file mode 100644 index 00000000000..ceb48d1b2db --- /dev/null +++ b/test/src/textprop-tests.el @@ -0,0 +1,72 @@ +;;; textprop-tests.el --- Test suite for text properties. + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; Author: Wolfgang Jenkner <wjenkner@inode.at> +;; Keywords: internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest textprop-tests-format () + "Test `format' with text properties." + ;; See Bug#21351. + (should (equal-including-properties + (format #("mouse-1, RET: %s -- w: copy %s" + 12 20 (face minibuffer-prompt) + 21 30 (face minibuffer-prompt)) + "visit" "link") + #("mouse-1, RET: visit -- w: copy link" + 12 23 (face minibuffer-prompt) + 24 35 (face minibuffer-prompt))))) + +(ert-deftest textprop-tests-font-lock--remove-face-from-text-property () + "Test `font-lock--remove-face-from-text-property'." + (let* ((string "foobar") + (stack (list string)) + (faces '(bold (:foreground "red") underline))) + ;; Build each string in `stack' by adding a face to the previous + ;; string. + (let ((faces (reverse faces))) + (push (copy-sequence (car stack)) stack) + (put-text-property 0 3 'font-lock-face (pop faces) (car stack)) + (push (copy-sequence (car stack)) stack) + (put-text-property 3 6 'font-lock-face (pop faces) (car stack)) + (push (copy-sequence (car stack)) stack) + (font-lock-prepend-text-property 2 5 + 'font-lock-face (pop faces) (car stack))) + ;; Check that removing the corresponding face from each string + ;; yields the previous string in `stack'. + (while faces + ;; (message "%S" (car stack)) + (should (equal-including-properties + (progn + (font-lock--remove-face-from-text-property 0 6 + 'font-lock-face + (pop faces) + (car stack)) + (pop stack)) + (car stack)))) + ;; Sanity check. + ;; (message "%S" (car stack)) + (should (and (equal-including-properties (pop stack) string) + (null stack))))) + +(provide 'textprop-tests) +;; textprop-tests.el ends here. diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el new file mode 100644 index 00000000000..73da72e8369 --- /dev/null +++ b/test/src/thread-tests.el @@ -0,0 +1,247 @@ +;;; threads.el --- tests for threads. + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(ert-deftest threads-is-one () + "test for existence of a thread" + (should (current-thread))) + +(ert-deftest threads-threadp () + "test of threadp" + (should (threadp (current-thread)))) + +(ert-deftest threads-type () + "test of thread type" + (should (eq (type-of (current-thread)) 'thread))) + +(ert-deftest threads-name () + "test for name of a thread" + (should + (string= "hi bob" (thread-name (make-thread #'ignore "hi bob"))))) + +(ert-deftest threads-alive () + "test for thread liveness" + (should + (thread-alive-p (make-thread #'ignore)))) + +(ert-deftest threads-all-threads () + "simple test for all-threads" + (should (listp (all-threads)))) + +(defvar threads-test-global nil) + +(defun threads-test-thread1 () + (setq threads-test-global 23)) + +(ert-deftest threads-basic () + "basic thread test" + (should + (progn + (setq threads-test-global nil) + (make-thread #'threads-test-thread1) + (while (not threads-test-global) + (thread-yield)) + threads-test-global))) + +(ert-deftest threads-join () + "test of thread-join" + (should + (progn + (setq threads-test-global nil) + (let ((thread (make-thread #'threads-test-thread1))) + (thread-join thread) + (and threads-test-global + (not (thread-alive-p thread))))))) + +(ert-deftest threads-join-self () + "cannot thread-join the current thread" + (should-error (thread-join (current-thread)))) + +(defvar threads-test-binding nil) + +(defun threads-test-thread2 () + (let ((threads-test-binding 23)) + (thread-yield)) + (setq threads-test-global 23)) + +(ert-deftest threads-let-binding () + "simple test of threads and let bindings" + (should + (progn + (setq threads-test-global nil) + (make-thread #'threads-test-thread2) + (while (not threads-test-global) + (thread-yield)) + (and (not threads-test-binding) + threads-test-global)))) + +(ert-deftest threads-mutexp () + "simple test of mutexp" + (should-not (mutexp 'hi))) + +(ert-deftest threads-mutexp-2 () + "another simple test of mutexp" + (should (mutexp (make-mutex)))) + +(ert-deftest threads-mutex-type () + "type-of mutex" + (should (eq (type-of (make-mutex)) 'mutex))) + +(ert-deftest threads-mutex-lock-unlock () + "test mutex-lock and unlock" + (should + (let ((mx (make-mutex))) + (mutex-lock mx) + (mutex-unlock mx) + t))) + +(ert-deftest threads-mutex-recursive () + "test mutex-lock and unlock" + (should + (let ((mx (make-mutex))) + (mutex-lock mx) + (mutex-lock mx) + (mutex-unlock mx) + (mutex-unlock mx) + t))) + +(defvar threads-mutex nil) +(defvar threads-mutex-key nil) + +(defun threads-test-mlock () + (mutex-lock threads-mutex) + (setq threads-mutex-key 23) + (while threads-mutex-key + (thread-yield)) + (mutex-unlock threads-mutex)) + +(ert-deftest threads-mutex-contention () + "test of mutex contention" + (should + (progn + (setq threads-mutex (make-mutex)) + (setq threads-mutex-key nil) + (make-thread #'threads-test-mlock) + ;; Wait for other thread to get the lock. + (while (not threads-mutex-key) + (thread-yield)) + ;; Try now. + (setq threads-mutex-key nil) + (mutex-lock threads-mutex) + (mutex-unlock threads-mutex) + t))) + +(defun threads-test-mlock2 () + (setq threads-mutex-key 23) + (mutex-lock threads-mutex)) + +(ert-deftest threads-mutex-signal () + "test signaling a blocked thread" + (should + (progn + (setq threads-mutex (make-mutex)) + (setq threads-mutex-key nil) + (mutex-lock threads-mutex) + (let ((thr (make-thread #'threads-test-mlock2))) + (while (not threads-mutex-key) + (thread-yield)) + (thread-signal thr 'quit nil) + (thread-join thr)) + t))) + +(defun threads-test-io-switch () + (setq threads-test-global 23)) + +(ert-deftest threads-io-switch () + "test that accept-process-output causes thread switch" + (should + (progn + (setq threads-test-global nil) + (make-thread #'threads-test-io-switch) + (while (not threads-test-global) + (accept-process-output nil 1)) + threads-test-global))) + +(ert-deftest threads-condvarp () + "simple test of condition-variable-p" + (should-not (condition-variable-p 'hi))) + +(ert-deftest threads-condvarp-2 () + "another simple test of condition-variable-p" + (should (condition-variable-p (make-condition-variable (make-mutex))))) + +(ert-deftest threads-condvar-type () + "type-of condvar" + (should (eq (type-of (make-condition-variable (make-mutex))) + 'condition-variable))) + +(ert-deftest threads-condvar-mutex () + "simple test of condition-mutex" + (should + (let ((m (make-mutex))) + (eq m (condition-mutex (make-condition-variable m)))))) + +(ert-deftest threads-condvar-name () + "simple test of condition-name" + (should + (eq nil (condition-name (make-condition-variable (make-mutex)))))) + +(ert-deftest threads-condvar-name-2 () + "another simple test of condition-name" + (should + (string= "hi bob" + (condition-name (make-condition-variable (make-mutex) + "hi bob"))))) +(defun call-error () + "Call `error'." + (error "Error is called")) + +;; This signals an error internally; the error should be caught. +(defun thread-custom () + (defcustom thread-custom-face 'highlight + "Face used for thread customizations." + :type 'face + :group 'widget-faces)) + +(ert-deftest thread-errors () + "Test what happens when a thread signals an error." + (should (threadp (make-thread #'call-error "call-error"))) + (should (threadp (make-thread #'thread-custom "thread-custom")))) + +(ert-deftest thread-sticky-point () + "Test bug #25165 with point movement in cloned buffer." + (with-temp-buffer + (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") + (goto-char (point-min)) + (clone-indirect-buffer nil nil) + (forward-char 20) + (sit-for 1) + (should (= (point) 21)))) + +(ert-deftest thread-signal-early () + "Test signaling a thread as soon as it is started by the OS." + (let ((thread + (make-thread #'(lambda () + (while t (thread-yield)))))) + (thread-signal thread 'error nil) + (sit-for 1) + (should-not (thread-alive-p thread)))) + +;;; threads.el ends here diff --git a/test/src/undo-tests.el b/test/src/undo-tests.el new file mode 100644 index 00000000000..b1c786993e8 --- /dev/null +++ b/test/src/undo-tests.el @@ -0,0 +1,448 @@ +;;; undo-tests.el --- Tests of primitive-undo + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: Aaron S. Hawley <aaron.s.hawley@gmail.com> + +;; This program is free software: you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation, either version 3 of the +;; License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see `http://www.gnu.org/licenses/'. + +;;; Commentary: + +;; Profiling when the code was translate from C to Lisp on 2012-12-24. + +;;; C + +;; (elp-instrument-function 'primitive-undo) +;; (load-file "undo-test.elc") +;; (benchmark 100 '(let ((undo-test5-error nil)) (undo-test-all))) +;; Elapsed time: 305.218000s (104.841000s in 14804 GCs) +;; M-x elp-results +;; Function Name Call Count Elapsed Time Average Time +;; primitive-undo 2600 3.4889999999 0.0013419230 + +;;; Lisp + +;; (load-file "primundo.elc") +;; (elp-instrument-function 'primitive-undo) +;; (benchmark 100 '(undo-test-all)) +;; Elapsed time: 295.974000s (104.582000s in 14704 GCs) +;; M-x elp-results +;; Function Name Call Count Elapsed Time Average Time +;; primitive-undo 2700 3.6869999999 0.0013655555 + +;;; Code: + +(require 'ert) + +(ert-deftest undo-test0 () + "Test basics of \\[undo]." + (with-temp-buffer + (buffer-enable-undo) + (condition-case err + (undo) + (error + (unless (string= "No further undo information" + (cadr err)) + (error err)))) + (undo-boundary) + (insert "This") + (undo-boundary) + (erase-buffer) + (undo-boundary) + (insert "That") + (undo-boundary) + (forward-word -1) + (undo-boundary) + (insert "With ") + (undo-boundary) + (forward-word -1) + (undo-boundary) + (kill-word 1) + (undo-boundary) + (put-text-property (point-min) (point-max) 'face 'bold) + (undo-boundary) + (remove-text-properties (point-min) (point-max) '(face default)) + (undo-boundary) + (set-buffer-multibyte (not enable-multibyte-characters)) + (undo-boundary) + (undo) + (should + (equal (should-error (undo-more nil)) + '(wrong-type-argument number-or-marker-p nil))) + (undo-more 7) + (should (string-equal "" (buffer-string))))) + +(ert-deftest undo-test1 () + "Test undo of \\[undo] command (redo)." + (with-temp-buffer + (buffer-enable-undo) + (undo-boundary) + (insert "This") + (undo-boundary) + (erase-buffer) + (undo-boundary) + (insert "That") + (undo-boundary) + (forward-word -1) + (undo-boundary) + (insert "With ") + (undo-boundary) + (forward-word -1) + (undo-boundary) + (kill-word 1) + (undo-boundary) + (facemenu-add-face 'bold (point-min) (point-max)) + (undo-boundary) + (set-buffer-multibyte (not enable-multibyte-characters)) + (undo-boundary) + (should + (string-equal (buffer-string) + (progn + (undo) + (undo-more 4) + (undo) + ;(undo-more -4) + (buffer-string)))))) + +(ert-deftest undo-test2 () + "Test basic redoing with \\[undo] command." + (with-temp-buffer + (buffer-enable-undo) + (undo-boundary) + (insert "One") + (undo-boundary) + (insert " Zero") + (undo-boundary) + (push-mark nil t) + (delete-region (save-excursion + (forward-word -1) + (point)) (point)) + (undo-boundary) + (beginning-of-line) + (insert "Zero") + (undo-boundary) + (undo) + (should + (string-equal (buffer-string) + (progn + (undo-more 2) + (undo) + (buffer-string)))))) + +(ert-deftest undo-test4 () + "Test \\[undo] of \\[flush-lines]." + (with-temp-buffer + (buffer-enable-undo) + (dotimes (i 1048576) + (if (zerop (% i 2)) + (insert "Evenses") + (insert "Oddses"))) + (undo-boundary) + (should + ;; Avoid string-equal because ERT will save the `buffer-string' + ;; to the explanation. Using `not' will record nil or non-nil. + (not + (null + (string-equal (buffer-string) + (progn + (flush-lines "oddses" (point-min) (point-max)) + (undo-boundary) + (undo) + (undo) + (buffer-string)))))))) + +(ert-deftest undo-test5 () + "Test basic redoing with \\[undo] command." + (with-temp-buffer + (buffer-enable-undo) + (undo-boundary) + (insert "AYE") + (undo-boundary) + (insert " BEE") + (undo-boundary) + (setq buffer-undo-list (cons '(0.0 bogus) buffer-undo-list)) + (push-mark nil t) + (delete-region (save-excursion + (forward-word -1) + (point)) (point)) + (undo-boundary) + (beginning-of-line) + (insert "CEE") + (undo-boundary) + (undo) + (setq buffer-undo-list (cons "bogus" buffer-undo-list)) + (should + (string-equal + (buffer-string) + (progn + (if (and (boundp 'undo-test5-error) (not undo-test5-error)) + (progn + (should (null (undo-more 2))) + (should (undo))) + ;; Errors are generated by new Lisp version of + ;; `primitive-undo' not by built-in C version. + (should + (equal (should-error (undo-more 2)) + '(error "Unrecognized entry in undo list (0.0 bogus)"))) + (should + (equal (should-error (undo)) + '(error "Unrecognized entry in undo list \"bogus\"")))) + (buffer-string)))))) + +;; http://debbugs.gnu.org/14824 +(ert-deftest undo-test-buffer-modified () + "Test undoing marks buffer unmodified." + (with-temp-buffer + (buffer-enable-undo) + (insert "1") + (undo-boundary) + (set-buffer-modified-p nil) + (insert "2") + (undo) + (should-not (buffer-modified-p)))) + +(ert-deftest undo-test-file-modified () + "Test undoing marks buffer visiting file unmodified." + (let ((tempfile (make-temp-file "undo-test"))) + (unwind-protect + (progn + (with-current-buffer (find-file-noselect tempfile) + (insert "1") + (undo-boundary) + (set-buffer-modified-p nil) + (insert "2") + (undo) + (should-not (buffer-modified-p)))) + (delete-file tempfile)))) + +(ert-deftest undo-test-region-not-most-recent () + "Test undo in region of an edit not the most recent." + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "1111") + (undo-boundary) + (goto-char 2) + (insert "2") + (forward-char 2) + (undo-boundary) + (insert "3") + (undo-boundary) + ;; Highlight around "2", not "3" + (push-mark (+ 3 (point-min)) t t) + (setq mark-active t) + (goto-char (point-min)) + (undo) + (should (string= (buffer-string) + "11131")))) + +(ert-deftest undo-test-region-deletion () + "Test undoing a deletion to demonstrate bug 17235." + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "12345") + (search-backward "4") + (undo-boundary) + (delete-forward-char 1) + (search-backward "1") + (undo-boundary) + (insert "xxxx") + (undo-boundary) + (insert "yy") + (search-forward "35") + (undo-boundary) + ;; Select "35" + (push-mark (point) t t) + (setq mark-active t) + (forward-char -2) + (undo) ; Expect "4" to come back + (should (string= (buffer-string) + "xxxxyy12345")))) + +(ert-deftest undo-test-region-example () + "The same example test case described in comments for +undo-make-selective-list." + ;; buf pos: + ;; 123456789 buffer-undo-list undo-deltas + ;; --------- ---------------- ----------- + ;; aaa (1 . 4) (1 . -3) + ;; aaba (3 . 4) N/A (in region) + ;; ccaaba (1 . 3) (1 . -2) + ;; ccaabaddd (7 . 10) (7 . -3) + ;; ccaabdd ("ad" . 6) (6 . 2) + ;; ccaabaddd (6 . 8) (6 . -2) + ;; | |<-- region: "caab", from 2 to 6 + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "aaa") + (goto-char 3) + (undo-boundary) + (insert "b") + (goto-char 1) + (undo-boundary) + (insert "cc") + (goto-char 7) + (undo-boundary) + (insert "ddd") + (search-backward "ad") + (undo-boundary) + (delete-forward-char 2) + (undo-boundary) + ;; Select "dd" + (push-mark (point) t t) + (setq mark-active t) + (goto-char (point-max)) + (undo) + (undo-boundary) + (should (string= (buffer-string) + "ccaabaddd")) + ;; Select "caab" + (push-mark 2 t t) + (setq mark-active t) + (goto-char 6) + (undo) + (undo-boundary) + (should (string= (buffer-string) + "ccaaaddd")))) + +(ert-deftest undo-test-region-eob () + "Test undo in region of a deletion at EOB, demonstrating bug 16411." + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "This sentence corrupted?") + (undo-boundary) + ;; Same as recipe at + ;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16411 + (insert "aaa") + (undo-boundary) + (undo) + ;; Select entire buffer + (push-mark (point) t t) + (setq mark-active t) + (goto-char (point-min)) + ;; Should undo the undo of "aaa", ie restore it. + (undo) + (should (string= (buffer-string) + "This sentence corrupted?aaa")))) + +(ert-deftest undo-test-marker-adjustment-nominal () + "Test nominal behavior of marker adjustments." + (with-temp-buffer + (buffer-enable-undo) + (insert "abcdefg") + (undo-boundary) + (let ((m (make-marker))) + (set-marker m 2 (current-buffer)) + (goto-char (point-min)) + (delete-forward-char 3) + (undo-boundary) + (should (= (point-min) (marker-position m))) + (undo) + (undo-boundary) + (should (= 2 (marker-position m)))))) + +(ert-deftest undo-test-region-t-marker () + "Test undo in region containing marker with t insertion-type." + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "abcdefg") + (undo-boundary) + (let ((m (make-marker))) + (set-marker-insertion-type m t) + (set-marker m (point-min) (current-buffer)) ; m at a + (goto-char (+ 2 (point-min))) + (push-mark (point) t t) + (setq mark-active t) + (goto-char (point-min)) + (delete-forward-char 1) ;; delete region covering "ab" + (undo-boundary) + (should (= (point-min) (marker-position m))) + ;; Resurrect "ab". m's insertion type means the reinsertion + ;; moves it forward 2, and then the marker adjustment returns it + ;; to its rightful place. + (undo) + (undo-boundary) + (should (= (point-min) (marker-position m)))))) + +(ert-deftest undo-test-marker-adjustment-moved () + "Test marker adjustment behavior when the marker moves. +Demonstrates bug 16818." + (with-temp-buffer + (buffer-enable-undo) + (insert "abcdefghijk") + (undo-boundary) + (let ((m (make-marker))) + (set-marker m 2 (current-buffer)) ; m at b + (goto-char (point-min)) + (delete-forward-char 3) ; m at d + (undo-boundary) + (set-marker m 4) ; m at g + (undo) + (undo-boundary) + ;; m still at g, but shifted 3 because deletion undone + (should (= 7 (marker-position m)))))) + +(ert-deftest undo-test-region-mark-adjustment () + "Test that the mark's marker adjustment in undo history doesn't +obstruct undo in region from finding the correct change group. +Demonstrates bug 16818." + (with-temp-buffer + (buffer-enable-undo) + (transient-mark-mode 1) + (insert "First line\n") + (insert "Second line\n") + (undo-boundary) + + (goto-char (point-min)) + (insert "aaa") + (undo-boundary) + + (undo) + (undo-boundary) + + (goto-char (point-max)) + (insert "bbb") + (undo-boundary) + + (push-mark (point) t t) + (setq mark-active t) + (goto-char (- (point) 3)) + (delete-forward-char 1) + (undo-boundary) + + (insert "bbb") + (undo-boundary) + + (goto-char (point-min)) + (push-mark (point) t t) + (setq mark-active t) + (goto-char (+ (point) 3)) + (undo) + (undo-boundary) + + (should (string= (buffer-string) "aaaFirst line\nSecond line\nbbb")))) + +(defun undo-test-all (&optional interactive) + "Run all tests for \\[undo]." + (interactive "p") + (if interactive + (ert-run-tests-interactively "^undo-") + (ert-run-tests-batch "^undo-"))) + +(provide 'undo-tests) +;;; undo-tests.el ends here diff --git a/test/src/xml-tests.el b/test/src/xml-tests.el new file mode 100644 index 00000000000..dc60197b59e --- /dev/null +++ b/test/src/xml-tests.el @@ -0,0 +1,74 @@ +;;; libxml-parse-tests.el --- Test suite for libxml parsing. + +;; Copyright (C) 2014-2016 Free Software Foundation, Inc. + +;; Author: Ulf Jasper <ulf.jasper@web.de> +;; Keywords: internal +;; Human-Keywords: internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) + +(defvar libxml-tests--data-comments-preserved + `(;; simple case + ("<?xml version=\"1.0\"?><foo baz=\"true\">bar</foo>" + . (foo ((baz . "true")) "bar")) + ;; toplevel comments -- first document child must not get lost + (,(concat "<?xml version=\"1.0\"?><foo>bar</foo><!--comment-1-->" + "<!--comment-2-->") + . (top nil (foo nil "bar") (comment nil "comment-1") + (comment nil "comment-2"))) + (,(concat "<?xml version=\"1.0\"?><!--comment-a--><foo a=\"b\">" + "<bar>blub</bar></foo><!--comment-b--><!--comment-c-->") + . (top nil (comment nil "comment-a") (foo ((a . "b")) (bar nil "blub")) + (comment nil "comment-b") (comment nil "comment-c")))) + "Alist of XML strings and their expected parse trees for preserved comments.") + +(defvar libxml-tests--data-comments-discarded + `(;; simple case + ("<?xml version=\"1.0\"?><foo baz=\"true\">bar</foo>" + . (foo ((baz . "true")) "bar")) + ;; toplevel comments -- first document child must not get lost + (,(concat "<?xml version=\"1.0\"?><foo>bar</foo><!--comment-1-->" + "<!--comment-2-->") + . (foo nil "bar")) + (,(concat "<?xml version=\"1.0\"?><!--comment-a--><foo a=\"b\">" + "<bar>blub</bar></foo><!--comment-b--><!--comment-c-->") + . (foo ((a . "b")) (bar nil "blub")))) + "Alist of XML strings and their expected parse trees for discarded comments.") + + +(ert-deftest libxml-tests () + "Test libxml." + (when (fboundp 'libxml-parse-xml-region) + (with-temp-buffer + (dolist (test libxml-tests--data-comments-preserved) + (erase-buffer) + (insert (car test)) + (should (equal (cdr test) + (libxml-parse-xml-region (point-min) (point-max))))) + (dolist (test libxml-tests--data-comments-discarded) + (erase-buffer) + (insert (car test)) + (should (equal (cdr test) + (libxml-parse-xml-region (point-min) (point-max) nil t))))))) + +;;; libxml-tests.el ends here |