From bb8a124214b2d2d19162f65e903b6e42df57e0dc Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Thu, 7 Dec 2017 15:50:25 +0300 Subject: [PATCH 1/5] fix(props): handle misspelled keys on prop validation object --- src/core/util/props.js | 26 ++++++++++++++++++++++++ test/unit/features/options/props.spec.js | 17 ++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/core/util/props.js b/src/core/util/props.js index 310514d7df6..39f81dc2669 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -18,6 +18,13 @@ type PropOptions = { validator: ?Function }; +const propOptionsNames = [ + 'type', + 'default', + 'required', + 'validator' +] + export function validateProp ( key: string, propOptions: Object, @@ -84,6 +91,24 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a : def } +/** + * Assert whether a prop object keys are valid. + */ +function assertPropObject ( + prop: Object, + key: string, + vm: ?Component +) { + Object.keys(prop) + .filter(name => propOptionsNames.indexOf(name) === -1) + .forEach(name => { + warn( + 'Invalid key "' + name + '" in validation rules object for prop "' + key + '".', + vm + ) + }) +} + /** * Assert whether a prop is valid. */ @@ -94,6 +119,7 @@ function assertProp ( vm: ?Component, absent: boolean ) { + assertPropObject(prop, name, vm) if (prop.required && absent) { warn( 'Missing required prop: "' + name + '"', diff --git a/test/unit/features/options/props.spec.js b/test/unit/features/options/props.spec.js index ae2baefff99..42acbe6b88b 100644 --- a/test/unit/features/options/props.spec.js +++ b/test/unit/features/options/props.spec.js @@ -512,4 +512,21 @@ describe('Options props', () => { expect(`"${attr}" is a reserved attribute`).toHaveBeenWarned() }) }) + + it('should warn about misspelled keys in prop validation object', () => { + new Vue({ + template: '', + components: { + test: { + template: '
', + props: { + value: { reqquired: true }, + count: { deafult: 1 } + } + } + } + }).$mount() + expect(`Invalid key "reqquired" in validation rules object for prop "value".`).toHaveBeenWarned() + expect(`Invalid key "deafult" in validation rules object for prop "count".`).toHaveBeenWarned() + }) }) From a4fb3bfeb49dd04ecce7e8b64d1c04af010c2f2b Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Mon, 11 Dec 2017 23:17:48 +0300 Subject: [PATCH 2/5] moving assertPropObject to initProps --- src/core/instance/state.js | 4 ++++ src/core/util/props.js | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index 4fa6f15bac8..850f64ecf1c 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -23,6 +23,7 @@ import { handleError, nativeWatch, validateProp, + assertPropObject, isPlainObject, isServerRendering, isReservedAttribute @@ -71,6 +72,9 @@ function initProps (vm: Component, propsOptions: Object) { // root instance props should be converted observerState.shouldConvert = isRoot for (const key in propsOptions) { + if (process.env.NODE_ENV !== 'production') { + assertPropObject(propsOptions[key], key, vm) + } keys.push(key) const value = validateProp(key, propsOptions, propsData, vm) /* istanbul ignore else */ diff --git a/src/core/util/props.js b/src/core/util/props.js index 39f81dc2669..ea092c04c11 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -94,7 +94,7 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a /** * Assert whether a prop object keys are valid. */ -function assertPropObject ( +export function assertPropObject ( prop: Object, key: string, vm: ?Component @@ -119,7 +119,6 @@ function assertProp ( vm: ?Component, absent: boolean ) { - assertPropObject(prop, name, vm) if (prop.required && absent) { warn( 'Missing required prop: "' + name + '"', From 6f2af73b772afcfd5870fb65cc05eab926fafbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D0=BA=D0=BE=D0=BB=D0=BE=D0=B2=20=D0=90=D0=BB?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Dec 2017 12:44:51 +0300 Subject: [PATCH 3/5] moving assertPropObject from initProps to normalizeProps --- src/core/instance/state.js | 4 ---- src/core/util/options.js | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index 850f64ecf1c..4fa6f15bac8 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -23,7 +23,6 @@ import { handleError, nativeWatch, validateProp, - assertPropObject, isPlainObject, isServerRendering, isReservedAttribute @@ -72,9 +71,6 @@ function initProps (vm: Component, propsOptions: Object) { // root instance props should be converted observerState.shouldConvert = isRoot for (const key in propsOptions) { - if (process.env.NODE_ENV !== 'production') { - assertPropObject(propsOptions[key], key, vm) - } keys.push(key) const value = validateProp(key, propsOptions, propsData, vm) /* istanbul ignore else */ diff --git a/src/core/util/options.js b/src/core/util/options.js index 945d43c69b8..049d49b1592 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -4,6 +4,7 @@ import config from '../config' import { warn } from './debug' import { nativeWatch } from './env' import { set } from '../observer/index' +import { assertPropObject } from './props' import { ASSET_TYPES, @@ -285,6 +286,9 @@ function normalizeProps (options: Object, vm: ?Component) { res[name] = isPlainObject(val) ? val : { type: val } + if (process.env.NODE_ENV !== 'production') { + assertPropObject(res[name], name, vm) + } } } else if (process.env.NODE_ENV !== 'production') { warn( From e2a2a7a4a8418fec8a9693278c202d9096914388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D0=BA=D0=BE=D0=BB=D0=BE=D0=B2=20=D0=90=D0=BB?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Dec 2017 12:54:10 +0300 Subject: [PATCH 4/5] rewrite assertPropObject with for..in --- src/core/util/options.js | 2 +- src/core/util/props.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index 049d49b1592..e8e5f082a5d 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -287,7 +287,7 @@ function normalizeProps (options: Object, vm: ?Component) { ? val : { type: val } if (process.env.NODE_ENV !== 'production') { - assertPropObject(res[name], name, vm) + assertPropObject(name, res[name], vm) } } } else if (process.env.NODE_ENV !== 'production') { diff --git a/src/core/util/props.js b/src/core/util/props.js index ea092c04c11..dcc2358e46d 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -95,18 +95,18 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a * Assert whether a prop object keys are valid. */ export function assertPropObject ( + propName: string, prop: Object, - key: string, vm: ?Component ) { - Object.keys(prop) - .filter(name => propOptionsNames.indexOf(name) === -1) - .forEach(name => { + for (const key in prop) { + if (propOptionsNames.indexOf(key) === -1) { warn( - 'Invalid key "' + name + '" in validation rules object for prop "' + key + '".', + `Invalid key "${key}" in validation rules object for prop "${propName}".`, vm ) - }) + } + } } /** From 9d20d8c92ef406467ec85b08d46e7443583980dd Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Dec 2017 11:37:56 -0500 Subject: [PATCH 5/5] Update options.js --- src/core/util/options.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index e8e5f082a5d..48215e2c273 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -283,12 +283,12 @@ function normalizeProps (options: Object, vm: ?Component) { for (const key in props) { val = props[key] name = camelize(key) + if (process.env.NODE_ENV !== 'production' && isPlainObject(val)) { + assertPropObject(name, val, vm) + } res[name] = isPlainObject(val) ? val : { type: val } - if (process.env.NODE_ENV !== 'production') { - assertPropObject(name, res[name], vm) - } } } else if (process.env.NODE_ENV !== 'production') { warn(