prettier.{format,formatWithCursor,check}() are now async (#12574)
This commit is contained in:
1 parent
2bcee631a2
commit
c6d6b25833
20 files changed
+198
-154
No files matched your search
@@ -0,0 +1,7 @@
|
||||
#### [BREAKING] Change public apis to asynchronous (#12574 by @fisker)
|
||||
|
||||
- `prettier.format()` returns `Promise<string>`
|
||||
- `prettier.formatWithCursor()` returns `Promise<{formatted: string, cursorOffset: number}>`
|
||||
- `prettier.check()` returns `Promise<boolean>`
|
||||
|
||||
More changes are coming...
|
||||
+3
-3
@@ -14,13 +14,13 @@ const prettier = require("prettier");
|
||||
`format` is used to format text using Prettier. `options.parser` must be set according to the language you are formatting (see the [list of available parsers](options.md#parser)). Alternatively, `options.filepath` can be specified for Prettier to infer the parser from the file extension. Other [options](options.md) may be provided to override the defaults.
|
||||
|
||||
```js
|
||||
prettier.format("foo ( );", { semi: false, parser: "babel" });
|
||||
await prettier.format("foo ( );", { semi: false, parser: "babel" });
|
||||
// -> "foo()"
|
||||
```
|
||||
|
||||
## `prettier.check(source [, options])`
|
||||
|
||||
`check` checks to see if the file has been formatted with Prettier given those options and returns a `Boolean`. This is similar to the `--check` or `--list-different` parameter in the CLI and is useful for running Prettier in CI scenarios.
|
||||
`check` checks to see if the file has been formatted with Prettier given those options and returns a `Promise<boolean>`. This is similar to the `--check` or `--list-different` parameter in the CLI and is useful for running Prettier in CI scenarios.
|
||||
|
||||
## `prettier.formatWithCursor(source [, options])`
|
||||
|
||||
@@ -29,7 +29,7 @@ prettier.format("foo ( );", { semi: false, parser: "babel" });
|
||||
The `cursorOffset` option should be provided, to specify where the cursor is. This option cannot be used with `rangeStart` and `rangeEnd`.
|
||||
|
||||
```js
|
||||
prettier.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
|
||||
await prettier.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
|
||||
// -> { formatted: '1;\n', cursorOffset: 1 }
|
||||
```
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ async function logFileInfoOrDie(context) {
|
||||
resolveConfig: config !== false,
|
||||
});
|
||||
|
||||
printToScreen(prettier.format(stringify(fileInfo), { parser: "json" }));
|
||||
printToScreen(await prettier.format(stringify(fileInfo), { parser: "json" }));
|
||||
}
|
||||
|
||||
export default logFileInfoOrDie;
|
||||
+33
-25
@@ -74,7 +74,7 @@ function writeOutput(context, result, options) {
|
||||
}
|
||||
}
|
||||
|
||||
function listDifferent(context, input, options, filename) {
|
||||
async function listDifferent(context, input, options, filename) {
|
||||
if (!context.argv.check && !context.argv.listDifferent) {
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ function listDifferent(context, input, options, filename) {
|
||||
"No parser and no file path given, couldn't infer a parser."
|
||||
);
|
||||
}
|
||||
if (!prettier.check(input, options)) {
|
||||
if (!(await prettier.check(input, options))) {
|
||||
if (!context.argv.write) {
|
||||
context.logger.log(filename);
|
||||
process.exitCode = 1;
|
||||
@@ -117,13 +117,15 @@ async function format(context, input, opt) {
|
||||
|
||||
if (context.argv.debugPrintDoc) {
|
||||
const doc = prettier.__debug.printToDoc(input, opt);
|
||||
return { formatted: prettier.__debug.formatDoc(doc) + "\n" };
|
||||
return { formatted: (await prettier.__debug.formatDoc(doc)) + "\n" };
|
||||
}
|
||||
|
||||
if (context.argv.debugPrintComments) {
|
||||
return {
|
||||
formatted: prettier.format(
|
||||
JSON.stringify(prettier.formatWithCursor(input, opt).comments || []),
|
||||
formatted: await prettier.format(
|
||||
JSON.stringify(
|
||||
(await prettier.formatWithCursor(input, opt)).comments || []
|
||||
),
|
||||
{ parser: "json" }
|
||||
),
|
||||
};
|
||||
@@ -137,8 +139,8 @@ async function format(context, input, opt) {
|
||||
}
|
||||
|
||||
if (context.argv.debugCheck) {
|
||||
const pp = prettier.format(input, opt);
|
||||
const pppp = prettier.format(pp, opt);
|
||||
const pp = await prettier.format(input, opt);
|
||||
const pppp = await prettier.format(pp, opt);
|
||||
if (pp !== pppp) {
|
||||
throw new errors.DebugError(
|
||||
"prettier(input) !== prettier(prettier(input))\n" +
|
||||
@@ -187,22 +189,28 @@ async function format(context, input, opt) {
|
||||
"'--debug-benchmark' option found, measuring formatWithCursor with 'benchmark' module."
|
||||
);
|
||||
const suite = new benchmark.Suite();
|
||||
suite
|
||||
.add("format", () => {
|
||||
prettier.formatWithCursor(input, opt);
|
||||
})
|
||||
.on("cycle", (event) => {
|
||||
const results = {
|
||||
benchmark: String(event.target),
|
||||
hz: event.target.hz,
|
||||
ms: event.target.times.cycle * 1000,
|
||||
};
|
||||
context.logger.debug(
|
||||
"'--debug-benchmark' measurements for formatWithCursor: " +
|
||||
JSON.stringify(results, null, 2)
|
||||
);
|
||||
})
|
||||
.run({ async: false });
|
||||
suite.add("format", {
|
||||
defer: true,
|
||||
async fn(deferred) {
|
||||
await prettier.formatWithCursor(input, opt);
|
||||
deferred.resolve();
|
||||
},
|
||||
});
|
||||
const result = await new Promise((resolve) => {
|
||||
suite
|
||||
.on("complete", (event) => {
|
||||
resolve({
|
||||
benchmark: String(event.target),
|
||||
hz: event.target.hz,
|
||||
ms: event.target.times.cycle * 1000,
|
||||
});
|
||||
})
|
||||
.run({ async: false });
|
||||
});
|
||||
context.logger.debug(
|
||||
"'--debug-benchmark' measurements for formatWithCursor: " +
|
||||
JSON.stringify(result, null, 2)
|
||||
);
|
||||
} else if (context.argv.debugRepeat > 0) {
|
||||
const repeat = context.argv.debugRepeat;
|
||||
context.logger.debug(
|
||||
@@ -214,7 +222,7 @@ async function format(context, input, opt) {
|
||||
for (let i = 0; i < repeat; ++i) {
|
||||
// should be using `performance.now()`, but only `Date` is cross-platform enough
|
||||
const startMs = Date.now();
|
||||
prettier.formatWithCursor(input, opt);
|
||||
await prettier.formatWithCursor(input, opt);
|
||||
totalMs += Date.now() - startMs;
|
||||
}
|
||||
const averageMs = totalMs / repeat;
|
||||
@@ -269,7 +277,7 @@ async function formatStdin(context) {
|
||||
|
||||
const options = await getOptionsForFile(context, filepath);
|
||||
|
||||
if (listDifferent(context, input, options, "(stdin)")) {
|
||||
if (await listDifferent(context, input, options, "(stdin)")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ async function main(rawArguments, logger) {
|
||||
|
||||
if (context.argv.supportInfo) {
|
||||
printToScreen(
|
||||
prettier.format(stringify(prettier.getSupportInfo()), {
|
||||
await prettier.format(stringify(prettier.getSupportInfo()), {
|
||||
parser: "json",
|
||||
})
|
||||
);
|
||||
|
||||
+5
-4
@@ -68,12 +68,13 @@ const formatWithCursor = withPlugins(core.formatWithCursor);
|
||||
const prettier = {
|
||||
formatWithCursor,
|
||||
|
||||
format(text, opts) {
|
||||
return formatWithCursor(text, opts).formatted;
|
||||
async format(text, opts) {
|
||||
const { formatted } = await formatWithCursor(text, opts);
|
||||
return formatted;
|
||||
},
|
||||
|
||||
check(text, opts) {
|
||||
const { formatted } = formatWithCursor(text, opts);
|
||||
async check(text, opts) {
|
||||
const { formatted } = await formatWithCursor(text, opts);
|
||||
return formatted === text;
|
||||
},
|
||||
|
||||
|
||||
+8
-4
@@ -275,7 +275,8 @@ function hasPragma(text, options) {
|
||||
return !selectedParser.hasPragma || selectedParser.hasPragma(text);
|
||||
}
|
||||
|
||||
function formatWithCursor(originalText, originalOptions) {
|
||||
// eslint-disable-next-line require-await
|
||||
async function formatWithCursor(originalText, originalOptions) {
|
||||
let { hasBOM, text, options } = normalizeInputAndOptions(
|
||||
originalText,
|
||||
normalizeOptions(originalOptions)
|
||||
@@ -341,11 +342,14 @@ const prettier = {
|
||||
},
|
||||
|
||||
// Doesn't handle shebang for now
|
||||
formatDoc(doc, options) {
|
||||
return formatWithCursor(printDocToDebug(doc), {
|
||||
async formatDoc(doc, options) {
|
||||
const text = printDocToDebug(doc);
|
||||
const { formatted } = await formatWithCursor(text, {
|
||||
...options,
|
||||
parser: "__js_expression",
|
||||
}).formatted;
|
||||
});
|
||||
|
||||
return formatted;
|
||||
},
|
||||
|
||||
printToDoc(originalText, options) {
|
||||
|
||||
+5
-4
@@ -33,12 +33,13 @@ const formatWithCursor = withPlugins(core.formatWithCursor);
|
||||
const prettierStandalone = {
|
||||
formatWithCursor,
|
||||
|
||||
format(text, opts) {
|
||||
return formatWithCursor(text, opts).formatted;
|
||||
async format(text, opts) {
|
||||
const { formatted } = await formatWithCursor(text, opts);
|
||||
return formatted;
|
||||
},
|
||||
|
||||
check(text, opts) {
|
||||
const { formatted } = formatWithCursor(text, opts);
|
||||
async check(text, opts) {
|
||||
const { formatted } = await formatWithCursor(text, opts);
|
||||
return formatted === text;
|
||||
},
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const { __dirname } = createEsmUtils(import.meta);
|
||||
|
||||
let prettier;
|
||||
|
||||
const { FULL_TEST } = process.env;
|
||||
const { FULL_TEST, TEST_STANDALONE } = process.env;
|
||||
const BOM = "\uFEFF";
|
||||
|
||||
const CURSOR_PLACEHOLDER = "<|>";
|
||||
@@ -119,6 +119,19 @@ const isTestDirectory = (dirname, name) =>
|
||||
path.join(__dirname, "../format", name) + path.sep
|
||||
);
|
||||
|
||||
const ensurePromise = (value) => {
|
||||
const isPromise = TEST_STANDALONE
|
||||
? // In standalone test, promise is from another context
|
||||
Object.prototype.toString.call(value) === "[object Promise]"
|
||||
: value instanceof Promise;
|
||||
|
||||
if (!isPromise) {
|
||||
throw new TypeError("Expected value to be a 'Promise'.");
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
function runSpec(fixtures, parsers, options) {
|
||||
let { importMeta, snippets = [] } = fixtures.importMeta
|
||||
? fixtures
|
||||
@@ -462,7 +475,6 @@ const insertCursor = (text, cursorOffset) =>
|
||||
CURSOR_PLACEHOLDER +
|
||||
text.slice(cursorOffset)
|
||||
: text;
|
||||
// eslint-disable-next-line require-await
|
||||
async function format(originalText, originalOptions) {
|
||||
const { text: input, options } = replacePlaceholders(
|
||||
originalText,
|
||||
@@ -470,9 +482,8 @@ async function format(originalText, originalOptions) {
|
||||
);
|
||||
const inputWithCursor = insertCursor(input, options.cursorOffset);
|
||||
|
||||
const { formatted: output, cursorOffset } = prettier.formatWithCursor(
|
||||
input,
|
||||
options
|
||||
const { formatted: output, cursorOffset } = await ensurePromise(
|
||||
prettier.formatWithCursor(input, options)
|
||||
);
|
||||
const outputWithCursor = insertCursor(output, cursorOffset);
|
||||
const eolVisualizedOutput = visualizeEndOfLine(outputWithCursor);
|
||||
|
||||
@@ -5,36 +5,36 @@ const { prettier } = run_spec;
|
||||
|
||||
run_spec(import.meta, ["babel", "typescript", "flow"]);
|
||||
|
||||
test("translates cursor correctly in basic case", () => {
|
||||
test("translates cursor correctly in basic case", async () => {
|
||||
expect(
|
||||
prettier.formatWithCursor(" 1", { parser: "babel", cursorOffset: 2 })
|
||||
await prettier.formatWithCursor(" 1", { parser: "babel", cursorOffset: 2 })
|
||||
).toMatchObject({
|
||||
formatted: "1;\n",
|
||||
cursorOffset: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test("positions cursor relative to closest node, not SourceElement", () => {
|
||||
test("positions cursor relative to closest node, not SourceElement", async () => {
|
||||
const code = "return 15";
|
||||
expect(
|
||||
prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 15 })
|
||||
await prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 15 })
|
||||
).toMatchObject({
|
||||
formatted: "return 15;\n",
|
||||
cursorOffset: 7,
|
||||
});
|
||||
});
|
||||
|
||||
test("keeps cursor inside formatted node", () => {
|
||||
test("keeps cursor inside formatted node", async () => {
|
||||
const code = "return 15";
|
||||
expect(
|
||||
prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 14 })
|
||||
await prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 14 })
|
||||
).toMatchObject({
|
||||
formatted: "return 15;\n",
|
||||
cursorOffset: 7,
|
||||
});
|
||||
});
|
||||
|
||||
test("doesn't insert second placeholder for nonexistent TypeAnnotation", () => {
|
||||
test("doesn't insert second placeholder for nonexistent TypeAnnotation", async () => {
|
||||
const code =
|
||||
"\n" +
|
||||
outdent`
|
||||
@@ -43,7 +43,7 @@ test("doesn't insert second placeholder for nonexistent TypeAnnotation", () => {
|
||||
})
|
||||
`;
|
||||
expect(
|
||||
prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 24 })
|
||||
await prettier.formatWithCursor(code, { parser: "babel", cursorOffset: 24 })
|
||||
).toMatchObject({
|
||||
formatted:
|
||||
outdent`
|
||||
@@ -55,11 +55,11 @@ test("doesn't insert second placeholder for nonexistent TypeAnnotation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("cursorOffset === rangeStart", () => {
|
||||
test("cursorOffset === rangeStart", async () => {
|
||||
const code = "1.0000\n2.0000\n3.0000";
|
||||
|
||||
expect(
|
||||
prettier.formatWithCursor(code, {
|
||||
await prettier.formatWithCursor(code, {
|
||||
parser: "babel",
|
||||
cursorOffset: 7,
|
||||
rangeStart: 7,
|
||||
|
||||
@@ -52,9 +52,9 @@ describe("standalone", () => {
|
||||
});
|
||||
|
||||
for (const parser of parserNames) {
|
||||
test(parser, () => {
|
||||
test(parser, async () => {
|
||||
const input = codeSamples(parser);
|
||||
const umdOutput = standalone.format(input, {
|
||||
const umdOutput = await standalone.format(input, {
|
||||
parser,
|
||||
plugins,
|
||||
});
|
||||
@@ -63,7 +63,7 @@ describe("standalone", () => {
|
||||
expect(typeof umdOutput).toBe("string");
|
||||
expect(umdOutput).not.toBe(input);
|
||||
|
||||
const esmOutput = esmStandalone.format(input, {
|
||||
const esmOutput = await esmStandalone.format(input, {
|
||||
parser,
|
||||
plugins: esmPlugins,
|
||||
});
|
||||
|
||||
@@ -36,28 +36,28 @@ describe("API", () => {
|
||||
done();
|
||||
});
|
||||
|
||||
const formatResultFromDoc = formatDoc(doc, options);
|
||||
test("prettier.formatDoc", () => {
|
||||
expect(formatResultFromDoc).toMatchSnapshot();
|
||||
});
|
||||
|
||||
const { formatted: stringFromDoc } = printDocToString(doc, options);
|
||||
test("prettier.printDocToString", () => {
|
||||
expect(stringFromDoc).toBe(formatted);
|
||||
});
|
||||
|
||||
const doc2 = new Function(
|
||||
`{ ${Object.keys(builders)} }`,
|
||||
`return ${formatResultFromDoc}`
|
||||
)(builders);
|
||||
const { formatted: stringFromDoc2 } = printDocToString(doc2, options);
|
||||
const formatResultFromDoc2 = formatDoc(doc2, options);
|
||||
test("output of prettier.formatDoc can be reused as code", () => {
|
||||
test("prettier.formatDoc", async () => {
|
||||
const formatResultFromDoc = await formatDoc(doc, options);
|
||||
expect(formatResultFromDoc).toMatchSnapshot();
|
||||
|
||||
const doc2 = new Function(
|
||||
`{ ${Object.keys(builders)} }`,
|
||||
`return ${formatResultFromDoc}`
|
||||
)(builders);
|
||||
|
||||
const { formatted: stringFromDoc2 } = printDocToString(doc2, options);
|
||||
expect(stringFromDoc2).toBe(formatted);
|
||||
|
||||
const formatResultFromDoc2 = await formatDoc(doc2, options);
|
||||
expect(formatResultFromDoc2).toBe(formatResultFromDoc);
|
||||
});
|
||||
|
||||
test("prettier.formatDoc prints things as expected", () => {
|
||||
test("prettier.formatDoc prints things as expected", async () => {
|
||||
const {
|
||||
indent,
|
||||
hardline,
|
||||
@@ -70,31 +70,31 @@ describe("API", () => {
|
||||
label,
|
||||
} = builders;
|
||||
|
||||
expect(formatDoc([indent(hardline), indent(literalline)])).toBe(
|
||||
expect(await formatDoc([indent(hardline), indent(literalline)])).toBe(
|
||||
"[indent(hardline), indent(literalline)]"
|
||||
);
|
||||
|
||||
expect(formatDoc(fill(["foo", hardline, "bar", literalline, "baz"]))).toBe(
|
||||
'fill(["foo", hardline, "bar", literalline, "baz"])'
|
||||
);
|
||||
expect(
|
||||
await formatDoc(fill(["foo", hardline, "bar", literalline, "baz"]))
|
||||
).toBe('fill(["foo", hardline, "bar", literalline, "baz"])');
|
||||
|
||||
expect(
|
||||
formatDoc(
|
||||
await formatDoc(
|
||||
// The argument of fill must not be passed to cleanDoc because it's not a doc
|
||||
fill(cleanDoc(["foo", literalline, "bar"])) // invalid fill
|
||||
)
|
||||
).toBe('fill(["foo", literallineWithoutBreakParent, breakParent, "bar"])');
|
||||
|
||||
expect(
|
||||
formatDoc(indentIfBreak(group(["1", line, "2"]), { groupId: "Q" }))
|
||||
await formatDoc(indentIfBreak(group(["1", line, "2"]), { groupId: "Q" }))
|
||||
).toBe('indentIfBreak(group(["1", line, "2"]), { groupId: "Q" })');
|
||||
|
||||
expect(formatDoc(label("foo", group(["1", line, "2"])))).toBe(
|
||||
expect(await formatDoc(label("foo", group(["1", line, "2"])))).toBe(
|
||||
'label("foo", group(["1", line, "2"]))'
|
||||
);
|
||||
|
||||
expect(formatDoc([ifBreak("a", "b"), ifBreak("a"), ifBreak("", "b")])).toBe(
|
||||
'[ifBreak("a", "b"), ifBreak("a"), ifBreak("", "b")]'
|
||||
);
|
||||
expect(
|
||||
await formatDoc([ifBreak("a", "b"), ifBreak("a"), ifBreak("", "b")])
|
||||
).toBe('[ifBreak("a", "b"), ifBreak("a"), ifBreak("", "b")]');
|
||||
});
|
||||
});
|
||||
@@ -2,17 +2,17 @@ import prettier from "prettier-local";
|
||||
import { outdent } from "outdent";
|
||||
import fooPlugin from "../plugins/defaultOptions/plugin.cjs";
|
||||
|
||||
test("yaml parser should handle CRLF correctly", () => {
|
||||
test("yaml parser should handle CRLF correctly", async () => {
|
||||
const input = "a:\r\n 123\r\n";
|
||||
expect(
|
||||
// use JSON.stringify to observe CRLF
|
||||
JSON.stringify(
|
||||
prettier.format(input, { parser: "yaml", endOfLine: "auto" })
|
||||
await prettier.format(input, { parser: "yaml", endOfLine: "auto" })
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("typescript parser should throw the first error when both JSX and non-JSX mode failed", () => {
|
||||
test("typescript parser should throw the first error when both JSX and non-JSX mode failed", async () => {
|
||||
const input = outdent`
|
||||
import React from "react";
|
||||
|
||||
@@ -23,43 +23,46 @@ test("typescript parser should throw the first error when both JSX and non-JSX m
|
||||
|
||||
label:
|
||||
`;
|
||||
expect(() =>
|
||||
await expect(
|
||||
prettier.format(input, { parser: "typescript" })
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
).rejects.toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
test("html parser should handle CRLF correctly", () => {
|
||||
test("html parser should handle CRLF correctly", async () => {
|
||||
const input = "<!--\r\n test\r\n test\r\n-->";
|
||||
expect(
|
||||
// use JSON.stringify to observe CRLF
|
||||
JSON.stringify(
|
||||
prettier.format(input, { parser: "html", endOfLine: "auto" })
|
||||
await prettier.format(input, { parser: "html", endOfLine: "auto" })
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("markdown parser should handle CRLF correctly", () => {
|
||||
test("markdown parser should handle CRLF correctly", async () => {
|
||||
const input = "```\r\n\r\n\r\n```";
|
||||
expect(
|
||||
// use JSON.stringify to observe CRLF
|
||||
JSON.stringify(
|
||||
prettier.format(input, { parser: "markdown", endOfLine: "auto" })
|
||||
await prettier.format(input, { parser: "markdown", endOfLine: "auto" })
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("should work with foo plugin instance", () => {
|
||||
test("should work with foo plugin instance", async () => {
|
||||
const input = "a:\r\n 123\r\n";
|
||||
expect(
|
||||
JSON.stringify(
|
||||
prettier.format(input, { parser: "foo-parser", plugins: [fooPlugin] })
|
||||
await prettier.format(input, {
|
||||
parser: "foo-parser",
|
||||
plugins: [fooPlugin],
|
||||
})
|
||||
)
|
||||
).toMatchInlineSnapshot('""{\\"tabWidth\\":8,\\"bracketSpacing\\":false}""');
|
||||
});
|
||||
|
||||
test("'Adjacent JSX' error should not be swallowed by Babel's error recovery", () => {
|
||||
test("'Adjacent JSX' error should not be swallowed by Babel's error recovery", async () => {
|
||||
const input = "<a></a>\n<b></b>";
|
||||
expect(() =>
|
||||
await expect(
|
||||
prettier.format(input, { parser: "babel" })
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
).rejects.toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
@@ -179,14 +179,14 @@ describe("API with no path and no parser", () => {
|
||||
global.console = _console;
|
||||
});
|
||||
|
||||
test("prettier.format", () => {
|
||||
expect(prettier.format(" foo ( )")).toBe("foo();\n");
|
||||
test("prettier.format", async () => {
|
||||
expect(await prettier.format(" foo ( )")).toBe("foo();\n");
|
||||
expect(global.console.warn).toHaveBeenCalledTimes(1);
|
||||
expect(global.console.warn.mock.calls[0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("prettier.check", () => {
|
||||
expect(prettier.check(" foo ( )")).toBe(false);
|
||||
test("prettier.check", async () => {
|
||||
expect(await prettier.check(" foo ( )")).toBe(false);
|
||||
expect(global.console.warn).toHaveBeenCalledTimes(1);
|
||||
expect(global.console.warn.mock.calls[0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ const { group, indent, line, lineSuffix, lineSuffixBoundary, softline } =
|
||||
prettier.doc.builders;
|
||||
|
||||
describe("lineSuffixBoundary", () => {
|
||||
test("should be correctly treated as a potential line break in `fits`", () => {
|
||||
test("should be correctly treated as a potential line break in `fits`", async () => {
|
||||
const doc = group([
|
||||
"let foo = [",
|
||||
indent([
|
||||
@@ -30,6 +30,6 @@ describe("lineSuffixBoundary", () => {
|
||||
];
|
||||
`;
|
||||
|
||||
expect(printDoc(doc)).toBe(expected);
|
||||
expect(await printDoc(doc)).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
import prettier from "prettier-local";
|
||||
import runPrettier from "../run-prettier.js";
|
||||
|
||||
test("allows custom parser provided as object", () => {
|
||||
const output = prettier.format("1", {
|
||||
test("allows custom parser provided as object", async () => {
|
||||
const output = await prettier.format("1", {
|
||||
parser(text) {
|
||||
expect(text).toBe("1");
|
||||
return {
|
||||
@@ -15,8 +15,8 @@ test("allows custom parser provided as object", () => {
|
||||
expect(output).toBe("2");
|
||||
});
|
||||
|
||||
test("allows usage of prettier's supported parsers", () => {
|
||||
const output = prettier.format("foo ( )", {
|
||||
test("allows usage of prettier's supported parsers", async () => {
|
||||
const output = await prettier.format("foo ( )", {
|
||||
parser(text, parsers) {
|
||||
expect(typeof parsers.babel).toBe("function");
|
||||
const ast = parsers.babel(text);
|
||||
@@ -27,10 +27,10 @@ test("allows usage of prettier's supported parsers", () => {
|
||||
expect(output).toBe("bar();\n");
|
||||
});
|
||||
|
||||
test("parsers should allow omit optional arguments", () => {
|
||||
test("parsers should allow omit optional arguments", async () => {
|
||||
let parsers;
|
||||
try {
|
||||
prettier.format("{}", {
|
||||
await prettier.format("{}", {
|
||||
parser(text, builtinParsers) {
|
||||
parsers = builtinParsers;
|
||||
},
|
||||
@@ -54,8 +54,8 @@ test("parsers should allow omit optional arguments", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("allows add empty `trailingComments` array", () => {
|
||||
const output = prettier.format("(foo /* comment */)( )", {
|
||||
test("allows add empty `trailingComments` array", async () => {
|
||||
const output = await prettier.format("(foo /* comment */)( )", {
|
||||
parser(text, parsers) {
|
||||
const ast = parsers.babel(text);
|
||||
|
||||
|
||||
@@ -21,33 +21,37 @@ describe("infers postcss parser with --list-different", () => {
|
||||
});
|
||||
|
||||
describe("infers parser from filename", () => {
|
||||
test("json from .prettierrc", () => {
|
||||
expect(prettier.format(" { } ", { filepath: "x/y/.prettierrc" })).toBe(
|
||||
"{}\n"
|
||||
);
|
||||
});
|
||||
|
||||
test("json from .stylelintrc", () => {
|
||||
expect(prettier.format(" { } ", { filepath: "x/y/.stylelintrc" })).toBe(
|
||||
"{}\n"
|
||||
);
|
||||
});
|
||||
|
||||
test("yaml from .stylelintrc", () => {
|
||||
test("json from .prettierrc", async () => {
|
||||
expect(
|
||||
prettier.format(" extends: '' ", { filepath: "x/y/.stylelintrc" })
|
||||
await prettier.format(" { } ", { filepath: "x/y/.prettierrc" })
|
||||
).toBe("{}\n");
|
||||
});
|
||||
|
||||
test("json from .stylelintrc", async () => {
|
||||
expect(
|
||||
await prettier.format(" { } ", { filepath: "x/y/.stylelintrc" })
|
||||
).toBe("{}\n");
|
||||
});
|
||||
|
||||
test("yaml from .stylelintrc", async () => {
|
||||
expect(
|
||||
await prettier.format(" extends: '' ", {
|
||||
filepath: "x/y/.stylelintrc",
|
||||
})
|
||||
).toBe('extends: ""\n');
|
||||
});
|
||||
|
||||
test("babel from Jakefile", () => {
|
||||
test("babel from Jakefile", async () => {
|
||||
expect(
|
||||
prettier.format("let foo = ( x = 1 ) => x", { filepath: "x/y/Jakefile" })
|
||||
await prettier.format("let foo = ( x = 1 ) => x", {
|
||||
filepath: "x/y/Jakefile",
|
||||
})
|
||||
).toBe("let foo = (x = 1) => x;\n");
|
||||
});
|
||||
|
||||
test("json from .swcrc", () => {
|
||||
test("json from .swcrc", async () => {
|
||||
expect(
|
||||
prettier.format(
|
||||
await prettier.format(
|
||||
/* indent */ `
|
||||
{
|
||||
"jsc": {
|
||||
|
||||
@@ -26,7 +26,7 @@ export default class PrettierFormat extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
format() {
|
||||
async format() {
|
||||
const {
|
||||
worker,
|
||||
code,
|
||||
@@ -37,9 +37,13 @@ export default class PrettierFormat extends React.Component {
|
||||
reformat,
|
||||
} = this.props;
|
||||
|
||||
worker
|
||||
.format(code, options, { ast, doc, comments, reformat })
|
||||
.then((result) => this.setState(result));
|
||||
const result = await worker.format(code, options, {
|
||||
ast,
|
||||
doc,
|
||||
comments,
|
||||
reformat,
|
||||
});
|
||||
this.setState(result);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -15,13 +15,13 @@ class App extends React.Component {
|
||||
this.worker = new WorkerApi("/worker.js");
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.worker.getMetadata().then(({ supportInfo, version }) => {
|
||||
this.setState({
|
||||
loaded: true,
|
||||
availableOptions: supportInfo.options.map(augmentOption),
|
||||
version: fixPrettierVersion(version),
|
||||
});
|
||||
async componentDidMount() {
|
||||
const { supportInfo, version } = await this.worker.getMetadata();
|
||||
|
||||
this.setState({
|
||||
loaded: true,
|
||||
availableOptions: supportInfo.options.map(augmentOption),
|
||||
version: fixPrettierVersion(version),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -30,10 +30,10 @@ for (const file in parsersLocation) {
|
||||
}
|
||||
}
|
||||
|
||||
self.onmessage = function (event) {
|
||||
self.onmessage = async function (event) {
|
||||
self.postMessage({
|
||||
uid: event.data.uid,
|
||||
message: handleMessage(event.data.message),
|
||||
message: await handleMessage(event.data.message),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ function serializeAst(ast) {
|
||||
);
|
||||
}
|
||||
|
||||
function handleMessage(message) {
|
||||
async function handleMessage(message) {
|
||||
if (message.type === "meta") {
|
||||
return {
|
||||
type: "meta",
|
||||
@@ -75,7 +75,7 @@ function handleMessage(message) {
|
||||
const plugins = [{ parsers }];
|
||||
options.plugins = plugins;
|
||||
|
||||
const formatResult = formatCode(message.code, options);
|
||||
const formatResult = await formatCode(message.code, options);
|
||||
|
||||
const response = {
|
||||
formatted: formatResult.formatted,
|
||||
@@ -99,7 +99,7 @@ function handleMessage(message) {
|
||||
|
||||
if (!errored) {
|
||||
try {
|
||||
ast = formatCode(ast, { parser: "json", plugins }).formatted;
|
||||
ast = (await formatCode(ast, { parser: "json", plugins })).formatted;
|
||||
} catch {
|
||||
ast = serializeAst(ast);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ function handleMessage(message) {
|
||||
|
||||
if (message.debug.doc) {
|
||||
try {
|
||||
response.debug.doc = prettier.__debug.formatDoc(
|
||||
response.debug.doc = await prettier.__debug.formatDoc(
|
||||
prettier.__debug.printToDoc(message.code, options),
|
||||
{ parser: "babel", plugins }
|
||||
);
|
||||
@@ -119,16 +119,17 @@ function handleMessage(message) {
|
||||
}
|
||||
|
||||
if (message.debug.comments) {
|
||||
response.debug.comments = formatCode(
|
||||
JSON.stringify(formatResult.comments || []),
|
||||
{ parser: "json", plugins }
|
||||
response.debug.comments = (
|
||||
await formatCode(JSON.stringify(formatResult.comments || []), {
|
||||
parser: "json",
|
||||
plugins,
|
||||
})
|
||||
).formatted;
|
||||
}
|
||||
|
||||
if (message.debug.reformat) {
|
||||
response.debug.reformatted = formatCode(
|
||||
response.formatted,
|
||||
options
|
||||
response.debug.reformatted = (
|
||||
await formatCode(response.formatted, options)
|
||||
).formatted;
|
||||
}
|
||||
|
||||
@@ -136,9 +137,9 @@ function handleMessage(message) {
|
||||
}
|
||||
}
|
||||
|
||||
function formatCode(text, options) {
|
||||
async function formatCode(text, options) {
|
||||
try {
|
||||
return prettier.formatWithCursor(text, options);
|
||||
return await prettier.formatWithCursor(text, options);
|
||||
} catch (e) {
|
||||
if (e.constructor && e.constructor.name === "SyntaxError") {
|
||||
// Likely something wrong with the user's code
|
||||
|
||||
Reference in new issue
Block a user