import { child, createIf, insert, renderEffect, template, // @ts-expect-error withDirectives, } from '../src' import { nextTick, ref } from '@vue/runtime-dom' import type { Mock } from 'vitest' import { makeRender } from './_utils' import { unmountComponent } from '../src/component' import { setElementText } from '../src/dom/prop' const define = makeRender() describe('createIf', () => { test('basic', async () => { // mock this template: //
{{counter}}
//zero
//zero
') const { host } = define(() => { const n0 = t0() insert( createIf( spyConditionFn, // v-if (spyIfFn ||= vi.fn(() => { const n2 = t1() renderEffect(() => { setElementText(n2, count.value) }) return n2 })), // v-else (spyElseFn ||= vi.fn(() => { const n4 = t2() return n4 })), ), n0 as any as ParentNode, ) return n0 }).render() expect(host.innerHTML).toBe('zero
1
2
zero
foo
')(), () => template('bar
')(), true, ) }, }).render() expect(html()).toBe('bar
') toggle.value = true await nextTick() // should not change expect(html()).toBe('bar
') }) // vapor custom directives have no lifecycle hooks. test.todo('should work with directive hooks', async () => { const calls: string[] = [] const show1 = ref(true) const show2 = ref(true) const update = ref(0) const spyConditionFn1 = vi.fn(() => show1.value) const spyConditionFn2 = vi.fn(() => show2.value) const vDirective: any = { created: (el: any, { value }: any) => calls.push(`${value} created`), beforeMount: (el: any, { value }: any) => calls.push(`${value} beforeMount`), mounted: (el: any, { value }: any) => calls.push(`${value} mounted`), beforeUpdate: (el: any, { value }: any) => calls.push(`${value} beforeUpdate`), updated: (el: any, { value }: any) => calls.push(`${value} updated`), beforeUnmount: (el: any, { value }: any) => calls.push(`${value} beforeUnmount`), unmounted: (el: any, { value }: any) => calls.push(`${value} unmounted`), } const t0 = template('') const { instance } = define(() => { const n1 = createIf( spyConditionFn1, () => { const n2 = t0() as ParentNode withDirectives(child(n2), [[vDirective, () => (update.value, '1')]]) return n2 }, () => createIf( spyConditionFn2, () => { const n2 = t0() as ParentNode withDirectives(child(n2), [[vDirective, () => '2']]) return n2 }, () => { const n2 = t0() as ParentNode withDirectives(child(n2), [[vDirective, () => '3']]) return n2 }, ), ) return [n1] }).render() await nextTick() expect(calls).toEqual(['1 created', '1 beforeMount', '1 mounted']) calls.length = 0 expect(spyConditionFn1).toHaveBeenCalledTimes(1) expect(spyConditionFn2).toHaveBeenCalledTimes(0) show1.value = false await nextTick() expect(calls).toEqual([ '1 beforeUnmount', '2 created', '2 beforeMount', '1 unmounted', '2 mounted', ]) calls.length = 0 expect(spyConditionFn1).toHaveBeenCalledTimes(2) expect(spyConditionFn2).toHaveBeenCalledTimes(1) show2.value = false await nextTick() expect(calls).toEqual([ '2 beforeUnmount', '3 created', '3 beforeMount', '2 unmounted', '3 mounted', ]) calls.length = 0 expect(spyConditionFn1).toHaveBeenCalledTimes(2) expect(spyConditionFn2).toHaveBeenCalledTimes(2) show1.value = true await nextTick() expect(calls).toEqual([ '3 beforeUnmount', '1 created', '1 beforeMount', '3 unmounted', '1 mounted', ]) calls.length = 0 expect(spyConditionFn1).toHaveBeenCalledTimes(3) expect(spyConditionFn2).toHaveBeenCalledTimes(2) update.value++ await nextTick() expect(calls).toEqual(['1 beforeUpdate', '1 updated']) calls.length = 0 expect(spyConditionFn1).toHaveBeenCalledTimes(3) expect(spyConditionFn2).toHaveBeenCalledTimes(2) unmountComponent(instance!) expect(calls).toEqual(['1 beforeUnmount', '1 unmounted']) expect(spyConditionFn1).toHaveBeenCalledTimes(3) expect(spyConditionFn2).toHaveBeenCalledTimes(2) }) })