| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { HMRRuntime } from '../src/hmr'
- import '../src/hmr'
- import { ComponentOptions, RenderFunction } from '../src/component'
- import {
- render,
- nodeOps,
- h,
- serializeInner,
- triggerEvent,
- TestElement,
- nextTick
- } from '@vue/runtime-test'
- import * as runtimeTest from '@vue/runtime-test'
- import { baseCompile } from '@vue/compiler-core'
- declare var __VUE_HMR_RUNTIME__: HMRRuntime
- const { createRecord, rerender, reload } = __VUE_HMR_RUNTIME__
- function compileToFunction(template: string) {
- const { code } = baseCompile(template)
- const render = new Function('Vue', code)(runtimeTest) as RenderFunction
- render._rc = true // isRuntimeCompiled
- return render
- }
- describe('hot module replacement', () => {
- test('inject global runtime', () => {
- expect(createRecord).toBeDefined()
- expect(rerender).toBeDefined()
- expect(reload).toBeDefined()
- })
- test('createRecord', () => {
- expect(createRecord('test1', {})).toBe(true)
- // if id has already been created, should return false
- expect(createRecord('test1', {})).toBe(false)
- })
- test('rerender', async () => {
- const root = nodeOps.createElement('div')
- const parentId = 'test2-parent'
- const childId = 'test2-child'
- const Child: ComponentOptions = {
- __hmrId: childId,
- render: compileToFunction(`<slot/>`)
- }
- createRecord(childId, Child)
- const Parent: ComponentOptions = {
- __hmrId: parentId,
- data() {
- return { count: 0 }
- },
- components: { Child },
- render: compileToFunction(
- `<div @click="count++">{{ count }}<Child>{{ count }}</Child></div>`
- )
- }
- createRecord(parentId, Parent)
- render(h(Parent), root)
- expect(serializeInner(root)).toBe(`<div>00</div>`)
- // Perform some state change. This change should be preserved after the
- // re-render!
- triggerEvent(root.children[0] as TestElement, 'click')
- await nextTick()
- expect(serializeInner(root)).toBe(`<div>11</div>`)
- // Update text while preserving state
- rerender(
- parentId,
- compileToFunction(
- `<div @click="count++">{{ count }}!<Child>{{ count }}</Child></div>`
- )
- )
- expect(serializeInner(root)).toBe(`<div>1!1</div>`)
- // Should force child update on slot content change
- rerender(
- parentId,
- compileToFunction(
- `<div @click="count++">{{ count }}!<Child>{{ count }}!</Child></div>`
- )
- )
- expect(serializeInner(root)).toBe(`<div>1!1!</div>`)
- // Should force update element children despite block optimization
- rerender(
- parentId,
- compileToFunction(
- `<div @click="count++">{{ count }}<span>{{ count }}</span>
- <Child>{{ count }}!</Child>
- </div>`
- )
- )
- expect(serializeInner(root)).toBe(`<div>1<span>1</span>1!</div>`)
- // Should force update child slot elements
- rerender(
- parentId,
- compileToFunction(
- `<div @click="count++">
- <Child><span>{{ count }}</span></Child>
- </div>`
- )
- )
- expect(serializeInner(root)).toBe(`<div><span>1</span></div>`)
- })
- test('reload', async () => {
- const root = nodeOps.createElement('div')
- const childId = 'test3-child'
- const unmoutSpy = jest.fn()
- const mountSpy = jest.fn()
- const Child: ComponentOptions = {
- __hmrId: childId,
- data() {
- return { count: 0 }
- },
- unmounted: unmoutSpy,
- render: compileToFunction(`<div @click="count++">{{ count }}</div>`)
- }
- createRecord(childId, Child)
- const Parent: ComponentOptions = {
- render: () => h(Child)
- }
- render(h(Parent), root)
- expect(serializeInner(root)).toBe(`<div>0</div>`)
- reload(childId, {
- __hmrId: childId,
- data() {
- return { count: 1 }
- },
- mounted: mountSpy,
- render: compileToFunction(`<div @click="count++">{{ count }}</div>`)
- })
- await nextTick()
- expect(serializeInner(root)).toBe(`<div>1</div>`)
- expect(unmoutSpy).toHaveBeenCalledTimes(1)
- expect(mountSpy).toHaveBeenCalledTimes(1)
- })
- })
|