From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Federico Tedin Newsgroups: gmane.emacs.devel Subject: [PATCH] Unit tests and lexical-binding for Tempo Date: Mon, 13 May 2019 16:00:17 -0300 Message-ID: <87h89yqiwu.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="161774"; mail-complaints-to="usenet@blaine.gmane.org" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon May 13 21:01:34 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hQGCc-000fwm-0a for ged-emacs-devel@m.gmane.org; Mon, 13 May 2019 21:01:34 +0200 Original-Received: from localhost ([127.0.0.1]:33734 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQGCb-00073U-2h for ged-emacs-devel@m.gmane.org; Mon, 13 May 2019 15:01:33 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:60931) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hQGBX-00070i-3W for emacs-devel@gnu.org; Mon, 13 May 2019 15:00:30 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hQGBU-0004Ow-KN for emacs-devel@gnu.org; Mon, 13 May 2019 15:00:27 -0400 Original-Received: from mail-qt1-x82c.google.com ([2607:f8b0:4864:20::82c]:37716) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hQGBU-0004Nn-8y for emacs-devel@gnu.org; Mon, 13 May 2019 15:00:24 -0400 Original-Received: by mail-qt1-x82c.google.com with SMTP id o7so16070143qtp.4 for ; Mon, 13 May 2019 12:00:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=KkQcesBSqzIdIOSjE+XNFolVuEnkkWgkKTWNoda3RYE=; b=pqrCz51R/Ws47rsKlVabOZkTx3qjKAjCGYhNMdeod+W0T2OooEc3fBd1NjpLyddi0D FtKR6jAFd0Mdq/2wVGCQl/EXLEbsuNgwNoSM58I1X52CzLA8UD1SDwYjEdqpmDc1QHJ4 CMm3h8b3HNQy8suLipPSmTO9lcVrgTtyzY4FIvz2Kco8WqfqO2PhAHBuezzl3cW+DiQV Bwo7XnB0xIZwNQFDbXlKWL6MVF87u7ImNorzz55V8NBUOzgl/7dKub+FRdHgYV8JcW4V 7O4XC5AJv3AOhVYIgZ6wj/ml3cEENlZ8wzVXdx5CDBZhFvMxyozYQXQDginP37OLaqIf bCmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=KkQcesBSqzIdIOSjE+XNFolVuEnkkWgkKTWNoda3RYE=; b=aUy+OGfvNsUcdwMdDX4It+TLvYIYZ+8cBKfY5Mg42/1TQRc2CDB3cuktxO5ZjKHzsO tVvRlAC0cARDnej2aCJ91ChMLiMnNre+WD9Jp/OZe0BOBGiVDWaDjw15w9Qt5eBvT6sp uMvIfSYh1RP4ZeuXkTbcK7wbDoLq+S/yeMToWrVjN5sqXJI322sYJ3nBtt9CPa5eARFH PFCxTMR/l8iqLleAhGJLwKSeQdSYLSzuLN/GZveVqEuLucyc4fmWNrrUwTeOr6fqkx0v 4HMiaF6gcc6rLtuU5fDXlJFAkiQEbT6+TLK7CXEG3o/NQzJfiSuOVrP2dPbgaarW1Agb xn2w== X-Gm-Message-State: APjAAAWdUjtoDJ1rte93krlEB522SOTHqjjFFzoqgybNW+VCHkoTZplt 5/Knv/U89KIj4V5xFyZyj/l5wpVid0Q= X-Google-Smtp-Source: APXvYqxtVKfCIH+3qYEeW+76fT2obRGLvwwq5mPl8GUPLPC4KEgqd/oQ/AF9wkDB31sJCZIqRP3eqw== X-Received: by 2002:ac8:3231:: with SMTP id x46mr25257779qta.328.1557774021172; Mon, 13 May 2019 12:00:21 -0700 (PDT) Original-Received: from hideo ([181.170.211.157]) by smtp.gmail.com with ESMTPSA id g15sm8810356qta.31.2019.05.13.12.00.19 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 May 2019 12:00:20 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::82c X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:236480 Archived-At: --=-=-= Content-Type: text/plain 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! --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=tempo.patch Content-Description: patch >From b377640c04e9318d67fcb74dfcfd9b455d78dca9 Mon Sep 17 00:00:00 2001 From: Federico Tedin 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 +;; 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 . + +;;; 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 --=-=-=--