test: basic tests for hooks
This commit is contained in:
parent
665cd8e3d9
commit
a6a571f973
60
packages/runtime-core/__tests__/hooks.spec.ts
Normal file
60
packages/runtime-core/__tests__/hooks.spec.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { withHooks, useState, h, nextTick, useEffect } from '../src'
|
||||||
|
import { renderIntsance, serialize, triggerEvent } from '@vue/runtime-test'
|
||||||
|
|
||||||
|
describe('hooks', () => {
|
||||||
|
it('useState', async () => {
|
||||||
|
const Counter = withHooks(() => {
|
||||||
|
const [count, setCount] = useState(0)
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
setCount(count + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
count
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const counter = renderIntsance(Counter)
|
||||||
|
expect(serialize(counter.$el)).toBe(`<div>0</div>`)
|
||||||
|
|
||||||
|
triggerEvent(counter.$el, 'click')
|
||||||
|
await nextTick()
|
||||||
|
expect(serialize(counter.$el)).toBe(`<div>1</div>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('useEffect', async () => {
|
||||||
|
let effect = -1
|
||||||
|
|
||||||
|
const Counter = withHooks(() => {
|
||||||
|
const [count, setCount] = useState(0)
|
||||||
|
useEffect(() => {
|
||||||
|
effect = count
|
||||||
|
})
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
setCount(count + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
count
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const counter = renderIntsance(Counter)
|
||||||
|
expect(effect).toBe(0)
|
||||||
|
triggerEvent(counter.$el, 'click')
|
||||||
|
await nextTick()
|
||||||
|
expect(effect).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('useEffect with empty keys', async () => {
|
||||||
|
// TODO
|
||||||
|
})
|
||||||
|
|
||||||
|
it('useEffect with keys', async () => {
|
||||||
|
// TODO
|
||||||
|
})
|
||||||
|
})
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentInstance, FunctionalComponent } from '../component'
|
import { ComponentInstance, FunctionalComponent, Component } from '../component'
|
||||||
import { mergeLifecycleHooks, Data } from '../componentOptions'
|
import { mergeLifecycleHooks, Data } from '../componentOptions'
|
||||||
import { VNode, Slots } from '../vdom'
|
import { VNode, Slots } from '../vdom'
|
||||||
import { observable } from '@vue/observer'
|
import { observable } from '@vue/observer'
|
||||||
@ -36,7 +36,7 @@ export function unsetCurrentInstance() {
|
|||||||
currentInstance = null
|
currentInstance = null
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useState(initial: any) {
|
export function useState<T>(initial: T): [T, (newValue: T) => void] {
|
||||||
if (!currentInstance) {
|
if (!currentInstance) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`useState must be called in a function passed to withHooks.`
|
`useState must be called in a function passed to withHooks.`
|
||||||
@ -107,20 +107,20 @@ function injectEffect(
|
|||||||
: effect
|
: effect
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withHooks<T extends FunctionalComponent>(render: T): T {
|
export function withHooks(render: FunctionalComponent): new () => Component {
|
||||||
return {
|
return class ComponentWithHooks extends Component {
|
||||||
displayName: render.name,
|
static displayName = render.name
|
||||||
created() {
|
created() {
|
||||||
hooksState.set(this._self, {
|
hooksState.set((this as any)._self, {
|
||||||
state: observable({}),
|
state: observable({}),
|
||||||
effects: []
|
effects: []
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
render(props: Data, slots: Slots, attrs: Data, parentVNode: VNode) {
|
render(props: Data, slots: Slots, attrs: Data, parentVNode: VNode) {
|
||||||
setCurrentInstance(this._self)
|
setCurrentInstance((this as any)._self)
|
||||||
const ret = render(props, slots, attrs, parentVNode)
|
const ret = render(props, slots, attrs, parentVNode)
|
||||||
unsetCurrentInstance()
|
unsetCurrentInstance()
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
} as any
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user