* Install `file-entry-cache` and types * Implement `FormatResultsCache` * Add `--cache` and `--cache-location` option * Implement `--cache` and `--cache-location` * Add tests for `--cache` * Add tests for `--cache-location` * Avoid spellcheck error * Update snapshots for new options * Add `groupBy` for website * Use `fs.promises` instead of `fs/promises` * Use `rimraf` instead of `fs.rm` * Fix properties order of `options` * Install `find-cache-dir` and types * Change default cache file location to `node_modules/.cache/prettier` * Fix tests following to change default cache file location * Update snapshots for changing default cache file location * Set `os.tmpdir()` as a fallback for default cache dir * Add docs for `--cache` and `--cache-location` * Use `sdbm` instead of `node:crypto` * Add changelog * Fix `getHashOfOptions` * Remove `cache-location` * `prettiercache` -> `prettier-cache` * Remove cache file when run Prettier without `--cache` option * Implement `--cache-strategy` * Add tests for invalid cache strategy * Fix lint problems * Tweaks tests * Add tests for timestamp * Add tests for `--cache-strategy` * Add docs for cache-strategy * Address review * Fix `findCacheFile` * Use Set.prototype.has * Throw error with --stdin-filepath * Update snapshots * Fix error for cache and stdin * Use string constructor instead of toString * Update changelog * Use flag validation * Fix `cache-strategy` definition * Update docs * Mark highlihgt * Throw error for `--cache-strategy` without `--cache` * Update docs * Fix typo * Updates snapshots * Update docs/cli.md Co-authored-by: Simon Lydell <simon.lydell@gmail.com> * Fix error message * Remove `:::` syntax * Defaults `content` * Update docs * Fix by Prettier Co-authored-by: Simon Lydell <simon.lydell@gmail.com>
374 lines
11 KiB
JavaScript
374 lines
11 KiB
JavaScript
"use strict";
|
|
|
|
const path = require("path");
|
|
const { promises: fs } = require("fs");
|
|
const rimraf = require("rimraf");
|
|
const { default: stripAnsi } = require("../../../vendors/strip-ansi.js");
|
|
|
|
const runPrettier = require("../run-prettier.js");
|
|
|
|
function resolveDir(dir) {
|
|
return path.join(__dirname, "..", dir);
|
|
}
|
|
|
|
describe("--cache option", () => {
|
|
const dir = resolveDir("cli/cache");
|
|
const defaultCacheFile = path.join(
|
|
dir,
|
|
"node_modules/.cache/prettier/.prettier-cache"
|
|
);
|
|
|
|
let contentA;
|
|
let contentB;
|
|
|
|
beforeAll(async () => {
|
|
contentA = await fs.readFile(path.join(dir, "a.js"), "utf8");
|
|
contentB = await fs.readFile(path.join(dir, "b.js"), "utf8");
|
|
});
|
|
|
|
afterEach(async () => {
|
|
rimraf.sync(path.join(dir, "node_modules"));
|
|
await fs.writeFile(path.join(dir, "a.js"), contentA);
|
|
await fs.writeFile(path.join(dir, "b.js"), contentB);
|
|
});
|
|
|
|
it("throw error when cache-strategy is invalid", async () => {
|
|
const { stderr } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"invalid",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(stderr.trim())).toBe(
|
|
'[error] Invalid --cache-strategy value. Expected "content" or "metadata", but received "invalid".'
|
|
);
|
|
});
|
|
|
|
it("throws error when use with --stdin-filepath", async () => {
|
|
const { stderr } = await runPrettier(
|
|
dir,
|
|
["--cache", "--stdin-filepath", "foo.js"],
|
|
{ input: "const a = a;" }
|
|
);
|
|
expect(stripAnsi(stderr.trim())).toBe(
|
|
"[error] `--cache` cannot be used with stdin."
|
|
);
|
|
});
|
|
|
|
it("throws error when use `--cache-strategy` without `--cache`.", async () => {
|
|
const { stderr } = await runPrettier(
|
|
dir,
|
|
["foo.js", "--cache-strategy", "content"],
|
|
{
|
|
input: "const a = a;",
|
|
}
|
|
);
|
|
expect(stripAnsi(stderr.trim())).toBe(
|
|
"[error] `--cache-strategy` cannot be used without `--cache`."
|
|
);
|
|
});
|
|
|
|
describe("--cache-strategy metadata", () => {
|
|
it("creates default cache file named `node_modules/.cache/prettier/.prettier-cache`", async () => {
|
|
await expect(fs.stat(defaultCacheFile)).rejects.toHaveProperty(
|
|
"code",
|
|
"ENOENT"
|
|
);
|
|
await runPrettier(dir, ["--cache", "--cache-strategy", "metadata", "."]);
|
|
await expect(fs.stat(defaultCacheFile)).resolves.not.toThrowError();
|
|
});
|
|
|
|
it("does'nt format when cache is available", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms \(cached\)$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("re-formats when a file has been updated.", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
// Update `a.js`
|
|
await fs.writeFile(path.join(dir, "a.js"), "const a = `a`;");
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
// the cache of `b.js` is only available.
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("re-formats when timestamp has been updated", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
// update timestamp
|
|
const time = new Date();
|
|
await fs.utimes(path.join(dir, "a.js"), time, time);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
// the cache of `b.js` is only available.
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("re-formats when options has been updated.", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
"--write",
|
|
"--trailing-comma",
|
|
"all",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("removes cache file when run Prettier without `--cache` option", async () => {
|
|
await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"metadata",
|
|
".",
|
|
]);
|
|
await expect(fs.stat(defaultCacheFile)).resolves.not.toThrowError();
|
|
await runPrettier(dir, ["--write", "."]);
|
|
await expect(fs.stat(defaultCacheFile)).rejects.toThrowError();
|
|
});
|
|
});
|
|
|
|
describe("--cache-strategy content", () => {
|
|
it("creates default cache file named `node_modules/.cache/prettier/.prettier-cache`", async () => {
|
|
await expect(fs.stat(defaultCacheFile)).rejects.toHaveProperty(
|
|
"code",
|
|
"ENOENT"
|
|
);
|
|
await runPrettier(dir, ["--cache", "--cache-strategy", "content", "."]);
|
|
await expect(fs.stat(defaultCacheFile)).resolves.not.toThrowError();
|
|
});
|
|
|
|
it("does'nt format when cache is available", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms \(cached\)$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("re-formats when a file has been updated.", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
// Update `a.js`
|
|
await fs.writeFile(path.join(dir, "a.js"), "const a = `a`;");
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
// the cache of `b.js` is only available.
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("does'nt re-format when timestamp has been updated", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
// update timestamp
|
|
const time = new Date();
|
|
await fs.utimes(path.join(dir, "a.js"), time, time);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms \(cached\)$/),
|
|
expect.stringMatching(/^b\.js .+ms \(cached\)$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("re-formats when options has been updated.", async () => {
|
|
const { stdout: firstStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--write",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(firstStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
|
|
const { stdout: secondStdout } = await runPrettier(dir, [
|
|
"--cache",
|
|
"--write",
|
|
"--cache-strategy",
|
|
"content",
|
|
"--trailing-comma",
|
|
"all",
|
|
".",
|
|
]);
|
|
expect(stripAnsi(secondStdout).split("\n").filter(Boolean)).toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/^a\.js .+ms$/),
|
|
expect.stringMatching(/^b\.js .+ms$/),
|
|
])
|
|
);
|
|
});
|
|
|
|
it("removes cache file when run Prettier without `--cache` option", async () => {
|
|
await runPrettier(dir, ["--cache", "--write", "."]);
|
|
await expect(fs.stat(defaultCacheFile)).resolves.not.toThrowError();
|
|
await runPrettier(dir, ["--write", "."]);
|
|
await expect(fs.stat(defaultCacheFile)).rejects.toThrowError();
|
|
});
|
|
});
|
|
});
|