diff --git a/src/core/util/options.js b/src/core/util/options.js index 6a583505..f49c8236 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -206,7 +206,7 @@ const defaultStrat = function (parentVal: any, childVal: any): any { * Make sure component options get converted to actual * constructors. */ -function guardComponents (options: Object) { +function normalizeComponents (options: Object) { if (options.components) { const components = options.components let def @@ -230,7 +230,7 @@ function guardComponents (options: Object) { * Ensure all props option syntax are normalized into the * Object-based format. */ -function guardProps (options: Object) { +function normalizeProps (options: Object) { const props = options.props if (!props) return const res = {} @@ -261,12 +261,13 @@ function guardProps (options: Object) { /** * Normalize raw function directives into object format. */ -function guardDirectives (options: Object) { +function normalizeDirectives (options: Object) { const dirs = options.directives if (dirs) { for (const key in dirs) { - if (typeof dirs[key] === 'function') { - dirs[key] = { update: dirs[key] } + const def = dirs[key] + if (typeof def === 'function') { + dirs[key] = { bind: def, update: def } } } } @@ -281,9 +282,9 @@ export function mergeOptions ( child: Object, vm?: Component ): Object { - guardComponents(child) - guardProps(child) - guardDirectives(child) + normalizeComponents(child) + normalizeProps(child) + normalizeDirectives(child) if (process.env.NODE_ENV !== 'production') { if (child.propsData && !vm) { warn('propsData can only be used as an instantiation option.') diff --git a/test/unit/features/options/assets.spec.js b/test/unit/features/options/assets.spec.js deleted file mode 100644 index e69de29b..00000000 diff --git a/test/unit/features/options/directives.spec.js b/test/unit/features/options/directives.spec.js new file mode 100644 index 00000000..5bac9ddb --- /dev/null +++ b/test/unit/features/options/directives.spec.js @@ -0,0 +1,92 @@ +import Vue from 'vue' + +describe('Options directives', () => { + it('basic usage', done => { + const bindSpy = jasmine.createSpy('bind') + const updateSpy = jasmine.createSpy('update') + const postupdateSpy = jasmine.createSpy('postupdate') + const unbindSpy = jasmine.createSpy('unbind') + + const assertContext = (el, binding, vnode) => { + expect(vnode.context).toBe(vm) + expect(binding.arg).toBe('arg') + expect(binding.modifiers).toEqual({ hello: true }) + } + + const vm = new Vue({ + template: '
{{ msg }}
', + data: { + msg: 'hi', + a: 'foo', + ok: true + }, + directives: { + test: { + bind (el, binding, vnode) { + bindSpy() + assertContext(el, binding, vnode) + expect(binding.value).toBe('foo') + expect(binding.oldValue).toBeUndefined() + }, + update (el, binding, vnode, oldVnode) { + updateSpy() + assertContext(el, binding, vnode) + expect(el).toBe(vm.$el) + expect(oldVnode).toBe(vm._vnode) + expect(oldVnode).not.toBe(vnode) + expect(binding.value).toBe('bar') + expect(binding.oldValue).toBe('foo') + }, + postupdate (el, binding, vnode) { + postupdateSpy() + assertContext(el, binding, vnode) + }, + unbind (el, binding, vnode) { + unbindSpy() + assertContext(el, binding, vnode) + } + } + } + }) + + vm.$mount() + expect(bindSpy).toHaveBeenCalled() + expect(updateSpy).not.toHaveBeenCalled() + expect(postupdateSpy).not.toHaveBeenCalled() + expect(unbindSpy).not.toHaveBeenCalled() + vm.a = 'bar' + waitForUpdate(() => { + expect(updateSpy).toHaveBeenCalled() + expect(postupdateSpy).toHaveBeenCalled() + expect(unbindSpy).not.toHaveBeenCalled() + vm.msg = 'bye' + }).then(() => { + expect(postupdateSpy.calls.count()).toBe(2) + vm.ok = false + }).then(() => { + expect(unbindSpy).toHaveBeenCalled() + }).then(done) + }) + + it('function shorthand', done => { + const spy = jasmine.createSpy('directive') + const vm = new Vue({ + template: '
', + data: { a: 'foo' }, + directives: { + test (el, binding, vnode) { + expect(vnode.context).toBe(vm) + expect(binding.arg).toBe('arg') + expect(binding.modifiers).toEqual({ hello: true }) + spy(binding.value, binding.oldValue) + } + } + }) + vm.$mount() + expect(spy).toHaveBeenCalledWith('foo', undefined) + vm.a = 'bar' + waitForUpdate(() => { + expect(spy).toHaveBeenCalledWith('bar', 'foo') + }).then(done) + }) +})