feat: support detailed `--help` (#2847)

* feat: support detailed --help

* refactor: put alias first, separate with comma

* feat: support detailed --help for --no-option

* docs: add missing type

* docs: remove `This requires node 8 or a transform`

* docs: remove config-precedence's choice descriptions in option.description

* docs: replace `option-name` with `flag`

* docs: update docs for `choices`

* docs: update `help` description

* docs: update error message

* docs: replace `undocumented` with empty string

* refactor: extract `getOptionDefaultValue`

* refactor: dynamically generate `defaults to ...`

* refactor: extract `getOptionWithLevenSuggestion`

* refactor: extract `createChoiceUsages`

* refactor: remove `optionTitleName`

* test: add `--help` tests for all options

* fix: handle `--help --help`

* feat: support `--help <alias>`

* refactor: use `flattenArray`

* feat: handle `--help <unknown>`

* docs: add description for `semi`, `color` and `bracket-spacing`

* fix: remove unnecessary option in `--help`
master
Ika 2017-09-21 13:54:13 +08:00 committed by Simon Lydell
parent 9b0d6b8de0
commit 184e368a9a
7 changed files with 588 additions and 72 deletions

View File

@ -28,6 +28,7 @@
"ignore": "^3.3.3",
"jest-docblock": "21.1.0",
"jest-validate": "21.1.0",
"leven": "2.1.0",
"mem": "1.1.0",
"minimatch": "3.0.4",
"minimist": "1.2.0",

View File

@ -48,8 +48,12 @@ const categoryOrder = [
* // Specify available choices for validation. They will also be displayed
* // in --help as <a|b|c>.
* // Use an object instead of a string if a choice is deprecated and should
* // be treated as `redirect` instead.
* choices?: Array<string | { value: string, deprecated: boolean, redirect: string }>;
* // be treated as `redirect` instead, or if you'd like to add description for
* // the choice.
* choices?: Array<
* | string
* | { value: string, description?: string, deprecated?: boolean, redirect?: string }
* >;
*
* // If the option has a value that is an exception to the regular value
* // constraints, indicate that value here (or use a function for more
@ -75,6 +79,7 @@ const detailedOptions = normalizeDetailedOptions({
type: "boolean",
category: CATEGORY_FORMAT,
forwardToApi: true,
description: "Print spaces between brackets.",
oppositeDescription: "Do not print spaces between brackets."
},
color: {
@ -84,6 +89,7 @@ const detailedOptions = normalizeDetailedOptions({
// See https://github.com/chalk/supports-color/#info for more information.
type: "boolean",
default: true,
description: "Colorize error messages.",
oppositeDescription: "Do not colorize error messages."
},
config: {
@ -97,15 +103,25 @@ const detailedOptions = normalizeDetailedOptions({
type: "choice",
category: CATEGORY_CONFIG,
default: "cli-override",
choices: ["cli-override", "file-override", "prefer-file"],
description: dedent(`
Define in which order config files and CLI options should be evaluated
cli-override | default config => config file => CLI options
file-override | default config => CLI options => config file
prefer-file | default config => config file (if config file is found) or
default config => CLI options (if no config file is found)
Defaults to cli-override.
`)
choices: [
{
value: "cli-override",
description: "CLI options take precedence over config file"
},
{
value: "file-override",
description: "Config file take precedence over CLI options"
},
{
value: "prefer-file",
description: dedent(`
If a config file is found will evaluate it and ignore other CLI options.
If no config file is found CLI options will evaluate as normal.
`)
}
],
description:
"Define in which order config files and CLI options should be evaluated."
},
"cursor-offset": {
type: "int",
@ -136,18 +152,18 @@ const detailedOptions = normalizeDetailedOptions({
deprecated: "Use `--parser flow` instead."
},
help: {
type: "boolean",
type: "flag",
alias: "h",
description: "Show help."
description: dedent(`
Show CLI usage, or details about the given flag.
Example: --help write
`)
},
"ignore-path": {
type: "path",
category: CATEGORY_CONFIG,
default: ".prettierignore",
description: dedent(`
Path to a file with patterns describing files to ignore.
Defaults to ./.prettierignore.
`)
description: "Path to a file with patterns describing files to ignore."
},
"jsx-bracket-same-line": {
type: "boolean",
@ -168,14 +184,14 @@ const detailedOptions = normalizeDetailedOptions({
forwardToApi: true,
exception: value => typeof value === "string", // Allow path to a parser module.
choices: ["flow", "babylon", "typescript", "postcss", "json", "graphql"],
description: "Which parser to use. Defaults to babylon.",
description: "Which parser to use.",
getter: (value, argv) => (argv["flow-parser"] ? "flow" : value)
},
"print-width": {
type: "int",
category: CATEGORY_FORMAT,
forwardToApi: true,
description: "The line length where Prettier will try wrap. Defaults to 80."
description: "The line length where Prettier will try wrap."
},
"range-end": {
type: "int",
@ -186,7 +202,6 @@ const detailedOptions = normalizeDetailedOptions({
Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
Defaults to Infinity.
`)
},
"range-start": {
@ -197,7 +212,6 @@ const detailedOptions = normalizeDetailedOptions({
Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
Defaults to 0.
`)
},
"require-pragma": {
@ -212,6 +226,7 @@ const detailedOptions = normalizeDetailedOptions({
type: "boolean",
category: CATEGORY_FORMAT,
forwardToApi: true,
description: "Print semicolons.",
oppositeDescription:
"Do not print semicolons, except at the beginning of lines which may need them."
},
@ -234,20 +249,27 @@ const detailedOptions = normalizeDetailedOptions({
type: "int",
category: CATEGORY_FORMAT,
forwardToApi: true,
description: "Number of spaces per indentation level. Defaults to 2."
description: "Number of spaces per indentation level."
},
"trailing-comma": {
type: "choice",
category: CATEGORY_FORMAT,
forwardToApi: true,
choices: [
"none",
"es5",
"all",
{ value: "none", description: "No trailing commas." },
{
value: "es5",
description:
"Trailing commas where valid in ES5 (objects, arrays, etc.)"
},
{
value: "all",
description:
"Trailing commas wherever possible (including function arguments)."
},
{ value: "", deprecated: true, redirect: "es5" }
],
description:
"Print trailing commas wherever possible when multi-line. Defaults to none."
description: "Print trailing commas wherever possible when multi-line."
},
"use-tabs": {
type: "boolean",
@ -332,8 +354,11 @@ function normalizeDetailedOptions(rawDetailedOptions) {
: kebabToCamel(name)),
choices:
option.choices &&
option.choices.map(
choice => (typeof choice === "object" ? choice : { value: choice })
option.choices.map(choice =>
Object.assign(
{ description: "", deprecated: false },
typeof choice === "object" ? choice : { value: choice }
)
),
getter: option.getter || (value => value)
});

View File

@ -9,6 +9,7 @@ const globby = require("globby");
const ignore = require("ignore");
const chalk = require("chalk");
const readline = require("readline");
const leven = require("leven");
const prettier = eval("require")("../index");
const cleanAST = require("./clean-ast").cleanAST;
@ -18,6 +19,8 @@ const validator = require("./cli-validator");
const apiDefaultOptions = require("./options").defaults;
const OPTION_USAGE_THRESHOLD = 25;
const CHOICE_USAGE_MARGIN = 3;
const CHOICE_USAGE_INDENTATION = 2;
function getOptions(argv) {
return constant.detailedOptions
@ -333,8 +336,7 @@ function formatFiles(argv) {
});
}
function createUsage() {
const options = constant.detailedOptions;
function getOptionsWithOpposites(options) {
// Add --no-foo after --foo.
const optionsWithOpposites = options.map(option => [
option.description ? option : null,
@ -346,11 +348,21 @@ function createUsage() {
})
: null
]);
const flattenedOptions = [].concat
.apply([], optionsWithOpposites)
.filter(Boolean);
return flattenArray(optionsWithOpposites).filter(Boolean);
}
const groupedOptions = groupBy(flattenedOptions, option => option.category);
function createUsage() {
const options = getOptionsWithOpposites(constant.detailedOptions).filter(
// remove unnecessary option (e.g. `semi`, `color`, etc.), which is only used for --help <flag>
option =>
!(
option.type === "boolean" &&
option.oppositeDescription &&
!option.name.startsWith("no-")
)
);
const groupedOptions = groupBy(options, option => option.category);
const firstCategories = constant.categoryOrder.slice(0, -1);
const lastCategories = constant.categoryOrder.slice(-1);
@ -372,20 +384,31 @@ function createUsage() {
}
function createOptionUsage(option, threshold) {
const name = `--${option.name}`;
const alias = option.alias ? `or -${option.alias}` : null;
const type = createOptionUsageType(option);
const header = [name, alias, type].filter(Boolean).join(" ");
const header = createOptionUsageHeader(option);
const optionDefaultValue = getOptionDefaultValue(option.name);
return createOptionUsageRow(
header,
`${option.description}${optionDefaultValue === undefined
? ""
: `\nDefaults to ${optionDefaultValue}.`}`,
threshold
);
}
function createOptionUsageHeader(option) {
const name = `--${option.name}`;
const alias = option.alias ? `-${option.alias},` : null;
const type = createOptionUsageType(option);
return [alias, name, type].filter(Boolean).join(" ");
}
function createOptionUsageRow(header, content, threshold) {
const separator =
header.length >= threshold
? `\n${" ".repeat(threshold)}`
: " ".repeat(threshold - header.length);
const description = option.description.replace(
/\n/g,
`\n${" ".repeat(threshold)}`
);
const description = content.replace(/\n/g, `\n${" ".repeat(threshold)}`);
return `${header}${separator}${description}`;
}
@ -404,6 +427,109 @@ function createOptionUsageType(option) {
}
}
function flattenArray(array) {
return [].concat.apply([], array);
}
function getOptionWithLevenSuggestion(options, optionName) {
// support aliases
const optionNameContainers = flattenArray(
options.map((option, index) => [
{ value: option.name, index },
option.alias ? { value: option.alias, index } : null
])
).filter(Boolean);
const optionNameContainer = optionNameContainers.find(
optionNameContainer => optionNameContainer.value === optionName
);
if (optionNameContainer !== undefined) {
return options[optionNameContainer.index];
}
const suggestedOptionNameContainer = optionNameContainers.find(
optionNameContainer => leven(optionNameContainer.value, optionName) < 3
);
if (suggestedOptionNameContainer !== undefined) {
const suggestedOptionName = suggestedOptionNameContainer.value;
console.warn(
`Unknown option name "${optionName}", did you mean "${suggestedOptionName}"?\n`
);
return options[suggestedOptionNameContainer.index];
}
console.warn(`Unknown option name "${optionName}"\n`);
return options.find(option => option.name === "help");
}
function createChoiceUsages(choices, margin, indentation) {
const activeChoices = choices.filter(choice => !choice.deprecated);
const threshold =
activeChoices
.map(choice => choice.value.length)
.reduce((current, length) => Math.max(current, length), 0) + margin;
return activeChoices.map(choice =>
indent(
createOptionUsageRow(choice.value, choice.description, threshold),
indentation
)
);
}
function createDetailedUsage(optionName) {
const option = getOptionWithLevenSuggestion(
getOptionsWithOpposites(constant.detailedOptions),
optionName
);
const header = createOptionUsageHeader(option);
const description = `\n\n${indent(option.description, 2)}`;
const choices =
option.type !== "choice"
? ""
: `\n\nValid options:\n\n${createChoiceUsages(
option.choices,
CHOICE_USAGE_MARGIN,
CHOICE_USAGE_INDENTATION
).join("\n")}`;
const optionDefaultValue = getOptionDefaultValue(option.name);
const defaults =
optionDefaultValue !== undefined
? `\n\nDefault: ${optionDefaultValue}`
: "";
return `${header}${description}${choices}${defaults}`;
}
function getOptionDefaultValue(optionName) {
// --no-option
if (!(optionName in constant.detailedOptionMap)) {
return undefined;
}
const option = constant.detailedOptionMap[optionName];
if (option.default !== undefined) {
return option.default;
}
const optionCamelName = kebabToCamel(optionName);
if (optionCamelName in apiDefaultOptions) {
return apiDefaultOptions[optionCamelName];
}
return undefined;
}
function kebabToCamel(str) {
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
}
function indent(str, spaces) {
return str.replace(/^/gm, " ".repeat(spaces));
}
@ -511,5 +637,6 @@ module.exports = {
formatStdin,
formatFiles,
createUsage,
createDetailedUsage,
normalizeArgv
};

View File

@ -20,8 +20,12 @@ function run(args) {
process.exit(0);
}
if (argv["help"]) {
console.log(util.createUsage());
if (argv["help"] !== undefined) {
console.log(
typeof argv["help"] === "string" && argv["help"] !== ""
? util.createDetailedUsage(argv["help"])
: util.createUsage()
);
process.exit(0);
}

View File

@ -1,5 +1,276 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`show detailed usage with --help bracket-spacing 1`] = `
"--bracket-spacing
Print spaces between brackets.
Default: true
"
`;
exports[`show detailed usage with --help color 1`] = `
"--color
Colorize error messages.
Default: true
"
`;
exports[`show detailed usage with --help config 1`] = `
"--config <path>
Path to a Prettier configuration file (.prettierrc, package.json, prettier.config.js).
"
`;
exports[`show detailed usage with --help config-precedence 1`] = `
"--config-precedence <cli-override|file-override|prefer-file>
Define in which order config files and CLI options should be evaluated.
Valid options:
cli-override CLI options take precedence over config file
file-override Config file take precedence over CLI options
prefer-file If a config file is found will evaluate it and ignore other CLI options.
If no config file is found CLI options will evaluate as normal.
Default: cli-override
"
`;
exports[`show detailed usage with --help cursor-offset 1`] = `
"--cursor-offset <int>
Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Default: -1
"
`;
exports[`show detailed usage with --help find-config-path 1`] = `
"--find-config-path <path>
Find and print the path to a configuration file for the given input file.
"
`;
exports[`show detailed usage with --help help 1`] = `
"-h, --help <flag>
Show CLI usage, or details about the given flag.
Example: --help write
"
`;
exports[`show detailed usage with --help ignore-path 1`] = `
"--ignore-path <path>
Path to a file with patterns describing files to ignore.
Default: .prettierignore
"
`;
exports[`show detailed usage with --help jsx-bracket-same-line 1`] = `
"--jsx-bracket-same-line
Put > on the last line instead of at a new line.
Default: false
"
`;
exports[`show detailed usage with --help l (alias) 1`] = `
"-l, --list-different
Print the names of files that are different from Prettier's formatting.
"
`;
exports[`show detailed usage with --help list-different 1`] = `
"-l, --list-different
Print the names of files that are different from Prettier's formatting.
"
`;
exports[`show detailed usage with --help no-bracket-spacing 1`] = `
"--no-bracket-spacing
Do not print spaces between brackets.
"
`;
exports[`show detailed usage with --help no-color 1`] = `
"--no-color
Do not colorize error messages.
"
`;
exports[`show detailed usage with --help no-config 1`] = `
"--no-config
Do not look for a configuration file.
"
`;
exports[`show detailed usage with --help no-semi 1`] = `
"--no-semi
Do not print semicolons, except at the beginning of lines which may need them.
"
`;
exports[`show detailed usage with --help parser 1`] = `
"--parser <flow|babylon|typescript|postcss|json|graphql>
Which parser to use.
Valid options:
flow
babylon
typescript
postcss
json
graphql
Default: babylon
"
`;
exports[`show detailed usage with --help print-width 1`] = `
"--print-width <int>
The line length where Prettier will try wrap.
Default: 80
"
`;
exports[`show detailed usage with --help range-end 1`] = `
"--range-end <int>
Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
Default: Infinity
"
`;
exports[`show detailed usage with --help range-start 1`] = `
"--range-start <int>
Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
Default: 0
"
`;
exports[`show detailed usage with --help require-pragma 1`] = `
"--require-pragma
Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
Default: false
"
`;
exports[`show detailed usage with --help semi 1`] = `
"--semi
Print semicolons.
Default: true
"
`;
exports[`show detailed usage with --help single-quote 1`] = `
"--single-quote
Use single quotes instead of double quotes.
Default: false
"
`;
exports[`show detailed usage with --help stdin 1`] = `
"--stdin
Force reading input from stdin.
"
`;
exports[`show detailed usage with --help stdin-filepath 1`] = `
"--stdin-filepath <path>
Path to the file to pretend that stdin comes from.
"
`;
exports[`show detailed usage with --help tab-width 1`] = `
"--tab-width <int>
Number of spaces per indentation level.
Default: 2
"
`;
exports[`show detailed usage with --help trailing-comma 1`] = `
"--trailing-comma <none|es5|all>
Print trailing commas wherever possible when multi-line.
Valid options:
none No trailing commas.
es5 Trailing commas where valid in ES5 (objects, arrays, etc.)
all Trailing commas wherever possible (including function arguments).
Default: none
"
`;
exports[`show detailed usage with --help use-tabs 1`] = `
"--use-tabs
Indent with tabs instead of spaces.
Default: false
"
`;
exports[`show detailed usage with --help version 1`] = `
"-v, --version
Print Prettier version.
"
`;
exports[`show detailed usage with --help with-node-modules 1`] = `
"--with-node-modules
Process files inside 'node_modules' directory.
"
`;
exports[`show detailed usage with --help write 1`] = `
"--write
Edit files in-place. (Beware!)
"
`;
exports[`show usage with --help 1`] = `
"Usage: prettier [options] [file/glob ...]
@ -8,44 +279,48 @@ Stdin is read if it is piped to Prettier and no files are given.
Output options:
--list-different or -l Print the names of files that are different from Prettier's formatting.
-l, --list-different Print the names of files that are different from Prettier's formatting.
--write Edit files in-place. (Beware!)
Format options:
--no-bracket-spacing Do not print spaces between brackets.
--jsx-bracket-same-line Put > on the last line instead of at a new line.
Defaults to false.
--parser <flow|babylon|typescript|postcss|json|graphql>
Which parser to use. Defaults to babylon.
--print-width <int> The line length where Prettier will try wrap. Defaults to 80.
Which parser to use.
Defaults to babylon.
--print-width <int> The line length where Prettier will try wrap.
Defaults to 80.
--no-semi Do not print semicolons, except at the beginning of lines which may need them.
--single-quote Use single quotes instead of double quotes.
--tab-width <int> Number of spaces per indentation level. Defaults to 2.
Defaults to false.
--tab-width <int> Number of spaces per indentation level.
Defaults to 2.
--trailing-comma <none|es5|all>
Print trailing commas wherever possible when multi-line. Defaults to none.
Print trailing commas wherever possible when multi-line.
Defaults to none.
--use-tabs Indent with tabs instead of spaces.
Defaults to false.
Config options:
--config <path> Path to a Prettier configuration file (.prettierrc, package.json, prettier.config.js).
--no-config Do not look for a configuration file.
--config-precedence <cli-override|file-override|prefer-file>
Define in which order config files and CLI options should be evaluated
cli-override | default config => config file => CLI options
file-override | default config => CLI options => config file
prefer-file | default config => config file (if config file is found) or
default config => CLI options (if no config file is found)
Define in which order config files and CLI options should be evaluated.
Defaults to cli-override.
--find-config-path <path>
Find and print the path to a configuration file for the given input file.
--ignore-path <path> Path to a file with patterns describing files to ignore.
Defaults to ./.prettierignore.
Defaults to .prettierignore.
--with-node-modules Process files inside 'node_modules' directory.
Editor options:
--cursor-offset <int> Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Defaults to -1.
--range-end <int> Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
@ -58,14 +333,54 @@ Editor options:
Other options:
--no-color Do not colorize error messages.
--help or -h Show help.
-h, --help <flag> Show CLI usage, or details about the given flag.
Example: --help write
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
Defaults to false.
--stdin Force reading input from stdin.
--stdin-filepath <path> Path to the file to pretend that stdin comes from.
--version or -v Print Prettier version.
-v, --version Print Prettier version.
"
`;
exports[`show warning with --help not-found (typo) 1`] = `
"--parser <flow|babylon|typescript|postcss|json|graphql>
Which parser to use.
Valid options:
flow
babylon
typescript
postcss
json
graphql
Default: babylon
"
`;
exports[`show warning with --help not-found (typo) 2`] = `
"Unknown option name \\"parserr\\", did you mean \\"parser\\"?
"
`;
exports[`show warning with --help not-found 1`] = `
"-h, --help <flag>
Show CLI usage, or details about the given flag.
Example: --help write
"
`;
exports[`show warning with --help not-found 2`] = `
"Unknown option name \\"not-found\\"
"
`;
@ -77,44 +392,48 @@ Stdin is read if it is piped to Prettier and no files are given.
Output options:
--list-different or -l Print the names of files that are different from Prettier's formatting.
-l, --list-different Print the names of files that are different from Prettier's formatting.
--write Edit files in-place. (Beware!)
Format options:
--no-bracket-spacing Do not print spaces between brackets.
--jsx-bracket-same-line Put > on the last line instead of at a new line.
Defaults to false.
--parser <flow|babylon|typescript|postcss|json|graphql>
Which parser to use. Defaults to babylon.
--print-width <int> The line length where Prettier will try wrap. Defaults to 80.
Which parser to use.
Defaults to babylon.
--print-width <int> The line length where Prettier will try wrap.
Defaults to 80.
--no-semi Do not print semicolons, except at the beginning of lines which may need them.
--single-quote Use single quotes instead of double quotes.
--tab-width <int> Number of spaces per indentation level. Defaults to 2.
Defaults to false.
--tab-width <int> Number of spaces per indentation level.
Defaults to 2.
--trailing-comma <none|es5|all>
Print trailing commas wherever possible when multi-line. Defaults to none.
Print trailing commas wherever possible when multi-line.
Defaults to none.
--use-tabs Indent with tabs instead of spaces.
Defaults to false.
Config options:
--config <path> Path to a Prettier configuration file (.prettierrc, package.json, prettier.config.js).
--no-config Do not look for a configuration file.
--config-precedence <cli-override|file-override|prefer-file>
Define in which order config files and CLI options should be evaluated
cli-override | default config => config file => CLI options
file-override | default config => CLI options => config file
prefer-file | default config => config file (if config file is found) or
default config => CLI options (if no config file is found)
Define in which order config files and CLI options should be evaluated.
Defaults to cli-override.
--find-config-path <path>
Find and print the path to a configuration file for the given input file.
--ignore-path <path> Path to a file with patterns describing files to ignore.
Defaults to ./.prettierignore.
Defaults to .prettierignore.
--with-node-modules Process files inside 'node_modules' directory.
Editor options:
--cursor-offset <int> Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Defaults to -1.
--range-end <int> Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
@ -127,12 +446,14 @@ Editor options:
Other options:
--no-color Do not colorize error messages.
--help or -h Show help.
-h, --help <flag> Show CLI usage, or details about the given flag.
Example: --help write
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
Defaults to false.
--stdin Force reading input from stdin.
--stdin-filepath <path> Path to the file to pretend that stdin comes from.
--version or -v Print Prettier version.
-v, --version Print Prettier version.
"

View File

@ -2,6 +2,7 @@
const prettier = require("../..");
const runPrettier = require("../runPrettier");
const constant = require("../../src/cli-constant");
test("show version with --version", () => {
const result = runPrettier("cli/with-shebang", ["--version"]);
@ -17,6 +18,43 @@ test("show usage with --help", () => {
expect(result.status).toEqual(0);
});
test(`show detailed usage with --help l (alias)`, () => {
const result = runPrettier("cli", ["--help", "l"]);
expect(result.stdout).toMatchSnapshot();
expect(result.status).toEqual(0);
});
constant.detailedOptions.forEach(option => {
const optionNames = [
option.description ? option.name : null,
option.oppositeDescription ? `no-${option.name}` : null
].filter(Boolean);
optionNames.forEach(optionName => {
test(`show detailed usage with --help ${optionName}`, () => {
const result = runPrettier("cli", ["--help", optionName]);
expect(result.stdout).toMatchSnapshot();
expect(result.status).toEqual(0);
});
});
});
test("show warning with --help not-found", () => {
const result = runPrettier("cli", ["--help", "not-found"]);
expect(result.stdout).toMatchSnapshot();
expect(result.stderr).toMatchSnapshot();
expect(result.status).toEqual(0);
});
test("show warning with --help not-found (typo)", () => {
const result = runPrettier("cli", ["--help", "parserr"]);
expect(result.stdout).toMatchSnapshot();
expect(result.stderr).toMatchSnapshot();
expect(result.status).toEqual(0);
});
test("throw error with --write + --debug-check", () => {
const result = runPrettier("cli", ["--write", "--debug-check"]);

View File

@ -2581,7 +2581,7 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
leven@^2.1.0:
leven@2.1.0, leven@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"