Skip to content

Commit 766b637

Browse files
authored
Ignore Boolean props in require-default-prop rule (#529)
* Ignore Boolean props in require-default-prop rule * Support edgecase with array of types
1 parent 6a117c2 commit 766b637

File tree

3 files changed

+85
-14
lines changed

3 files changed

+85
-14
lines changed

docs/rules/require-default-prop.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
44

5-
This rule requires default value to be set for each props that are not marked as `required`.
5+
This rule requires default value to be set for each props that are not marked as `required` (except `Boolean` props).
66

77
## Rule Details
88

@@ -12,10 +12,11 @@ Examples of **incorrect** code for this rule:
1212
props: {
1313
a: Number,
1414
b: [Number, String],
15-
c: {
15+
c: [Boolean, Number],
16+
d: {
1617
type: Number
1718
},
18-
d: {
19+
e: {
1920
type: Number,
2021
required: false
2122
}
@@ -38,6 +39,9 @@ props: {
3839
type: Number,
3940
default: 0,
4041
required: false
42+
},
43+
d: {
44+
type: Boolean, // Boolean is the only type that doesn't require default
4145
}
4246
}
4347
```

lib/rules/require-default-prop.js

+47-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ module.exports = {
6161
/**
6262
* Finds all props that don't have a default value set
6363
* @param {Property} propsNode - Vue component's "props" node
64-
* @return {boolean}
64+
* @return {Array} Array of props without "default" value
6565
*/
6666
function findPropsWithoutDefaultValue (propsNode) {
6767
return propsNode.value.properties
@@ -75,6 +75,50 @@ module.exports = {
7575
})
7676
}
7777

78+
/**
79+
* Detects whether given value node is a Boolean type
80+
* @param {Node} value
81+
* @return {Boolean}
82+
*/
83+
function isValueNodeOfBooleanType (value) {
84+
return (
85+
value.type === 'Identifier' &&
86+
value.name === 'Boolean'
87+
) || (
88+
value.type === 'ArrayExpression' &&
89+
value.elements.length === 1 &&
90+
value.elements[0].type === 'Identifier' &&
91+
value.elements[0].name === 'Boolean'
92+
)
93+
}
94+
95+
/**
96+
* Detects whether given prop node is a Boolean
97+
* @param {Node} prop
98+
* @return {Boolean}
99+
*/
100+
function isBooleanProp (prop) {
101+
const value = prop.value
102+
103+
return isValueNodeOfBooleanType(value) || (
104+
value.type === 'ObjectExpression' &&
105+
value.properties.find(p =>
106+
p.key.type === 'Identifier' &&
107+
p.key.name === 'type' &&
108+
isValueNodeOfBooleanType(p.value)
109+
)
110+
)
111+
}
112+
113+
/**
114+
* Excludes purely Boolean props from the Array
115+
* @param {Array} props - Array with props
116+
* @return {Array}
117+
*/
118+
function excludeBooleanProps (props) {
119+
return props.filter(prop => !isBooleanProp(prop))
120+
}
121+
78122
// ----------------------------------------------------------------------
79123
// Public
80124
// ----------------------------------------------------------------------
@@ -91,8 +135,9 @@ module.exports = {
91135
if (!propsNode) return
92136

93137
const propsWithoutDefault = findPropsWithoutDefaultValue(propsNode)
138+
const propsToReport = excludeBooleanProps(propsWithoutDefault)
94139

95-
propsWithoutDefault.forEach(prop => {
140+
propsToReport.forEach(prop => {
96141
context.report({
97142
node: prop,
98143
message: `Prop '{{propName}}' requires default value to be set.`,

tests/lib/rules/require-default-prop.js

+31-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const parserOptions = {
1919
// Tests
2020
// ------------------------------------------------------------------------------
2121

22-
const ruleTester = new RuleTester()
22+
const ruleTester = new RuleTester({ parserOptions })
2323
ruleTester.run('require-default-prop', rule, {
2424

2525
valid: [
@@ -46,12 +46,27 @@ ruleTester.run('require-default-prop', rule, {
4646
required: false,
4747
'default': 'lorem'
4848
},
49+
e: {
50+
type: Boolean
51+
},
52+
f: {
53+
type: Boolean,
54+
required: false
55+
},
56+
g: {
57+
type: Boolean,
58+
default: true
59+
},
60+
h: {
61+
type: [Boolean]
62+
},
63+
i: Boolean,
64+
j: [Boolean],
4965
// eslint-disable-next-line require-default-prop
50-
e: Number
66+
k: Number
5167
}
5268
}
53-
`,
54-
parserOptions
69+
`
5570
},
5671
{
5772
filename: 'test.vue',
@@ -70,8 +85,7 @@ ruleTester.run('require-default-prop', rule, {
7085
}
7186
}
7287
}
73-
`,
74-
parserOptions
88+
`
7589
},
7690
{
7791
filename: 'test.vue',
@@ -98,8 +112,7 @@ ruleTester.run('require-default-prop', rule, {
98112
}
99113
}
100114
}
101-
`,
102-
parserOptions
115+
`
103116
}
104117
],
105118

@@ -117,11 +130,14 @@ ruleTester.run('require-default-prop', rule, {
117130
d: {
118131
type: Number,
119132
required: false
133+
},
134+
e: [Boolean, String],
135+
f: {
136+
type: [Boolean, String],
120137
}
121138
}
122139
}
123140
`,
124-
parserOptions,
125141
errors: [{
126142
message: `Prop 'a' requires default value to be set.`,
127143
line: 4
@@ -134,6 +150,12 @@ ruleTester.run('require-default-prop', rule, {
134150
}, {
135151
message: `Prop 'd' requires default value to be set.`,
136152
line: 9
153+
}, {
154+
message: `Prop 'e' requires default value to be set.`,
155+
line: 13
156+
}, {
157+
message: `Prop 'f' requires default value to be set.`,
158+
line: 14
137159
}]
138160
}
139161
]

0 commit comments

Comments
 (0)