From: Federico Tedin <federicotedin@gmail.com>
To: emacs-devel@gnu.org
Subject: [PATCH] Unit tests and lexical-binding for Tempo
Date: Mon, 13 May 2019 16:00:17 -0300 [thread overview]
Message-ID: <87h89yqiwu.fsf@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 367 bytes --]
Hi all,
I have added the lexical-binding header to tempo.el, and added in some
unit tests that test the different tags/elements that a Tempo template can
contain. I've also expanded the documentation for
`tempo-define-template' to mention the user variable
`tempo-user-elements', and made three variables buffer-local.
Any feedback is greatly appreciated.
Thanks!
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 11605 bytes --]
From b377640c04e9318d67fcb74dfcfd9b455d78dca9 Mon Sep 17 00:00:00 2001
From: Federico Tedin <federicotedin@gmail.com>
Date: Mon, 13 May 2019 15:55:09 -0300
Subject: [PATCH 1/1] Use lexical-binding in tempo.el and add tests
* lisp/tempo.el: Use lexical-binding.
(tempo-define-template): Expand documentation to mention
`tempo-user-elements'.
(tempo-named-insertions, tempo-region-start, tempo-region-stop): Make
them buffer-local.
* test/lisp/tempo-tests.el: Add tests for tempo.el.
---
lisp/tempo.el | 18 ++-
test/lisp/tempo-tests.el | 229 +++++++++++++++++++++++++++++++++++++++
2 files changed, 241 insertions(+), 6 deletions(-)
create mode 100644 test/lisp/tempo-tests.el
diff --git a/lisp/tempo.el b/lisp/tempo.el
index 28afbec0f4..66192439cc 100644
--- a/lisp/tempo.el
+++ b/lisp/tempo.el
@@ -1,4 +1,4 @@
-;;; tempo.el --- Flexible template insertion
+;;; tempo.el --- Flexible template insertion -*- lexical-binding: t; -*-
;; Copyright (C) 1994-1995, 2001-2019 Free Software Foundation, Inc.
@@ -211,6 +211,9 @@ tempo-region-stop
(make-variable-buffer-local 'tempo-match-finder)
(make-variable-buffer-local 'tempo-collection)
(make-variable-buffer-local 'tempo-dirty-collection)
+(make-variable-buffer-local 'tempo-named-insertions)
+(make-variable-buffer-local 'tempo-region-start)
+(make-variable-buffer-local 'tempo-region-stop)
;;; Functions
@@ -268,11 +271,14 @@ tempo-define-template
- `n>': Inserts a newline and indents line.
- `o': Like `%' but leaves the point before the newline.
- nil: It is ignored.
- - Anything else: It is evaluated and the result is treated as an
- element to be inserted. One additional tag is useful for these
- cases. If an expression returns a list (l foo bar), the elements
- after `l' will be inserted according to the usual rules. This makes
- it possible to return several elements from one expression."
+ - Anything else: Each function in `tempo-user-elements' is called
+ with it as argument until one of them returns non-nil, and the
+ result is inserted. If all of them return nil, it is evaluated and
+ the result is treated as an element to be inserted. One additional
+ tag is useful for these cases. If an expression returns a list (l
+ foo bar), the elements after `l' will be inserted according to the
+ usual rules. This makes it possible to return several elements
+ from one expression."
(let* ((template-name (intern (concat "tempo-template-"
name)))
(command-name template-name))
diff --git a/test/lisp/tempo-tests.el b/test/lisp/tempo-tests.el
new file mode 100644
index 0000000000..4ce0830700
--- /dev/null
+++ b/test/lisp/tempo-tests.el
@@ -0,0 +1,229 @@
+;;; tempo-tests.el --- Test suite for tempo.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; Author: Federico Tedin <federicotedin@gmail.com>
+;; Keywords: tempo
+
+;; 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/>.
+
+;;; Code:
+
+(require 'tempo)
+
+(ert-deftest string-element-test ()
+ "Test a template containing a string element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("GNU Emacs Tempo test"))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "GNU Emacs Tempo test"))))
+
+(ert-deftest p-bare-element-test ()
+ "Test a template containing a bare `p' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("abcde" p))
+ (tempo-insert-template 'tempo-template-test nil)
+ (tempo-forward-mark)
+ (should (equal (point) 6))))
+
+(ert-deftest r-bare-element-test ()
+ "Test a template containing a bare `r' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("abcde" r "ghijk"))
+ (insert "F")
+ (set-mark-command nil)
+ (goto-char (point-min))
+ (tempo-insert-template 'tempo-template-test t)
+ (should (equal (buffer-string) "abcdeFghijk"))))
+
+(ert-deftest p-element-test ()
+ "Testing template containing a `p' (prompt) element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("hello " (p ">")))
+ (setq tempo-interactive t)
+ (cl-letf (((symbol-function 'read-string) (lambda (_) "world")))
+ (tempo-insert-template 'tempo-template-test nil))
+ (should (equal (buffer-string) "hello world"))))
+
+(ert-deftest P-element-test ()
+ "Testing template containing a `P' (prompt) element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("hello " (P ">")))
+ (setq tempo-interactive nil) ;; `P' will ignore this
+ (cl-letf (((symbol-function 'read-string) (lambda (_) "world")))
+ (tempo-insert-template 'tempo-template-test nil))
+ (should (equal (buffer-string) "hello world"))))
+
+(ert-deftest r-element-test ()
+ "Testing template containing an `r' (with prompt) element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("abcde" (r ">") "ghijk"))
+ (setq tempo-interactive t)
+ (cl-letf (((symbol-function 'read-string) (lambda (_) "F")))
+ (tempo-insert-template 'tempo-template-test nil))
+ (should (equal (buffer-string) "abcdeFghijk"))))
+
+(ert-deftest s-element-test ()
+ "Testing template containing an `s' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("hello " (p ">" P1) " " (s P1)))
+ (setq tempo-interactive t)
+ (cl-letf (((symbol-function 'read-string) (lambda (_) "world!")))
+ (tempo-insert-template 'tempo-template-test nil))
+ (should (equal (buffer-string) "hello world! world!"))))
+
+(ert-deftest &-element-test ()
+ "Testing template containing an `&' element."
+ (tempo-define-template "test" '(& "test"))
+ (with-temp-buffer
+ (insert " ")
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) " test")))
+ (with-temp-buffer
+ (insert "hello")
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "hello\ntest"))))
+
+(ert-deftest %-element-test ()
+ "Testing template containing an `%' element."
+ (tempo-define-template "test" '("test" %))
+ (with-temp-buffer
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "test")))
+ (with-temp-buffer
+ (insert "hello")
+ (goto-char (point-min))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "test\nhello"))))
+
+(ert-deftest n-element-test ()
+ "Testing template containing an `n' element."
+ (tempo-define-template "test" '("test" n "test"))
+ (with-temp-buffer
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "test\ntest"))))
+
+(ert-deftest n>-element-test ()
+ "Testing template containing an `n>' element."
+ (tempo-define-template "test" '("(progn" n> "(list 1 2 3))"))
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (tempo-insert-template 'tempo-template-test nil)
+ ;; Tempo should have inserted two spaces before (list 1 2 3)
+ (should (equal (buffer-string) "(progn\n (list 1 2 3))"))))
+
+(ert-deftest >-element-test ()
+ "Testing template containing a `>' element."
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert "(progn\n)")
+ (backward-char)
+ (tempo-define-template "test" '("(list 1 2 3)" >))
+ (tempo-insert-template 'tempo-template-test nil)
+ ;; Tempo should have inserted two spaces before (list 1 2 3)
+ (should (equal (buffer-string) "(progn\n (list 1 2 3))"))))
+
+(ert-deftest r>-bare-element-test ()
+ "Testing template containing a bare `r>' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("(progn" n r> ")"))
+ (emacs-lisp-mode)
+ (insert "(list 1 2 3)")
+ (set-mark-command nil)
+ (goto-char (point-min))
+ (tempo-insert-template 'tempo-template-test t)
+ ;; Tempo should have inserted two spaces before (list 1 2 3)
+ (should (equal (buffer-string) "(progn\n (list 1 2 3))"))))
+
+(ert-deftest r>-element-test ()
+ "Testing template containing an `r>' (with prompt) element."
+ (tempo-define-template "test" '("(progn" n (r> ":") ")"))
+ (with-temp-buffer
+ ;; Test on-region use
+ (emacs-lisp-mode)
+ (setq tempo-interactive nil)
+ (insert "(list 1 2 3)")
+ (set-mark-command nil)
+ (goto-char (point-min))
+ (tempo-insert-template 'tempo-template-test t)
+ (should (equal (buffer-string) "(progn\n (list 1 2 3))")))
+ (with-temp-buffer
+ ;; Test interactive use
+ (emacs-lisp-mode)
+ (setq tempo-interactive t)
+ (cl-letf (((symbol-function 'read-string) (lambda (_) " (list 1 2 3)")))
+ (tempo-insert-template 'tempo-template-test nil))
+ (should (equal (buffer-string) "(progn\n (list 1 2 3))"))))
+
+(ert-deftest o-element-test ()
+ "Testing template containing an `o' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("test" o))
+ (insert "hello")
+ (goto-char (point-min))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "test\nhello"))
+ (should (equal (point) 5))))
+
+(ert-deftest nil-element-test ()
+ "Testing template with nil elements."
+ (with-temp-buffer
+ (tempo-define-template "test" '("Hello," nil " World!"))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "Hello, World!"))))
+
+(ert-deftest eval-element-test ()
+ "Testing template with Emacs Lisp expressions."
+ (with-temp-buffer
+ (tempo-define-template "test" '((int-to-string (+ 1 1)) "=" (concat "1" "+1")))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "2=1+1"))))
+
+(ert-deftest l-element-test ()
+ "Testing template containing an `l' element."
+ (with-temp-buffer
+ (tempo-define-template "test" '("list: " (l "1, " "2, " (int-to-string (+ 1 2)))))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "list: 1, 2, 3"))))
+
+(ert-deftest tempo-user-elements-test ()
+ "Testing a template containing an element to be used as an argument
+in a call to a function in `tempo-user-elements'."
+ (with-temp-buffer
+ (make-variable-buffer-local 'tempo-user-elements)
+ (add-to-list 'tempo-user-elements (lambda (x) (int-to-string (* x x))))
+ (tempo-define-template "test" '(1 " " 2 " " 3 " " 4))
+ (tempo-insert-template 'tempo-template-test nil)
+ (should (equal (buffer-string) "1 4 9 16"))))
+
+(ert-deftest expand-tag-test ()
+ "Testing expansion of a template with a tag."
+ (with-temp-buffer
+ (tempo-define-template "test" '("Hello, World!") "hello")
+ (insert "hello")
+ (tempo-complete-tag)
+ (should (equal (buffer-string) "Hello, World!"))))
+
+(ert-deftest expand-partial-tag-test ()
+ "Testing expansion of a template with a tag, with a partial match."
+ (with-temp-buffer
+ (tempo-define-template "test" '("Hello, World!") "hello")
+ (insert "hel")
+ (tempo-complete-tag)
+ (should (equal (buffer-string) "Hello, World!"))))
+
+(provide 'tempo-tests)
+;;; tempo-tests.el ends here
--
2.17.1
next reply other threads:[~2019-05-13 19:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-13 19:00 Federico Tedin [this message]
2019-05-14 0:49 ` [PATCH] Unit tests and lexical-binding for Tempo Basil L. Contovounesios
2019-05-14 21:44 ` Federico Tedin
2019-05-20 15:26 ` Basil L. Contovounesios
2019-05-20 19:32 ` Federico Tedin
2019-05-21 14:30 ` Basil L. Contovounesios
2019-05-21 16:30 ` Federico Tedin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87h89yqiwu.fsf@gmail.com \
--to=federicotedin@gmail.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.