test(ssr): ssr + hydration integration test

This commit is contained in:
Evan You 2020-03-06 15:14:12 -05:00
parent 3be3785f94
commit f7a026109d

View File

@ -7,6 +7,7 @@ import {
Portal, Portal,
createStaticVNode createStaticVNode
} from '@vue/runtime-dom' } from '@vue/runtime-dom'
import { renderToString } from '@vue/server-renderer'
function mountWithHydration(html: string, render: () => any) { function mountWithHydration(html: string, render: () => any) {
const container = document.createElement('div') const container = document.createElement('div')
@ -172,7 +173,99 @@ describe('SSR hydration', () => {
}) })
// compile SSR + client render fn from the same template & hydrate // compile SSR + client render fn from the same template & hydrate
test('full compiler integration', () => {}) test('full compiler integration', async () => {
const mounted: string[] = []
const log = jest.fn()
const toggle = ref(true)
const Child = {
data() {
return {
count: 0,
text: 'hello',
style: {
color: 'red'
}
}
},
mounted() {
mounted.push('child')
},
template: `
<div>
<span class="count" :style="style">{{ count }}</span>
<button class="inc" @click="count++">inc</button>
<button class="change" @click="style.color = 'green'" >change color</button>
<button class="emit" @click="$emit('foo')">emit</button>
<span class="text">{{ text }}</span>
<input v-model="text">
</div>
`
}
const App = {
setup() {
return { toggle }
},
mounted() {
mounted.push('parent')
},
template: `
<div>
<span>hello</span>
<template v-if="toggle">
<Child @foo="log('child')"/>
<template v-if="true">
<button class="parent-click" @click="log('click')">click me</button>
</template>
</template>
<span>hello</span>
</div>`,
components: {
Child
},
methods: {
log
}
}
const container = document.createElement('div')
// server render
container.innerHTML = await renderToString(h(App))
// hydrate
createSSRApp(App).mount(container)
// assert interactions
// 1. parent button click
triggerEvent('click', container.querySelector('.parent-click')!)
expect(log).toHaveBeenCalledWith('click')
// 2. child inc click + text interpolation
const count = container.querySelector('.count') as HTMLElement
expect(count.textContent).toBe(`0`)
triggerEvent('click', container.querySelector('.inc')!)
await nextTick()
expect(count.textContent).toBe(`1`)
// 3. child color click + style binding
expect(count.style.color).toBe('red')
triggerEvent('click', container.querySelector('.change')!)
await nextTick()
expect(count.style.color).toBe('green')
// 4. child event emit
triggerEvent('click', container.querySelector('.emit')!)
expect(log).toHaveBeenCalledWith('child')
// 5. child v-model
const text = container.querySelector('.text')!
const input = container.querySelector('input')!
expect(text.textContent).toBe('hello')
input.value = 'bye'
triggerEvent('input', input)
await nextTick()
expect(text.textContent).toBe('bye')
})
describe('mismatch handling', () => { describe('mismatch handling', () => {
test('text', () => {}) test('text', () => {})