]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test(ssr): ssr + hydration integration test
authorEvan You <yyx990803@gmail.com>
Fri, 6 Mar 2020 20:14:12 +0000 (15:14 -0500)
committerEvan You <yyx990803@gmail.com>
Fri, 6 Mar 2020 20:14:12 +0000 (15:14 -0500)
packages/compiler-core/__tests__/hydration.spec.ts

index 0fd3f723240f8e0587f2bee8da972f2bd746eefc..37672db06fc9ca4020d6bcc762309843920a9da9 100644 (file)
@@ -7,6 +7,7 @@ import {
   Portal,
   createStaticVNode
 } from '@vue/runtime-dom'
+import { renderToString } from '@vue/server-renderer'
 
 function mountWithHydration(html: string, render: () => any) {
   const container = document.createElement('div')
@@ -172,7 +173,99 @@ describe('SSR hydration', () => {
   })
 
   // 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', () => {
     test('text', () => {})