test(runtime-vapor): tidy custom directives test
This commit is contained in:
parent
30f6eec3c1
commit
886440d240
|
@ -152,7 +152,7 @@ describe('api: createVaporApp', () => {
|
|||
expect(host.innerHTML).toBe(`foobar!barbaz!`)
|
||||
})
|
||||
|
||||
test.todo('directive', () => {
|
||||
test('directive', () => {
|
||||
const spy1 = vi.fn()
|
||||
const spy2 = vi.fn()
|
||||
|
||||
|
@ -167,12 +167,12 @@ describe('api: createVaporApp', () => {
|
|||
},
|
||||
}).create()
|
||||
|
||||
const FooBar = { mounted: spy1 }
|
||||
const FooBar = spy1
|
||||
app.directive('FooBar', FooBar)
|
||||
expect(app.directive('FooBar')).toBe(FooBar)
|
||||
|
||||
app.directive('BarBaz', { mounted: spy2 })
|
||||
app.directive('BarBaz', { mounted: spy2 })
|
||||
app.directive('BarBaz', spy2)
|
||||
app.directive('BarBaz', spy2)
|
||||
expect(
|
||||
'Directive "BarBaz" has already been registered in target app.',
|
||||
).toHaveBeenWarnedTimes(1)
|
||||
|
|
|
@ -104,7 +104,7 @@ describe('api: setup context', () => {
|
|||
const Wrapper = defineComponent({
|
||||
setup(_) {
|
||||
const n0 = createSlot('default')
|
||||
setInheritAttrs(false, true)
|
||||
setInheritAttrs(true)
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,418 +0,0 @@
|
|||
import {
|
||||
type DirectiveBinding,
|
||||
type DirectiveHook,
|
||||
createComponent,
|
||||
defineComponent,
|
||||
nextTick,
|
||||
ref,
|
||||
renderEffect,
|
||||
setText,
|
||||
template,
|
||||
withDirectives,
|
||||
} from '../src'
|
||||
import {
|
||||
type Component,
|
||||
type ComponentInternalInstance,
|
||||
currentInstance,
|
||||
} from '../src/component'
|
||||
import { makeRender } from './_utils'
|
||||
|
||||
const define = makeRender()
|
||||
|
||||
describe.todo('directives', () => {
|
||||
it('should work', async () => {
|
||||
const count = ref(0)
|
||||
|
||||
function assertBindings(binding: DirectiveBinding) {
|
||||
expect(binding.value).toBe(count.value)
|
||||
expect(binding.arg).toBe('foo')
|
||||
expect(binding.instance).toBe(_instance)
|
||||
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
|
||||
}
|
||||
|
||||
const beforeMount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should not be inserted yet
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(host.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
|
||||
expect(el).toBe(_node)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const mounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be inserted now
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const beforeUpdate = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
// node should not have been updated yet
|
||||
expect(el.childNodes[0].textContent).toBe(`${count.value - 1}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const updated = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
// node should have been updated
|
||||
expect(el.childNodes[0].textContent).toBe(`${count.value}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const beforeUnmount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be removed now
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const unmounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should have been removed
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(host.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const dir = {
|
||||
beforeMount,
|
||||
mounted,
|
||||
beforeUpdate,
|
||||
updated,
|
||||
beforeUnmount,
|
||||
unmounted,
|
||||
}
|
||||
|
||||
let _instance: ComponentInternalInstance | null = null
|
||||
let _node: Node | null = null
|
||||
|
||||
const { host, render } = define({
|
||||
setup() {
|
||||
_instance = currentInstance
|
||||
},
|
||||
render() {
|
||||
_node = template('<div>')()
|
||||
renderEffect(() => {
|
||||
setText(_node!, count.value)
|
||||
})
|
||||
withDirectives(_node, [
|
||||
[
|
||||
dir,
|
||||
// value
|
||||
() => count.value,
|
||||
// argument
|
||||
'foo',
|
||||
// modifiers
|
||||
{ ok: true },
|
||||
],
|
||||
])
|
||||
return _node
|
||||
},
|
||||
})
|
||||
const { app } = render()
|
||||
|
||||
expect(beforeMount).toHaveBeenCalledTimes(1)
|
||||
expect(mounted).toHaveBeenCalledTimes(1)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(1)
|
||||
expect(updated).toHaveBeenCalledTimes(1)
|
||||
|
||||
app.unmount()
|
||||
expect(beforeUnmount).toHaveBeenCalledTimes(1)
|
||||
expect(unmounted).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should work with a function directive', async () => {
|
||||
const count = ref(0)
|
||||
|
||||
function assertBindings(binding: DirectiveBinding) {
|
||||
expect(binding.value).toBe(count.value)
|
||||
expect(binding.arg).toBe('foo')
|
||||
expect(binding.instance).toBe(_instance)
|
||||
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
|
||||
}
|
||||
|
||||
const fn = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(host)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
let _instance: ComponentInternalInstance | null = null
|
||||
let _node: Node | null = null
|
||||
const Comp = {
|
||||
setup() {
|
||||
_instance = currentInstance
|
||||
},
|
||||
render() {
|
||||
_node = template('<div>')()
|
||||
renderEffect(() => {
|
||||
setText(_node!, count.value)
|
||||
})
|
||||
withDirectives(_node, [
|
||||
[
|
||||
fn,
|
||||
// value
|
||||
() => count.value,
|
||||
// argument
|
||||
'foo',
|
||||
// modifiers
|
||||
{ ok: true },
|
||||
],
|
||||
])
|
||||
return _node
|
||||
},
|
||||
}
|
||||
|
||||
const { host, render } = define(Comp)
|
||||
render()
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(fn).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('should work on components', async () => {
|
||||
const count = ref(0)
|
||||
|
||||
function assertBindings(binding: DirectiveBinding) {
|
||||
expect(binding.value).toBe(count.value)
|
||||
expect(binding.arg).toBe('foo')
|
||||
expect(binding.instance).toBe(_instance)
|
||||
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
|
||||
}
|
||||
|
||||
const beforeMount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should not be inserted yet
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(host.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const mounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be inserted now
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const beforeUpdate = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
// node should not have been updated yet
|
||||
expect(el.childNodes[0].textContent).toBe(`${count.value - 1}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const updated = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
// node should have been updated
|
||||
expect(el.childNodes[0].textContent).toBe(`${count.value}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const beforeUnmount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be removed now
|
||||
expect(el.parentNode).toBe(host)
|
||||
expect(host.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const unmounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should have been removed
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(host.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook)
|
||||
|
||||
const dir = {
|
||||
beforeMount,
|
||||
mounted,
|
||||
beforeUpdate,
|
||||
updated,
|
||||
beforeUnmount,
|
||||
unmounted,
|
||||
}
|
||||
|
||||
let _instance: ComponentInternalInstance | null = null
|
||||
let _node: Node | null = null
|
||||
|
||||
const Child = (props: { count: number }) => {
|
||||
_node = template('<div>')()
|
||||
renderEffect(() => {
|
||||
setText(_node!, props.count)
|
||||
})
|
||||
return _node
|
||||
}
|
||||
|
||||
const Comp = {
|
||||
setup() {
|
||||
_instance = currentInstance
|
||||
},
|
||||
render() {
|
||||
_node = template('<div>')()
|
||||
return withDirectives(
|
||||
createComponent(Child, { count: () => count.value }),
|
||||
[
|
||||
[
|
||||
dir,
|
||||
// value
|
||||
() => count.value,
|
||||
// argument
|
||||
'foo',
|
||||
// modifiers
|
||||
{ ok: true },
|
||||
],
|
||||
],
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const { host, render } = define(Comp)
|
||||
render()
|
||||
|
||||
expect(beforeMount).toHaveBeenCalledTimes(1)
|
||||
expect(mounted).toHaveBeenCalledTimes(1)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(1)
|
||||
expect(updated).toHaveBeenCalledTimes(1)
|
||||
|
||||
render(null, host)
|
||||
expect(beforeUnmount).toHaveBeenCalledTimes(1)
|
||||
expect(unmounted).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
// #2298
|
||||
it('directive merging on component root', () => {
|
||||
const d1 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const d2 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const Comp: Component = {
|
||||
render() {
|
||||
return withDirectives(template('<div>')(), [[d2]])
|
||||
},
|
||||
}
|
||||
|
||||
const App = {
|
||||
name: 'App',
|
||||
render() {
|
||||
return withDirectives(createComponent(Comp), [[d1]])
|
||||
},
|
||||
}
|
||||
|
||||
define(App).render()
|
||||
expect(d1.mounted).toHaveBeenCalled()
|
||||
expect(d2.mounted).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('should disable tracking inside directive lifecycle hooks', async () => {
|
||||
const count = ref(0)
|
||||
const text = ref('')
|
||||
const beforeUpdate = vi.fn(() => count.value++)
|
||||
|
||||
const App = {
|
||||
render() {
|
||||
const node = template('<p>')()
|
||||
renderEffect(() => {
|
||||
setText(node, text.value)
|
||||
})
|
||||
return withDirectives(node, [
|
||||
[
|
||||
{
|
||||
beforeUpdate,
|
||||
},
|
||||
],
|
||||
])
|
||||
},
|
||||
}
|
||||
|
||||
define(App).render()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(0)
|
||||
expect(count.value).toBe(0)
|
||||
|
||||
text.value = 'foo'
|
||||
await nextTick()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(1)
|
||||
expect(count.value).toBe(1)
|
||||
})
|
||||
|
||||
test('should receive exposeProxy for closed instances', async () => {
|
||||
let res: string
|
||||
const App = defineComponent({
|
||||
setup(_, { expose }) {
|
||||
expose({
|
||||
msg: 'Test',
|
||||
})
|
||||
|
||||
return withDirectives(template('<p>')(), [
|
||||
[
|
||||
{
|
||||
mounted(el, { instance }) {
|
||||
res = instance.exposed!.msg
|
||||
},
|
||||
},
|
||||
],
|
||||
])
|
||||
},
|
||||
})
|
||||
define(App).render()
|
||||
expect(res!).toBe('Test')
|
||||
})
|
||||
|
||||
test('should not throw with unknown directive', async () => {
|
||||
const d1 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const App = {
|
||||
name: 'App',
|
||||
render() {
|
||||
// simulates the code generated on an unknown directive
|
||||
return withDirectives(template('<div>')(), [[undefined], [d1]])
|
||||
},
|
||||
}
|
||||
|
||||
define(App).render()
|
||||
expect(d1.mounted).toHaveBeenCalled()
|
||||
})
|
||||
})
|
|
@ -1,295 +0,0 @@
|
|||
import { ref } from '@vue/reactivity'
|
||||
import {
|
||||
type ComponentInternalInstance,
|
||||
type DirectiveBinding,
|
||||
type DirectiveHook,
|
||||
createComponent,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
renderEffect,
|
||||
setText,
|
||||
template,
|
||||
withDirectives,
|
||||
} from '@vue/runtime-vapor'
|
||||
import { makeRender } from '../_utils'
|
||||
|
||||
const define = makeRender()
|
||||
|
||||
describe.todo('directives', () => {
|
||||
it('should work', async () => {
|
||||
const count = ref(0)
|
||||
|
||||
function assertBindings(binding: DirectiveBinding) {
|
||||
expect(binding.value).toBe(count.value)
|
||||
expect(binding.arg).toBe('foo')
|
||||
expect(binding.instance).toBe(_instance)
|
||||
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
|
||||
}
|
||||
|
||||
const beforeMount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should not be inserted yet
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(root.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
|
||||
// expect(vnode).toBe(_vnode)
|
||||
// expect(prevVNode).toBe(null)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const mounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be inserted now
|
||||
expect(el.parentNode).toBe(root)
|
||||
expect(root.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const beforeUpdate = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(root)
|
||||
expect(root.children[0]).toBe(el)
|
||||
|
||||
// node should not have been updated yet
|
||||
expect(el.firstChild?.textContent).toBe(`${count.value - 1}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const updated = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(root)
|
||||
expect(root.children[0]).toBe(el)
|
||||
|
||||
// node should have been updated
|
||||
expect(el.firstChild?.textContent).toBe(`${count.value}`)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const beforeUnmount = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should be removed now
|
||||
expect(el.parentNode).toBe(root)
|
||||
expect(root.children[0]).toBe(el)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const unmounted = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
// should have been removed
|
||||
expect(el.parentNode).toBe(null)
|
||||
expect(root.children.length).toBe(0)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
const dir = {
|
||||
beforeMount,
|
||||
mounted,
|
||||
beforeUpdate,
|
||||
updated,
|
||||
beforeUnmount,
|
||||
unmounted,
|
||||
}
|
||||
|
||||
let _instance: ComponentInternalInstance | null = null
|
||||
const { render } = define({
|
||||
setup() {
|
||||
_instance = getCurrentInstance()
|
||||
},
|
||||
render() {
|
||||
const n0 = template('<div></div>')()
|
||||
renderEffect(() => setText(n0, count.value))
|
||||
withDirectives(n0, [
|
||||
[
|
||||
dir,
|
||||
// value
|
||||
() => count.value,
|
||||
// argument
|
||||
'foo',
|
||||
// modifiers
|
||||
{ ok: true },
|
||||
],
|
||||
])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const root = document.createElement('div')
|
||||
|
||||
render(null, root)
|
||||
expect(beforeMount).toHaveBeenCalledTimes(1)
|
||||
expect(mounted).toHaveBeenCalledTimes(1)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(1)
|
||||
expect(updated).toHaveBeenCalledTimes(1)
|
||||
|
||||
render(null, root)
|
||||
expect(beforeUnmount).toHaveBeenCalledTimes(1)
|
||||
expect(unmounted).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should work with a function directive', async () => {
|
||||
const count = ref(0)
|
||||
|
||||
function assertBindings(binding: DirectiveBinding) {
|
||||
expect(binding.value).toBe(count.value)
|
||||
expect(binding.arg).toBe('foo')
|
||||
expect(binding.instance).toBe(_instance)
|
||||
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
|
||||
}
|
||||
|
||||
const fn = vi.fn(((el, binding) => {
|
||||
expect(el.tagName).toBe('DIV')
|
||||
expect(el.parentNode).toBe(root)
|
||||
|
||||
assertBindings(binding)
|
||||
}) as DirectiveHook<Element>)
|
||||
|
||||
let _instance: ComponentInternalInstance | null = null
|
||||
const { render } = define({
|
||||
setup() {
|
||||
_instance = getCurrentInstance()
|
||||
},
|
||||
render() {
|
||||
const n0 = template('<div></div>')()
|
||||
renderEffect(() => setText(n0, count.value))
|
||||
withDirectives(n0, [
|
||||
[
|
||||
fn,
|
||||
// value
|
||||
() => count.value,
|
||||
// argument
|
||||
'foo',
|
||||
// modifiers
|
||||
{ ok: true },
|
||||
],
|
||||
])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const root = document.createElement('div')
|
||||
render(null, root)
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(fn).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
// #2298
|
||||
it('directive merging on component root', () => {
|
||||
const d1 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const d2 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const Comp = {
|
||||
render() {
|
||||
const n0 = template('<div></div>')()
|
||||
withDirectives(n0, [[d2]])
|
||||
return n0
|
||||
},
|
||||
}
|
||||
|
||||
const { render } = define({
|
||||
name: 'App',
|
||||
render() {
|
||||
const n0 = createComponent(Comp)
|
||||
withDirectives(n0, [[d1]])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const root = document.createElement('div')
|
||||
render(null, root)
|
||||
expect(d1.mounted).toHaveBeenCalled()
|
||||
expect(d2.mounted).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('should disable tracking inside directive lifecycle hooks', async () => {
|
||||
const count = ref(0)
|
||||
const text = ref('')
|
||||
const beforeUpdate = vi.fn(() => count.value++)
|
||||
|
||||
const { render } = define({
|
||||
render() {
|
||||
const n0 = template('<p></p>')()
|
||||
renderEffect(() => setText(n0, text.value))
|
||||
withDirectives(n0, [
|
||||
[
|
||||
{
|
||||
beforeUpdate,
|
||||
},
|
||||
],
|
||||
])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const root = document.createElement('div')
|
||||
render(null, root)
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(0)
|
||||
expect(count.value).toBe(0)
|
||||
|
||||
text.value = 'foo'
|
||||
await nextTick()
|
||||
expect(beforeUpdate).toHaveBeenCalledTimes(1)
|
||||
expect(count.value).toBe(1)
|
||||
})
|
||||
|
||||
test('should receive exposeProxy for closed instances', async () => {
|
||||
let res: string
|
||||
const { render } = define({
|
||||
setup(_, { expose }) {
|
||||
expose({
|
||||
msg: 'Test',
|
||||
})
|
||||
},
|
||||
render() {
|
||||
const n0 = template('<p>Lore Ipsum</p>')()
|
||||
withDirectives(n0, [
|
||||
[
|
||||
{
|
||||
mounted(el, { instance }) {
|
||||
res = (instance.exposed as any).msg as string
|
||||
},
|
||||
},
|
||||
],
|
||||
])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
const root = document.createElement('div')
|
||||
render(null, root)
|
||||
expect(res!).toBe('Test')
|
||||
})
|
||||
|
||||
test('should not throw with unknown directive', async () => {
|
||||
const d1 = {
|
||||
mounted: vi.fn(),
|
||||
}
|
||||
const { render } = define({
|
||||
name: 'App',
|
||||
render() {
|
||||
const n0 = template('<div></div>')()
|
||||
// simulates the code generated on an unknown directive
|
||||
withDirectives(n0, [[undefined], [d1]])
|
||||
return n0
|
||||
},
|
||||
})
|
||||
|
||||
const root = document.createElement('div')
|
||||
render(null, root)
|
||||
expect(d1.mounted).toHaveBeenCalled()
|
||||
})
|
||||
})
|
|
@ -28,7 +28,8 @@ const createDemo = (defaultValue: boolean) =>
|
|||
on(n1 as HTMLElement, 'click', () => handleClick)
|
||||
return n0
|
||||
})
|
||||
describe.todo('directive: v-show', () => {
|
||||
|
||||
describe('directive: v-show', () => {
|
||||
test('basic', async () => {
|
||||
const { host } = createDemo(true).render()
|
||||
const btn = host.querySelector('button')
|
||||
|
@ -66,7 +67,7 @@ describe.todo('directive: v-show', () => {
|
|||
},
|
||||
})
|
||||
|
||||
const { instance, host } = define({
|
||||
const { host } = define({
|
||||
render() {
|
||||
const n1 = t1()
|
||||
const n2 = createComponent(Child, [], null, true)
|
||||
|
@ -77,7 +78,6 @@ describe.todo('directive: v-show', () => {
|
|||
}).render()
|
||||
|
||||
expect(host.innerHTML).toBe('<button>toggle</button><div>child</div>')
|
||||
expect(instance?.scope.dirs!.get(n0)![0].dir).toBe(vShow)
|
||||
|
||||
const btn = host.querySelector('button')
|
||||
btn?.click()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { insert, normalizeBlock, prepend, remove } from '../../src/dom/element'
|
||||
import { fragmentKey } from '../../src/apiRender'
|
||||
import { fragmentKey, normalizeBlock } from '../../src/block'
|
||||
import { insert, prepend, remove } from '../../src/dom/element'
|
||||
|
||||
const node1 = document.createTextNode('node1')
|
||||
const node2 = document.createTextNode('node2')
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
import {
|
||||
type Directive,
|
||||
children,
|
||||
createFor,
|
||||
nextTick,
|
||||
ref,
|
||||
renderEffect,
|
||||
shallowRef,
|
||||
template,
|
||||
triggerRef,
|
||||
withDirectives,
|
||||
} from '../src'
|
||||
import { makeRender } from './_utils'
|
||||
import { unmountComponent } from '../src/apiRender'
|
||||
|
||||
const define = makeRender()
|
||||
|
||||
|
@ -194,122 +189,6 @@ describe('createFor', () => {
|
|||
expect(host.innerHTML).toBe('<!--for-->')
|
||||
})
|
||||
|
||||
test.fails('should work with directive hooks', async () => {
|
||||
const calls: string[] = []
|
||||
const list = ref([0])
|
||||
const update = ref(0)
|
||||
const add = () => list.value.push(list.value.length)
|
||||
const spySrcFn = vi.fn(() => list.value)
|
||||
|
||||
const vDirective: Directive = {
|
||||
created: (el, { value }) => calls.push(`${value} created`),
|
||||
beforeMount: (el, { value }) => calls.push(`${value} beforeMount`),
|
||||
mounted: (el, { value }) => calls.push(`${value} mounted`),
|
||||
beforeUpdate: (el, { value }) => calls.push(`${value} beforeUpdate`),
|
||||
updated: (el, { value }) => calls.push(`${value} updated`),
|
||||
beforeUnmount: (el, { value }) => calls.push(`${value} beforeUnmount`),
|
||||
unmounted: (el, { value }) => calls.push(`${value} unmounted`),
|
||||
}
|
||||
|
||||
const t0 = template('<p></p>')
|
||||
const { instance } = define(() => {
|
||||
const n1 = createFor(spySrcFn, ctx0 => {
|
||||
const n2 = t0()
|
||||
const n3 = children(n2, 0)
|
||||
withDirectives(n3, [[vDirective, () => ctx0[0]]])
|
||||
renderEffect(() => {
|
||||
calls.push(`${ctx0[0]} effecting`)
|
||||
})
|
||||
return n2
|
||||
})
|
||||
renderEffect(() => update.value)
|
||||
return [n1]
|
||||
}).render()
|
||||
|
||||
await nextTick()
|
||||
// `${item index} ${hook name}`
|
||||
expect(calls).toEqual([
|
||||
'0 created',
|
||||
'0 effecting',
|
||||
'0 beforeMount',
|
||||
'0 mounted',
|
||||
])
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(1)
|
||||
|
||||
add()
|
||||
await nextTick()
|
||||
expect(calls).toEqual([
|
||||
'0 beforeUpdate',
|
||||
'1 created',
|
||||
'1 effecting',
|
||||
'1 beforeMount',
|
||||
'0 updated',
|
||||
'1 mounted',
|
||||
])
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(2)
|
||||
|
||||
list.value.reverse()
|
||||
await nextTick()
|
||||
expect(calls).toEqual([
|
||||
'1 beforeUpdate',
|
||||
'0 beforeUpdate',
|
||||
'1 effecting',
|
||||
'0 effecting',
|
||||
'1 updated',
|
||||
'0 updated',
|
||||
])
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(3)
|
||||
list.value.reverse()
|
||||
await nextTick()
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(4)
|
||||
|
||||
update.value++
|
||||
await nextTick()
|
||||
expect(calls).toEqual([
|
||||
'0 beforeUpdate',
|
||||
'1 beforeUpdate',
|
||||
'0 updated',
|
||||
'1 updated',
|
||||
])
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(4)
|
||||
|
||||
// change item
|
||||
list.value[1] = 2
|
||||
await nextTick()
|
||||
expect(calls).toEqual([
|
||||
'0 beforeUpdate',
|
||||
'2 beforeUpdate',
|
||||
'2 effecting',
|
||||
'0 updated',
|
||||
'2 updated',
|
||||
])
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(5)
|
||||
list.value[1] = 1
|
||||
await nextTick()
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(6)
|
||||
|
||||
// remove the last item
|
||||
list.value.pop()
|
||||
await nextTick()
|
||||
expect(calls).toEqual([
|
||||
'0 beforeUpdate',
|
||||
'1 beforeUnmount',
|
||||
'0 updated',
|
||||
'1 unmounted',
|
||||
])
|
||||
calls.length = 0
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(7)
|
||||
|
||||
unmountComponent(instance!)
|
||||
expect(calls).toEqual(['0 beforeUnmount', '0 unmounted'])
|
||||
expect(spySrcFn).toHaveBeenCalledTimes(7)
|
||||
})
|
||||
|
||||
test('de-structured value', async () => {
|
||||
const list = ref([{ name: '1' }, { name: '2' }, { name: '3' }])
|
||||
function reverse() {
|
||||
|
|
|
@ -10,12 +10,9 @@ import { makeRender } from '../_utils'
|
|||
const define = makeRender()
|
||||
|
||||
describe('resolveAssets', () => {
|
||||
test('todo', () => {
|
||||
expect(true).toBeTruthy()
|
||||
})
|
||||
test('should work', () => {
|
||||
const FooBar = () => []
|
||||
const BarBaz = { mounted: () => null }
|
||||
const BarBaz = () => undefined
|
||||
let component1: Component | string
|
||||
let component2: Component | string
|
||||
let component3: Component | string
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
validateComponentName,
|
||||
} from './component'
|
||||
import { warn } from './warning'
|
||||
import { type Directive, version } from '.'
|
||||
import { version } from '.'
|
||||
import {
|
||||
normalizeContainer,
|
||||
render,
|
||||
|
@ -15,7 +15,7 @@ import {
|
|||
} from './apiRender'
|
||||
import type { InjectionKey } from './apiInject'
|
||||
import type { RawProps } from './componentProps'
|
||||
import { validateDirectiveName } from './directives'
|
||||
import { type Directive, validateDirectiveName } from './directives'
|
||||
import { devtoolsInitApp, setDevtoolsHook } from './devtools'
|
||||
|
||||
let uid = 0
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { camelize, capitalize, isString } from '@vue/shared'
|
||||
import { type Directive, warn } from '..'
|
||||
import { warn } from '../warning'
|
||||
import type { Directive } from '../directives'
|
||||
import { type Component, currentInstance } from '../component'
|
||||
import { getComponentName } from '../component'
|
||||
|
||||
export const COMPONENTS = 'components'
|
||||
export const DIRECTIVES = 'directives'
|
||||
const COMPONENTS = 'components'
|
||||
const DIRECTIVES = 'directives'
|
||||
|
||||
export type AssetTypes = typeof COMPONENTS | typeof DIRECTIVES
|
||||
|
||||
|
|
Loading…
Reference in New Issue