Skip to content

Commit ec4357b

Browse files
authored
Handle when an option could have multiple types in rule options lists (#498)
1 parent d3795f6 commit ec4357b

5 files changed

Lines changed: 106 additions & 25 deletions

File tree

lib/rule-options-list.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
import { markdownTable } from 'markdown-table';
66
import type { RuleModule } from './types.js';
77
import { RuleOption, getAllNamedOptions } from './rule-options.js';
8-
import { capitalizeOnlyFirstLetter, sanitizeMarkdownTable } from './string.js';
8+
import { sanitizeMarkdownTable } from './string.js';
99

1010
export enum COLUMN_TYPE {
1111
// Alphabetical order.
@@ -64,9 +64,7 @@ function ruleOptionToColumnValues(ruleOption: RuleOption): {
6464
: undefined,
6565
[COLUMN_TYPE.NAME]: `\`${ruleOption.name}\``,
6666
[COLUMN_TYPE.REQUIRED]: ruleOption.required ? 'Yes' : undefined,
67-
[COLUMN_TYPE.TYPE]: ruleOption.type
68-
? capitalizeOnlyFirstLetter(ruleOption.type)
69-
: undefined,
67+
[COLUMN_TYPE.TYPE]: ruleOption.type || undefined,
7068
};
7169

7270
return columns;

lib/rule-options.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import traverse from 'json-schema-traverse';
22
import type { JSONSchema } from '@typescript-eslint/utils';
3+
import { capitalizeOnlyFirstLetter } from './string.js';
34

45
export type RuleOption = {
56
name: string;
@@ -11,6 +12,14 @@ export type RuleOption = {
1112
deprecated?: boolean;
1213
};
1314

15+
function typeToString(
16+
type: JSONSchema.JSONSchema4TypeName[] | JSONSchema.JSONSchema4TypeName
17+
): string {
18+
return Array.isArray(type)
19+
? type.map((item) => capitalizeOnlyFirstLetter(item)).join(', ')
20+
: capitalizeOnlyFirstLetter(type);
21+
}
22+
1423
/**
1524
* Gather a list of named options from a rule schema.
1625
* @param jsonSchema - the JSON schema to check
@@ -43,9 +52,13 @@ export function getAllNamedOptions(
4352
value.type === 'array' &&
4453
!Array.isArray(value.items) &&
4554
value.items?.type
46-
? `${value.items.type.toString()}[]`
55+
? `${
56+
Array.isArray(value.items.type) && value.items.type.length > 1
57+
? `(${typeToString(value.items.type)})`
58+
: typeToString(value.items.type)
59+
}[]`
4760
: value.type
48-
? value.type.toString()
61+
? typeToString(value.type)
4962
: undefined,
5063
description: value.description,
5164
default: value.default,

test/lib/generate/__snapshots__/rule-options-list-test.ts.snap

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ exports[`generate (rule options list) basic generates the documentation 1`] = `
77
## Options
88
<!-- begin auto-generated rule options list -->
99
10-
| Name | Description | Type | Choices | Default | Required | Deprecated |
11-
| :----- | :---------------------------- | :------- | :---------------- | :------- | :------- | :--------- |
12-
| \`arr1\` | | Array | | | | |
13-
| \`arr2\` | | String[] | | | | |
14-
| \`bar\` | Choose how to use the rule. | String | \`always\`, \`never\` | \`always\` | Yes | |
15-
| \`baz\` | | | | \`true\` | Yes | |
16-
| \`biz\` | | | | | | |
17-
| \`foo\` | Enable some kind of behavior. | Boolean | | \`false\` | | Yes |
10+
| Name | Description | Type | Choices | Default | Required | Deprecated |
11+
| :------------------------- | :---------------------------- | :------------------ | :---------------- | :------- | :------- | :--------- |
12+
| \`arr1\` | | Array | | | | |
13+
| \`arrWithArrType\` | | String, Boolean | | | | |
14+
| \`arrWithArrTypeSingleItem\` | | String | | | | |
15+
| \`arrWithItemsArrayType\` | | (String, Boolean)[] | | | | |
16+
| \`arrWithItemsType\` | | String[] | | | | |
17+
| \`bar\` | Choose how to use the rule. | String | \`always\`, \`never\` | \`always\` | Yes | |
18+
| \`baz\` | | | | \`true\` | Yes | |
19+
| \`biz\` | | | | | | |
20+
| \`foo\` | Enable some kind of behavior. | Boolean | | \`false\` | | Yes |
1821
1922
<!-- end auto-generated rule options list -->"
2023
`;

test/lib/generate/rule-options-list-test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,24 @@ describe('generate (rule options list)', function () {
4848
arr1: {
4949
type: "array",
5050
},
51-
arr2: {
51+
arrWithArrType: {
52+
type: ["string", "boolean"],
53+
},
54+
arrWithArrTypeSingleItem: {
55+
type: ["string"],
56+
},
57+
arrWithItemsType: {
5258
type: "array",
5359
items: {
5460
type: "string"
5561
}
5662
},
63+
arrWithItemsArrayType: {
64+
type: "array",
65+
items: {
66+
type: ["string", "boolean"]
67+
}
68+
},
5769
},
5870
required: ["bar"],
5971
additionalProperties: false

test/lib/rule-options-test.ts

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('rule options', function () {
5252
"enum": undefined,
5353
"name": "optionToDoSomething1",
5454
"required": false,
55-
"type": "boolean",
55+
"type": "Boolean",
5656
},
5757
{
5858
"default": undefined,
@@ -64,7 +64,7 @@ describe('rule options', function () {
6464
],
6565
"name": "optionToDoSomething2",
6666
"required": false,
67-
"type": "string",
67+
"type": "String",
6868
},
6969
{
7070
"default": undefined,
@@ -102,7 +102,7 @@ describe('rule options', function () {
102102
"enum": undefined,
103103
"name": "optionToDoSomething",
104104
"required": false,
105-
"type": "boolean",
105+
"type": "Boolean",
106106
},
107107
]
108108
`);
@@ -141,7 +141,7 @@ describe('rule options', function () {
141141
"enum": undefined,
142142
"name": "optionToDoSomething1",
143143
"required": false,
144-
"type": "boolean",
144+
"type": "Boolean",
145145
},
146146
{
147147
"default": false,
@@ -150,7 +150,7 @@ describe('rule options', function () {
150150
"enum": undefined,
151151
"name": "optionToDoSomething2",
152152
"required": false,
153-
"type": "boolean",
153+
"type": "Boolean",
154154
},
155155
]
156156
`);
@@ -182,7 +182,7 @@ describe('rule options', function () {
182182
"enum": undefined,
183183
"name": "optionToDoSomething",
184184
"required": false,
185-
"type": "boolean",
185+
"type": "Boolean",
186186
},
187187
]
188188
`);
@@ -214,7 +214,7 @@ describe('rule options', function () {
214214
"enum": undefined,
215215
"name": "optionToDoSomething",
216216
"required": false,
217-
"type": "boolean",
217+
"type": "Boolean",
218218
},
219219
]
220220
`);
@@ -255,7 +255,7 @@ describe('rule options', function () {
255255
"enum": undefined,
256256
"name": "optionToDoSomething1",
257257
"required": false,
258-
"type": "object[]",
258+
"type": "Object[]",
259259
},
260260
{
261261
"default": undefined,
@@ -264,7 +264,7 @@ describe('rule options', function () {
264264
"enum": undefined,
265265
"name": "optionToDoSomething2",
266266
"required": false,
267-
"type": "array",
267+
"type": "Array",
268268
},
269269
{
270270
"default": false,
@@ -273,7 +273,62 @@ describe('rule options', function () {
273273
"enum": undefined,
274274
"name": "optionToDoSomething2",
275275
"required": false,
276-
"type": "boolean",
276+
"type": "Boolean",
277+
},
278+
]
279+
`);
280+
});
281+
282+
it('handles when type is an array', function () {
283+
expect(
284+
getAllNamedOptions([
285+
{
286+
type: 'object',
287+
properties: {
288+
optionToDoSomething1: {
289+
type: 'array',
290+
items: {
291+
type: ['boolean', 'string'],
292+
},
293+
},
294+
optionToDoSomething2: {
295+
type: ['boolean', 'string'],
296+
},
297+
optionToDoSomething3: {
298+
type: ['boolean'],
299+
},
300+
},
301+
additionalProperties: false,
302+
},
303+
])
304+
).toMatchInlineSnapshot(`
305+
[
306+
{
307+
"default": undefined,
308+
"deprecated": undefined,
309+
"description": undefined,
310+
"enum": undefined,
311+
"name": "optionToDoSomething1",
312+
"required": false,
313+
"type": "(Boolean, String)[]",
314+
},
315+
{
316+
"default": undefined,
317+
"deprecated": undefined,
318+
"description": undefined,
319+
"enum": undefined,
320+
"name": "optionToDoSomething2",
321+
"required": false,
322+
"type": "Boolean, String",
323+
},
324+
{
325+
"default": undefined,
326+
"deprecated": undefined,
327+
"description": undefined,
328+
"enum": undefined,
329+
"name": "optionToDoSomething3",
330+
"required": false,
331+
"type": "Boolean",
277332
},
278333
]
279334
`);

0 commit comments

Comments
 (0)