| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| import chai from 'chai' |
| import sinon from 'sinon' |
| import sinonChai from 'sinon-chai' |
| const { expect } = chai |
| chai.use(sinonChai) |
| |
| import Vm from '../../../../../runtime/frameworks/legacy/vm' |
| import { Document } from '../../../../../runtime/vdom' |
| |
| describe('bind and fire events', () => { |
| let doc, customComponentMap, spy |
| |
| function checkReady (vm, handler) { |
| /* istanbul ignore else */ |
| if (vm._ready) { |
| handler() |
| } |
| else { |
| vm.$on('hook:ready', handler) |
| } |
| } |
| |
| beforeEach(() => { |
| spy = sinon.spy() |
| doc = new Document('test', '', spy) |
| customComponentMap = {} |
| }) |
| |
| afterEach(() => { |
| doc.destroy() |
| }) |
| |
| it('bind event and fire in a single dom', (done) => { |
| customComponentMap.foo = { |
| template: { |
| type: 'container', |
| attr: { |
| a: function () { return this.x } |
| }, |
| events: { click: 'handleClick' } |
| }, |
| data: function () { |
| return { x: 1 } |
| }, |
| methods: { |
| handleClick: function () { |
| this.x = 2 |
| } |
| } |
| } |
| |
| const app = { doc, customComponentMap } |
| const vm = new Vm('foo', customComponentMap.foo, { _app: app }) |
| |
| checkReady(vm, function () { |
| expect(doc.body.event.click.handler).a('function') |
| |
| const el = doc.body |
| expect(el.attr.a).eql(1) |
| expect(spy.args.length).eql(1) |
| expect(doc.listener.updates.length).eql(0) |
| |
| el.event.click.handler({ xxx: 1 }) |
| expect(el.attr.a).eql(2) |
| expect(spy.args.length).eql(2) |
| expect(spy.args[1][0]).eql([ |
| { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 2 }] } |
| ]) |
| |
| done() |
| }) |
| }) |
| |
| it('emit, broadcast and dispatch vm events', (done) => { |
| customComponentMap.foo = { |
| template: { |
| type: 'aaa', |
| children: [{ type: 'bar', component: true }] |
| } |
| } |
| customComponentMap.bar = { |
| template: { |
| type: 'bbb' |
| } |
| } |
| |
| const app = { doc, customComponentMap } |
| const vm = new Vm('foo', customComponentMap.foo, { _app: app }) |
| |
| checkReady(vm, function () { |
| doc.close() |
| |
| expect(vm._childrenVms.length).eql(1) |
| |
| const subVm = vm._childrenVms[0] |
| expect(vm._type).eql('foo') |
| expect(subVm._type).eql('bar') |
| |
| const spyA = sinon.spy() |
| const spyB = sinon.spy() |
| |
| vm.$on('customTypeA', spyA) |
| subVm.$on('customTypeA', spyB) |
| |
| let detail = { aaa: 111 } |
| vm.$emit('customTypeA', detail) |
| expect(spyA.args.length).eql(1) |
| expect(spyB.args.length).eql(0) |
| |
| detail = { aaa: 111 } |
| subVm.$emit('customTypeA', detail) |
| expect(spyA.args.length).eql(1) |
| expect(spyB.args.length).eql(1) |
| |
| detail = { aaa: 111 } |
| vm.$broadcast('customTypeA', detail) |
| expect(spyA.args.length).eql(2) |
| expect(spyB.args.length).eql(2) |
| |
| detail = { aaa: 111 } |
| subVm.$broadcast('customTypeA', detail) |
| expect(spyA.args.length).eql(2) |
| expect(spyB.args.length).eql(3) |
| |
| detail = { aaa: 111 } |
| vm.$dispatch('customTypeA', detail) |
| expect(spyA.args.length).eql(3) |
| expect(spyB.args.length).eql(3) |
| |
| detail = { aaa: 111 } |
| subVm.$dispatch('customTypeA', detail) |
| expect(spyA.args.length).eql(4) |
| expect(spyB.args.length).eql(4) |
| |
| vm.$off('customTypeA', spyA) |
| subVm.$off('customTypeA') |
| |
| detail = { aaa: 111 } |
| vm.$emit('customTypeA', detail) |
| detail = { aaa: 111 } |
| subVm.$emit('customTypeA', detail) |
| detail = { aaa: 111 } |
| vm.$broadcast('customTypeA', detail) |
| detail = { aaa: 111 } |
| subVm.$broadcast('customTypeA', detail) |
| detail = { aaa: 111 } |
| vm.$dispatch('customTypeA', detail) |
| detail = { aaa: 111 } |
| subVm.$dispatch('customTypeA', detail) |
| |
| expect(spyA.args.length).eql(4) |
| expect(spyB.args.length).eql(4) |
| |
| const spyAA = function (e) { |
| e.stop() |
| spyA() |
| } |
| const spyBB = function (e) { |
| e.stop() |
| spyB() |
| } |
| |
| vm.$on('customTypeA', spyAA) |
| subVm.$on('customTypeA', spyBB) |
| vm.$off() |
| vm.$off('unknownTypeA', spyA) |
| |
| detail = { aaa: 111 } |
| vm.$emit('customTypeA', detail) |
| expect(spyA.args.length).eql(5) |
| expect(spyB.args.length).eql(4) |
| detail = { aaa: 111 } |
| subVm.$emit('customTypeA', detail) |
| expect(spyA.args.length).eql(5) |
| expect(spyB.args.length).eql(5) |
| detail = { aaa: 111 } |
| vm.$broadcast('customTypeA', detail) |
| expect(spyA.args.length).eql(6) |
| expect(spyB.args.length).eql(5) |
| detail = { aaa: 111 } |
| subVm.$broadcast('customTypeA', detail) |
| expect(spyA.args.length).eql(6) |
| expect(spyB.args.length).eql(6) |
| detail = { aaa: 111 } |
| vm.$dispatch('customTypeA', detail) |
| expect(spyA.args.length).eql(7) |
| expect(spyB.args.length).eql(6) |
| detail = { aaa: 111 } |
| subVm.$dispatch('customTypeA', detail) |
| expect(spyA.args.length).eql(7) |
| expect(spyB.args.length).eql(7) |
| |
| done() |
| }) |
| }) |
| |
| it('broadcast for repeat vms', (done) => { |
| const vmSpy = sinon.spy() |
| const subVmSpy = sinon.spy() |
| |
| customComponentMap.foo = { |
| data: function () { |
| return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] } |
| }, |
| template: { |
| type: 'container', |
| children: [{ |
| type: 'bar', component: true, |
| repeat: function () { return this.list } |
| }] |
| }, |
| events: { |
| customTypeA: function (e) { |
| vmSpy(this, e) |
| } |
| } |
| } |
| customComponentMap.bar = { |
| template: { |
| type: 'aaa' |
| }, |
| events: { |
| customTypeA: function (e) { |
| subVmSpy(this, e) |
| } |
| } |
| } |
| |
| const app = { doc, customComponentMap } |
| const vm = new Vm('foo', customComponentMap.foo, { _app: app }) |
| |
| checkReady(vm, function () { |
| doc.close() |
| expect(vm._childrenVms.length).eql(3) |
| |
| let detail = { aaa: 111 } |
| vm.$emit('customTypeA', detail) |
| expect(vmSpy.args.length).eql(1) |
| expect(subVmSpy.args.length).eql(0) |
| expect(vmSpy.args[0][0]).equal(vm) |
| expect(vmSpy.args[0][1]).is.an.object |
| expect(vmSpy.args[0][1].detail).equal(detail) |
| |
| detail = { aaa: 111 } |
| vm.$broadcast('customTypeA', detail) |
| expect(vmSpy.args.length).eql(2) |
| expect(subVmSpy.args.length).eql(3) |
| expect(vmSpy.args[1][0]).equal(vm) |
| expect(vmSpy.args[1][1]).is.an.object |
| expect(vmSpy.args[1][1].detail).equal(detail) |
| expect(subVmSpy.args[1][0]).equal(vm._childrenVms[1]) |
| expect(subVmSpy.args[1][1]).is.an.object |
| expect(subVmSpy.args[1][1].detail).equal(detail) |
| |
| done() |
| }) |
| }) |
| |
| it('dispatch from repeat vms', (done) => { |
| const vmSpy = sinon.spy() |
| const subVmSpy = sinon.spy() |
| |
| customComponentMap.foo = { |
| data: function () { |
| return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] } |
| }, |
| template: { |
| type: 'container', |
| children: [{ |
| type: 'bar', component: true, |
| repeat: function () { return this.list } |
| }] |
| }, |
| events: { |
| customTypeA: function (e) { |
| vmSpy(this, e) |
| } |
| } |
| } |
| customComponentMap.bar = { |
| template: { |
| type: 'aaa' |
| }, |
| events: { |
| customTypeA: function (e) { |
| subVmSpy(this, e) |
| } |
| } |
| } |
| |
| const app = { doc, customComponentMap } |
| const vm = new Vm('foo', customComponentMap.foo, { _app: app }) |
| |
| checkReady(vm, function () { |
| doc.close() |
| expect(vm._childrenVms.length).eql(3) |
| |
| let detail = { aaa: 111 } |
| const subVm = vm._childrenVms[1] |
| subVm.$emit('customTypeA', detail) |
| expect(vmSpy.args.length).eql(0) |
| expect(subVmSpy.args.length).eql(1) |
| expect(subVmSpy.args[0][0]).equal(subVm) |
| expect(subVmSpy.args[0][1]).is.an.object |
| expect(subVmSpy.args[0][1].detail).equal(detail) |
| |
| detail = { aaa: 111 } |
| subVm.$dispatch('customTypeA', detail) |
| expect(vmSpy.args.length).eql(1) |
| expect(subVmSpy.args.length).eql(2) |
| expect(vmSpy.args[0][0]).equal(vm) |
| expect(vmSpy.args[0][1]).is.an.object |
| expect(vmSpy.args[0][1].detail).equal(detail) |
| expect(subVmSpy.args[1][0]).equal(subVm) |
| expect(subVmSpy.args[1][1]).is.an.object |
| expect(subVmSpy.args[1][1].detail).equal(detail) |
| |
| done() |
| }) |
| }) |
| |
| it('lifecycel events', (done) => { |
| const vmSpy = sinon.spy() |
| |
| customComponentMap.foo = { |
| template: { |
| type: 'aaa', |
| children: [{ type: 'bar', component: true }] |
| }, |
| data: function () { |
| return { |
| x: 1 |
| } |
| }, |
| init: function (e) { |
| vmSpy(this, e) |
| expect(this._data).is.not.ok |
| expect(this.x).is.not.ok |
| expect(this._parentEl).is.not.ok |
| }, |
| created: function (e) { |
| vmSpy(this, e) |
| expect(this._data).is.ok |
| expect(this.x).is.ok |
| expect(this._parentEl).is.not.ok |
| }, |
| ready: function (e) { |
| vmSpy(this, e) |
| expect(this._data).is.ok |
| expect(this.x).is.ok |
| expect(this._parentEl).is.ok |
| expect(this._parentEl.children.length).eql(1) |
| } |
| } |
| customComponentMap.bar = { |
| template: { |
| type: 'bbb' |
| }, |
| created: function (e) { |
| vmSpy(this, e) |
| } |
| } |
| |
| const app = { doc, customComponentMap } |
| const evSpy = sinon.spy() |
| const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, null, |
| { |
| 'hook:init': () => evSpy('hook:init'), |
| 'hook:created': () => evSpy('hook:created'), |
| 'hook:ready': () => evSpy('hook:ready') |
| } |
| ) |
| |
| checkReady(vm, function () { |
| doc.close() |
| |
| expect(vmSpy.args.length).eql(4) |
| |
| const subVm = vm._childrenVms[0] |
| const calls = vmSpy.args.map(args => [args[0], args[1].type]) |
| expect(calls).eql([ |
| [vm, 'hook:init'], |
| [vm, 'hook:created'], |
| [subVm, 'hook:created'], |
| [vm, 'hook:ready'] |
| ]) |
| |
| expect(evSpy.callCount).to.be.equal(3) |
| expect(evSpy.args).to.deep.equal([ |
| ['hook:init'], |
| ['hook:created'], |
| ['hook:ready'] |
| ]) |
| |
| done() |
| }) |
| }) |
| }) |