Files
test-repo/tests/integration/__tests__/cache.js
T
Sosuke SuzukiandSimon Lydell fdccc0f48e Add --cache CLI option (#12800)
* 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>
2022-06-11 23:32:32 +09:00

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();
});
});
});