var _ = require('../../../../src/util')
var Vue = require('../../../../src/vue')
if (_.inBrowser) {
describe('v-component', function () {
var el
beforeEach(function () {
el = document.createElement('div')
document.body.appendChild(el)
spyOn(_, 'warn')
})
afterEach(function () {
document.body.removeChild(el)
})
it('static', function () {
new Vue({
el: el,
template: '',
components: {
test: {
data: function () {
return { a: 123 }
},
template: '{{a}}'
}
}
})
expect(el.innerHTML).toBe('123')
})
it('replace', function () {
new Vue({
el: el,
template: '',
components: {
test: {
replace: true,
data: function () {
return { a: 123 }
},
template: '
{{a}}
'
}
}
})
expect(el.innerHTML).toBe('123
')
})
it('allow v-component on table elements', function () {
var vm = new Vue({
el: el,
template: '',
components: {
test: {
data: function () {
return { a: 123 }
},
template: '{{a}} | '
}
}
})
expect(el.innerHTML).toBe(vm.$options.template.replace(//, '| 123 |
'))
expect(_.warn).not.toHaveBeenCalled()
})
it('inline-template', function () {
new Vue({
el: el,
template: '{{a}}',
data: {
a: 'parent'
},
components: {
test: {
data: function () {
return { a: 'child' }
},
template: 'child option template'
}
}
})
expect(el.innerHTML).toBe('child')
})
it('block replace', function () {
new Vue({
el: el,
template: '',
components: {
test: {
replace: true,
data: function () {
return { a: 123, b: 234 }
},
template: '{{a}}
{{b}}
'
}
}
})
expect(el.innerHTML).toBe('123
234
')
})
it('dynamic', function (done) {
var vm = new Vue({
el: el,
template: '',
data: {
view: 'view-a'
},
components: {
'view-a': {
template: 'AAA
',
replace: true,
data: function () {
return { view: 'a' }
}
},
'view-b': {
template: 'BBB
',
replace: true,
data: function () {
return { view: 'b' }
}
}
}
})
expect(el.innerHTML).toBe('AAA
')
vm.view = 'view-b'
_.nextTick(function () {
expect(el.innerHTML).toBe('BBB
')
vm.view = ''
_.nextTick(function () {
expect(el.innerHTML).toBe('')
done()
})
})
})
it('keep-alive', function (done) {
var spyA = jasmine.createSpy()
var spyB = jasmine.createSpy()
var vm = new Vue({
el: el,
template: '',
data: {
view: 'view-a'
},
components: {
'view-a': {
created: spyA,
template: 'AAA
',
replace: true
},
'view-b': {
created: spyB,
template: 'BBB
',
replace: true
}
}
})
expect(el.innerHTML).toBe('AAA
')
expect(spyA.calls.count()).toBe(1)
expect(spyB.calls.count()).toBe(0)
vm.view = 'view-b'
_.nextTick(function () {
expect(el.innerHTML).toBe('BBB
')
expect(spyA.calls.count()).toBe(1)
expect(spyB.calls.count()).toBe(1)
vm.view = 'view-a'
_.nextTick(function () {
expect(el.innerHTML).toBe('AAA
')
expect(spyA.calls.count()).toBe(1)
expect(spyB.calls.count()).toBe(1)
vm.view = 'view-b'
_.nextTick(function () {
expect(el.innerHTML).toBe('BBB
')
expect(spyA.calls.count()).toBe(1)
expect(spyB.calls.count()).toBe(1)
done()
})
})
})
})
it('should compile parent template directives & content in parent scope', function (done) {
var vm = new Vue({
el: el,
data: {
ok: false,
message: 'hello'
},
template: '{{message}}',
components: {
test: {
template: ' {{message}}
',
replace: true,
data: function () {
return {
message: 'world'
}
}
}
}
})
expect(el.firstChild.style.display).toBe('none')
expect(el.firstChild.textContent).toBe('hello world')
vm.ok = true
vm.message = 'bye'
_.nextTick(function () {
expect(el.firstChild.style.display).toBe('')
expect(el.firstChild.textContent).toBe('bye world')
done()
})
})
it('parent content + v-if', function (done) {
var vm = new Vue({
el: el,
data: {
ok: false,
message: 'hello'
},
template: '{{message}}',
components: {
test: {
template: ' {{message}}',
data: function () {
return {
message: 'world'
}
}
}
}
})
expect(el.textContent).toBe('')
expect(vm.$children.length).toBe(0)
expect(vm._directives.length).toBe(1) // v-if
vm.ok = true
_.nextTick(function () {
expect(vm.$children.length).toBe(1)
expect(vm._directives.length).toBe(3) // v-if, v-component, v-text
expect(el.textContent).toBe('hello world')
done()
})
})
it('props', function () {
new Vue({
el: el,
data: {
list: [{a: 1}, {a: 2}]
},
template: '',
components: {
test: {
template: '',
replace: true,
props: ['collection']
}
}
})
expect(el.innerHTML).toBe('')
})
it('wait-for for static component', function () {
var vm = new Vue({
el: el,
template: '',
components: {
'view-a': {
template: 'AAA'
}
}
})
expect(el.textContent).toBe('')
vm.$children[0].$emit('ok')
expect(el.textContent).toBe('AAA')
})
it('sync wait-for inside compiled hook', function () {
new Vue({
el: el,
template: '',
components: {
'view-a': {
template: 'AAA',
compiled: function () {
expect(el.textContent).toBe('')
this.$emit('ok')
}
}
}
})
expect(el.textContent).toBe('AAA')
})
it('wait-for for dynamic components', function (done) {
var vm = new Vue({
el: el,
data: {
view: 'view-a'
},
template: '',
components: {
'view-a': {
template: 'AAA'
},
'view-b': {
template: 'BBB'
}
}
})
vm.$children[0].$emit('ok')
expect(el.textContent).toBe('AAA')
vm.view = 'view-b'
_.nextTick(function () {
expect(el.textContent).toBe('AAA')
// old vm is already removed, this is the new vm
expect(vm.$children.length).toBe(1)
vm.$children[0].$emit('ok')
expect(el.textContent).toBe('BBB')
// ensure switching before ready event correctly
// cleans up the component being waited on.
// see #1152
vm.view = 'view-a'
_.nextTick(function () {
vm.view = 'view-b'
_.nextTick(function () {
expect(vm.$children.length).toBe(1)
expect(vm.$children[0].$el.textContent).toBe('BBB')
done()
})
})
})
})
// #1150
it('wait-for + keep-alive', function (done) {
var vm = new Vue({
el: el,
data: {
view: 'view-a'
},
template: '',
components: {
'view-a': {
template: 'AAA'
},
'view-b': {
template: 'BBB'
}
}
})
vm.$children[0].$emit('ok')
expect(el.textContent).toBe('AAA')
vm.view = 'view-b'
_.nextTick(function () {
expect(vm.$children.length).toBe(2)
vm.$children[1].$emit('ok')
expect(el.textContent).toBe('BBB')
vm.view = 'view-a'
_.nextTick(function () {
// should switch without the need to emit
// because of keep-alive
expect(el.textContent).toBe('AAA')
done()
})
})
})
it('transition-mode: in-out', function (done) {
var spy1 = jasmine.createSpy('enter')
var spy2 = jasmine.createSpy('leave')
var next
var vm = new Vue({
el: el,
data: {
view: 'view-a'
},
template: '',
components: {
'view-a': { template: 'AAA' },
'view-b': { template: 'BBB' }
},
transitions: {
test: {
enter: function (el, done) {
spy1()
next = done
},
leave: function (el, done) {
spy2()
_.nextTick(done)
}
}
}
})
expect(el.textContent).toBe('AAA')
vm.view = 'view-b'
_.nextTick(function () {
expect(spy1).toHaveBeenCalled()
expect(spy2).not.toHaveBeenCalled()
expect(el.textContent).toBe('AAABBB')
next()
_.nextTick(function () {
expect(spy2).toHaveBeenCalled()
_.nextTick(function () {
expect(el.textContent).toBe('BBB')
done()
})
})
})
})
it('transition-mode: out-in', function (done) {
var spy1 = jasmine.createSpy('enter')
var spy2 = jasmine.createSpy('leave')
var next
var vm = new Vue({
el: el,
data: {
view: 'view-a'
},
template: '',
components: {
'view-a': { template: 'AAA' },
'view-b': { template: 'BBB' }
},
transitions: {
test: {
enter: function (el, done) {
spy2()
_.nextTick(done)
},
leave: function (el, done) {
spy1()
next = done
}
}
}
})
expect(el.textContent).toBe('AAA')
vm.view = 'view-b'
_.nextTick(function () {
expect(spy1).toHaveBeenCalled()
expect(spy2).not.toHaveBeenCalled()
expect(el.textContent).toBe('AAA')
next()
expect(spy2).toHaveBeenCalled()
expect(el.textContent).toBe('BBB')
done()
})
})
it('teardown', function (done) {
var vm = new Vue({
el: el,
template: '',
data: {
view: 'test'
},
components: {
test: {},
test2: {}
}
})
vm.view = 'test2'
_.nextTick(function () {
expect(vm.$children.length).toBe(2)
var child = vm.$children[0]
var child2 = vm.$children[1]
vm._directives[0].unbind()
expect(vm._directives[0].cache).toBeNull()
expect(vm.$children.length).toBe(0)
expect(child._isDestroyed).toBe(true)
expect(child2._isDestroyed).toBe(true)
done()
})
})
it('already mounted warn', function () {
el.setAttribute('v-_component', 'test')
new Vue({
el: el
})
expect(hasWarned(_, 'cannot mount component "test" on already mounted element')).toBe(true)
})
it('not found component should not throw', function () {
expect(function () {
new Vue({
el: el,
template: ''
})
}).not.toThrow()
})
})
}