Skip to content

Commit c73f5b4

Browse files
committed
Implement basic validation for native types with non array type specified
1 parent 0d7b40e commit c73f5b4

File tree

2 files changed

+72
-28
lines changed

2 files changed

+72
-28
lines changed

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

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ module.exports = {
3131
},
3232

3333
create (context) {
34-
// variables should be defined here
35-
3634
// ----------------------------------------------------------------------
3735
// Helpers
3836
// ----------------------------------------------------------------------
@@ -48,6 +46,32 @@ module.exports = {
4846
)
4947
}
5048

49+
function ucFirst (text) {
50+
return text[0].toUpperCase() + text.slice(1)
51+
}
52+
53+
function getValueType (node) {
54+
if (node.type === 'CallExpression') { // Symbol(), Number() ...
55+
if (node.callee.type === 'Identifier' && NATIVE_TYPES.has(node.callee.name)) {
56+
return node.callee.name
57+
}
58+
} else if (node.type === 'TemplateLiteral') { // String
59+
return 'String'
60+
} else if (node.type === 'Literal') { // String, Boolean, Number
61+
if (node.value === null) return null
62+
const type = ucFirst(typeof node.value)
63+
if (NATIVE_TYPES.has(type)) {
64+
return type
65+
}
66+
} else if (node.type === 'ArrayExpression') { // Array
67+
return 'Array'
68+
} else if (node.type === 'ObjectExpression') { // Array
69+
return 'Object'
70+
}
71+
// FunctionExpression, ArrowFunctionExpression
72+
return null
73+
}
74+
5175
// ----------------------------------------------------------------------
5276
// Public
5377
// ----------------------------------------------------------------------
@@ -67,16 +91,28 @@ module.exports = {
6791

6892
for (const prop of properties) {
6993
const type = getPropertyNode(prop.value, 'type')
70-
if (!type || !NATIVE_TYPES.has(type.value.name)) return
94+
let typeName = type ? type.value.name : null
95+
if (!NATIVE_TYPES.has(typeName)) {
96+
return
97+
}
98+
99+
if (typeName === 'Object' || typeName === 'Array') {
100+
typeName = 'Function'
101+
}
71102

72103
const def = getPropertyNode(prop.value, 'default')
73104
if (!def) return
74105

106+
const defType = getValueType(def.value)
107+
if (defType === typeName) return
108+
75109
context.report({
76110
node: def,
77-
message: "Prop '{{name}}' has invalid default value.",
111+
message: "Type of default value prop '{{name}}' is a '{{defType}}' but should be a '{{typeName}}'.",
78112
data: {
79-
name: prop.key.name
113+
name: prop.key.name,
114+
defType,
115+
typeName
80116
}
81117
})
82118
}

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

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ ruleTester.run('require-valid-default-prop', rule, {
8282
propK: {
8383
type: Array,
8484
default () { }
85+
},
86+
propI: {
87+
type: Symbol,
88+
default: Symbol('a')
89+
},
90+
propJ: {
91+
type: String,
92+
default: \`Foo\`
8593
}
8694
}
8795
})`,
@@ -102,7 +110,7 @@ ruleTester.run('require-valid-default-prop', rule, {
102110
}`,
103111
parserOptions,
104112
errors: [{
105-
message: "Prop 'foo' has invalid default value.",
113+
message: "Type of default value prop 'foo' is a 'String' but should be a 'Number'.",
106114
type: 'Property',
107115
line: 5
108116
}]
@@ -119,7 +127,7 @@ ruleTester.run('require-valid-default-prop', rule, {
119127
}`,
120128
parserOptions,
121129
errors: [{
122-
message: "Prop 'foo' has invalid default value.",
130+
message: "Type of default value prop 'foo' is a 'Boolean' but should be a 'Number'.",
123131
type: 'Property',
124132
line: 5
125133
}]
@@ -136,7 +144,7 @@ ruleTester.run('require-valid-default-prop', rule, {
136144
}`,
137145
parserOptions,
138146
errors: [{
139-
message: "Prop 'foo' has invalid default value.",
147+
message: "Type of default value prop 'foo' is a 'Object' but should be a 'Number'.",
140148
type: 'Property',
141149
line: 5
142150
}]
@@ -153,7 +161,7 @@ ruleTester.run('require-valid-default-prop', rule, {
153161
}`,
154162
parserOptions,
155163
errors: [{
156-
message: "Prop 'foo' has invalid default value.",
164+
message: "Type of default value prop 'foo' is a 'Array' but should be a 'Number'.",
157165
type: 'Property',
158166
line: 5
159167
}]
@@ -170,7 +178,7 @@ ruleTester.run('require-valid-default-prop', rule, {
170178
}`,
171179
parserOptions,
172180
errors: [{
173-
message: "Prop 'foo' has invalid default value.",
181+
message: "Type of default value prop 'foo' is a 'Number' but should be a 'String'.",
174182
type: 'Property',
175183
line: 5
176184
}]
@@ -187,7 +195,7 @@ ruleTester.run('require-valid-default-prop', rule, {
187195
}`,
188196
parserOptions,
189197
errors: [{
190-
message: "Prop 'foo' has invalid default value.",
198+
message: "Type of default value prop 'foo' is a 'Object' but should be a 'String'.",
191199
type: 'Property',
192200
line: 5
193201
}]
@@ -204,7 +212,7 @@ ruleTester.run('require-valid-default-prop', rule, {
204212
}`,
205213
parserOptions,
206214
errors: [{
207-
message: "Prop 'foo' has invalid default value.",
215+
message: "Type of default value prop 'foo' is a 'Array' but should be a 'String'.",
208216
type: 'Property',
209217
line: 5
210218
}]
@@ -221,7 +229,7 @@ ruleTester.run('require-valid-default-prop', rule, {
221229
}`,
222230
parserOptions,
223231
errors: [{
224-
message: "Prop 'foo' has invalid default value.",
232+
message: "Type of default value prop 'foo' is a 'String' but should be a 'Boolean'.",
225233
type: 'Property',
226234
line: 5
227235
}]
@@ -238,7 +246,7 @@ ruleTester.run('require-valid-default-prop', rule, {
238246
}`,
239247
parserOptions,
240248
errors: [{
241-
message: "Prop 'foo' has invalid default value.",
249+
message: "Type of default value prop 'foo' is a 'Number' but should be a 'Boolean'.",
242250
type: 'Property',
243251
line: 5
244252
}]
@@ -255,7 +263,7 @@ ruleTester.run('require-valid-default-prop', rule, {
255263
}`,
256264
parserOptions,
257265
errors: [{
258-
message: "Prop 'foo' has invalid default value.",
266+
message: "Type of default value prop 'foo' is a 'Object' but should be a 'Boolean'.",
259267
type: 'Property',
260268
line: 5
261269
}]
@@ -272,7 +280,7 @@ ruleTester.run('require-valid-default-prop', rule, {
272280
}`,
273281
parserOptions,
274282
errors: [{
275-
message: "Prop 'foo' has invalid default value.",
283+
message: "Type of default value prop 'foo' is a 'Array' but should be a 'Boolean'.",
276284
type: 'Property',
277285
line: 5
278286
}]
@@ -289,7 +297,7 @@ ruleTester.run('require-valid-default-prop', rule, {
289297
}`,
290298
parserOptions,
291299
errors: [{
292-
message: "Prop 'foo' has invalid default value.",
300+
message: "Type of default value prop 'foo' is a 'String' but should be a 'Function'.",
293301
type: 'Property',
294302
line: 5
295303
}]
@@ -306,7 +314,7 @@ ruleTester.run('require-valid-default-prop', rule, {
306314
}`,
307315
parserOptions,
308316
errors: [{
309-
message: "Prop 'foo' has invalid default value.",
317+
message: "Type of default value prop 'foo' is a 'Number' but should be a 'Function'.",
310318
type: 'Property',
311319
line: 5
312320
}]
@@ -323,7 +331,7 @@ ruleTester.run('require-valid-default-prop', rule, {
323331
}`,
324332
parserOptions,
325333
errors: [{
326-
message: "Prop 'foo' has invalid default value.",
334+
message: "Type of default value prop 'foo' is a 'Boolean' but should be a 'Function'.",
327335
type: 'Property',
328336
line: 5
329337
}]
@@ -340,7 +348,7 @@ ruleTester.run('require-valid-default-prop', rule, {
340348
}`,
341349
parserOptions,
342350
errors: [{
343-
message: "Prop 'foo' has invalid default value.",
351+
message: "Type of default value prop 'foo' is a 'Object' but should be a 'Function'.",
344352
type: 'Property',
345353
line: 5
346354
}]
@@ -351,13 +359,13 @@ ruleTester.run('require-valid-default-prop', rule, {
351359
props: {
352360
foo: {
353361
type: Object,
354-
default: []
355-
}
362+
default: []
363+
}
356364
}
357365
}`,
358366
parserOptions,
359367
errors: [{
360-
message: "Prop 'foo' has invalid default value.",
368+
message: "Type of default value prop 'foo' is a 'Array' but should be a 'Function'.",
361369
type: 'Property',
362370
line: 5
363371
}]
@@ -374,7 +382,7 @@ ruleTester.run('require-valid-default-prop', rule, {
374382
}`,
375383
parserOptions,
376384
errors: [{
377-
message: "Prop 'foo' has invalid default value.",
385+
message: "Type of default value prop 'foo' is a 'String' but should be a 'Function'.",
378386
type: 'Property',
379387
line: 5
380388
}]
@@ -391,7 +399,7 @@ ruleTester.run('require-valid-default-prop', rule, {
391399
}`,
392400
parserOptions,
393401
errors: [{
394-
message: "Prop 'foo' has invalid default value.",
402+
message: "Type of default value prop 'foo' is a 'Number' but should be a 'Function'.",
395403
type: 'Property',
396404
line: 5
397405
}]
@@ -408,7 +416,7 @@ ruleTester.run('require-valid-default-prop', rule, {
408416
}`,
409417
parserOptions,
410418
errors: [{
411-
message: "Prop 'foo' has invalid default value.",
419+
message: "Type of default value prop 'foo' is a 'Boolean' but should be a 'Function'.",
412420
type: 'Property',
413421
line: 5
414422
}]
@@ -425,7 +433,7 @@ ruleTester.run('require-valid-default-prop', rule, {
425433
}`,
426434
parserOptions,
427435
errors: [{
428-
message: "Prop 'foo' has invalid default value.",
436+
message: "Type of default value prop 'foo' is a 'Object' but should be a 'Function'.",
429437
type: 'Property',
430438
line: 5
431439
}]
@@ -442,7 +450,7 @@ ruleTester.run('require-valid-default-prop', rule, {
442450
}`,
443451
parserOptions,
444452
errors: [{
445-
message: "Prop 'foo' has invalid default value.",
453+
message: "Type of default value prop 'foo' is a 'Array' but should be a 'Function'.",
446454
type: 'Property',
447455
line: 5
448456
}]

0 commit comments

Comments
 (0)