2016-07-14 21:51:25 +00:00
|
|
|
import Vue from 'vue'
|
2022-05-23 07:15:29 +00:00
|
|
|
import { injectStyles, waitForUpdate, nextFrame } from './helpers'
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-23 07:15:29 +00:00
|
|
|
describe('Transition group', () => {
|
2022-05-20 02:30:13 +00:00
|
|
|
const { duration, buffer } = injectStyles()
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
let el
|
|
|
|
beforeEach(() => {
|
|
|
|
el = document.createElement('div')
|
|
|
|
document.body.appendChild(el)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
function createBasicVM(useIs?, appear = false) {
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `
|
2016-07-14 21:51:25 +00:00
|
|
|
<div>
|
2022-05-20 02:30:13 +00:00
|
|
|
${
|
|
|
|
useIs
|
|
|
|
? `<span is="transition-group">`
|
|
|
|
: `<transition-group${appear ? ` appear` : ``}>`
|
|
|
|
}
|
2016-07-14 21:51:25 +00:00
|
|
|
<div v-for="item in items" :key="item" class="test">{{ item }}</div>
|
|
|
|
${useIs ? `</span>` : `</transition-group>`}
|
|
|
|
</div>
|
|
|
|
`,
|
2022-05-20 02:30:13 +00:00
|
|
|
data: {
|
|
|
|
items: ['a', 'b', 'c']
|
2016-07-14 21:51:25 +00:00
|
|
|
}
|
2022-05-20 02:30:13 +00:00
|
|
|
}).$mount(el)
|
|
|
|
if (!appear) {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
|
|
|
)
|
2016-07-14 21:51:25 +00:00
|
|
|
}
|
2022-05-20 02:30:13 +00:00
|
|
|
return vm
|
|
|
|
}
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('enter', done => {
|
|
|
|
const vm = createBasicVM()
|
|
|
|
vm.items.push('d', 'e')
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
['a', 'b', 'c'].map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`<div class="test v-enter v-enter-active">d</div>` +
|
|
|
|
`<div class="test v-enter v-enter-active">e</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
['a', 'b', 'c'].map(i => `<div class="test">${i}</div>`).join('') +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-enter-active v-enter-to">d</div>` +
|
|
|
|
`<div class="test v-enter-active v-enter-to">e</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration + buffer)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('leave', done => {
|
|
|
|
const vm = createBasicVM()
|
|
|
|
vm.items = ['b']
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test v-leave v-leave-active">a</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test v-leave v-leave-active">c</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-leave-active v-leave-to">a</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`<div class="test">b</div>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-leave-active v-leave-to">c</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration + buffer)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('enter + leave', done => {
|
|
|
|
const vm = createBasicVM()
|
|
|
|
vm.items = ['b', 'c', 'd']
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test v-leave v-leave-active">a</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
|
|
|
`<div class="test v-enter v-enter-active">d</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-leave-active v-leave-to">a</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-enter-active v-enter-to">d</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration + buffer)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('use with "is" attribute', done => {
|
|
|
|
const vm = createBasicVM(true)
|
|
|
|
vm.items = ['b', 'c', 'd']
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test v-leave v-leave-active">a</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
|
|
|
`<div class="test v-enter v-enter-active">d</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-leave-active v-leave-to">a</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test v-enter-active v-enter-to">d</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration + buffer)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('appear', done => {
|
|
|
|
const vm = createBasicVM(false, true /* appear */)
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
vm.items
|
|
|
|
.map(i => `<div class="test v-enter v-enter-active">${i}</div>`)
|
|
|
|
.join('') +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items
|
|
|
|
.map(
|
|
|
|
i => `<div class="test v-enter-active v-enter-to">${i}</div>`
|
|
|
|
)
|
|
|
|
.join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration + buffer)
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.map(i => `<div class="test">${i}</div>`).join('') +
|
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('events', done => {
|
|
|
|
let next
|
2022-05-23 07:15:29 +00:00
|
|
|
const beforeEnterSpy = jasmine.createSpy()
|
|
|
|
const afterEnterSpy = jasmine.createSpy()
|
|
|
|
const afterLeaveSpy = jasmine.createSpy()
|
2022-05-20 02:30:13 +00:00
|
|
|
const vm = new Vue({
|
|
|
|
template: `
|
2016-07-14 21:51:25 +00:00
|
|
|
<div>
|
|
|
|
<transition-group @before-enter="beforeEnter" @after-enter="afterEnter" @after-leave="afterLeave">
|
|
|
|
<div v-for="item in items" :key="item" class="test">{{ item }}</div>
|
|
|
|
</transition-group>
|
|
|
|
</div>
|
|
|
|
`,
|
2022-05-20 02:30:13 +00:00
|
|
|
data: {
|
|
|
|
items: ['a', 'b', 'c']
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
beforeEnter(el) {
|
|
|
|
expect(el.textContent).toBe('d')
|
|
|
|
beforeEnterSpy()
|
2016-07-14 21:51:25 +00:00
|
|
|
},
|
2022-05-20 02:30:13 +00:00
|
|
|
afterEnter(el) {
|
|
|
|
expect(el.textContent).toBe('d')
|
|
|
|
afterEnterSpy()
|
|
|
|
next()
|
|
|
|
},
|
|
|
|
afterLeave(el) {
|
|
|
|
expect(el.textContent).toBe('a')
|
|
|
|
afterLeaveSpy()
|
|
|
|
next()
|
2016-07-14 21:51:25 +00:00
|
|
|
}
|
2022-05-20 02:30:13 +00:00
|
|
|
}
|
|
|
|
}).$mount(el)
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items.push('d')
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test">a</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
|
|
|
`<div class="test v-enter v-enter-active">d</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
2022-05-23 07:15:29 +00:00
|
|
|
expect(beforeEnterSpy.calls.count()).toBe(1)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(_next => {
|
|
|
|
next = _next
|
|
|
|
})
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test">a</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
|
|
|
`<div class="test">d</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-23 07:15:29 +00:00
|
|
|
expect(afterEnterSpy.calls.count()).toBe(1)
|
2016-07-14 21:51:25 +00:00
|
|
|
vm.items.shift()
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(_next => {
|
|
|
|
next = _next
|
|
|
|
})
|
|
|
|
.then(() => {
|
2016-07-14 21:51:25 +00:00
|
|
|
expect(vm.$el.innerHTML).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">c</div>` +
|
|
|
|
`<div class="test">d</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-23 07:15:29 +00:00
|
|
|
expect(afterLeaveSpy.calls.count()).toBe(1)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('move', done => {
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `
|
2016-07-14 21:51:25 +00:00
|
|
|
<div>
|
|
|
|
<transition-group name="group">
|
|
|
|
<div v-for="item in items" :key="item" class="test">{{ item }}</div>
|
|
|
|
</transition-group>
|
|
|
|
</div>
|
|
|
|
`,
|
2022-05-20 02:30:13 +00:00
|
|
|
data: {
|
|
|
|
items: ['a', 'b', 'c']
|
|
|
|
}
|
|
|
|
}).$mount(el)
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.items = ['d', 'b', 'a']
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="test group-enter group-enter-active">d</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test group-move">a</div>` +
|
|
|
|
`<div class="test group-leave group-leave-active group-move">c</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`</span>`
|
2022-05-20 02:30:13 +00:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2016-07-17 05:40:31 +00:00
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
2016-07-14 21:51:25 +00:00
|
|
|
`<span>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test group-enter-active group-enter-to">d</div>` +
|
2016-07-14 21:51:25 +00:00
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test group-move">a</div>` +
|
2016-12-27 20:03:48 +00:00
|
|
|
`<div class="test group-leave-active group-move group-leave-to">c</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration * 2)
|
|
|
|
.then(() => {
|
2016-07-17 05:40:31 +00:00
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
2016-07-14 21:51:25 +00:00
|
|
|
`<span>` +
|
|
|
|
`<div class="test">d</div>` +
|
|
|
|
`<div class="test">b</div>` +
|
|
|
|
`<div class="test">a</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2016-07-14 21:51:25 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
|
|
|
})
|
2016-07-14 21:51:25 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
it('warn unkeyed children', () => {
|
|
|
|
new Vue({
|
|
|
|
template: `<div><transition-group><div v-for="i in 3"></div></transition-group></div>`
|
|
|
|
}).$mount()
|
|
|
|
expect(
|
|
|
|
'<transition-group> children must be keyed: <div>'
|
|
|
|
).toHaveBeenWarned()
|
|
|
|
})
|
2017-07-05 01:17:35 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
// GitHub issue #6006
|
|
|
|
it('should work with dynamic name', done => {
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `
|
2017-07-05 01:17:35 +00:00
|
|
|
<div>
|
|
|
|
<transition-group :name="name">
|
|
|
|
<div v-for="item in items" :key="item">{{ item }}</div>
|
|
|
|
</transition-group>
|
|
|
|
</div>
|
|
|
|
`,
|
2022-05-20 02:30:13 +00:00
|
|
|
data: {
|
|
|
|
items: ['a', 'b', 'c'],
|
|
|
|
name: 'group'
|
|
|
|
}
|
|
|
|
}).$mount(el)
|
2017-07-05 01:17:35 +00:00
|
|
|
|
2022-05-20 02:30:13 +00:00
|
|
|
vm.name = 'invalid-name'
|
|
|
|
vm.items = ['b', 'c', 'a']
|
|
|
|
waitForUpdate(() => {
|
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
|
|
|
`<span>` + `<div>b</div>` + `<div>c</div>` + `<div>a</div>` + `</span>`
|
|
|
|
)
|
|
|
|
vm.name = 'group'
|
|
|
|
vm.items = ['a', 'b', 'c']
|
|
|
|
})
|
|
|
|
.thenWaitFor(nextFrame)
|
|
|
|
.then(() => {
|
2017-07-05 01:17:35 +00:00
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div class="group-move">a</div>` +
|
|
|
|
`<div class="group-move">b</div>` +
|
|
|
|
`<div class="group-move">c</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2017-07-05 01:17:35 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.thenWaitFor(duration * 2 + buffer)
|
|
|
|
.then(() => {
|
2017-07-05 01:17:35 +00:00
|
|
|
expect(vm.$el.innerHTML.replace(/\s?style=""(\s?)/g, '$1')).toBe(
|
|
|
|
`<span>` +
|
|
|
|
`<div>a</div>` +
|
|
|
|
`<div>b</div>` +
|
|
|
|
`<div>c</div>` +
|
2022-05-20 02:30:13 +00:00
|
|
|
`</span>`
|
2017-07-05 01:17:35 +00:00
|
|
|
)
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|
|
|
|
.then(done)
|
2016-07-14 21:51:25 +00:00
|
|
|
})
|
2022-05-20 02:30:13 +00:00
|
|
|
})
|