vue3-core/packages/server-renderer/__tests__/ssrWatch.spec.ts

203 lines
4.8 KiB
TypeScript

import {
createSSRApp,
defineComponent,
h,
nextTick,
ref,
watch,
watchEffect,
} from 'vue'
import { type SSRContext, renderToString } from '../src'
describe('ssr: watch', () => {
// #6013
test('should work w/ flush:sync', async () => {
const App = defineComponent(() => {
const count = ref(0)
let msg = ''
watch(
count,
() => {
msg = 'hello world'
},
{ flush: 'sync' },
)
count.value = 1
expect(msg).toBe('hello world')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles!.length).toBe(1)
expect(html).toMatch('hello world')
})
test('should work with flush: sync and immediate: true', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watch(
text,
() => {
msg = text.value
},
{ flush: 'sync', immediate: true },
)
expect(msg).toBe('start')
text.value = 'changed'
expect(msg).toBe('changed')
text.value = 'changed again'
expect(msg).toBe('changed again')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles!.length).toBe(1)
expect(html).toMatch('changed again')
await nextTick()
expect(msg).toBe('changed again')
})
test('should run once with immediate: true', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watch(
text,
() => {
msg = String(text.value)
},
{ immediate: true },
)
text.value = 'changed'
expect(msg).toBe('start')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles).toBeUndefined()
expect(html).toMatch('start')
await nextTick()
expect(msg).toBe('start')
})
test('should run once with immediate: true and flush: post', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watch(
text,
() => {
msg = String(text.value)
},
{ immediate: true, flush: 'post' },
)
text.value = 'changed'
expect(msg).toBe('start')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles).toBeUndefined()
expect(html).toMatch('start')
await nextTick()
expect(msg).toBe('start')
})
})
describe('ssr: watchEffect', () => {
test('should run with flush: sync', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watchEffect(
() => {
msg = text.value
},
{ flush: 'sync' },
)
expect(msg).toBe('start')
text.value = 'changed'
expect(msg).toBe('changed')
text.value = 'changed again'
expect(msg).toBe('changed again')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles!.length).toBe(1)
expect(html).toMatch('changed again')
await nextTick()
expect(msg).toBe('changed again')
})
test('should run once with default flush (pre)', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watchEffect(() => {
msg = text.value
})
text.value = 'changed'
expect(msg).toBe('start')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles).toBeUndefined()
expect(html).toMatch('start')
await nextTick()
expect(msg).toBe('start')
})
test('should not run for flush: post', async () => {
const text = ref('start')
let msg = 'unchanged'
const App = defineComponent(() => {
watchEffect(
() => {
msg = text.value
},
{ flush: 'post' },
)
text.value = 'changed'
expect(msg).toBe('unchanged')
return () => h('div', null, msg)
})
const app = createSSRApp(App)
const ctx: SSRContext = {}
const html = await renderToString(app, ctx)
expect(ctx.__watcherHandles).toBeUndefined()
expect(html).toMatch('unchanged')
await nextTick()
expect(msg).toBe('unchanged')
})
})