Skip to content

Commit

Permalink
refactor: make the warning messages more explicit (close vuejs#7764) (v…
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuriy Alekseyev authored and yyx990803 committed Aug 17, 2018
1 parent c944827 commit 59860b0
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
45 changes: 42 additions & 3 deletions src/core/util/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ function assertProp (
valid = assertedType.valid
}
}

if (!valid) {
warn(
`Invalid prop: type check failed for prop "${name}".` +
` Expected ${expectedTypes.map(capitalize).join(', ')}` +
`, got ${toRawType(value)}.`,
getInvalidTypeMessage(name, value, expectedTypes),
vm
)
return
Expand Down Expand Up @@ -200,3 +199,43 @@ function getTypeIndex (type, expectedTypes): number {
}
return -1
}

function getInvalidTypeMessage (name, value, expectedTypes) {
let message = `Invalid prop: type check failed for prop "${name}".` +
` Expected ${expectedTypes.map(capitalize).join(', ')}`
const expectedType = expectedTypes[0]
const receivedType = toRawType(value)
const expectedValue = styleValue(value, expectedType)
const receivedValue = styleValue(value, receivedType)
// check if we need to specify expected value
if (expectedTypes.length === 1 &&
isExplicable(expectedType) &&
!isBoolean(expectedType, receivedType)) {
message += ` with value ${expectedValue}`
}
message += `, got ${receivedType} `
// check if we need to specify received value
if (isExplicable(receivedType)) {
message += `with value ${receivedValue}.`
}
return message
}

function styleValue (value, type) {
if (type === 'String') {
return `"${value}"`
} else if (type === 'Number') {
return `${Number(value)}`
} else {
return `${value}`
}
}

function isExplicable (value) {
const explicitTypes = ['string', 'number', 'boolean']
return explicitTypes.some(elem => value.toLowerCase() === elem)
}

function isBoolean (...args) {
return args.some(elem => elem.toLowerCase() === 'boolean')
}
30 changes: 22 additions & 8 deletions test/unit/features/options/props.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,42 +171,56 @@ describe('Options props', () => {
makeInstance('hello', String)
expect(console.error.calls.count()).toBe(0)
makeInstance(123, String)
expect('Expected String').toHaveBeenWarned()
expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned()
})

it('number', () => {
makeInstance(123, Number)
expect(console.error.calls.count()).toBe(0)
makeInstance('123', Number)
expect('Expected Number').toHaveBeenWarned()
expect('Expected Number with value 123, got String with value "123"').toHaveBeenWarned()
})

it('number & boolean', () => {
makeInstance(123, Number)
expect(console.error.calls.count()).toBe(0)
makeInstance(false, Number)
expect('Expected Number, got Boolean with value false').toHaveBeenWarned()
})

it('string & boolean', () => {
makeInstance('hello', String)
expect(console.error.calls.count()).toBe(0)
makeInstance(true, String)
expect('Expected String, got Boolean with value true').toHaveBeenWarned()
})

it('boolean', () => {
makeInstance(true, Boolean)
expect(console.error.calls.count()).toBe(0)
makeInstance('123', Boolean)
expect('Expected Boolean').toHaveBeenWarned()
expect('Expected Boolean, got String with value "123"').toHaveBeenWarned()
})

it('function', () => {
makeInstance(() => {}, Function)
expect(console.error.calls.count()).toBe(0)
makeInstance(123, Function)
expect('Expected Function').toHaveBeenWarned()
expect('Expected Function, got Number with value 123').toHaveBeenWarned()
})

it('object', () => {
makeInstance({}, Object)
expect(console.error.calls.count()).toBe(0)
makeInstance([], Object)
expect('Expected Object').toHaveBeenWarned()
expect('Expected Object, got Array').toHaveBeenWarned()
})

it('array', () => {
makeInstance([], Array)
expect(console.error.calls.count()).toBe(0)
makeInstance({}, Array)
expect('Expected Array').toHaveBeenWarned()
expect('Expected Array, got Object').toHaveBeenWarned()
})

it('primitive wrapper objects', () => {
Expand All @@ -225,7 +239,7 @@ describe('Options props', () => {
makeInstance(Symbol('foo'), Symbol)
expect(console.error.calls.count()).toBe(0)
makeInstance({}, Symbol)
expect('Expected Symbol').toHaveBeenWarned()
expect('Expected Symbol, got Object').toHaveBeenWarned()
})
}

Expand Down Expand Up @@ -257,7 +271,7 @@ describe('Options props', () => {
makeInstance(123, Number, v => v === 234)
expect('custom validator check failed').toHaveBeenWarned()
makeInstance(123, String, v => v === 123)
expect('Expected String').toHaveBeenWarned()
expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned()
})

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

0 comments on commit 59860b0

Please sign in to comment.