From db41412e5475d7ebe6793d080d3934d83369b4f4 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 17:55:12 -0700 Subject: [PATCH 01/13] Move analyze test files to a single directory --- test/jest/__snapshots__/analyze.test.js.snap | 2 +- test/jest/analyze.test.js | 8 ++++---- test/jest/{ => analyze}/dsl/.gitignore | 0 test/jest/{ => analyze}/dsl/Eask | 0 test/jest/{ => analyze}/dsl/check-dsl.el | 0 test/jest/{ => analyze}/metadata/.gitignore | 0 test/jest/{ => analyze}/metadata/Eask | 0 test/jest/{ => analyze}/metadata/check-metadata.el | 0 8 files changed, 5 insertions(+), 5 deletions(-) rename test/jest/{ => analyze}/dsl/.gitignore (100%) rename test/jest/{ => analyze}/dsl/Eask (100%) rename test/jest/{ => analyze}/dsl/check-dsl.el (100%) rename test/jest/{ => analyze}/metadata/.gitignore (100%) rename test/jest/{ => analyze}/metadata/Eask (100%) rename test/jest/{ => analyze}/metadata/check-metadata.el (100%) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index 71298295..54deddd8 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`analyze in ./dsl matches snapshot 1`] = ` +exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` { "stderr": " ~/Eask:9:18 Error: ✗ Multiple definition of \`package' diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index cef00035..0b848e30 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -1,8 +1,8 @@ const { TestContext } = require("./helpers"); describe("analyze", () => { - describe("in ./dsl", () => { - const ctx = new TestContext("./test/jest/dsl"); + describe("in ./analyze/dsl", () => { + const ctx = new TestContext("./test/jest/analyze/dsl"); it("handles plain text", async () => { await ctx.runEask("analyze"); @@ -38,8 +38,8 @@ describe("analyze", () => { }); }); - describe("in ./metadata", () => { - const ctx = new TestContext("./test/jest/metadata"); + describe("in ./analyze/metadata", () => { + const ctx = new TestContext("./test/jest/analyze/metadata"); it("handles plain text", async () => { await ctx.runEask("analyze"); diff --git a/test/jest/dsl/.gitignore b/test/jest/analyze/dsl/.gitignore similarity index 100% rename from test/jest/dsl/.gitignore rename to test/jest/analyze/dsl/.gitignore diff --git a/test/jest/dsl/Eask b/test/jest/analyze/dsl/Eask similarity index 100% rename from test/jest/dsl/Eask rename to test/jest/analyze/dsl/Eask diff --git a/test/jest/dsl/check-dsl.el b/test/jest/analyze/dsl/check-dsl.el similarity index 100% rename from test/jest/dsl/check-dsl.el rename to test/jest/analyze/dsl/check-dsl.el diff --git a/test/jest/metadata/.gitignore b/test/jest/analyze/metadata/.gitignore similarity index 100% rename from test/jest/metadata/.gitignore rename to test/jest/analyze/metadata/.gitignore diff --git a/test/jest/metadata/Eask b/test/jest/analyze/metadata/Eask similarity index 100% rename from test/jest/metadata/Eask rename to test/jest/analyze/metadata/Eask diff --git a/test/jest/metadata/check-metadata.el b/test/jest/analyze/metadata/check-metadata.el similarity index 100% rename from test/jest/metadata/check-metadata.el rename to test/jest/analyze/metadata/check-metadata.el From 51766ed05235c35dde23b92b7b9977caa38f73b3 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Mon, 31 Mar 2025 14:17:04 -0700 Subject: [PATCH 02/13] Port analyze exit-status tests to jest --- test/jest/analyze.test.js | 38 ++++++++++++++++++++++++++++ test/jest/analyze/errors/Eask-error | 2 ++ test/jest/analyze/errors/Eask-normal | 3 +++ test/jest/analyze/errors/Eask-warn | 5 ++++ 4 files changed, 48 insertions(+) create mode 100644 test/jest/analyze/errors/Eask-error create mode 100644 test/jest/analyze/errors/Eask-normal create mode 100644 test/jest/analyze/errors/Eask-warn diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 0b848e30..667e5767 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -51,4 +51,42 @@ describe("analyze", () => { await ctx.runEask("analyze Eask --json"); }); }); + + describe("in ./analyze/errors", () => { + const ctx = new TestContext("./test/jest/analyze/errors"); + + // Eask-normal - no errors or warnings + // Eask-warn - only warnings + // Eask-error - errors and warnings + + it("should check Eask-normal", async () => { + await ctx.runEask("analyze Eask-normal"); + }); + + it("should check Eask-warn", async () => { + await ctx.runEask("analyze Eask-warn"); + }); + + it.failing("should error on Eask-errors", async () => { + await expect(ctx.runEask("analyze Eask-error")).rejects.toThrow(); + }); + + it.failing("should error when using --strict on Eask-warn", async () => { + await expect(ctx.runEask("analyze --strict Eask-warn")).rejects.toThrow(); + }); + + // sanity check: flag should not change behavior in this case + // this is because the menaing of --allow-error is "continue to the end" + it.failing("should error when --allow-error is set", async () => { + await expect( + ctx.runEask("analyze Eask-error --allow-error"), + ).rejects.toThrow(); + }); + + it.failing("should check all files when --allow-error is set", async () => { + await expect( + ctx.runEask("analyze --allow-error Eask-normal Eask-error"), + ).rejects.toMatchObject({ stderr: "(Checked 2 files)" }); + }); + }); }); diff --git a/test/jest/analyze/errors/Eask-error b/test/jest/analyze/errors/Eask-error new file mode 100644 index 00000000..3d2cb3f3 --- /dev/null +++ b/test/jest/analyze/errors/Eask-error @@ -0,0 +1,2 @@ +(package "" "" "") +(scrog "unrecognized") diff --git a/test/jest/analyze/errors/Eask-normal b/test/jest/analyze/errors/Eask-normal new file mode 100644 index 00000000..00169f2d --- /dev/null +++ b/test/jest/analyze/errors/Eask-normal @@ -0,0 +1,3 @@ +;; -*- mode: eask; lexical-binding: t -*- +(package "check-dsl" "0.0.1" "Test for DSL") +(keywords "dsl") diff --git a/test/jest/analyze/errors/Eask-warn b/test/jest/analyze/errors/Eask-warn new file mode 100644 index 00000000..9fdb2623 --- /dev/null +++ b/test/jest/analyze/errors/Eask-warn @@ -0,0 +1,5 @@ +(package "check-dsl" "0.0.1" "Test for DSL") + +(keywords "dsl") + +(package-file "none.el") From 92baf0aaa015657e3faae3ea138463cc3f2b63a0 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 18:23:37 -0700 Subject: [PATCH 03/13] Make analyze --allow-error test more specific --- test/jest/analyze.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 667e5767..ed3116ed 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -83,10 +83,28 @@ describe("analyze", () => { ).rejects.toThrow(); }); + it.failing("should print Checked when there are errors", async () => { + await expect(ctx.runEask("analyze Eask-error")).rejects.toMatchObject({ + stderr: "(Checked 1 file)", + }); + }); + it.failing("should check all files when --allow-error is set", async () => { + // this is not a great test because when there is any error it doesn't print this note await expect( ctx.runEask("analyze --allow-error Eask-normal Eask-error"), ).rejects.toMatchObject({ stderr: "(Checked 2 files)" }); }); + + // although the output does match, it still doesn't exit with an error + it.failing( + "should have later warnings when --allow-error is set", + async () => { + await expect( + ctx.runEask("analyze --allow-error Eask-error Eask-warn"), + // this warning is specific to Eask-warn + ).rejects.toMatchObject({ stderr: "missing `none.el'" }); + }, + ); }); }); From 9b51950122f6680fb2d97be9a8ef932a7681d5ef Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 20:33:04 -0700 Subject: [PATCH 04/13] eask analyze prints to stdout to filter messages --- lisp/core/analyze.el | 17 +++++++---- test/jest/__snapshots__/analyze.test.js.snap | 4 +-- test/jest/analyze.test.js | 30 +++++++++++++++++--- test/jest/analyze/errors/Eask-lexical | 2 ++ 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 test/jest/analyze/errors/Eask-lexical diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index 882c4b55..50ca0890 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -93,18 +93,23 @@ Argument LEVEL and MSG are data from the debug log signal." (t #'eask-analyze--write-plain-text)) level msg)))) +(defun eask-stdout (msg &rest args) + "Like `eask-msg' but prints to stdout." + (eask-princ (apply #'eask--format-paint-kwds msg args) nil) + (eask-princ "\n" nil)) + (defun eask-analyze--file (files) "Lint list of Eask FILES." (let (checked-files content) ;; Linting (dolist (file files) (eask--silent-error - (eask--save-load-eask-file file - (push file checked-files)))) + (eask--save-load-eask-file file + (push file checked-files)))) ;; Print result (eask-msg "") - (cond ((and (eask-json-p) ; JSON format + (cond ((and (eask-json-p) ; JSON format (or eask-analyze--warnings eask-analyze--errors)) (setq content (eask-analyze--pretty-json (json-encode @@ -112,8 +117,8 @@ Argument LEVEL and MSG are data from the debug log signal." (errors . ,eask-analyze--errors))))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (eask-msg content))) - (eask-analyze--log ; Plain text + (eask-stdout content))) + (eask-analyze--log ; Plain text (setq content (with-temp-buffer (dolist (msg (reverse eask-analyze--log)) @@ -121,7 +126,7 @@ Argument LEVEL and MSG are data from the debug log signal." (buffer-string))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (mapc #'eask-msg (reverse eask-analyze--log)))) + (mapc #'eask-stdout (reverse eask-analyze--log)))) (t (eask-info "(Checked %s file%s)" (length checked-files) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index 54deddd8..3ab04b7e 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -3,7 +3,8 @@ exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` { "stderr": " -~/Eask:9:18 Error: ✗ Multiple definition of \`package' +", + "stdout": "~/Eask:9:18 Error: ✗ Multiple definition of \`package' ~/Eask:12:55 Error: ✗ Multiple definition of \`website-url' ~/Eask:14:16 Error: ✗ Multiple definition of \`keywords' ~/Eask:17:15 Warning: 💡 Warning regarding duplicate author name, name @@ -22,6 +23,5 @@ exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` ~/Eask:50:2 Error: ✗ Define dependencies with the same name \`f' ~/Eask:50:2 Error: ✗ Define dependencies with the same name \`f' with different version ", - "stdout": "", } `; diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index ed3116ed..c40da0a8 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -1,5 +1,15 @@ const { TestContext } = require("./helpers"); +/** + * Clean output and attempt to parse as JSON. + * Throws if failing. + * @param {string} s + * @returns {object} the parsed JSON. + */ +function tryJSON(s) { + return JSON.parse(s.trim() || "{}"); +} + describe("analyze", () => { describe("in ./analyze/dsl", () => { const ctx = new TestContext("./test/jest/analyze/dsl"); @@ -10,11 +20,11 @@ describe("analyze", () => { }); it("handles json option", async () => { - const { stderr } = await ctx.runEask("analyze --json"); + const { stdout } = await ctx.runEask("analyze --json"); await ctx.runEask("analyze Eask --json"); // try to parse output, errors if not valid - JSON.parse(stderr); + tryJSON(stdout); }); it("matches snapshot", async () => { @@ -24,9 +34,9 @@ describe("analyze", () => { }); it("should report multiple definitions", async () => { - const { stderr } = await ctx.runEask("analyze"); + const { stdout } = await ctx.runEask("analyze"); // expect this substring - expect(stderr).toMatch("Multiple definition of `package'"); + expect(stdout).toMatch("Multiple definition of `package'"); }); }); @@ -71,6 +81,18 @@ describe("analyze", () => { await expect(ctx.runEask("analyze Eask-error")).rejects.toThrow(); }); + // JSON + it("handles json option when no errors", async () => { + const { stdout } = await ctx.runEask("analyze --json Eask-normal"); + tryJSON(stdout); + }); + + it("handles json option when lexical binding warnings are present", async () => { + const { stdout } = await ctx.runEask("analyze --json Eask-lexical"); + tryJSON(stdout); + }); + + // --strict and --allow-error it.failing("should error when using --strict on Eask-warn", async () => { await expect(ctx.runEask("analyze --strict Eask-warn")).rejects.toThrow(); }); diff --git a/test/jest/analyze/errors/Eask-lexical b/test/jest/analyze/errors/Eask-lexical new file mode 100644 index 00000000..1b2c2e27 --- /dev/null +++ b/test/jest/analyze/errors/Eask-lexical @@ -0,0 +1,2 @@ +(package "check-dsl" "0.0.1" "Test for DSL") +(keywords "dsl") From f4e1a72bcd22501bf24a65e8c9e689490f139433 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 20:35:23 -0700 Subject: [PATCH 05/13] always print checked n files --- lisp/core/analyze.el | 10 +++++----- test/jest/__snapshots__/analyze.test.js.snap | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index 50ca0890..3d85782a 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -126,11 +126,11 @@ Argument LEVEL and MSG are data from the debug log signal." (buffer-string))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (mapc #'eask-stdout (reverse eask-analyze--log)))) - (t - (eask-info "(Checked %s file%s)" - (length checked-files) - (eask--sinr checked-files "" "s")))) + (mapc #'eask-stdout (reverse eask-analyze--log))))) + + (eask-info "(Checked %s file%s)" + (length checked-files) + (eask--sinr checked-files "" "s")) ;; Output file (when (and content (eask-output)) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index 3ab04b7e..18b9e991 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -3,6 +3,8 @@ exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` { "stderr": " + +(Checked 1 file) ", "stdout": "~/Eask:9:18 Error: ✗ Multiple definition of \`package' ~/Eask:12:55 Error: ✗ Multiple definition of \`website-url' From de14f9fe0ba4492ad262d2d7646ae2b0f723b9de Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 22:52:51 -0700 Subject: [PATCH 06/13] exit with 1 if eask analyze finds any errors --- lisp/core/analyze.el | 8 +- test/jest/__snapshots__/analyze.test.js.snap | 298 +++++++++++++++++++ test/jest/analyze.test.js | 80 +++-- test/jest/helpers.js | 4 + 4 files changed, 361 insertions(+), 29 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index 3d85782a..5ef4f464 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -28,6 +28,8 @@ ;; JSON format (defvar eask-analyze--warnings nil) (defvar eask-analyze--errors nil) +;; Error flag +(defvar eask-analyze--error-p nil) (defun eask-analyze--pretty-json (json) "Return pretty JSON." @@ -87,6 +89,8 @@ information." Argument LEVEL and MSG are data from the debug log signal." (unless (string= " *temp*" (buffer-name)) ; avoid error from `package-file' directive + (when (eq 'error level) + (setq eask-analyze--error-p t)) (with-current-buffer (or (eask-analyze--load-buffer) (buffer-name)) (funcall (cond ((eask-json-p) #'eask-analyze--write-json-format) @@ -153,7 +157,9 @@ Argument LEVEL and MSG are data from the debug log signal." (cond ;; Files found, do the action! (files - (eask-analyze--file files)) + (eask-analyze--file files) + (when eask-analyze--error-p + (eask--exit 1))) ;; Pattern defined, but no file found! (patterns (eask-info "(No files match wildcard: %s)" diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index 18b9e991..d364ea9c 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -1,5 +1,303 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`analyze in ./analyze/dsl handles json option 1`] = ` +"{ + "warnings": [ + { + "range": { + "start": { + "line": 25, + "col": 0, + "pos": 853 + }, + "end": { + "line": 25, + "col": 35, + "pos": 888 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "💡 Pkg-file seems to be missing \`check-pkg.el'" + }, + { + "range": { + "start": { + "line": 20, + "col": 0, + "pos": 709 + }, + "end": { + "line": 20, + "col": 17, + "pos": 726 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "💡 Warning regarding duplicate license name, GPLv3" + }, + { + "range": { + "start": { + "line": 17, + "col": 0, + "pos": 613 + }, + "end": { + "line": 17, + "col": 15, + "pos": 628 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "💡 Warning regarding duplicate author name, name" + } + ], + "errors": [ + { + "range": { + "start": { + "line": 46, + "col": 0, + "pos": 1696 + }, + "end": { + "line": 50, + "col": 2, + "pos": 1908 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Define dependencies with the same name \`f' with different version" + }, + { + "range": { + "start": { + "line": 46, + "col": 0, + "pos": 1696 + }, + "end": { + "line": 50, + "col": 2, + "pos": 1908 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Define dependencies with the same name \`f'" + }, + { + "range": { + "start": { + "line": 44, + "col": 0, + "pos": 1596 + }, + "end": { + "line": 44, + "col": 27, + "pos": 1623 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Define dependencies with the same name \`dash' with different version" + }, + { + "range": { + "start": { + "line": 43, + "col": 0, + "pos": 1576 + }, + "end": { + "line": 43, + "col": 19, + "pos": 1595 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Define dependencies with the same name \`dash'" + }, + { + "range": { + "start": { + "line": 40, + "col": 0, + "pos": 1474 + }, + "end": { + "line": 40, + "col": 20, + "pos": 1494 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Define dependencies with the same name \`emacs'" + }, + { + "range": { + "start": { + "line": 37, + "col": 0, + "pos": 1304 + }, + "end": { + "line": 37, + "col": 15, + "pos": 1319 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Unknown package archive \`local'" + }, + { + "range": { + "start": { + "line": 37, + "col": 0, + "pos": 1304 + }, + "end": { + "line": 37, + "col": 15, + "pos": 1319 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Invalid archive name \`local'" + }, + { + "range": { + "start": { + "line": 35, + "col": 0, + "pos": 1229 + }, + "end": { + "line": 35, + "col": 24, + "pos": 1253 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Unknown package archive \`magic-archive'" + }, + { + "range": { + "start": { + "line": 33, + "col": 0, + "pos": 1214 + }, + "end": { + "line": 33, + "col": 13, + "pos": 1227 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of source \`gnu'" + }, + { + "range": { + "start": { + "line": 30, + "col": 0, + "pos": 1073 + }, + "end": { + "line": 30, + "col": 61, + "pos": 1134 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Run-script with the same key name is not allowed: \`test\`" + }, + { + "range": { + "start": { + "line": 26, + "col": 0, + "pos": 953 + }, + "end": { + "line": 26, + "col": 35, + "pos": 988 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of \`package-descriptor'" + }, + { + "range": { + "start": { + "line": 23, + "col": 0, + "pos": 822 + }, + "end": { + "line": 23, + "col": 29, + "pos": 851 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of \`package-file'" + }, + { + "range": { + "start": { + "line": 14, + "col": 0, + "pos": 517 + }, + "end": { + "line": 14, + "col": 16, + "pos": 533 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of \`keywords'" + }, + { + "range": { + "start": { + "line": 12, + "col": 0, + "pos": 383 + }, + "end": { + "line": 12, + "col": 55, + "pos": 438 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of \`website-url'" + }, + { + "range": { + "start": { + "line": 9, + "col": 0, + "pos": 290 + }, + "end": { + "line": 9, + "col": 18, + "pos": 308 + } + }, + "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", + "message": "✗ Multiple definition of \`package'" + } + ] +} +" +`; + exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` { "stderr": " diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index c40da0a8..c0bff5c4 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -15,28 +15,41 @@ describe("analyze", () => { const ctx = new TestContext("./test/jest/analyze/dsl"); it("handles plain text", async () => { - await ctx.runEask("analyze"); - await ctx.runEask("analyze Eask"); + await expect(ctx.runEask("analyze")).rejects.toThrow(); + await expect(ctx.runEask("analyze Eask")).rejects.toThrow(); }); it("handles json option", async () => { - const { stdout } = await ctx.runEask("analyze --json"); - await ctx.runEask("analyze Eask --json"); - - // try to parse output, errors if not valid - tryJSON(stdout); + // alternate command order + await expect(ctx.runEask("analyze Eask --json")).rejects.toThrow(); + try { + await ctx.runEask("analyze --json"); + } catch (e) { + tryJSON(e.stdout); + expect(e.stdout).toMatchSnapshot(); + } }); it("matches snapshot", async () => { - const res = await ctx.runEask("analyze"); - const resClean = res.sanitized().raw(); - expect(resClean).toMatchSnapshot(); + try { + await ctx.runEask("analyze"); + expect.failing(); + } catch (e) { + expect(e.code).toBe(1); + const res = ctx.errorToCommandOutput(e); + const resClean = res.sanitized().raw(); + expect(resClean).toMatchSnapshot(); + } }); it("should report multiple definitions", async () => { - const { stdout } = await ctx.runEask("analyze"); - // expect this substring - expect(stdout).toMatch("Multiple definition of `package'"); + try { + await ctx.runEask("analyze"); + expect.failing(); + } catch ({ stdout }) { + // expect this substring + expect(stdout).toMatch("Multiple definition of `package'"); + } }); }); @@ -52,13 +65,23 @@ describe("analyze", () => { const ctx = new TestContext("./test/jest/analyze/metadata"); it("handles plain text", async () => { - await ctx.runEask("analyze"); - await ctx.runEask("analyze Eask"); + await expect(ctx.runEask("analyze")).rejects.toThrow(); + await expect(ctx.runEask("analyze Eask")).rejects.toThrow( + expect.objectContaining({ + code: 1, + stderr: expect.stringContaining("(Checked 1 file)"), + }), + ); }); it("handles json", async () => { - await ctx.runEask("analyze --json"); - await ctx.runEask("analyze Eask --json"); + await expect(ctx.runEask("analyze --json")).rejects.toThrow(); + await expect(ctx.runEask("analyze Eask --json")).rejects.toThrow( + expect.objectContaining({ + code: 1, + stderr: expect.stringContaining("(Checked 1 file)"), + }), + ); }); }); @@ -77,7 +100,7 @@ describe("analyze", () => { await ctx.runEask("analyze Eask-warn"); }); - it.failing("should error on Eask-errors", async () => { + it("should error on Eask-errors", async () => { await expect(ctx.runEask("analyze Eask-error")).rejects.toThrow(); }); @@ -99,18 +122,20 @@ describe("analyze", () => { // sanity check: flag should not change behavior in this case // this is because the menaing of --allow-error is "continue to the end" - it.failing("should error when --allow-error is set", async () => { + it("should error when --allow-error is set", async () => { await expect( ctx.runEask("analyze Eask-error --allow-error"), ).rejects.toThrow(); }); + // TODO prints 0 for some reason it.failing("should print Checked when there are errors", async () => { await expect(ctx.runEask("analyze Eask-error")).rejects.toMatchObject({ stderr: "(Checked 1 file)", }); }); + // TODO prints 1 for some reason it.failing("should check all files when --allow-error is set", async () => { // this is not a great test because when there is any error it doesn't print this note await expect( @@ -119,14 +144,13 @@ describe("analyze", () => { }); // although the output does match, it still doesn't exit with an error - it.failing( - "should have later warnings when --allow-error is set", - async () => { - await expect( - ctx.runEask("analyze --allow-error Eask-error Eask-warn"), - // this warning is specific to Eask-warn - ).rejects.toMatchObject({ stderr: "missing `none.el'" }); - }, - ); + it("should have later warnings when --allow-error is set", async () => { + await expect( + ctx.runEask("analyze --allow-error Eask-error Eask-warn"), + // this warning is specific to Eask-warn + ).rejects.toMatchObject({ + stdout: expect.stringContaining("missing `none.el'"), + }); + }); }); }); diff --git a/test/jest/helpers.js b/test/jest/helpers.js index 31980c8f..d23488af 100644 --- a/test/jest/helpers.js +++ b/test/jest/helpers.js @@ -241,6 +241,10 @@ class TestContext { .catch(() => {}); // ignore "does not exist errors" } } + + errorToCommandOutput(e) { + return new CommandOutput(e, this.cwd); + } } module.exports = { From aa45fa86038926f321404a13900836d4ecc25a1c Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 22:58:31 -0700 Subject: [PATCH 07/13] Fix counting bug --- lisp/core/analyze.el | 1 + test/jest/analyze.test.js | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index 5ef4f464..fc71c99d 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -109,6 +109,7 @@ Argument LEVEL and MSG are data from the debug log signal." (dolist (file files) (eask--silent-error (eask--save-load-eask-file file + (push file checked-files) (push file checked-files)))) ;; Print result diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index c0bff5c4..22582b2a 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -76,12 +76,10 @@ describe("analyze", () => { it("handles json", async () => { await expect(ctx.runEask("analyze --json")).rejects.toThrow(); - await expect(ctx.runEask("analyze Eask --json")).rejects.toThrow( - expect.objectContaining({ - code: 1, - stderr: expect.stringContaining("(Checked 1 file)"), - }), - ); + await expect(ctx.runEask("analyze Eask --json")).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("(Checked 1 file)"), + }); }); }); @@ -128,19 +126,19 @@ describe("analyze", () => { ).rejects.toThrow(); }); - // TODO prints 0 for some reason - it.failing("should print Checked when there are errors", async () => { + it("should print Checked when there are errors", async () => { await expect(ctx.runEask("analyze Eask-error")).rejects.toMatchObject({ - stderr: "(Checked 1 file)", + stderr: expect.stringContaining("(Checked 1 file)"), }); }); - // TODO prints 1 for some reason - it.failing("should check all files when --allow-error is set", async () => { + it("should check all files when --allow-error is set", async () => { // this is not a great test because when there is any error it doesn't print this note await expect( ctx.runEask("analyze --allow-error Eask-normal Eask-error"), - ).rejects.toMatchObject({ stderr: "(Checked 2 files)" }); + ).rejects.toMatchObject({ + stderr: expect.stringContaining("(Checked 2 files)"), + }); }); // although the output does match, it still doesn't exit with an error From dd0b63127054bc1f4ba2c7e2b96c4375437cb765 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 31 Oct 2025 23:13:32 -0700 Subject: [PATCH 08/13] Print empty json when no errors --- lisp/core/analyze.el | 14 +++++++------- test/jest/analyze.test.js | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index fc71c99d..bd906c56 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -114,15 +114,15 @@ Argument LEVEL and MSG are data from the debug log signal." ;; Print result (eask-msg "") - (cond ((and (eask-json-p) ; JSON format - (or eask-analyze--warnings eask-analyze--errors)) - (setq content - (eask-analyze--pretty-json (json-encode - `((warnings . ,eask-analyze--warnings) - (errors . ,eask-analyze--errors))))) + (cond ((eask-json-p) ; JSON format + (when (or eask-analyze--warnings eask-analyze--errors) + (setq content + (eask-analyze--pretty-json (json-encode + `((warnings . ,eask-analyze--warnings) + (errors . ,eask-analyze--errors)))))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (eask-stdout content))) + (eask-stdout (or content "{}")))) (eask-analyze--log ; Plain text (setq content (with-temp-buffer diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 22582b2a..03bdb806 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -2,12 +2,13 @@ const { TestContext } = require("./helpers"); /** * Clean output and attempt to parse as JSON. + * Does not accept empty strings as JSON. * Throws if failing. * @param {string} s * @returns {object} the parsed JSON. */ function tryJSON(s) { - return JSON.parse(s.trim() || "{}"); + return JSON.parse(s.trim()); } describe("analyze", () => { From 4f2ad6282093bac9c09fbd5d1b7320aefa485775 Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sat, 1 Nov 2025 17:17:49 +0800 Subject: [PATCH 09/13] chore: minor improvements --- lisp/core/analyze.el | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index bd906c56..daf571b3 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -37,8 +37,9 @@ (defun eask-analyze--load-buffer () "Return the current file loading session." - (car (cl-remove-if-not - (lambda (elm) (string-prefix-p " *load*-" (buffer-name elm))) (buffer-list)))) + (car (cl-remove-if-not (lambda (elm) + (string-prefix-p " *load*-" (buffer-name elm))) + (buffer-list)))) (defun eask-analyze--write-json-format (level msg) "Prepare log for JSON format. @@ -98,7 +99,9 @@ Argument LEVEL and MSG are data from the debug log signal." level msg)))) (defun eask-stdout (msg &rest args) - "Like `eask-msg' but prints to stdout." + "Like `eask-msg' but prints to stdout. + +For arguments MSG and ARGS, please see function `eask-msg' for the " (eask-princ (apply #'eask--format-paint-kwds msg args) nil) (eask-princ "\n" nil)) @@ -108,13 +111,13 @@ Argument LEVEL and MSG are data from the debug log signal." ;; Linting (dolist (file files) (eask--silent-error - (eask--save-load-eask-file file - (push file checked-files) - (push file checked-files)))) + (eask--save-load-eask-file file + (push file checked-files)))) ;; Print result (eask-msg "") - (cond ((eask-json-p) ; JSON format + (cond ((eask-json-p) ; JSON format + ;; Fill content with result. (when (or eask-analyze--warnings eask-analyze--errors) (setq content (eask-analyze--pretty-json (json-encode @@ -122,8 +125,8 @@ Argument LEVEL and MSG are data from the debug log signal." (errors . ,eask-analyze--errors)))))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (eask-stdout (or content "{}")))) - (eask-analyze--log ; Plain text + (eask-stdout (or content "{}")))) + (eask-analyze--log ; Plain text (setq content (with-temp-buffer (dolist (msg (reverse eask-analyze--log)) @@ -131,7 +134,7 @@ Argument LEVEL and MSG are data from the debug log signal." (buffer-string))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (mapc #'eask-stdout (reverse eask-analyze--log))))) + (mapc #'eask-stdout (reverse eask-analyze--log))))) (eask-info "(Checked %s file%s)" (length checked-files) @@ -160,7 +163,7 @@ Argument LEVEL and MSG are data from the debug log signal." (files (eask-analyze--file files) (when eask-analyze--error-p - (eask--exit 1))) + (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns (eask-info "(No files match wildcard: %s)" From 691182e04efac995e05aa060dbbe515e1ce4f8a1 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Wed, 5 Nov 2025 11:04:46 -0800 Subject: [PATCH 10/13] revert: eask analyze prints to stdout to filter messages JSON now printed without pretty-printing to ease testing --- lisp/core/analyze.el | 20 +- test/jest/__snapshots__/analyze.test.js.snap | 304 +------------------ test/jest/analyze.test.js | 35 ++- 3 files changed, 37 insertions(+), 322 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index daf571b3..bd186caa 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -98,13 +98,6 @@ Argument LEVEL and MSG are data from the debug log signal." (t #'eask-analyze--write-plain-text)) level msg)))) -(defun eask-stdout (msg &rest args) - "Like `eask-msg' but prints to stdout. - -For arguments MSG and ARGS, please see function `eask-msg' for the " - (eask-princ (apply #'eask--format-paint-kwds msg args) nil) - (eask-princ "\n" nil)) - (defun eask-analyze--file (files) "Lint list of Eask FILES." (let (checked-files content) @@ -112,6 +105,8 @@ For arguments MSG and ARGS, please see function `eask-msg' for the " (dolist (file files) (eask--silent-error (eask--save-load-eask-file file + (push file checked-files) + ;; also count files with errors in the total count (push file checked-files)))) ;; Print result @@ -119,13 +114,12 @@ For arguments MSG and ARGS, please see function `eask-msg' for the " (cond ((eask-json-p) ; JSON format ;; Fill content with result. (when (or eask-analyze--warnings eask-analyze--errors) - (setq content - (eask-analyze--pretty-json (json-encode - `((warnings . ,eask-analyze--warnings) - (errors . ,eask-analyze--errors)))))) + (setq content (json-encode + `((warnings . ,eask-analyze--warnings) + (errors . ,eask-analyze--errors))))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (eask-stdout (or content "{}")))) + (eask-msg (or content "{}")))) (eask-analyze--log ; Plain text (setq content (with-temp-buffer @@ -134,7 +128,7 @@ For arguments MSG and ARGS, please see function `eask-msg' for the " (buffer-string))) ;; XXX: When printing the result, no color allow. (eask--with-no-color - (mapc #'eask-stdout (reverse eask-analyze--log))))) + (mapc #'eask-msg (reverse eask-analyze--log))))) (eask-info "(Checked %s file%s)" (length checked-files) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index d364ea9c..6a12f930 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -1,310 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`analyze in ./analyze/dsl handles json option 1`] = ` -"{ - "warnings": [ - { - "range": { - "start": { - "line": 25, - "col": 0, - "pos": 853 - }, - "end": { - "line": 25, - "col": 35, - "pos": 888 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "💡 Pkg-file seems to be missing \`check-pkg.el'" - }, - { - "range": { - "start": { - "line": 20, - "col": 0, - "pos": 709 - }, - "end": { - "line": 20, - "col": 17, - "pos": 726 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "💡 Warning regarding duplicate license name, GPLv3" - }, - { - "range": { - "start": { - "line": 17, - "col": 0, - "pos": 613 - }, - "end": { - "line": 17, - "col": 15, - "pos": 628 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "💡 Warning regarding duplicate author name, name" - } - ], - "errors": [ - { - "range": { - "start": { - "line": 46, - "col": 0, - "pos": 1696 - }, - "end": { - "line": 50, - "col": 2, - "pos": 1908 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Define dependencies with the same name \`f' with different version" - }, - { - "range": { - "start": { - "line": 46, - "col": 0, - "pos": 1696 - }, - "end": { - "line": 50, - "col": 2, - "pos": 1908 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Define dependencies with the same name \`f'" - }, - { - "range": { - "start": { - "line": 44, - "col": 0, - "pos": 1596 - }, - "end": { - "line": 44, - "col": 27, - "pos": 1623 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Define dependencies with the same name \`dash' with different version" - }, - { - "range": { - "start": { - "line": 43, - "col": 0, - "pos": 1576 - }, - "end": { - "line": 43, - "col": 19, - "pos": 1595 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Define dependencies with the same name \`dash'" - }, - { - "range": { - "start": { - "line": 40, - "col": 0, - "pos": 1474 - }, - "end": { - "line": 40, - "col": 20, - "pos": 1494 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Define dependencies with the same name \`emacs'" - }, - { - "range": { - "start": { - "line": 37, - "col": 0, - "pos": 1304 - }, - "end": { - "line": 37, - "col": 15, - "pos": 1319 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Unknown package archive \`local'" - }, - { - "range": { - "start": { - "line": 37, - "col": 0, - "pos": 1304 - }, - "end": { - "line": 37, - "col": 15, - "pos": 1319 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Invalid archive name \`local'" - }, - { - "range": { - "start": { - "line": 35, - "col": 0, - "pos": 1229 - }, - "end": { - "line": 35, - "col": 24, - "pos": 1253 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Unknown package archive \`magic-archive'" - }, - { - "range": { - "start": { - "line": 33, - "col": 0, - "pos": 1214 - }, - "end": { - "line": 33, - "col": 13, - "pos": 1227 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of source \`gnu'" - }, - { - "range": { - "start": { - "line": 30, - "col": 0, - "pos": 1073 - }, - "end": { - "line": 30, - "col": 61, - "pos": 1134 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Run-script with the same key name is not allowed: \`test\`" - }, - { - "range": { - "start": { - "line": 26, - "col": 0, - "pos": 953 - }, - "end": { - "line": 26, - "col": 35, - "pos": 988 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of \`package-descriptor'" - }, - { - "range": { - "start": { - "line": 23, - "col": 0, - "pos": 822 - }, - "end": { - "line": 23, - "col": 29, - "pos": 851 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of \`package-file'" - }, - { - "range": { - "start": { - "line": 14, - "col": 0, - "pos": 517 - }, - "end": { - "line": 14, - "col": 16, - "pos": 533 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of \`keywords'" - }, - { - "range": { - "start": { - "line": 12, - "col": 0, - "pos": 383 - }, - "end": { - "line": 12, - "col": 55, - "pos": 438 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of \`website-url'" - }, - { - "range": { - "start": { - "line": 9, - "col": 0, - "pos": 290 - }, - "end": { - "line": 9, - "col": 18, - "pos": 308 - } - }, - "filename": "/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask", - "message": "✗ Multiple definition of \`package'" - } - ] -} +" +{"warnings":[{"range":{"start":{"line":25,"col":0,"pos":853},"end":{"line":25,"col":35,"pos":888}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Pkg-file seems to be missing \`check-pkg.el'"},{"range":{"start":{"line":20,"col":0,"pos":709},"end":{"line":20,"col":17,"pos":726}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Warning regarding duplicate license name, GPLv3"},{"range":{"start":{"line":17,"col":0,"pos":613},"end":{"line":17,"col":15,"pos":628}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Warning regarding duplicate author name, name"}],"errors":[{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`f' with different version"},{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`f'"},{"range":{"start":{"line":44,"col":0,"pos":1596},"end":{"line":44,"col":27,"pos":1623}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`dash' with different version"},{"range":{"start":{"line":43,"col":0,"pos":1576},"end":{"line":43,"col":19,"pos":1595}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`dash'"},{"range":{"start":{"line":40,"col":0,"pos":1474},"end":{"line":40,"col":20,"pos":1494}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`emacs'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Unknown package archive \`local'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Invalid archive name \`local'"},{"range":{"start":{"line":35,"col":0,"pos":1229},"end":{"line":35,"col":24,"pos":1253}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Unknown package archive \`magic-archive'"},{"range":{"start":{"line":33,"col":0,"pos":1214},"end":{"line":33,"col":13,"pos":1227}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of source \`gnu'"},{"range":{"start":{"line":30,"col":0,"pos":1073},"end":{"line":30,"col":61,"pos":1134}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Run-script with the same key name is not allowed: \`test\`"},{"range":{"start":{"line":26,"col":0,"pos":953},"end":{"line":26,"col":35,"pos":988}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package-descriptor'"},{"range":{"start":{"line":23,"col":0,"pos":822},"end":{"line":23,"col":29,"pos":851}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package-file'"},{"range":{"start":{"line":14,"col":0,"pos":517},"end":{"line":14,"col":16,"pos":533}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`keywords'"},{"range":{"start":{"line":12,"col":0,"pos":383},"end":{"line":12,"col":55,"pos":438}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`website-url'"},{"range":{"start":{"line":9,"col":0,"pos":290},"end":{"line":9,"col":18,"pos":308}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package'"}]} +(Checked 1 file) " `; exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` { "stderr": " - -(Checked 1 file) -", - "stdout": "~/Eask:9:18 Error: ✗ Multiple definition of \`package' +~/Eask:9:18 Error: ✗ Multiple definition of \`package' ~/Eask:12:55 Error: ✗ Multiple definition of \`website-url' ~/Eask:14:16 Error: ✗ Multiple definition of \`keywords' ~/Eask:17:15 Warning: 💡 Warning regarding duplicate author name, name @@ -322,6 +28,8 @@ exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` ~/Eask:44:27 Error: ✗ Define dependencies with the same name \`dash' with different version ~/Eask:50:2 Error: ✗ Define dependencies with the same name \`f' ~/Eask:50:2 Error: ✗ Define dependencies with the same name \`f' with different version +(Checked 1 file) ", + "stdout": "", } `; diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 03bdb806..c72c0f14 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -2,13 +2,26 @@ const { TestContext } = require("./helpers"); /** * Clean output and attempt to parse as JSON. - * Does not accept empty strings as JSON. * Throws if failing. * @param {string} s * @returns {object} the parsed JSON. */ function tryJSON(s) { - return JSON.parse(s.trim()); + // The main use case of analyze --json is flycheck/flymake + // both of which accept mixed JSON/text output. + // So the test should filter non-JSON output in a similar way + // See flycheck--json-parser for reference + const lines = s.split("\n"); + const json = lines.filter((x) => x.startsWith("{") || x.startsWith("[")); + if (json.length > 1) { + console.warn("command produced multiple JSON objects as output"); + } + + if (json.length == 0) { + return {}; + } else { + return JSON.parse(json[0]); + } } describe("analyze", () => { @@ -26,8 +39,8 @@ describe("analyze", () => { try { await ctx.runEask("analyze --json"); } catch (e) { - tryJSON(e.stdout); - expect(e.stdout).toMatchSnapshot(); + tryJSON(e.stderr); + expect(e.stderr).toMatchSnapshot(); } }); @@ -47,9 +60,9 @@ describe("analyze", () => { try { await ctx.runEask("analyze"); expect.failing(); - } catch ({ stdout }) { + } catch ({ stderr }) { // expect this substring - expect(stdout).toMatch("Multiple definition of `package'"); + expect(stderr).toMatch("Multiple definition of `package'"); } }); }); @@ -105,13 +118,13 @@ describe("analyze", () => { // JSON it("handles json option when no errors", async () => { - const { stdout } = await ctx.runEask("analyze --json Eask-normal"); - tryJSON(stdout); + const { stderr } = await ctx.runEask("analyze --json Eask-normal"); + tryJSON(stderr); }); it("handles json option when lexical binding warnings are present", async () => { - const { stdout } = await ctx.runEask("analyze --json Eask-lexical"); - tryJSON(stdout); + const { stderr } = await ctx.runEask("analyze --json Eask-lexical"); + tryJSON(stderr); }); // --strict and --allow-error @@ -148,7 +161,7 @@ describe("analyze", () => { ctx.runEask("analyze --allow-error Eask-error Eask-warn"), // this warning is specific to Eask-warn ).rejects.toMatchObject({ - stdout: expect.stringContaining("missing `none.el'"), + stderr: expect.stringContaining("missing `none.el'"), }); }); }); From fff8e0b60271d384a7a0c24139a9c51b0f27efb3 Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Wed, 5 Nov 2025 11:09:08 -0800 Subject: [PATCH 11/13] Fix unsanitized JSON snapshot --- test/jest/__snapshots__/analyze.test.js.snap | 9 ++++++--- test/jest/analyze.test.js | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index 6a12f930..f0a61444 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -1,10 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`analyze in ./analyze/dsl handles json option 1`] = ` -" -{"warnings":[{"range":{"start":{"line":25,"col":0,"pos":853},"end":{"line":25,"col":35,"pos":888}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Pkg-file seems to be missing \`check-pkg.el'"},{"range":{"start":{"line":20,"col":0,"pos":709},"end":{"line":20,"col":17,"pos":726}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Warning regarding duplicate license name, GPLv3"},{"range":{"start":{"line":17,"col":0,"pos":613},"end":{"line":17,"col":15,"pos":628}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"💡 Warning regarding duplicate author name, name"}],"errors":[{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`f' with different version"},{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`f'"},{"range":{"start":{"line":44,"col":0,"pos":1596},"end":{"line":44,"col":27,"pos":1623}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`dash' with different version"},{"range":{"start":{"line":43,"col":0,"pos":1576},"end":{"line":43,"col":19,"pos":1595}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`dash'"},{"range":{"start":{"line":40,"col":0,"pos":1474},"end":{"line":40,"col":20,"pos":1494}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Define dependencies with the same name \`emacs'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Unknown package archive \`local'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Invalid archive name \`local'"},{"range":{"start":{"line":35,"col":0,"pos":1229},"end":{"line":35,"col":24,"pos":1253}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Unknown package archive \`magic-archive'"},{"range":{"start":{"line":33,"col":0,"pos":1214},"end":{"line":33,"col":13,"pos":1227}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of source \`gnu'"},{"range":{"start":{"line":30,"col":0,"pos":1073},"end":{"line":30,"col":61,"pos":1134}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Run-script with the same key name is not allowed: \`test\`"},{"range":{"start":{"line":26,"col":0,"pos":953},"end":{"line":26,"col":35,"pos":988}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package-descriptor'"},{"range":{"start":{"line":23,"col":0,"pos":822},"end":{"line":23,"col":29,"pos":851}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package-file'"},{"range":{"start":{"line":14,"col":0,"pos":517},"end":{"line":14,"col":16,"pos":533}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`keywords'"},{"range":{"start":{"line":12,"col":0,"pos":383},"end":{"line":12,"col":55,"pos":438}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`website-url'"},{"range":{"start":{"line":9,"col":0,"pos":290},"end":{"line":9,"col":18,"pos":308}},"filename":"/home/naver/git/eask-cli/test/jest/analyze/dsl/Eask","message":"✗ Multiple definition of \`package'"}]} +{ + "stderr": " +{"warnings":[{"range":{"start":{"line":25,"col":0,"pos":853},"end":{"line":25,"col":35,"pos":888}},"filename":"~/Eask","message":"💡 Pkg-file seems to be missing \`check-pkg.el'"},{"range":{"start":{"line":20,"col":0,"pos":709},"end":{"line":20,"col":17,"pos":726}},"filename":"~/Eask","message":"💡 Warning regarding duplicate license name, GPLv3"},{"range":{"start":{"line":17,"col":0,"pos":613},"end":{"line":17,"col":15,"pos":628}},"filename":"~/Eask","message":"💡 Warning regarding duplicate author name, name"}],"errors":[{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`f' with different version"},{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`f'"},{"range":{"start":{"line":44,"col":0,"pos":1596},"end":{"line":44,"col":27,"pos":1623}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`dash' with different version"},{"range":{"start":{"line":43,"col":0,"pos":1576},"end":{"line":43,"col":19,"pos":1595}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`dash'"},{"range":{"start":{"line":40,"col":0,"pos":1474},"end":{"line":40,"col":20,"pos":1494}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`emacs'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"~/Eask","message":"✗ Unknown package archive \`local'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"~/Eask","message":"✗ Invalid archive name \`local'"},{"range":{"start":{"line":35,"col":0,"pos":1229},"end":{"line":35,"col":24,"pos":1253}},"filename":"~/Eask","message":"✗ Unknown package archive \`magic-archive'"},{"range":{"start":{"line":33,"col":0,"pos":1214},"end":{"line":33,"col":13,"pos":1227}},"filename":"~/Eask","message":"✗ Multiple definition of source \`gnu'"},{"range":{"start":{"line":30,"col":0,"pos":1073},"end":{"line":30,"col":61,"pos":1134}},"filename":"~/Eask","message":"✗ Run-script with the same key name is not allowed: \`test\`"},{"range":{"start":{"line":26,"col":0,"pos":953},"end":{"line":26,"col":35,"pos":988}},"filename":"~/Eask","message":"✗ Multiple definition of \`package-descriptor'"},{"range":{"start":{"line":23,"col":0,"pos":822},"end":{"line":23,"col":29,"pos":851}},"filename":"~/Eask","message":"✗ Multiple definition of \`package-file'"},{"range":{"start":{"line":14,"col":0,"pos":517},"end":{"line":14,"col":16,"pos":533}},"filename":"~/Eask","message":"✗ Multiple definition of \`keywords'"},{"range":{"start":{"line":12,"col":0,"pos":383},"end":{"line":12,"col":55,"pos":438}},"filename":"~/Eask","message":"✗ Multiple definition of \`website-url'"},{"range":{"start":{"line":9,"col":0,"pos":290},"end":{"line":9,"col":18,"pos":308}},"filename":"~/Eask","message":"✗ Multiple definition of \`package'"}]} (Checked 1 file) -" +", + "stdout": "", +} `; exports[`analyze in ./analyze/dsl matches snapshot 1`] = ` diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index c72c0f14..0eebc7bd 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -40,7 +40,9 @@ describe("analyze", () => { await ctx.runEask("analyze --json"); } catch (e) { tryJSON(e.stderr); - expect(e.stderr).toMatchSnapshot(); + const res = ctx.errorToCommandOutput(e); + const resClean = res.sanitized().raw(); + expect(resClean).toMatchSnapshot(); } }); From 826b058f3f108e3abc2ea249b3777273de90779d Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Wed, 5 Nov 2025 11:29:34 -0800 Subject: [PATCH 12/13] --strict flag exits with code 1 --- lisp/core/analyze.el | 9 ++++++++- test/jest/analyze.test.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index bd186caa..58158ea6 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -28,6 +28,9 @@ ;; JSON format (defvar eask-analyze--warnings nil) (defvar eask-analyze--errors nil) + +;; Warning flag +(defvar eask-analyze--warning-p nil) ;; Error flag (defvar eask-analyze--error-p nil) @@ -92,6 +95,8 @@ Argument LEVEL and MSG are data from the debug log signal." (unless (string= " *temp*" (buffer-name)) ; avoid error from `package-file' directive (when (eq 'error level) (setq eask-analyze--error-p t)) + (when (eq 'warn level) + (setq eask-analyze--warning-p t)) (with-current-buffer (or (eask-analyze--load-buffer) (buffer-name)) (funcall (cond ((eask-json-p) #'eask-analyze--write-json-format) @@ -156,7 +161,9 @@ Argument LEVEL and MSG are data from the debug log signal." ;; Files found, do the action! (files (eask-analyze--file files) - (when eask-analyze--error-p + (when (or eask-analyze--error-p + ;; strict flag turns warnings into errors + (and eask-analyze--warning-p (eask-strict-p))) (eask--exit 'failure))) ;; Pattern defined, but no file found! (patterns diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 0eebc7bd..03cf34a4 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -130,7 +130,7 @@ describe("analyze", () => { }); // --strict and --allow-error - it.failing("should error when using --strict on Eask-warn", async () => { + it("should error when using --strict on Eask-warn", async () => { await expect(ctx.runEask("analyze --strict Eask-warn")).rejects.toThrow(); }); From 0fc0e05281aaa7db9d7b8fdb83b01be8d9b97b9f Mon Sep 17 00:00:00 2001 From: Josh Bax Date: Fri, 7 Nov 2025 11:36:11 -0800 Subject: [PATCH 13/13] pretty-print JSON in analyze output --- lisp/core/analyze.el | 7 +- test/jest/__snapshots__/analyze.test.js.snap | 295 ++++++++++++++++++- test/jest/analyze.test.js | 19 +- 3 files changed, 311 insertions(+), 10 deletions(-) diff --git a/lisp/core/analyze.el b/lisp/core/analyze.el index 58158ea6..13a715f1 100644 --- a/lisp/core/analyze.el +++ b/lisp/core/analyze.el @@ -119,9 +119,10 @@ Argument LEVEL and MSG are data from the debug log signal." (cond ((eask-json-p) ; JSON format ;; Fill content with result. (when (or eask-analyze--warnings eask-analyze--errors) - (setq content (json-encode - `((warnings . ,eask-analyze--warnings) - (errors . ,eask-analyze--errors))))) + (setq content + (eask-analyze--pretty-json (json-encode + `((warnings . ,eask-analyze--warnings) + (errors . ,eask-analyze--errors)))))) ;; XXX: When printing the result, no color allow. (eask--with-no-color (eask-msg (or content "{}")))) diff --git a/test/jest/__snapshots__/analyze.test.js.snap b/test/jest/__snapshots__/analyze.test.js.snap index f0a61444..65506abe 100644 --- a/test/jest/__snapshots__/analyze.test.js.snap +++ b/test/jest/__snapshots__/analyze.test.js.snap @@ -3,7 +3,300 @@ exports[`analyze in ./analyze/dsl handles json option 1`] = ` { "stderr": " -{"warnings":[{"range":{"start":{"line":25,"col":0,"pos":853},"end":{"line":25,"col":35,"pos":888}},"filename":"~/Eask","message":"💡 Pkg-file seems to be missing \`check-pkg.el'"},{"range":{"start":{"line":20,"col":0,"pos":709},"end":{"line":20,"col":17,"pos":726}},"filename":"~/Eask","message":"💡 Warning regarding duplicate license name, GPLv3"},{"range":{"start":{"line":17,"col":0,"pos":613},"end":{"line":17,"col":15,"pos":628}},"filename":"~/Eask","message":"💡 Warning regarding duplicate author name, name"}],"errors":[{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`f' with different version"},{"range":{"start":{"line":46,"col":0,"pos":1696},"end":{"line":50,"col":2,"pos":1908}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`f'"},{"range":{"start":{"line":44,"col":0,"pos":1596},"end":{"line":44,"col":27,"pos":1623}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`dash' with different version"},{"range":{"start":{"line":43,"col":0,"pos":1576},"end":{"line":43,"col":19,"pos":1595}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`dash'"},{"range":{"start":{"line":40,"col":0,"pos":1474},"end":{"line":40,"col":20,"pos":1494}},"filename":"~/Eask","message":"✗ Define dependencies with the same name \`emacs'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"~/Eask","message":"✗ Unknown package archive \`local'"},{"range":{"start":{"line":37,"col":0,"pos":1304},"end":{"line":37,"col":15,"pos":1319}},"filename":"~/Eask","message":"✗ Invalid archive name \`local'"},{"range":{"start":{"line":35,"col":0,"pos":1229},"end":{"line":35,"col":24,"pos":1253}},"filename":"~/Eask","message":"✗ Unknown package archive \`magic-archive'"},{"range":{"start":{"line":33,"col":0,"pos":1214},"end":{"line":33,"col":13,"pos":1227}},"filename":"~/Eask","message":"✗ Multiple definition of source \`gnu'"},{"range":{"start":{"line":30,"col":0,"pos":1073},"end":{"line":30,"col":61,"pos":1134}},"filename":"~/Eask","message":"✗ Run-script with the same key name is not allowed: \`test\`"},{"range":{"start":{"line":26,"col":0,"pos":953},"end":{"line":26,"col":35,"pos":988}},"filename":"~/Eask","message":"✗ Multiple definition of \`package-descriptor'"},{"range":{"start":{"line":23,"col":0,"pos":822},"end":{"line":23,"col":29,"pos":851}},"filename":"~/Eask","message":"✗ Multiple definition of \`package-file'"},{"range":{"start":{"line":14,"col":0,"pos":517},"end":{"line":14,"col":16,"pos":533}},"filename":"~/Eask","message":"✗ Multiple definition of \`keywords'"},{"range":{"start":{"line":12,"col":0,"pos":383},"end":{"line":12,"col":55,"pos":438}},"filename":"~/Eask","message":"✗ Multiple definition of \`website-url'"},{"range":{"start":{"line":9,"col":0,"pos":290},"end":{"line":9,"col":18,"pos":308}},"filename":"~/Eask","message":"✗ Multiple definition of \`package'"}]} +{ + "warnings": [ + { + "range": { + "start": { + "line": 25, + "col": 0, + "pos": 853 + }, + "end": { + "line": 25, + "col": 35, + "pos": 888 + } + }, + "filename": "~/Eask", + "message": "💡 Pkg-file seems to be missing \`check-pkg.el'" + }, + { + "range": { + "start": { + "line": 20, + "col": 0, + "pos": 709 + }, + "end": { + "line": 20, + "col": 17, + "pos": 726 + } + }, + "filename": "~/Eask", + "message": "💡 Warning regarding duplicate license name, GPLv3" + }, + { + "range": { + "start": { + "line": 17, + "col": 0, + "pos": 613 + }, + "end": { + "line": 17, + "col": 15, + "pos": 628 + } + }, + "filename": "~/Eask", + "message": "💡 Warning regarding duplicate author name, name" + } + ], + "errors": [ + { + "range": { + "start": { + "line": 46, + "col": 0, + "pos": 1696 + }, + "end": { + "line": 50, + "col": 2, + "pos": 1908 + } + }, + "filename": "~/Eask", + "message": "✗ Define dependencies with the same name \`f' with different version" + }, + { + "range": { + "start": { + "line": 46, + "col": 0, + "pos": 1696 + }, + "end": { + "line": 50, + "col": 2, + "pos": 1908 + } + }, + "filename": "~/Eask", + "message": "✗ Define dependencies with the same name \`f'" + }, + { + "range": { + "start": { + "line": 44, + "col": 0, + "pos": 1596 + }, + "end": { + "line": 44, + "col": 27, + "pos": 1623 + } + }, + "filename": "~/Eask", + "message": "✗ Define dependencies with the same name \`dash' with different version" + }, + { + "range": { + "start": { + "line": 43, + "col": 0, + "pos": 1576 + }, + "end": { + "line": 43, + "col": 19, + "pos": 1595 + } + }, + "filename": "~/Eask", + "message": "✗ Define dependencies with the same name \`dash'" + }, + { + "range": { + "start": { + "line": 40, + "col": 0, + "pos": 1474 + }, + "end": { + "line": 40, + "col": 20, + "pos": 1494 + } + }, + "filename": "~/Eask", + "message": "✗ Define dependencies with the same name \`emacs'" + }, + { + "range": { + "start": { + "line": 37, + "col": 0, + "pos": 1304 + }, + "end": { + "line": 37, + "col": 15, + "pos": 1319 + } + }, + "filename": "~/Eask", + "message": "✗ Unknown package archive \`local'" + }, + { + "range": { + "start": { + "line": 37, + "col": 0, + "pos": 1304 + }, + "end": { + "line": 37, + "col": 15, + "pos": 1319 + } + }, + "filename": "~/Eask", + "message": "✗ Invalid archive name \`local'" + }, + { + "range": { + "start": { + "line": 35, + "col": 0, + "pos": 1229 + }, + "end": { + "line": 35, + "col": 24, + "pos": 1253 + } + }, + "filename": "~/Eask", + "message": "✗ Unknown package archive \`magic-archive'" + }, + { + "range": { + "start": { + "line": 33, + "col": 0, + "pos": 1214 + }, + "end": { + "line": 33, + "col": 13, + "pos": 1227 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of source \`gnu'" + }, + { + "range": { + "start": { + "line": 30, + "col": 0, + "pos": 1073 + }, + "end": { + "line": 30, + "col": 61, + "pos": 1134 + } + }, + "filename": "~/Eask", + "message": "✗ Run-script with the same key name is not allowed: \`test\`" + }, + { + "range": { + "start": { + "line": 26, + "col": 0, + "pos": 953 + }, + "end": { + "line": 26, + "col": 35, + "pos": 988 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of \`package-descriptor'" + }, + { + "range": { + "start": { + "line": 23, + "col": 0, + "pos": 822 + }, + "end": { + "line": 23, + "col": 29, + "pos": 851 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of \`package-file'" + }, + { + "range": { + "start": { + "line": 14, + "col": 0, + "pos": 517 + }, + "end": { + "line": 14, + "col": 16, + "pos": 533 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of \`keywords'" + }, + { + "range": { + "start": { + "line": 12, + "col": 0, + "pos": 383 + }, + "end": { + "line": 12, + "col": 55, + "pos": 438 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of \`website-url'" + }, + { + "range": { + "start": { + "line": 9, + "col": 0, + "pos": 290 + }, + "end": { + "line": 9, + "col": 18, + "pos": 308 + } + }, + "filename": "~/Eask", + "message": "✗ Multiple definition of \`package'" + } + ] +} (Checked 1 file) ", "stdout": "", diff --git a/test/jest/analyze.test.js b/test/jest/analyze.test.js index 03cf34a4..1054be49 100644 --- a/test/jest/analyze.test.js +++ b/test/jest/analyze.test.js @@ -11,16 +11,23 @@ function tryJSON(s) { // both of which accept mixed JSON/text output. // So the test should filter non-JSON output in a similar way // See flycheck--json-parser for reference - const lines = s.split("\n"); - const json = lines.filter((x) => x.startsWith("{") || x.startsWith("[")); - if (json.length > 1) { - console.warn("command produced multiple JSON objects as output"); - } + // This is a rough approximation of the greedy JSON parsing + // that flycheck uses + // It will yield a false negative if: + // - a non-JSON output line begins with a space + // - there is more that one JSON object in the output + const lines = s.split("\n"); + const json = lines.filter((x) => x.match("^[{}\\[\\] ]")); if (json.length == 0) { return {}; } else { - return JSON.parse(json[0]); + const result = JSON.parse(json.join("\n")); + if (typeof result == "string") { + // this case is a single string prefixed with whitespace + return {}; + } + return result; } }