denote-test.el (21144B)
1 ;;; denote-test.el --- Unit tests for Denote -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2023 Free Software Foundation, Inc. 4 5 ;; Author: Protesilaos Stavrou <info@protesilaos.com> 6 ;; Maintainer: Denote Development <~protesilaos/denote@lists.sr.ht> 7 ;; URL: https://git.sr.ht/~protesilaos/denote 8 ;; Mailing-List: https://lists.sr.ht/~protesilaos/denote 9 10 ;; This file is NOT part of GNU Emacs. 11 12 ;; This program is free software; you can redistribute it and/or modify 13 ;; it under the terms of the GNU General Public License as published by 14 ;; the Free Software Foundation, either version 3 of the License, or 15 ;; (at your option) any later version. 16 ;; 17 ;; This program is distributed in the hope that it will be useful, 18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 ;; GNU General Public License for more details. 21 ;; 22 ;; You should have received a copy of the GNU General Public License 23 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 24 25 ;;; Commentary: 26 27 ;; WORK-IN-PROGRESS 28 29 ;;; Code: 30 31 (require 'ert) 32 (require 'denote) 33 34 (ert-deftest denote-test--denote--make-denote-directory () 35 "Test that `denote--make-denote-directory' creates the directory." 36 (should (null (denote--make-denote-directory)))) 37 38 (ert-deftest denote-test--denote-directory () 39 "Test that variable `denote-directory' returns an absolute directory name." 40 (let ((path (denote-directory))) 41 (should (and (file-directory-p path) 42 (file-name-absolute-p path))))) 43 44 (ert-deftest denote-test--denote--slug-no-punct () 45 "Test that `denote--slug-no-punct' removes punctuation from the string. 46 Concretely, replace with spaces anything that matches the 47 `denote-excluded-punctuation-regexp' and 48 `denote-excluded-punctuation-extra-regexp'." 49 (should (equal (denote--slug-no-punct "This is !@# test") 50 "This is test"))) 51 52 (ert-deftest denote-test--denote--slug-hyphenate () 53 "Test that `denote--slug-hyphenate' hyphenates the string. 54 Also replace multiple hyphens with a single one and remove any 55 leading and trailing hyphen." 56 (should (equal (denote--slug-hyphenate "__ This is a test __ ") 57 "This-is-a-test"))) 58 59 (ert-deftest denote-test--denote-sluggify () 60 "Test that `denote-sluggify' sluggifies the string. 61 To sluggify is to (i) downcase, (ii) hyphenate, (iii) de-punctuate, and (iv) remove spaces from the string." 62 (should (equal (denote-sluggify 'title " ___ !~!!$%^ This iS a tEsT ++ ?? ") 63 "this-is-a-test"))) 64 65 (ert-deftest denote-test--denote--slug-put-equals () 66 "Test that `denote--slug-put-equals' replaces spaces/underscores with =. 67 Otherwise do the same as what is described in 68 `denote-test--denote--slug-hyphenate'. 69 70 The use of the equals sign is for the SIGNATURE field of the 71 Denote file name." 72 (should (equal (denote--slug-put-equals "__ This is a test __ ") 73 "This=is=a=test"))) 74 75 (ert-deftest denote-test--denote-sluggify-signature () 76 "Test that `denote-sluggify-signature' sluggifies the string for file signatures. 77 This is like `denote-test--denote-sluggify', except that it also 78 accounts for what we describe in `denote-test--denote--slug-put-equals'." 79 (should (equal (denote-sluggify-signature "--- ___ !~!!$%^ This -iS- a tEsT ++ ?? ") 80 "this=is=a=test"))) 81 82 (ert-deftest denote-test--denote-sluggify-keyword () 83 "Test that `denote-sluggify-keyword' sluggifies the string while joining words. 84 In this context, to join words is to elimitate any space or 85 delimiter between them. 86 87 Otherwise, this is like `denote-test--denote-sluggify'." 88 (should (equal (denote-sluggify-keyword "--- ___ !~!!$%^ This iS a - tEsT ++ ?? ") 89 "thisisatest"))) 90 91 (ert-deftest denote-test--denote-sluggify-keywords () 92 "Test that `denote-sluggify-keywords' sluggifies a list of strings. 93 The function also account for the value of the user option 94 `denote-allow-multi-word-keywords'." 95 (should 96 (equal (denote-sluggify-keywords '("one !@# --- one" " two" "__ three __")) 97 '("oneone" "two" "three")))) 98 99 (ert-deftest denote-test--denote--file-empty-p () 100 "Test that `denote--file-empty-p' returns non-nil on empty file." 101 ;; (should (null (denote--file-empty-p user-init-file)) 102 (should (let ((file (make-temp-file "denote-test"))) 103 (prog1 104 (denote--file-empty-p file) 105 (delete-file file))))) 106 107 (ert-deftest denote-test--denote-file-is-note-p () 108 "Test that `denote-file-is-note-p' checks that files is a Denote note. 109 For our purposes, a note must note be a directory, must satisfy 110 `file-regular-p', its path must be part of the variable 111 `denote-directory', it must have a Denote identifier in its name, 112 and use one of the extensions implied by `denote-file-type'." 113 (should (let* ((tmp (temporary-file-directory)) 114 (denote-directory tmp) 115 (file (concat tmp "20230522T154900--test__keyword.txt"))) 116 (with-current-buffer (find-file-noselect file) 117 (write-file file)) 118 (prog1 119 (denote-file-is-note-p file) 120 (delete-file file))))) 121 122 (ert-deftest denote-test--denote-file-has-identifier-p () 123 "Test that `denote-file-has-identifier-p' checks for a Denote identifier." 124 (should (denote-file-has-identifier-p "20230522T154900--test__keyword.txt")) 125 (should (null (denote-file-has-identifier-p "T154900--test__keyword.txt")))) 126 127 (ert-deftest denote-test--denote-file-has-signature-p () 128 "Test that `denote-file-has-signature-p' checks for a Denote signature." 129 (should (denote-file-has-signature-p "20230522T154900==sig--test__keyword.txt")) 130 (should (null (denote-file-has-signature-p "20230522T154900--test__keyword.txt")))) 131 132 (ert-deftest denote-test--denote-file-has-supported-extension-p () 133 "Test that `denote-file-has-supported-extension-p' matches a supported extension." 134 (should 135 (member 136 (file-name-extension "20230522T154900==sig--test__keyword.txt" :period) 137 (denote-file-type-extensions-with-encryption))) 138 (should 139 (null 140 (member 141 (file-name-extension "20230522T154900==sig--test__keyword" :period) 142 (denote-file-type-extensions-with-encryption))))) 143 144 (ert-deftest denote-test--denote-file-type-extensions () 145 "Test that `denote-file-type-extensions' returns file extensions. 146 We check for the common file type extensions, though the user can 147 theoretically set `denote-file-types' to nil and handle things on 148 their own. We do not have to test for that scenario, because 149 such a user will be redefining large parts of Denote's behaviour 150 with regard to file types." 151 (let ((extensions (denote-file-type-extensions))) 152 (should (or (member ".md" extensions) 153 (member ".org" extensions) 154 (member ".txt" extensions))))) 155 156 (ert-deftest denote-test--denote-file-type-extensions-with-encryption () 157 "Test that `denote-file-type-extensions-with-encryption' covers encryption. 158 Extend what we do in `denote-test--denote-file-type-extensions'." 159 (let ((extensions (denote-file-type-extensions-with-encryption))) 160 (should (or (member ".md" extensions) 161 (member ".org" extensions) 162 (member ".txt" extensions) 163 (member ".md.gpg" extensions) 164 (member ".org.gpg" extensions) 165 (member ".txt.gpg" extensions) 166 (member ".md.age" extensions) 167 (member ".org.age" extensions) 168 (member ".txt.age" extensions))))) 169 170 (ert-deftest denote-test--denote-surround-with-quotes () 171 "Test that `denote-surround-with-quotes' returns a string in quotes." 172 (should (and (equal (denote-surround-with-quotes "test") "\"test\"") 173 (equal (denote-surround-with-quotes "") "\"\"") 174 (equal (denote-surround-with-quotes nil) "\"\"") 175 (equal (denote-surround-with-quotes 'wrong) "\"\"") 176 (equal (denote-surround-with-quotes '(wrong)) "\"\"")))) 177 178 (ert-deftest denote-test--denote--format-front-matter () 179 "Test that `denote--format-front-matter' formats front matter correctly." 180 (should (and (equal (denote--format-front-matter "" "" '("") "" 'text) 181 (mapconcat #'identity 182 '("title: " 183 "date: " 184 "tags: " 185 "identifier: " 186 "---------------------------\n\n") 187 "\n")) 188 189 (equal 190 (denote--format-front-matter 191 "Some test" "2023-06-05" '("one" "two") 192 "20230605T102234" 'text) 193 (mapconcat #'identity 194 '("title: Some test" 195 "date: 2023-06-05" 196 "tags: one two" 197 "identifier: 20230605T102234" 198 "---------------------------\n\n") 199 "\n")))) 200 201 (should (and (equal (denote--format-front-matter "" "" nil "" 'org) 202 (mapconcat #'identity 203 '("#+title: " 204 "#+date: " 205 "#+filetags: " 206 "#+identifier: " 207 "\n") 208 "\n")) 209 210 (equal 211 (denote--format-front-matter 212 "Some test" "2023-06-05" '("one" "two") 213 "20230605T102234" 'org) 214 (mapconcat #'identity 215 '("#+title: Some test" 216 "#+date: 2023-06-05" 217 "#+filetags: :one:two:" 218 "#+identifier: 20230605T102234" 219 "\n") 220 "\n")))) 221 222 (should (and (equal (denote--format-front-matter "" "" nil "" 'markdown-yaml) 223 (mapconcat #'identity 224 '("---" 225 "title: \"\"" 226 "date: " 227 "tags: []" 228 "identifier: \"\"" 229 "---" 230 "\n") 231 "\n")) 232 233 (equal 234 (denote--format-front-matter 235 "Some test" "2023-06-05" '("one" "two") 236 "20230605T102234" 'markdown-yaml) 237 (mapconcat #'identity 238 '("---" 239 "title: \"Some test\"" 240 "date: 2023-06-05" 241 "tags: [\"one\", \"two\"]" 242 "identifier: \"20230605T102234\"" 243 "---" 244 "\n") 245 "\n")))) 246 247 (should (and (equal (denote--format-front-matter "" "" nil "" 'markdown-toml) 248 (mapconcat #'identity 249 '("+++" 250 "title = \"\"" 251 "date = " 252 "tags = []" 253 "identifier = \"\"" 254 "+++" 255 "\n") 256 "\n")) 257 258 (equal 259 (denote--format-front-matter 260 "Some test" "2023-06-05" '("one" "two") 261 "20230605T102234" 'markdown-toml) 262 (mapconcat #'identity 263 '("+++" 264 "title = \"Some test\"" 265 "date = 2023-06-05" 266 "tags = [\"one\", \"two\"]" 267 "identifier = \"20230605T102234\"" 268 "+++" 269 "\n") 270 "\n"))))) 271 272 (ert-deftest denote-test--denote-format-file-name () 273 "Test that `denote-format-file-name' returns all expected paths." 274 (let* ((title "Some test") 275 (id (format-time-string denote-id-format (denote-valid-date-p "2023-11-28 05:53:11"))) 276 (denote-directory "/tmp/test-denote") 277 (kws '("one" "two"))) 278 (should-error (denote-format-file-name 279 nil 280 id 281 kws 282 title 283 (denote--file-extension 'org) 284 "")) 285 286 (should-error (denote-format-file-name 287 "" 288 id 289 kws 290 title 291 (denote--file-extension 'org) 292 "")) 293 294 (should-error (denote-format-file-name 295 denote-directory ; notice this is the `let' bound value without the suffix 296 id 297 kws 298 title 299 (denote--file-extension 'org) 300 "")) 301 302 (should-error (denote-format-file-name 303 (denote-directory) 304 nil 305 kws 306 title 307 (denote--file-extension 'org) 308 "")) 309 310 (should-error (denote-format-file-name 311 (denote-directory) 312 "" 313 kws 314 title 315 (denote--file-extension 'org) 316 "")) 317 318 (should-error (denote-format-file-name 319 (denote-directory) 320 "0123456" 321 kws 322 title 323 (denote--file-extension 'org) 324 "")) 325 326 (should (equal (denote-format-file-name 327 (denote-directory) 328 id 329 kws 330 title 331 (denote--file-extension 'org) 332 "") 333 "/tmp/test-denote/20231128T055311--some-test__one_two.org")) 334 335 (should (equal (denote-format-file-name 336 (denote-directory) 337 id 338 nil 339 "" 340 (denote--file-extension 'org) 341 "") 342 "/tmp/test-denote/20231128T055311.org")) 343 344 (should (equal (denote-format-file-name 345 (denote-directory) 346 id 347 nil 348 nil 349 (denote--file-extension 'org) 350 nil) 351 "/tmp/test-denote/20231128T055311.org")) 352 353 (should (equal (denote-format-file-name 354 (denote-directory) 355 id 356 kws 357 title 358 (denote--file-extension 'org) 359 "sig") 360 "/tmp/test-denote/20231128T055311==sig--some-test__one_two.org")))) 361 362 (ert-deftest denote-test--denote-get-file-extension () 363 "Test that `denote-get-file-extension' gets the correct file extension." 364 (should (and (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing") "") 365 (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org") ".org") 366 (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.gpg") ".org.gpg") 367 (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.age") ".org.age")))) 368 369 (ert-deftest denote-test--denote-get-file-extension-sans-encryption () 370 "Test that `denote-get-file-extension-sans-encryption' gets the file extension without encryption." 371 (should (and (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing") "") 372 (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org") ".org") 373 (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.gpg") ".org") 374 (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.age") ".org")))) 375 376 (ert-deftest denote-test--denote-filetype-heuristics () 377 "Test that `denote-filetype-heuristics' gets the correct file type." 378 (should (and (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing") (caar denote-file-types)) 379 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org") 'org) 380 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.gpg") 'org) 381 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.age") 'org) 382 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing") 'org) 383 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt") 'text) 384 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.gpg") 'text) 385 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.age") 'text) 386 ;; NOTE 2023-10-11: It returns `markdown-yaml' as a fallback. In 387 ;; an actual file, it reads the file contents to determine what 388 ;; it is and can return `markdown-toml'. In principle, we should 389 ;; be testing this here, though I prefer to keep things simple. 390 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md") 'markdown-yaml) 391 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.gpg") 'markdown-yaml) 392 (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.age") 'markdown-yaml)))) 393 394 (ert-deftest denote-test--denote-convert-file-name-keywords-to-crm () 395 "Ensure that `denote-convert-file-name-keywords-to-crm' returns words as comma-separated string." 396 (should 397 (and (equal (denote-convert-file-name-keywords-to-crm "_denote_keywords_testing") "denote,keywords,testing") 398 (equal (denote-convert-file-name-keywords-to-crm "_denote") "denote") 399 (equal (denote-convert-file-name-keywords-to-crm "") "")))) 400 401 (ert-deftest denote-test--denote-get-identifier () 402 "Test that `denote-get-identifier' returns an identifier." 403 (should (and (equal (denote-get-identifier) (format-time-string denote-id-format (current-time))) 404 (equal (denote-get-identifier "2024-02-01 10:34") "20240201T103400") 405 (equal (denote-get-identifier 1705644188) "20240119T080308") 406 (equal (denote-get-identifier '(26026 4251)) "20240119T080307"))) 407 (should-error (denote-get-identifier "Invalid date"))) 408 409 ;;;; denote-journal-extras.el 410 411 (require 'denote-journal-extras) 412 413 (ert-deftest denote-test--denote-journal-extras-daily--title-format () 414 "Make sure that `denote-journal-extras-daily--title-format' yields the desired format." 415 (should (and 416 ;; These three should prompt, but I am here treating the 417 ;; prompt as if already returned a string. The test for 418 ;; the `denote-title-prompt' can be separate. 419 (stringp 420 (cl-letf (((symbol-function 'denote-title-prompt) #'identity) 421 (denote-journal-extras-title-format nil)) 422 (denote-journal-extras-daily--title-format))) 423 424 (stringp 425 (cl-letf (((symbol-function 'denote-title-prompt) #'identity) 426 (denote-journal-extras-title-format t)) 427 (denote-journal-extras-daily--title-format))) 428 429 (stringp 430 (cl-letf (((symbol-function 'denote-title-prompt) #'identity) 431 (denote-journal-extras-title-format :some-arbitrary-keyword)) 432 (denote-journal-extras-daily--title-format))) 433 434 ;; And these return the following values 435 (string-match-p 436 "\\<.*?\\>" 437 (let ((denote-journal-extras-title-format 'day)) 438 (denote-journal-extras-daily--title-format))) 439 440 (string-match-p 441 "\\<.*?\\> [0-9]\\{,2\\} \\<.*?\\> [0-9]\\{,4\\}" 442 (let ((denote-journal-extras-title-format 'day-date-month-year)) 443 (denote-journal-extras-daily--title-format))) 444 445 (string-match-p 446 "\\<.*?\\> [0-9]\\{,2\\} \\<.*?\\> [0-9]\\{,4\\} [0-9]\\{,2\\}:[0-9]\\{,2\\} \\<.*?\\>" 447 (let ((denote-journal-extras-title-format 'day-date-month-year-12h)) 448 (denote-journal-extras-daily--title-format))) 449 450 (string-match-p 451 "\\<.*?\\> [0-9]\\{,2\\} \\<.*?\\> [0-9]\\{,4\\} [0-9]\\{,2\\}:[0-9]\\{,2\\}" 452 (let ((denote-journal-extras-title-format 'day-date-month-year-24h)) 453 (denote-journal-extras-daily--title-format)))))) 454 455 (provide 'denote-test) 456 ;;; denote-test.el ends here