Skip to content

Commit 59860b0

Browse files
Yuriy Alekseyevyyx990803
Yuriy Alekseyev
authored andcommitted
refactor: make the warning messages more explicit (close #7764) (#7881)
1 parent c944827 commit 59860b0

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

src/core/util/props.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,10 @@ function assertProp (
127127
valid = assertedType.valid
128128
}
129129
}
130+
130131
if (!valid) {
131132
warn(
132-
`Invalid prop: type check failed for prop "${name}".` +
133-
` Expected ${expectedTypes.map(capitalize).join(', ')}` +
134-
`, got ${toRawType(value)}.`,
133+
getInvalidTypeMessage(name, value, expectedTypes),
135134
vm
136135
)
137136
return
@@ -200,3 +199,43 @@ function getTypeIndex (type, expectedTypes): number {
200199
}
201200
return -1
202201
}
202+
203+
function getInvalidTypeMessage (name, value, expectedTypes) {
204+
let message = `Invalid prop: type check failed for prop "${name}".` +
205+
` Expected ${expectedTypes.map(capitalize).join(', ')}`
206+
const expectedType = expectedTypes[0]
207+
const receivedType = toRawType(value)
208+
const expectedValue = styleValue(value, expectedType)
209+
const receivedValue = styleValue(value, receivedType)
210+
// check if we need to specify expected value
211+
if (expectedTypes.length === 1 &&
212+
isExplicable(expectedType) &&
213+
!isBoolean(expectedType, receivedType)) {
214+
message += ` with value ${expectedValue}`
215+
}
216+
message += `, got ${receivedType} `
217+
// check if we need to specify received value
218+
if (isExplicable(receivedType)) {
219+
message += `with value ${receivedValue}.`
220+
}
221+
return message
222+
}
223+
224+
function styleValue (value, type) {
225+
if (type === 'String') {
226+
return `"${value}"`
227+
} else if (type === 'Number') {
228+
return `${Number(value)}`
229+
} else {
230+
return `${value}`
231+
}
232+
}
233+
234+
function isExplicable (value) {
235+
const explicitTypes = ['string', 'number', 'boolean']
236+
return explicitTypes.some(elem => value.toLowerCase() === elem)
237+
}
238+
239+
function isBoolean (...args) {
240+
return args.some(elem => elem.toLowerCase() === 'boolean')
241+
}

test/unit/features/options/props.spec.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,42 +171,56 @@ describe('Options props', () => {
171171
makeInstance('hello', String)
172172
expect(console.error.calls.count()).toBe(0)
173173
makeInstance(123, String)
174-
expect('Expected String').toHaveBeenWarned()
174+
expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned()
175175
})
176176

177177
it('number', () => {
178178
makeInstance(123, Number)
179179
expect(console.error.calls.count()).toBe(0)
180180
makeInstance('123', Number)
181-
expect('Expected Number').toHaveBeenWarned()
181+
expect('Expected Number with value 123, got String with value "123"').toHaveBeenWarned()
182+
})
183+
184+
it('number & boolean', () => {
185+
makeInstance(123, Number)
186+
expect(console.error.calls.count()).toBe(0)
187+
makeInstance(false, Number)
188+
expect('Expected Number, got Boolean with value false').toHaveBeenWarned()
189+
})
190+
191+
it('string & boolean', () => {
192+
makeInstance('hello', String)
193+
expect(console.error.calls.count()).toBe(0)
194+
makeInstance(true, String)
195+
expect('Expected String, got Boolean with value true').toHaveBeenWarned()
182196
})
183197

184198
it('boolean', () => {
185199
makeInstance(true, Boolean)
186200
expect(console.error.calls.count()).toBe(0)
187201
makeInstance('123', Boolean)
188-
expect('Expected Boolean').toHaveBeenWarned()
202+
expect('Expected Boolean, got String with value "123"').toHaveBeenWarned()
189203
})
190204

191205
it('function', () => {
192206
makeInstance(() => {}, Function)
193207
expect(console.error.calls.count()).toBe(0)
194208
makeInstance(123, Function)
195-
expect('Expected Function').toHaveBeenWarned()
209+
expect('Expected Function, got Number with value 123').toHaveBeenWarned()
196210
})
197211

198212
it('object', () => {
199213
makeInstance({}, Object)
200214
expect(console.error.calls.count()).toBe(0)
201215
makeInstance([], Object)
202-
expect('Expected Object').toHaveBeenWarned()
216+
expect('Expected Object, got Array').toHaveBeenWarned()
203217
})
204218

205219
it('array', () => {
206220
makeInstance([], Array)
207221
expect(console.error.calls.count()).toBe(0)
208222
makeInstance({}, Array)
209-
expect('Expected Array').toHaveBeenWarned()
223+
expect('Expected Array, got Object').toHaveBeenWarned()
210224
})
211225

212226
it('primitive wrapper objects', () => {
@@ -225,7 +239,7 @@ describe('Options props', () => {
225239
makeInstance(Symbol('foo'), Symbol)
226240
expect(console.error.calls.count()).toBe(0)
227241
makeInstance({}, Symbol)
228-
expect('Expected Symbol').toHaveBeenWarned()
242+
expect('Expected Symbol, got Object').toHaveBeenWarned()
229243
})
230244
}
231245

@@ -257,7 +271,7 @@ describe('Options props', () => {
257271
makeInstance(123, Number, v => v === 234)
258272
expect('custom validator check failed').toHaveBeenWarned()
259273
makeInstance(123, String, v => v === 123)
260-
expect('Expected String').toHaveBeenWarned()
274+
expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned()
261275
})
262276

263277
it('multiple types + custom validator', () => {

0 commit comments

Comments
 (0)