diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lisp/bookmark-resources/example.txt | 3 | ||||
-rw-r--r-- | test/lisp/bookmark-resources/test.bmk | 10 | ||||
-rw-r--r-- | test/lisp/bookmark-tests.el | 319 |
3 files changed, 332 insertions, 0 deletions
diff --git a/test/lisp/bookmark-resources/example.txt b/test/lisp/bookmark-resources/example.txt new file mode 100644 index 00000000000..b66fc078269 --- /dev/null +++ b/test/lisp/bookmark-resources/example.txt @@ -0,0 +1,3 @@ +This text file is used by bookmark-tests.el + +;; example.txt ends here. diff --git a/test/lisp/bookmark-resources/test.bmk b/test/lisp/bookmark-resources/test.bmk new file mode 100644 index 00000000000..c238fe1c8d4 --- /dev/null +++ b/test/lisp/bookmark-resources/test.bmk @@ -0,0 +1,10 @@ +;;;; Emacs Bookmark Format Version 1 ;;;; -*- coding: utf-8-emacs -*- +;;; This format is meant to be slightly human-readable; +;;; nevertheless, you probably don't want to edit it. +;;; -*- End Of Bookmark File Format Version Stamp -*- +(("name" + (filename . "/some/file") + (front-context-string . "abc") + (rear-context-string . "def") + (position . 3)) +) diff --git a/test/lisp/bookmark-tests.el b/test/lisp/bookmark-tests.el new file mode 100644 index 00000000000..6fa0b1e98d0 --- /dev/null +++ b/test/lisp/bookmark-tests.el @@ -0,0 +1,319 @@ +;;; bookmark-tests.el --- Tests for bookmark.el -*- lexical-binding: t -*- + +;; Copyright (C) 2019 Free Software Foundation, Inc. + +;; Author: Stefan Kangas <stefankangas@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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'bookmark) + +(defvar bookmark-tests-data-dir + (file-truename + (expand-file-name "bookmark-resources/" + (file-name-directory (or load-file-name + buffer-file-name)))) + "Base directory of bookmark-tests.el data files.") + +(defvar bookmark-tests-bookmark-file + (expand-file-name "test.bmk" bookmark-tests-data-dir) + "Bookmark file used for testing.") + +(defvar bookmark-tests-example-file + ;; We use abbreviate-file-name here to match the behaviour of + ;; `bookmark-buffer-file-name'. + (abbreviate-file-name (expand-file-name "example.txt" bookmark-tests-data-dir)) + "Example file used for testing.") + +;; The values below should match `bookmark-tests-bookmark-file'. We cache +;; these values to speed up tests by avoiding unnecessary I/O. This +;; makes tests run 5-10 times faster on my system. +(eval-and-compile ; needed by `with-bookmark-test' macro + (defvar bookmark-tests-bookmark '("name" + (filename . "/some/file") + (front-context-string . "abc") + (rear-context-string . "def") + (position . 3)) + "Cached value used in bookmark-tests.el.")) + +(defvar bookmark-tests-cache-timestamp + (cons bookmark-tests-bookmark-file + (nth 5 (file-attributes + bookmark-tests-bookmark-file))) + "Cached value used in bookmark-tests.el.") + +(defmacro with-bookmark-test (&rest body) + "Create environment for testing bookmark.el and evaluate BODY. +Ensure a clean environment for testing, and do not change user +data when running tests interactively." + `(with-temp-buffer + (let ((bookmark-alist (quote (,(copy-sequence bookmark-tests-bookmark)))) + (bookmark-default-file bookmark-tests-bookmark-file) + (bookmark-bookmarks-timestamp bookmark-tests-cache-timestamp) + bookmark-save-flag) + ,@body))) + +(defmacro with-bookmark-test-file (&rest body) + "Create environment for testing bookmark.el and evaluate BODY. +Same as `with-bookmark-test' but also opens the resource file +example.txt in a buffer, which can be accessed by callers through +the lexically-bound variable `buffer'." + `(let ((buffer (find-file-noselect bookmark-tests-example-file))) + (unwind-protect + (with-bookmark-test + ,@body) + (kill-buffer buffer)))) + +(ert-deftest bookmark-tests-all-names () + (with-bookmark-test + (should (equal (bookmark-all-names) '("name"))))) + +(ert-deftest bookmark-tests-get-bookmark () + (with-bookmark-test + (should (equal (bookmark-get-bookmark "name") bookmark-tests-bookmark)))) + +(ert-deftest bookmark-tests-get-bookmark-record () + (with-bookmark-test + (should (equal (bookmark-get-bookmark-record "name") (cdr bookmark-tests-bookmark))))) + +(ert-deftest bookmark-tests-record-getters-and-setters-new () + (with-temp-buffer + (let* ((buffer-file-name "test") + (bmk (bookmark-make-record))) + (bookmark-set-name bmk "foobar") + (should (equal (bookmark-name-from-full-record bmk) "foobar")) + (bookmark-set-filename bmk "file/name") + (should (equal (bookmark-get-filename bmk) "file/name")) + (bookmark-set-position bmk 123) + (should (equal (bookmark-get-position bmk) 123)) + (bookmark-set-front-context-string bmk "front") + (should (equal (bookmark-get-front-context-string bmk) "front")) + (bookmark-set-rear-context-string bmk "rear") + (should (equal (bookmark-get-rear-context-string bmk) "rear")) + (bookmark-prop-set bmk 'filename "prop") + (should (equal (bookmark-prop-get bmk 'filename) "prop"))))) + +(ert-deftest bookmark-tests-maybe-historicize-string () + (let ((bookmark-history)) + (bookmark-maybe-historicize-string "foo") + (should (equal (car bookmark-history) "foo")))) + +(ert-deftest bookmark-tests-make-record () + (with-bookmark-test-file + (let* ((record `("example.txt" (filename . ,bookmark-tests-example-file) + (front-context-string . "is text file is ") + (rear-context-string) + (position . 3) + (defaults "example.txt")))) + (with-current-buffer buffer + (goto-char 3) + (should (equal (bookmark-make-record) record)) + ;; calling twice gives same record + (should (equal (bookmark-make-record) record)))))) + +(ert-deftest bookmark-tests-make-record-function () + (with-bookmark-test + (let ((buffer-file-name "test")) + ;; Named bookmark + (let ((bookmark-make-record-function (lambda () '("<name>")))) + (should (equal (bookmark-make-record) + '("<name>")))) + ;; SECOND format + (let ((bookmark-make-record-function (lambda () '(((position . 2)))))) + (should (equal (bookmark-make-record) + '("test" ((position . 2) (defaults "test")))))) + ;; CURRENT format + (let ((bookmark-make-record-function (lambda () '((position . 2))))) + (should (equal (bookmark-make-record) + '("test" (position . 2) (defaults "test")))))))) + +(ert-deftest bookmark-tests-set () + (with-bookmark-test-file + (let ((bmk1 `("foo" (filename . ,bookmark-tests-example-file) + (front-context-string . "This text file i") + (rear-context-string) + (position . 1))) + (bmk2 `("foo" (filename . ,bookmark-tests-example-file) + (front-context-string) + (rear-context-string . ".txt ends here.\n") + (position . 72))) + bookmark-alist) + (with-current-buffer buffer + ;; 1. bookmark-set + ;; Set first bookmark + (goto-char (point-min)) + (bookmark-set "foo") + (should (equal bookmark-alist (list bmk1))) + ;; Replace that bookmark + (goto-char (point-max)) + (bookmark-set "foo") + (should (equal bookmark-alist (list bmk2))) + ;; Push another bookmark with the same name + (goto-char (point-min)) + (bookmark-set "foo" t) ; NO-OVERWRITE is t + (should (equal bookmark-alist (list bmk1 bmk2))) + + ;; 2. bookmark-set-no-overwrite + ;; Don't overwrite + (should-error (bookmark-set-no-overwrite "foo")) + ;; Set new bookmark + (setq bookmark-alist nil) + (bookmark-set-no-overwrite "foo") + (should (equal bookmark-alist (list bmk1))) + ;; Push another bookmark with the same name + (goto-char (point-max)) + (bookmark-set-no-overwrite "foo" t) ; PUSH-BOOKMARK is t + (should (equal bookmark-alist (list bmk2 bmk1))) + + ;; 3. bookmark-set-internal + (should-error (bookmark-set-internal "foo" "bar" t)))))) + +(ert-deftest bookmark-tests-kill-line () + (with-temp-buffer + (insert "foobar\n") + (goto-char (point-min)) + (bookmark-kill-line) + (should (equal (buffer-string) "\n"))) + (with-temp-buffer + (insert "foobar\n") + (goto-char (point-min)) + (bookmark-kill-line t) ; including newline + (should (equal (buffer-string) "")))) + +(ert-deftest bookmark-tests-default-annotation-text () + (should (stringp (bookmark-default-annotation-text "foo"))) + (should (string-match "foo" (bookmark-default-annotation-text "foo")))) + +(ert-deftest bookmark-tests-insert-annotation () + (with-bookmark-test + (should-error (bookmark-insert-annotation "a missing bookmark")) + (bookmark-insert-annotation "name") + (should (equal (buffer-string) (bookmark-default-annotation-text "name")))) + (with-bookmark-test + (bookmark-set-annotation "name" "some stuff") + (bookmark-insert-annotation "name") + (should (string-match "some stuff" (buffer-string))))) + +(ert-deftest bookmark-tests-edit-annotation () + (with-bookmark-test + (bookmark-edit-annotation "name") + (insert "new text") + (bookmark-send-edited-annotation) + (should (equal (bookmark-get-annotation "name") "new text")))) + +(ert-deftest bookmark-tests-jump () + (with-bookmark-test-file + (with-current-buffer buffer + (bookmark-set "test")) + (bookmark-jump "test") + (should (equal (current-buffer) buffer)) + (should-error (bookmark-jump nil)))) + +(ert-deftest bookmark-tests-insert-location () + (with-bookmark-test + (bookmark-insert-location "name") + (should (equal (buffer-string) "/some/file")))) + +(ert-deftest bookmark-tests-location () + (with-bookmark-test + (should (equal (bookmark-location "name") "/some/file")))) + +(ert-deftest bookmark-tests-rename () + (with-bookmark-test + (bookmark-rename "name" "newname") + (should (equal (bookmark-all-names) '("newname"))))) + +(ert-deftest bookmark-tests-insert () + (with-bookmark-test-file + (with-current-buffer buffer + (bookmark-set "test")) + (bookmark-insert "test") + (should (string-match "^This text file is used by bookmark-tests.el" + (buffer-string))))) + +(ert-deftest bookmark-tests-delete () + (with-bookmark-test + (bookmark-delete "name") + (should (equal bookmark-alist nil)))) + +(defmacro with-bookmark-test-save-load (&rest body) + "Create environment for testing bookmark.el and evaluate BODY. +Same as `with-bookmark-test' but also sets a temporary +`bookmark-default-file', evaluates BODY, and then runs the test +that saves and then loads the bookmark file." + `(with-bookmark-test + (let ((file (make-temp-file "bookmark-tests-"))) + (unwind-protect + (let ((bookmark-default-file file) + (old-alist bookmark-alist)) + ,@body + (bookmark-save nil file t) + (setq bookmark-alist nil) + (bookmark-load file nil t) + (should (equal bookmark-alist old-alist))) + (delete-file file))))) + +(defvar bookmark-tests-non-ascii-data + (concat "Здра́вствуйте!" "中文,普通话,汉语" "åäöøñ" + "こんにちは" "你好" "Dobrý deň" + "∀ p ∈ world • hello p □" + ;; These do not yield valid UTF-8 byte sequences. + ;; WARNING: If you try to evaluate the first one of these, + ;; there is a risk that Emacs will crash. Buyer beware. + (decode-coding-string "\xE3\x32\x9A\x36" 'chinese-gb18030) + (char-to-string (decode-char 'eight-bit #x81)))) + +(ert-deftest bookmark-tests-save () + (with-bookmark-test-save-load + ;; Just run the default test according to the macro. + t)) + +(ert-deftest bookmark-tests-save/non-ascii-bookmark-name () + (with-bookmark-test-save-load + (bookmark-set-name "name" bookmark-tests-non-ascii-data))) + +(ert-deftest bookmark-tests-save/non-ascii-annotation () + (with-bookmark-test-save-load + (bookmark-set-annotation "name" bookmark-tests-non-ascii-data))) + +(ert-deftest bookmark-tests-maybe-rename () + (let ((bookmark '("foo"))) + (bookmark-maybe-rename bookmark '("foo")) + (should (equal bookmark '("foo<2>"))))) + +(ert-deftest bookmark-tests-load () + (with-bookmark-test + (should-error (bookmark-load "no/such/file")) + (let* ((bookmark-alist '())) + (bookmark-load bookmark-tests-bookmark-file nil t) + (should (equal bookmark-alist (list bookmark-tests-bookmark))) + (bookmark-load bookmark-tests-bookmark-file t t) ; OVERWRITE is t + (should (equal bookmark-alist (list bookmark-tests-bookmark))) + ;; Append + (bookmark-load bookmark-tests-bookmark-file nil t) ; OVERWRITE is nil + (should (equal bookmark-alist + (list bookmark-tests-bookmark + (cons "name<2>" (cdr bookmark-tests-bookmark)))))))) + +;; TODO: Add tests for bookmark-bmenu. + +(provide 'bookmark-tests) +;;; bookmark-tests.el ends here |