From 491e54937c89bdcc1fad1cdae17a300798c80719 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Fri, 31 Jan 2025 16:44:19 +0000 Subject: [PATCH 1/5] test: add infer-parser tests Adds the `infer-parser` tests from prettier. Also updates the `runCLI` util to only execute the binary once a test actually runs. --- test/__fixtures__/infer-parser/FOO | 0 test/__fixtures__/infer-parser/foo.js | 1 + .../infer-parser/interpreters/zx-script | 3 + .../infer-parser/known-unknown/known.js | 2 + .../infer-parser/known-unknown/unknown.jsonl | 4 + .../__snapshots__/infer-parser.js.snap | 56 +++++++ test/__tests__/infer-parser.js | 156 ++++++++++++++++++ 7 files changed, 222 insertions(+) create mode 100644 test/__fixtures__/infer-parser/FOO create mode 100644 test/__fixtures__/infer-parser/foo.js create mode 100644 test/__fixtures__/infer-parser/interpreters/zx-script create mode 100644 test/__fixtures__/infer-parser/known-unknown/known.js create mode 100644 test/__fixtures__/infer-parser/known-unknown/unknown.jsonl create mode 100644 test/__tests__/__snapshots__/infer-parser.js.snap create mode 100644 test/__tests__/infer-parser.js diff --git a/test/__fixtures__/infer-parser/FOO b/test/__fixtures__/infer-parser/FOO new file mode 100644 index 0000000..e69de29 diff --git a/test/__fixtures__/infer-parser/foo.js b/test/__fixtures__/infer-parser/foo.js new file mode 100644 index 0000000..9da4d43 --- /dev/null +++ b/test/__fixtures__/infer-parser/foo.js @@ -0,0 +1 @@ +foo ( ) diff --git a/test/__fixtures__/infer-parser/interpreters/zx-script b/test/__fixtures__/infer-parser/interpreters/zx-script new file mode 100644 index 0000000..074fca5 --- /dev/null +++ b/test/__fixtures__/infer-parser/interpreters/zx-script @@ -0,0 +1,3 @@ +#!/usr/bin/env zx + +await $`cat package.json | grep name` diff --git a/test/__fixtures__/infer-parser/known-unknown/known.js b/test/__fixtures__/infer-parser/known-unknown/known.js new file mode 100644 index 0000000..a77f53e --- /dev/null +++ b/test/__fixtures__/infer-parser/known-unknown/known.js @@ -0,0 +1,2 @@ +hello( 'world' +) diff --git a/test/__fixtures__/infer-parser/known-unknown/unknown.jsonl b/test/__fixtures__/infer-parser/known-unknown/unknown.jsonl new file mode 100644 index 0000000..9720dd6 --- /dev/null +++ b/test/__fixtures__/infer-parser/known-unknown/unknown.jsonl @@ -0,0 +1,4 @@ +{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} +{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} +{"name": "May", "wins": []} +{"name": "Deloise", "wins": [["three of a kind", "5♣"]]} diff --git a/test/__tests__/__snapshots__/infer-parser.js.snap b/test/__tests__/__snapshots__/infer-parser.js.snap new file mode 100644 index 0000000..534bfa0 --- /dev/null +++ b/test/__tests__/__snapshots__/infer-parser.js.snap @@ -0,0 +1,56 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`--check with unknown path and no parser multiple files (stderr) 1`] = ` +"[error] FOO: UndefinedParserError: No parser could be inferred for file "/Users/jg/code/prettier-cli/test/__fixtures__/infer-parser/FOO". +[warn] foo.js +[warn] Code style issues found in 1 file. Run Prettier with --write to fix." +`; + +exports[`--check with unknown path and no parser multiple files (stdout) 1`] = `"Checking formatting..."`; + +exports[`--check with unknown path and no parser specific file is ignored (stderr) 1`] = `""`; + +exports[`--check with unknown path and no parser specific file is ignored (stdout) 1`] = ` +"Checking formatting... +All matched files use Prettier code style!" +`; + +exports[`--list-different with unknown path and no parser multiple files (stderr) 1`] = `"FOO"`; + +exports[`--list-different with unknown path and no parser specific file should be ignored (stderr) 1`] = `""`; + +exports[`--write with unknown path and no parser multiple files (stderr) 1`] = `"[error] FOO: UndefinedParserError: No parser could be inferred for file "/Users/jg/code/prettier-cli/test/__fixtures__/infer-parser/FOO"."`; + +exports[`--write with unknown path and no parser multiple files (stdout) 1`] = `"foo.js"`; + +exports[`--write with unknown path and no parser multiple files (write) 1`] = ` +[ + { + "content": "foo(); +", + "filename": "foo.js", + }, +] +`; + +exports[`--write with unknown path and no parser specific file should be ignored (stderr) 1`] = `""`; + +exports[`Known/Unknown (stdout) 1`] = `"known.js"`; + +exports[`stdin no path and no parser --check logs error but exits with 1 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "stdin"."`; + +exports[`stdin no path and no parser --list-different logs error but exits with 1 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "stdin"."`; + +exports[`stdin no path and no parser logs error and exits with 2 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "stdin"."`; + +exports[`stdin with unknown path and no parser --check logs error but exits with 1 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "foo"."`; + +exports[`stdin with unknown path and no parser --list-different logs error but exits with 1 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "foo"."`; + +exports[`stdin with unknown path and no parser logs error and exits with 2 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "foo"."`; + +exports[`unknown path and no parser multiple files (stderr) 1`] = `""`; + +exports[`unknown path and no parser multiple files (stdout) 1`] = `"foo();"`; + +exports[`unknown path and no parser specific file is ignored (stderr) 1`] = `""`; diff --git a/test/__tests__/infer-parser.js b/test/__tests__/infer-parser.js new file mode 100644 index 0000000..93c3a94 --- /dev/null +++ b/test/__tests__/infer-parser.js @@ -0,0 +1,156 @@ +import { runCli } from "../utils"; + +describe("stdin no path and no parser", () => { + describe("logs error and exits with 2", () => { + runCli("infer-parser/", [], { input: "foo" }).test({ + status: 1, + stdout: "", + write: [], + }); + }); + + // TODO (43081j): in prettier, this tests that it exits with 0 for + // whatever reason. should we do the same? + describe("--check logs error but exits with 1", () => { + runCli("infer-parser/", ["--check"], { + input: "foo", + }).test({ + status: 1, + stdout: "", + write: [], + }); + }); + + // TODO (43081j): in prettier, this tests that it exits with 0 for + // whatever reason. should we do the same? + describe("--list-different logs error but exits with 1", () => { + runCli("infer-parser/", ["--list-different"], { + input: "foo", + }).test({ + status: 1, + stdout: "", + write: [], + }); + }); +}); + +describe("stdin with unknown path and no parser", () => { + describe("logs error and exits with 2", () => { + runCli("infer-parser/", ["--stdin-filepath", "foo"], { + input: "foo", + }).test({ + status: 1, + stdout: "", + write: [], + }); + }); + + // TODO (43081j): in prettier, this tests that it exits with 0 for + // whatever reason. should we do the same? + describe("--check logs error but exits with 1", () => { + runCli("infer-parser/", ["--check", "--stdin-filepath", "foo"], { + input: "foo", + }).test({ + status: 1, + stdout: "", + write: [], + }); + }); + + // TODO (43081j): in prettier, this tests that it exits with 0 for + // whatever reason. should we do the same? + describe("--list-different logs error but exits with 1", () => { + runCli( + "infer-parser/", + ["--list-different", "--stdin-filepath", "foo"], + { input: "foo" }, + ).test({ + status: 1, + stdout: "", + write: [], + }); + }); +}); + +describe("unknown path and no parser", () => { + describe("specific file is ignored", () => { + runCli("infer-parser/", ["--end-of-line", "lf", "FOO"]).test({ + status: 0, + stdout: "", + write: [], + }); + }); + + // TODO (43081j): this currently eats parser errors up, we need to decide + // if when !check && !list && !write we should still log parser errors to + // stderr + describe("multiple files", () => { + runCli("infer-parser/", ["--end-of-line", "lf", "*"]).test({ + status: 1, + write: [], + }); + }); +}); + +describe("--check with unknown path and no parser", () => { + describe("specific file is ignored", () => { + runCli("infer-parser/", ["--check", "FOO"]).test({ + status: 0, + write: [], + }); + }); + + describe("multiple files", () => { + runCli("infer-parser/", ["--check", "*"]).test({ + status: 1, + write: [], + }); + }); +}); + +describe("--list-different with unknown path and no parser", () => { + describe("specific file should be ignored", () => { + runCli("infer-parser/", ["--list-different", "FOO"]).test({ + status: 0, + stdout: "", + write: [], + }); + }); + + describe("multiple files", () => { + runCli("infer-parser/", ["--list-different", "*"]).test({ + status: 1, + stdout: "foo.js", + write: [], + }); + }); +}); + +describe("--write with unknown path and no parser", () => { + describe("specific file should be ignored", () => { + runCli("infer-parser/", ["--write", "FOO"]).test({ + status: 0, + stdout: "", + write: [], + }); + }); + + describe("multiple files", () => { + runCli("infer-parser/", ["--write", "*"]).test({ + status: 1, + }); + }); +}); + +describe("Known/Unknown", () => { + runCli("infer-parser/known-unknown", [ + "--end-of-line", + "lf", + "--list-different", + ".", + ]).test({ + status: 1, + stderr: "", + write: [], + }); +}); From 50b7054a0424e4f6a23800e8774e5d8dd7fc5a2e Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:56:52 +0000 Subject: [PATCH 2/5] test: inline stderr since it contains paths --- test/__tests__/__snapshots__/infer-parser.js.snap | 8 -------- test/__tests__/infer-parser.js | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/__tests__/__snapshots__/infer-parser.js.snap b/test/__tests__/__snapshots__/infer-parser.js.snap index 534bfa0..c81fa10 100644 --- a/test/__tests__/__snapshots__/infer-parser.js.snap +++ b/test/__tests__/__snapshots__/infer-parser.js.snap @@ -1,11 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`--check with unknown path and no parser multiple files (stderr) 1`] = ` -"[error] FOO: UndefinedParserError: No parser could be inferred for file "/Users/jg/code/prettier-cli/test/__fixtures__/infer-parser/FOO". -[warn] foo.js -[warn] Code style issues found in 1 file. Run Prettier with --write to fix." -`; - exports[`--check with unknown path and no parser multiple files (stdout) 1`] = `"Checking formatting..."`; exports[`--check with unknown path and no parser specific file is ignored (stderr) 1`] = `""`; @@ -19,8 +13,6 @@ exports[`--list-different with unknown path and no parser multiple files (stderr exports[`--list-different with unknown path and no parser specific file should be ignored (stderr) 1`] = `""`; -exports[`--write with unknown path and no parser multiple files (stderr) 1`] = `"[error] FOO: UndefinedParserError: No parser could be inferred for file "/Users/jg/code/prettier-cli/test/__fixtures__/infer-parser/FOO"."`; - exports[`--write with unknown path and no parser multiple files (stdout) 1`] = `"foo.js"`; exports[`--write with unknown path and no parser multiple files (write) 1`] = ` diff --git a/test/__tests__/infer-parser.js b/test/__tests__/infer-parser.js index 93c3a94..20118a5 100644 --- a/test/__tests__/infer-parser.js +++ b/test/__tests__/infer-parser.js @@ -1,4 +1,8 @@ import { runCli } from "../utils"; +import { color } from "specialist"; +import path from 'node:path'; + +const FIXTURES_PATH = path.join(process.cwd(), "test", "__fixtures__"); describe("stdin no path and no parser", () => { describe("logs error and exits with 2", () => { @@ -104,6 +108,9 @@ describe("--check with unknown path and no parser", () => { runCli("infer-parser/", ["--check", "*"]).test({ status: 1, write: [], + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "${FIXTURES_PATH}/infer-parser/FOO". +[${color.yellow('warn')}] foo.js +[${color.yellow('warn')}] Code style issues found in 1 file. Run Prettier with --write to fix.` }); }); }); @@ -138,6 +145,7 @@ describe("--write with unknown path and no parser", () => { describe("multiple files", () => { runCli("infer-parser/", ["--write", "*"]).test({ status: 1, + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "${FIXTURES_PATH}/infer-parser/FOO".`, }); }); }); From 7f0d9c6979442e54d09378f835810b2704c71025 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Sun, 2 Mar 2025 21:05:16 +0100 Subject: [PATCH 3/5] feat: add `dump` to error logging --- src/index.ts | 2 +- test/__tests__/__snapshots__/infer-parser.js.snap | 2 +- test/__tests__/infer-parser.js | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index fd7319d..9db9737 100644 --- a/src/index.ts +++ b/src/index.ts @@ -182,7 +182,7 @@ async function runGlobs(options: Options, pluginsDefaultOptions: PluginsOptions, const filePath = filesPathsTargets[i]; const fileNameToDisplay = normalizeToPosix(fastRelativePath(rootPath, filePath)); //TODO: Make sure the error is syntax-highlighted when possible - if (options.check || options.write) { + if (options.check || options.write || options.dump) { stderr.prefixed.error(`${fileNameToDisplay}: ${error}`); } else if (options.list) { stderr.error(fileNameToDisplay); diff --git a/test/__tests__/__snapshots__/infer-parser.js.snap b/test/__tests__/__snapshots__/infer-parser.js.snap index c81fa10..78c70f6 100644 --- a/test/__tests__/__snapshots__/infer-parser.js.snap +++ b/test/__tests__/__snapshots__/infer-parser.js.snap @@ -41,7 +41,7 @@ exports[`stdin with unknown path and no parser --list-different logs error but e exports[`stdin with unknown path and no parser logs error and exits with 2 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "foo"."`; -exports[`unknown path and no parser multiple files (stderr) 1`] = `""`; +exports[`unknown path and no parser multiple files (stderr) 1`] = `"[error] FOO: UndefinedParserError: No parser could be inferred for file "/tmp/prettier-infer-parser-68670a6cfd1d189a6f3c7fb6c5932306/FOO"."`; exports[`unknown path and no parser multiple files (stdout) 1`] = `"foo();"`; diff --git a/test/__tests__/infer-parser.js b/test/__tests__/infer-parser.js index 20118a5..1323188 100644 --- a/test/__tests__/infer-parser.js +++ b/test/__tests__/infer-parser.js @@ -1,8 +1,5 @@ import { runCli } from "../utils"; import { color } from "specialist"; -import path from 'node:path'; - -const FIXTURES_PATH = path.join(process.cwd(), "test", "__fixtures__"); describe("stdin no path and no parser", () => { describe("logs error and exits with 2", () => { @@ -108,7 +105,7 @@ describe("--check with unknown path and no parser", () => { runCli("infer-parser/", ["--check", "*"]).test({ status: 1, write: [], - stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "${FIXTURES_PATH}/infer-parser/FOO". + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "__FIXTURES__/FOO". [${color.yellow('warn')}] foo.js [${color.yellow('warn')}] Code style issues found in 1 file. Run Prettier with --write to fix.` }); @@ -145,7 +142,7 @@ describe("--write with unknown path and no parser", () => { describe("multiple files", () => { runCli("infer-parser/", ["--write", "*"]).test({ status: 1, - stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "${FIXTURES_PATH}/infer-parser/FOO".`, + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "__FIXTURES__/FOO".`, }); }); }); From 5d792db44b09849fdf82ecd71cad2d5798a4b417 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:02:49 +0100 Subject: [PATCH 4/5] test: update fixture path in assertions --- test/__tests__/infer-parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/__tests__/infer-parser.js b/test/__tests__/infer-parser.js index 1323188..2d30665 100644 --- a/test/__tests__/infer-parser.js +++ b/test/__tests__/infer-parser.js @@ -105,7 +105,7 @@ describe("--check with unknown path and no parser", () => { runCli("infer-parser/", ["--check", "*"]).test({ status: 1, write: [], - stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "__FIXTURES__/FOO". + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "$CWD/FOO". [${color.yellow('warn')}] foo.js [${color.yellow('warn')}] Code style issues found in 1 file. Run Prettier with --write to fix.` }); @@ -142,7 +142,7 @@ describe("--write with unknown path and no parser", () => { describe("multiple files", () => { runCli("infer-parser/", ["--write", "*"]).test({ status: 1, - stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "__FIXTURES__/FOO".`, + stderr: `[${color.red('error')}] FOO: UndefinedParserError: No parser could be inferred for file "$CWD/FOO".`, }); }); }); From 373147c4dd5bcdc8745f4b3d0da72a77fb90a91d Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:49:38 +0100 Subject: [PATCH 5/5] test: update snapshots --- src/utils.ts | 5 +---- test/__tests__/__snapshots__/early-exit.js.snap | 10 +++++----- test/__tests__/__snapshots__/infer-parser.js.snap | 4 ++-- test/__tests__/early-exit.js | 12 ++++++++---- test/__tests__/infer-parser.js | 5 +---- test/utils.js | 7 ++++--- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index decbab3..454bcf0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -736,10 +736,7 @@ function zipObjectUnless(keys: T[], values: U[], unless: (valu /** * Replace `\` with `/` on Windows */ -const normalizeToPosix = - path.sep === "\\" - ? (filepath: string): string => filepath.replaceAll("\\", "/") - : (filepath: string): string => filepath; +const normalizeToPosix = path.sep === "\\" ? (filepath: string): string => filepath.replaceAll("\\", "/") : (filepath: string): string => filepath; export { castArray, diff --git a/test/__tests__/__snapshots__/early-exit.js.snap b/test/__tests__/__snapshots__/early-exit.js.snap index 0012bdb..8f09756 100644 --- a/test/__tests__/__snapshots__/early-exit.js.snap +++ b/test/__tests__/__snapshots__/early-exit.js.snap @@ -1,10 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`show usage with --help (stderr) 1`] = `""`; - -exports[`show usage with --help (stdout) 1`] = ` +exports[`show usage with --help shows help text 1`] = ` " - prettier 3.5.3 + prettier $VERSION USAGE @@ -134,7 +132,9 @@ exports[`show usage with --help (stdout) 1`] = ` " `; -exports[`show usage with --help (write) 1`] = `[]`; +exports[`show usage with --help shows help text 2`] = `""`; + +exports[`show usage with --help shows help text 3`] = `[]`; exports[`show version with --version (stderr) 1`] = `""`; diff --git a/test/__tests__/__snapshots__/infer-parser.js.snap b/test/__tests__/__snapshots__/infer-parser.js.snap index 78c70f6..f96466e 100644 --- a/test/__tests__/__snapshots__/infer-parser.js.snap +++ b/test/__tests__/__snapshots__/infer-parser.js.snap @@ -41,8 +41,8 @@ exports[`stdin with unknown path and no parser --list-different logs error but e exports[`stdin with unknown path and no parser logs error and exits with 2 (stderr) 1`] = `"[error] UndefinedParserError: No parser could be inferred for file "foo"."`; -exports[`unknown path and no parser multiple files (stderr) 1`] = `"[error] FOO: UndefinedParserError: No parser could be inferred for file "/tmp/prettier-infer-parser-68670a6cfd1d189a6f3c7fb6c5932306/FOO"."`; +exports[`unknown path and no parser multiple files are ignored (stderr) 1`] = `"[error] FOO: UndefinedParserError: No parser could be inferred for file "$CWD/FOO"."`; -exports[`unknown path and no parser multiple files (stdout) 1`] = `"foo();"`; +exports[`unknown path and no parser multiple files are ignored (stdout) 1`] = `"foo();"`; exports[`unknown path and no parser specific file is ignored (stderr) 1`] = `""`; diff --git a/test/__tests__/early-exit.js b/test/__tests__/early-exit.js index f6fb6f5..143b4ca 100644 --- a/test/__tests__/early-exit.js +++ b/test/__tests__/early-exit.js @@ -11,10 +11,14 @@ describe("show version with --version", () => { }); describe("show usage with --help", () => { - runCli("", [ - "--help", - ]).test({ - status: 0, + it("shows help text", async () => { + const result = await runCli("", [ + "--help", + ]); + expect(result.status).toBe(0); + expect(result.stdout.replaceAll(PRETTIER_VERSION, "$VERSION")).toMatchSnapshot(); + expect(result.stderr).toMatchSnapshot(); + expect(result.write).toMatchSnapshot(); }); }); diff --git a/test/__tests__/infer-parser.js b/test/__tests__/infer-parser.js index 2d30665..2237bc1 100644 --- a/test/__tests__/infer-parser.js +++ b/test/__tests__/infer-parser.js @@ -82,10 +82,7 @@ describe("unknown path and no parser", () => { }); }); - // TODO (43081j): this currently eats parser errors up, we need to decide - // if when !check && !list && !write we should still log parser errors to - // stderr - describe("multiple files", () => { + describe("multiple files are ignored", () => { runCli("infer-parser/", ["--end-of-line", "lf", "*"]).test({ status: 1, write: [], diff --git a/test/utils.js b/test/utils.js index 10dd8cc..2f9da29 100644 --- a/test/utils.js +++ b/test/utils.js @@ -97,12 +97,13 @@ async function getIsolatedFixtures(dir) { }; } -function getNormalizedOutput(output, options) { +function getNormalizedOutput(output, cwd) { // \r is trimmed from jest snapshots by default; // manually replacing this character with /*CR*/ to test its true presence // If ignoreLineEndings is specified, \r is simply deleted instead // output = output.replace(/\r/gu, options.ignoreLineEndings ? "" : "/*CR*/"); //TODO output = output.replace(/(\r?\n|\r)$/, ""); + output = output.replaceAll(cwd, "$CWD"); return output; } @@ -125,8 +126,8 @@ async function runCommand(dir, args, options) { } const status = await result.code; - const stdout = getNormalizedOutput((await result.stdout).toString()); - const stderr = getNormalizedOutput((await result.stderr).toString()); + const stdout = getNormalizedOutput((await result.stdout).toString(), cwd); + const stderr = getNormalizedOutput((await result.stderr).toString(), cwd); const write = (await archive?.getDiff()) || []; await fixtures?.dispose();