diff --git a/lisp/_prepare.el b/lisp/_prepare.el index 77915034..a929a421 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -479,10 +479,15 @@ You can pass BUFFER-OR-NAME to replace current buffer." (with-current-buffer (or buffer-or-name (current-buffer)) (goto-char (point-min)) (while (not (eobp)) - (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) - (cond ((string-match-p "[: ][Ee]rror: " line) (eask-error line)) - ((string-match-p "[: ][Ww]arning: " line) (eask-warn line)) - (t (eask-log line)))) + (let ((line (buffer-substring-no-properties (line-beginning-position) + (line-end-position)))) + ;; The variable `line' can contains format specifier, avoid it with `%s'! + (cond ((string-match-p "[: ][Ee]rror: " line) + (eask-error "%s" line)) + ((string-match-p "[: ][Ww]arning: " line) + (eask-warn "%s" line)) + (t + (eask-log "%s" line)))) (forward-line 1)))) (defun eask-delete-file (filename) @@ -1821,7 +1826,8 @@ Execute forms BODY limit by the verbosity level (SYMBOL)." (defun eask--ansi (symbol string) "Paint STRING with color defined by log level (SYMBOL)." (if-let* ((ansi-function (cdr (assq symbol eask-level-color)))) - (funcall ansi-function string) + ;; The `%s` is use to avoid `not enough arguments for string` error. + (funcall ansi-function "%s" string) string)) (defun eask--format (prefix fmt &rest args) @@ -1829,41 +1835,39 @@ Execute forms BODY limit by the verbosity level (SYMBOL)." Argument PREFIX is a string identify the type of this messages. Arguments FMT and ARGS are used to pass through function `format'." - (apply #'format - (concat (when eask-timestamps (format-time-string "%Y-%m-%d %H:%M:%S ")) - (when eask-log-level (concat prefix " ")) - fmt) - args)) + (concat (when eask-timestamps (format-time-string "%Y-%m-%d %H:%M:%S ")) + (when eask-log-level (concat prefix " ")) + (apply #'format fmt args))) -(defun eask--msg (symbol prefix msg &rest args) +(defun eask--msg (symbol prefix fmt &rest args) "If level (SYMBOL) is at or below `eask-verbosity'; then, log the message. -For arguments PREFIX, MSG and ARGS, please see funtion `eask--format' for the +For arguments PREFIX, FMT and ARGS, please see funtion `eask--format' for the detials." (eask-with-verbosity symbol - (let* ((string (apply #'eask--format prefix msg args)) - (output (eask--ansi symbol string)) + (let* ((output (apply #'eask--format prefix fmt args)) + (output (eask--ansi symbol output)) (output (eask--msg-displayable-kwds output)) ; Don't color, but replace it! (func (cl-case symbol ((or error warn) symbol) - (t #'message)))) + (t #'message)))) (funcall func "%s" output)))) -(defun eask-debug (msg &rest args) - "Send debug message; see function `eask--msg' for arguments MSG and ARGS." - (apply #'eask--msg 'debug "[DEBUG]" msg args)) -(defun eask-log (msg &rest args) - "Send log message; see function `eask--msg' for arguments MSG and ARGS." - (apply #'eask--msg 'log "[LOG]" msg args)) -(defun eask-info (msg &rest args) - "Send info message; see function `eask--msg' for arguments MSG and ARGS." - (apply #'eask--msg 'info "[INFO]" msg args)) -(defun eask-warn (msg &rest args) - "Send warn message; see function `eask--msg' for arguments MSG and ARGS." - (apply #'eask--msg 'warn "[WARNING]" msg args)) -(defun eask-error (msg &rest args) - "Send error message; see function `eask--msg' for arguments MSG and ARGS." - (apply #'eask--msg 'error "[ERROR]" msg args)) +(defun eask-debug (fmt &rest args) + "Send debug message; see function `eask--msg' for arguments FMT and ARGS." + (apply #'eask--msg 'debug "[DEBUG]" fmt args)) +(defun eask-log (fmt &rest args) + "Send log message; see function `eask--msg' for arguments FMT and ARGS." + (apply #'eask--msg 'log "[LOG]" fmt args)) +(defun eask-info (fmt &rest args) + "Send info message; see function `eask--msg' for arguments FMT and ARGS." + (apply #'eask--msg 'info "[INFO]" fmt args)) +(defun eask-warn (fmt &rest args) + "Send warn message; see function `eask--msg' for arguments FMT and ARGS." + (apply #'eask--msg 'warn "[WARNING]" fmt args)) +(defun eask-error (fmt &rest args) + "Send error message; see function `eask--msg' for arguments FMT and ARGS." + (apply #'eask--msg 'error "[ERROR]" fmt args)) (defun eask--msg-char-displayable (char replacement s) "Ensure CHAR is displayable in S; if not, we fallback to REPLACEMENT @@ -1963,6 +1967,12 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." (defvar eask-inhibit-error-message nil "Non-nil to stop error/warning message.") +(defvar eask--has-error-p nil + "Non-nil if an error has occurred.") + +(defvar eask--has-warn-p nil + "Non-nil if a warning has occurred.") + (defmacro eask-ignore-errors (&rest body) "Execute BODY without killing the process." (declare (indent 0) (debug t)) @@ -1981,8 +1991,8 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." (defun eask--trigger-error () "Trigger error event." (when (and (not eask--ignore-error-p) - (not (eask-checker-p))) ; ignore when checking Eask-file - (if (eask-allow-error-p) ; Trigger error at the right time + (not (eask-checker-p))) ; Ignore when checking Eask-file. + (if (eask-allow-error-p) ; Trigger error at the right time. (add-hook 'eask-after-command-hook #'eask--exit) (eask--exit)))) @@ -1990,6 +2000,7 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." "On error. Arguments FNC and ARGS are used for advice `:around'." + (setq eask--has-error-p t) (let ((msg (eask--ansi 'error (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) @@ -2001,6 +2012,7 @@ Arguments FNC and ARGS are used for advice `:around'." "On warn. Arguments FNC and ARGS are used for advice `:around'." + (setq eask--has-warn-p t) (let ((msg (eask--ansi 'warn (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) diff --git a/lisp/lint/elint.el b/lisp/lint/elint.el index cc4edac3..278f4815 100644 --- a/lisp/lint/elint.el +++ b/lisp/lint/elint.el @@ -40,8 +40,14 @@ (eask-lint-first-newline) (eask-msg "`%s` with elint" (ansi-green file)) (eask-with-verbosity 'debug (elint-file filename)) - (eask-print-log-buffer (elint-get-log-buffer)) - (kill-buffer (elint-get-log-buffer)))) + (let ((log-buffer (elint-get-log-buffer))) + (eask-print-log-buffer log-buffer) + (kill-buffer log-buffer)))) + +(defun eask-lint-elint--has-error-p () + "Return non-nil if we should report error for exit status." + (and eask--has-warn-p + (eask-strict-p))) (eask-start (require 'elint) @@ -56,7 +62,10 @@ (eask-msg "") (eask-info "(Total of %s file%s %s checked)" (length files) (eask--sinr files "" "s") - (eask--sinr files "has" "have"))) + (eask--sinr files "has" "have")) + ;; Report error. + (when (eask-lint-elint--has-error-p) + (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns (eask-info "(No files match wildcard: %s)" diff --git a/lisp/lint/elsa.el b/lisp/lint/elsa.el index fdc52e16..21392432 100644 --- a/lisp/lint/elsa.el +++ b/lisp/lint/elsa.el @@ -53,11 +53,19 @@ (if errors (--each (reverse errors) (let ((line (string-trim (concat file ":" (elsa-message-format it))))) - (cond ((string-match-p "[: ][Ee]rror:" line) (eask-error line)) - ((string-match-p "[: ][Ww]arning:" line) (eask-warn line)) + (cond ((string-match-p "[: ][Ee]rror:" line) + (eask-error line)) + ((string-match-p "[: ][Ww]arning:" line) + (eask-warn line)) (t (eask-log line))))) (eask-msg "No issues found")))) +(defun eask-lint-elsa--has-error-p () + "Return non-nil if we should report error for exit status." + (or eask--has-error-p + (and eask--has-warn-p + (eask-strict-p)))) + (eask-start ;; Preparation (eask-archive-install-packages '("gnu" "melpa") @@ -77,7 +85,10 @@ (mapcar #'eask-lint-elsa--analyse-file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s"))) + (eask--sinr files "" "s")) + ;; Report error. + (when (eask-lint-elsa--has-error-p) + (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/lisp/lint/indent.el b/lisp/lint/indent.el index dc9e5467..ea6c3e96 100644 --- a/lisp/lint/indent.el +++ b/lisp/lint/indent.el @@ -53,9 +53,10 @@ (bs (buffer-string))) (eask-with-temp-buffer (insert bs)) (eask--silent (indent-region (point-min) (point-max))) - (if (/= tick (buffer-modified-tick)) + (if-let* (((/= tick (buffer-modified-tick))) + (infos (eask-lint-indent--undo-infos buffer-undo-list))) ;; Indentation changed: warn for each line. - (dolist (info (eask-lint-indent--undo-infos buffer-undo-list)) + (dolist (info infos) (let* ((line (nth 0 info)) (column (nth 1 info)) (current (eask-with-buffer @@ -68,9 +69,12 @@ (let* ((patterns (eask-args)) (files (if patterns (eask-expand-file-specs (eask-args)) (eask-package-el-files)))) - (eask-install-dependencies) - (eask-with-verbosity 'debug - (ignore-errors (mapc #'load (eask-package-el-files)))) + ;; XXX: Load all dependencies and elisp files to ensure + ;; all macros' indentation is applied. + (progn + (eask-install-dependencies) + (eask-with-verbosity 'debug + (ignore-errors (mapc #'load (eask-package-el-files))))) (cond ;; Files found, do the action! (files diff --git a/lisp/lint/package.el b/lisp/lint/package.el index 676ddcdc..9ba6d09b 100644 --- a/lisp/lint/package.el +++ b/lisp/lint/package.el @@ -57,6 +57,11 @@ (kill-current-buffer))) (eask-print-log-buffer "*Package-Lint*")) +(defun eask-lint-package--has-error-p () + "Return non-nil if we should report error for exit status." + (and eask--has-warn-p + (eask-strict-p))) + (eask-start ;; Preparation (eask-archive-install-packages '("gnu" "melpa") @@ -77,7 +82,10 @@ (mapcar #'eask-lint-package--file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s"))) + (eask--sinr files "" "s")) + ;; Report error. + (when (eask-lint-package--has-error-p) + (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/lisp/lint/regexps.el b/lisp/lint/regexps.el index 9540863c..5818ef3d 100644 --- a/lisp/lint/regexps.el +++ b/lisp/lint/regexps.el @@ -47,12 +47,13 @@ (with-current-buffer (find-file filename) (setq errors (relint-buffer (current-buffer))) (dolist (err errors) - (let* ((msg (nth 0 err)) - (error-pos (nth 2 err)) - (severity (nth 5 err)) + (let* ((msg (seq-elt err 0)) + (error-pos (seq-elt err 2)) + (severity (seq-elt err 7)) (report-func (pcase severity - (`error #'eask-error) - (`warning #'eask-warn)))) + (`error #'eask-error) + (`warning #'eask-warn) + (_ #'eask-info)))) (funcall report-func "%s:%s %s: %s" file (line-number-at-pos error-pos) (capitalize (eask-2str severity)) msg))) @@ -60,6 +61,11 @@ (eask-msg "No issues found")) (kill-current-buffer)))) +(defun eask-lint-regexps--has-error-p () + "Return non-nil if we should report error for exit status." + (and eask--has-warn-p + (eask-strict-p))) + (eask-start ;; Preparation (eask-archive-install-packages '("gnu") @@ -79,7 +85,10 @@ (mapcar #'eask-lint-regexps--relint-file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s"))) + (eask--sinr files "" "s")) + ;; Report error. + (when (eask-lint-regexps--has-error-p) + (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/test/jest/lint.test.js b/test/jest/lint.test.js new file mode 100644 index 00000000..aeed67b5 --- /dev/null +++ b/test/jest/lint.test.js @@ -0,0 +1,256 @@ +const { TestContext } = require("./helpers"); + +describe("lint", () => { + const ctx = new TestContext("./test/jest/lint"); + + beforeEach(async () => { + await ctx.runEask("clean elc"); + }); + + afterAll(() => { + ctx.cleanUp(); + }); + + describe("partial input", () => { + it("eask lint should error", async () => { + await expect(ctx.runEask("eask lint")).rejects.toMatchObject({ code: 1 }); + }); + }); + + describe("checkdoc", () => { + it("should work on declare-ok.el", async () => { + await expect( + ctx.runEask("lint checkdoc declare-ok.el"), + ).resolves.toMatchObject({ + stderr: expect.stringContaining("No issues found"), + }); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint checkdoc --strict checkdoc-fail.el"), + ).rejects.toMatchObject({ + code: 1, + }); + }); + + it("should error given --strict and --allow-error", async () => { + await expect( + ctx.runEask("lint checkdoc --strict checkdoc-fail.el declare-ok.el"), + ).rejects.toMatchObject({ + code: 1, + // expect that declare-ok was checked too + stderr: expect.stringContaining("`declare-ok.el` with checkdoc"), + }); + }); + }); + + describe("declare", () => { + it("should work on declare-ok.el", async () => { + await expect( + ctx.runEask("lint declare declare-ok.el"), + ).resolves.toMatchObject({ + stderr: expect.stringContaining("No issues found"), + }); + }); + + it("should work on declare-fail.el (warnings ignored)", async () => { + await ctx.runEask("lint declare declare-fail.el"); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint declare --strict declare-fail.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should error given --strict --allow-error", async () => { + await expect( + ctx.runEask("lint declare --strict --allow-error ./*.el"), + ).rejects.toMatchObject({ + code: 1, + // expect that declare-ok was checked too + stderr: expect.stringContaining("`declare-ok.el` with check-declare"), + }); + }); + }); + + describe("elint", () => { + it("should work on declare-ok.el", async () => { + await ctx.runEask("lint elint declare-ok.el"); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint elint --strict checkdoc-fail.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should check both files given --strict --allow-error", async () => { + await expect( + ctx.runEask( + "lint elint --strict --allow-error checkdoc-fail.el declare-ok.el", + ), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("`declare-ok.el` with elint"), + }); + }); + }); + + describe("elisp-lint", () => { + it("should work on elisp-lint-ok.el", async () => { + await ctx.runEask("lint elisp-lint --strict elisp-lint-ok.el"); + }); + + it("should work on declare-ok.el (warnings)", async () => { + await ctx.runEask("lint elisp-lint declare-ok.el"); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint elisp-lint --strict declare-ok.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should work with --strict --allow-error", async () => { + await expect( + ctx.runEask( + "lint elisp-lint --strict --allow-error checkdoc-fail.el elisp-lint-ok.el", + ), + ).rejects.toMatchObject({ + stderr: expect.stringContaining("2 files linted"), + }); + }); + }); + + describe("elsa", () => { + // prints a lot of garbage + // likely an upstream problem, unclear how to fix + it("should work on elisp-lint-ok.el", async () => { + await ctx.runEask("lint elsa elisp-lint-ok.el"); + }); + + it("should work on elsa-warn.el (warnings)", async () => { + await ctx.runEask("lint elsa elsa-warn.el"); + }); + + it("should error on declare-ok.el", async () => { + await expect( + ctx.runEask("lint elsa declare-ok.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint elsa --strict elsa-warn.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should run all files given --allow-error", async () => { + await expect( + ctx.runEask( + "lint elsa --strict --allow-errors elsa-warn.el elisp-lint-ok.el", + ), + ).rejects.toMatchObject({ code: 1 }); + }); + }); + + describe("indent", () => { + it("should work on indent-warn.el", async () => { + await ctx.runEask("lint indent indent-warn.el"); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint indent --strict indent-warn.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should work with --strict --allow-error", async () => { + await expect( + ctx.runEask( + "lint indent --strict --allow-error indent-warn.el declare-ok.el", + ), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("2 files linted"), + }); + }); + }); + + describe("keywords", () => { + // always errors so --strict doesn't matter + // checks only Eask and x-pkg.el, so --allow-error doesn't matter + + it("should error in an empty project", async () => { + const ctxEmpty = new TestContext("./test/jest/lint"); + await expect(ctxEmpty.runEask("lint keywords")).rejects.toThrow(); + }); + + it("should work in keywords-ok", async () => { + const ctxOk = new TestContext("./test/jest/lint/keywords-ok"); + await expect(ctxOk.runEask("lint keywords")).resolves.toMatchObject({ + stderr: expect.stringContaining("No issues found"), + }); + }); + + it("should error in keywords-bad", async () => { + const ctxBad = new TestContext("./test/jest/lint/keywords-bad"); + await expect(ctxBad.runEask("lint keywords")).rejects.toMatchObject({ + stderr: expect.stringContaining("Missing a standard keyword"), + }); + }); + }); + + describe("package", () => { + it("should work on declare-ok.el", async () => { + await ctx.runEask("lint package declare-ok.el"); + }); + + it("should error given --strict", async () => { + await expect( + ctx.runEask("lint package --strict declare-ok.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + // note that all files are checked anyway so --allow-error has no effect + it("should check all files given --allow-error", async () => { + await expect( + ctx.runEask("lint package --allow-error *.el"), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("`declare-ok.el` with package-lint"), + }); + }); + }); + + describe("regexps", () => { + it("should work on declare-ok.el", async () => { + await ctx.runEask("lint regexps declare-ok.el"); + }); + + it("should have warnings on regexp-warn.el", async () => { + await expect( + ctx.runEask("lint regexps regexp-warn.el"), + ).resolves.toMatchObject({ stderr: expect.stringContaining("Warning:") }); + }); + + it("should error on regexp-warn.el with --strict", async () => { + await expect( + ctx.runEask("lint regexps --strict regexp-warn.el"), + ).rejects.toMatchObject({ code: 1 }); + }); + + it("should work with --allow-error", async () => { + await expect( + ctx.runEask( + "lint regexps --allow-error --strict regexp-warn.el declare-ok.el", + ), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("2 files linted"), + }); + }); + }); +}); diff --git a/test/jest/lint/Eask b/test/jest/lint/Eask new file mode 100644 index 00000000..4fed337f --- /dev/null +++ b/test/jest/lint/Eask @@ -0,0 +1,7 @@ +(package "lint" + "0.0.1" + "Test project for lint") +(package-file "lint-pkg.el") + +(source 'gnu) +(source 'melpa) diff --git a/test/jest/lint/checkdoc-fail.el b/test/jest/lint/checkdoc-fail.el new file mode 100644 index 00000000..f521198d --- /dev/null +++ b/test/jest/lint/checkdoc-fail.el @@ -0,0 +1,29 @@ +;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;; Tests for the command ert + +;;; Code: + +(defun my-foo (arg) + ".make a lot of checkdoc errors + +in this " ignore) + +;;; declare-ok.el ends here diff --git a/test/jest/lint/declare-fail.el b/test/jest/lint/declare-fail.el new file mode 100644 index 00000000..2a3207e5 --- /dev/null +++ b/test/jest/lint/declare-fail.el @@ -0,0 +1,24 @@ +;;; declare-fail.el --- Test lint declare -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;;; Code: + +(declare-function not-a-function "subr.el" (x y z)) + +;;; declare-fail.el ends here diff --git a/test/jest/lint/declare-ok.el b/test/jest/lint/declare-ok.el new file mode 100644 index 00000000..70ab1bfe --- /dev/null +++ b/test/jest/lint/declare-ok.el @@ -0,0 +1,26 @@ +;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;; Tests for the command ert + +;;; Code: + +(declare-function ignore "subr.el" (&rest args)) + +;;; declare-ok.el ends here diff --git a/test/jest/lint/elisp-lint-ok.el b/test/jest/lint/elisp-lint-ok.el new file mode 100644 index 00000000..29915e81 --- /dev/null +++ b/test/jest/lint/elisp-lint-ok.el @@ -0,0 +1,21 @@ +;;; elisp-lint-ok.el --- Test the linting -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;;; Version: 0.0.1 +;;; URL: https://foo.com +;;; Package-Requires: ((emacs "28.1")) + +;;; Commentary: + +;; Tests linting with elisp-lint +;; Also clean for packge lint + +;;; Code: + +(defun elisp-lint-ok-foo () + "Nothing here." + (message "ok")) + +(provide 'elisp-lint-ok) +;;; elisp-lint-ok.el ends here diff --git a/test/jest/lint/elsa-warn.el b/test/jest/lint/elsa-warn.el new file mode 100644 index 00000000..d7e9ace4 --- /dev/null +++ b/test/jest/lint/elsa-warn.el @@ -0,0 +1,29 @@ +;;; elsa-warn.el --- Test elsa linting -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;; Test elsa. +;; Should only cause warnings + +;;; Code: + +(defun elsa-warn-foo () + (some-foo) ;; not declared warning + (message "Ok")) + +;;; elsa-warn.el ends here diff --git a/test/jest/lint/indent-warn.el b/test/jest/lint/indent-warn.el new file mode 100644 index 00000000..d2d6156e --- /dev/null +++ b/test/jest/lint/indent-warn.el @@ -0,0 +1,31 @@ +;;; indent-warn.el --- Test indent linting -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;; Test indent. +;; Should only cause warnings + +;;; Code: + +(defun indent-warn-foo () + (if 't + (message "Ok") + (message + "no"))) + +;;; indent-warn.el ends here diff --git a/test/jest/lint/keywords-bad/Eask b/test/jest/lint/keywords-bad/Eask new file mode 100644 index 00000000..9089c7f2 --- /dev/null +++ b/test/jest/lint/keywords-bad/Eask @@ -0,0 +1,15 @@ +;; -*- mode: eask; lexical-binding: t -*- + +(package "keywords-ok" + "1.0.0" + "") + +(keywords "bag" "frog") + +(package-file "keywords-ok.el") + +(script "test" "echo \"Error: no test specified\" && exit 1") + +(source "gnu") + +(depends-on "emacs" "26.1") diff --git a/test/jest/lint/keywords-bad/keywords-ok.el b/test/jest/lint/keywords-bad/keywords-ok.el new file mode 100644 index 00000000..0d110f0b --- /dev/null +++ b/test/jest/lint/keywords-bad/keywords-ok.el @@ -0,0 +1,36 @@ +;;; keywords-ok.el --- summary -*- lexical-binding: t -*- + +;; Author: +;; Maintainer: +;; Version: 1.0.0 +;; Package-Requires: (dependencies) +;; Keywords: frog, bag + + +;; This file is not part of GNU Emacs + +;; This program 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. + +;; This program 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 this program. If not, see . + + +;;; Commentary: + +;; commentary + +;;; Code: + +(message "Hello World!") + +(provide 'keywords-ok) + +;;; keywords-ok.el ends here diff --git a/test/jest/lint/keywords-ok/Eask b/test/jest/lint/keywords-ok/Eask new file mode 100644 index 00000000..a904c514 --- /dev/null +++ b/test/jest/lint/keywords-ok/Eask @@ -0,0 +1,15 @@ +;; -*- mode: eask; lexical-binding: t -*- + +(package "keywords-ok" + "1.0.0" + "") + +(keywords "tools") + +(package-file "keywords-ok.el") + +(script "test" "echo \"Error: no test specified\" && exit 1") + +(source "gnu") + +(depends-on "emacs" "26.1") diff --git a/test/jest/lint/keywords-ok/keywords-ok.el b/test/jest/lint/keywords-ok/keywords-ok.el new file mode 100644 index 00000000..4d8e9d65 --- /dev/null +++ b/test/jest/lint/keywords-ok/keywords-ok.el @@ -0,0 +1,36 @@ +;;; keywords-ok.el --- summary -*- lexical-binding: t -*- + +;; Author: +;; Maintainer: +;; Version: version +;; Package-Requires: (dependencies) +;; Keywords: tools + + +;; This file is not part of GNU Emacs + +;; This program 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. + +;; This program 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 this program. If not, see . + + +;;; Commentary: + +;; commentary + +;;; Code: + +(message "Hello World!") + +(provide 'keywords-ok) + +;;; keywords-ok.el ends here diff --git a/test/jest/lint/regexp-warn.el b/test/jest/lint/regexp-warn.el new file mode 100644 index 00000000..ecfdc2b2 --- /dev/null +++ b/test/jest/lint/regexp-warn.el @@ -0,0 +1,28 @@ +;;; regexp-warn.el --- Test regexp linting -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; This program 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. + +;; This program 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 this program. If not, see . + +;;; Commentary: + +;; Test regexp. +;; Should only cause warnings + +;;; Code: + +(defun regexp-warn-foo () + (re-search-backward "^[.:wrod:]$")) + +;;; regexp-warn.el ends here