1;;; checkdoc-tests.el --- unit tests for checkdoc.el -*- lexical-binding: t; -*- 2 3;; Copyright (C) 2016-2021 Free Software Foundation, Inc. 4 5;; Author: Philipp Stephani <phst@google.com> 6 7;; This file is part of GNU Emacs. 8 9;; GNU Emacs is free software; you can redistribute it and/or modify 10;; it under the terms of the GNU General Public License as published by 11;; the Free Software Foundation, either version 3 of the License, or 12;; (at your option) any later version. 13 14;; GNU Emacs is distributed in the hope that it will be useful, 15;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17;; GNU General Public License for more details. 18 19;; You should have received a copy of the GNU General Public License 20;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 21 22;;; Commentary: 23 24;; Unit tests for lisp/emacs-lisp/checkdoc.el. 25 26;;; Code: 27 28(require 'checkdoc) 29 30(require 'elisp-mode) 31(require 'ert) 32 33(ert-deftest checkdoc-tests--bug-24998 () 34 "Checks that Bug#24998 is fixed." 35 (with-temp-buffer 36 (emacs-lisp-mode) 37 (insert "(defun foo())") 38 (should-error (checkdoc-defun) :type 'user-error))) 39 40(ert-deftest checkdoc-cl-defmethod-ok () 41 "Checkdoc should be happy with a simple correct cl-defmethod." 42 (with-temp-buffer 43 (emacs-lisp-mode) 44 (insert "(cl-defmethod foo (a) \"Return A.\")") 45 (checkdoc-defun))) 46 47(ert-deftest checkdoc-cl-defmethod-with-types-ok () 48 "Checkdoc should be happy with a cl-defmethod using types." 49 (with-temp-buffer 50 (emacs-lisp-mode) 51 ;; this method matches if A is the symbol `smthg' and if b is a list: 52 (insert "(cl-defmethod foo ((a (eql 'smthg)) (b list)) \"Return A+B.\")") 53 (checkdoc-defun))) 54 55(ert-deftest checkdoc-cl-defmethod-qualified-ok () 56 "Checkdoc should be happy with a `cl-defmethod' using qualifiers." 57 (with-temp-buffer 58 (emacs-lisp-mode) 59 (insert "(cl-defmethod test :around ((a (eql 'smthg))) \"Return A.\")") 60 (checkdoc-defun))) 61 62(ert-deftest checkdoc-cl-defmethod-with-extra-qualifier-ok () 63 "Checkdoc should be happy with a :extra qualified `cl-defmethod'." 64 (with-temp-buffer 65 (emacs-lisp-mode) 66 (insert "(cl-defmethod foo :extra \"foo\" ((a (eql 'smthg))) \"Return A.\")") 67 (checkdoc-defun)) 68 69 (with-temp-buffer 70 (emacs-lisp-mode) 71 (insert 72 "(cl-defmethod foo :extra \"foo\" :after ((a (eql 'smthg))) \"Return A.\")") 73 (checkdoc-defun))) 74 75(ert-deftest checkdoc-cl-defmethod-with-extra-qualifier-and-nil-args-ok () 76 "Checkdoc should be happy with a 0-arity :extra qualified `cl-defmethod'." 77 (with-temp-buffer 78 (emacs-lisp-mode) 79 (insert "(cl-defmethod foo :extra \"foo\" () \"Return A.\")") 80 (checkdoc-defun))) 81 82(ert-deftest checkdoc-cl-defun-with-key-ok () 83 "Checkdoc should be happy with a cl-defun using &key." 84 (with-temp-buffer 85 (emacs-lisp-mode) 86 (insert "(cl-defun foo (&key a (b 27)) \"Return :A+:B.\")") 87 (checkdoc-defun))) 88 89(ert-deftest checkdoc-cl-defun-with-allow-other-keys-ok () 90 "Checkdoc should be happy with a cl-defun using &allow-other-keys." 91 (with-temp-buffer 92 (emacs-lisp-mode) 93 (insert "(cl-defun foo (&key a &allow-other-keys) \"Return :A.\")") 94 (checkdoc-defun))) 95 96(ert-deftest checkdoc-cl-defun-with-default-optional-value-ok () 97 "Checkdoc should be happy with a cl-defun using default values for optional args." 98 (with-temp-buffer 99 (emacs-lisp-mode) 100 ;; B is optional and equals 1+a if not provided. HAS-BS is non-nil 101 ;; if B was provided in the call: 102 (insert "(cl-defun foo (a &optional (b (1+ a) has-bs)) \"Return A + B.\")") 103 (checkdoc-defun))) 104 105(ert-deftest checkdoc-cl-defun-with-destructuring-ok () 106 "Checkdoc should be happy with a cl-defun destructuring its arguments." 107 (with-temp-buffer 108 (emacs-lisp-mode) 109 (insert "(cl-defun foo ((a b &optional c) d) \"Return A+B+C+D.\")") 110 (checkdoc-defun))) 111 112(ert-deftest checkdoc-tests--next-docstring () 113 "Checks that the one-argument form of `defvar' works. 114See the comments in Bug#24998." 115 (with-temp-buffer 116 (emacs-lisp-mode) 117 (insert "(defvar foo) 118\(defvar foo bar \"baz\") 119\(require 'foo)") 120 (goto-char (point-min)) 121 (should (checkdoc-next-docstring)) 122 (should (looking-at-p "\"baz\")")) 123 (should-not (checkdoc-next-docstring)))) 124 125(defun checkdoc-tests--abbrev-test (buffer-contents goto-string) 126 (with-temp-buffer 127 (emacs-lisp-mode) 128 (insert buffer-contents) 129 (goto-char (point-min)) 130 (re-search-forward goto-string) 131 (checkdoc-in-abbreviation-p (point)))) 132 133(ert-deftest checkdoc-tests-in-abbrevation-p/basic-case () 134 (should (checkdoc-tests--abbrev-test "foo bar e.g. baz" "e.g")) 135 (should (checkdoc-tests--abbrev-test "behavior/errors etc. that" "etc")) 136 (should (checkdoc-tests--abbrev-test "foo vs. bar" "vs")) 137 (should (checkdoc-tests--abbrev-test "spy a.k.a. spy" "a.k.a"))) 138 139(ert-deftest checkdoc-tests-in-abbrevation-p/with-parens () 140 (should (checkdoc-tests--abbrev-test "foo bar (e.g. baz)" "e.g"))) 141 142(ert-deftest checkdoc-tests-in-abbrevation-p/with-escaped-parens () 143 (should (checkdoc-tests--abbrev-test "foo\n\\(e.g. baz)" "e.g"))) 144 145(ert-deftest checkdoc-tests-in-abbrevation-p/single-char () 146 (should (checkdoc-tests--abbrev-test "a. foo bar" "a"))) 147 148(ert-deftest checkdoc-tests-in-abbrevation-p/with-em-dash () 149 (should (checkdoc-tests--abbrev-test "foo bar baz---e.g." "e.g"))) 150 151(ert-deftest checkdoc-tests-in-abbrevation-p/incorrect-abbreviation () 152 (should-not (checkdoc-tests--abbrev-test "foo bar a.b.c." "a.b.c"))) 153 154(defun checkdoc-test-error-format-is-good (msg &optional reverse literal) 155 (with-temp-buffer 156 (erase-buffer) 157 (emacs-lisp-mode) 158 (let ((standard-output (current-buffer))) 159 (if literal 160 (print (format "(error \"%s\")" msg)) 161 (prin1 `(error ,msg)))) 162 (goto-char (length "(error \"")) 163 (if reverse 164 (should (checkdoc--error-bad-format-p)) 165 (should-not (checkdoc--error-bad-format-p))))) 166 167(defun checkdoc-test-error-format-is-bad (msg &optional literal) 168 (checkdoc-test-error-format-is-good msg t literal)) 169 170(ert-deftest checkdoc-tests-error-message-bad-format-p () 171 (checkdoc-test-error-format-is-good "Foo") 172 (checkdoc-test-error-format-is-good "Foo: bar baz") 173 (checkdoc-test-error-format-is-good "some-symbol: Foo") 174 (checkdoc-test-error-format-is-good "`some-symbol' foo bar") 175 (checkdoc-test-error-format-is-good "%sfoo") 176 (checkdoc-test-error-format-is-good "avl-tree-enter:\\ 177 Updated data does not match existing data" nil 'literal)) 178 179(ert-deftest checkdoc-tests-error-message-bad-format-p/defined-symbols () 180 (defvar checkdoc-tests--var-symbol nil) 181 (checkdoc-test-error-format-is-good "checkdoc-tests--var-symbol foo bar baz") 182 (defun checkdoc-tests--fun-symbol ()) 183 (checkdoc-test-error-format-is-good "checkdoc-tests--fun-symbol foo bar baz")) 184 185(ert-deftest checkdoc-tests-error-message-bad-format-p/not-capitalized () 186 (checkdoc-test-error-format-is-bad "foo") 187 (checkdoc-test-error-format-is-bad "some-symbol: foo") 188 (checkdoc-test-error-format-is-bad "avl-tree-enter:\ 189 updated data does not match existing data")) 190 191(ert-deftest checkdoc-tests-fix-y-or-n-p () 192 (with-temp-buffer 193 (emacs-lisp-mode) 194 (let ((standard-output (current-buffer)) 195 (checkdoc-autofix-flag 'automatic)) 196 (prin1 '(y-or-n-p "foo")) ; "foo" 197 (goto-char (length "(y-or-n-p ")) 198 (checkdoc--fix-y-or-n-p) 199 (should (equal (buffer-string) "(y-or-n-p \"foo?\")"))))) 200 201(ert-deftest checkdoc-tests-fix-y-or-n-p/no-change () 202 (with-temp-buffer 203 (emacs-lisp-mode) 204 (let ((standard-output (current-buffer)) 205 (checkdoc-autofix-flag 'automatic)) 206 (prin1 '(y-or-n-p "foo?")) ; "foo?" 207 (goto-char (length "(y-or-n-p ")) 208 (checkdoc--fix-y-or-n-p) 209 (should (equal (buffer-string) "(y-or-n-p \"foo?\")"))))) 210 211(ert-deftest checkdoc-tests-fix-y-or-n-p/with-space () 212 (with-temp-buffer 213 (emacs-lisp-mode) 214 (let ((standard-output (current-buffer)) 215 (checkdoc-autofix-flag 'automatic)) 216 (prin1 '(y-or-n-p "foo? ")) ; "foo? " 217 (goto-char (length "(y-or-n-p ")) 218 (checkdoc--fix-y-or-n-p) 219 (should (equal (buffer-string) "(y-or-n-p \"foo? \")"))))) 220 221;;; checkdoc-tests.el ends here 222