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 { VNode, Slots } from '../vdom'
|
||||
import { observable } from '@vue/observer'
|
||||
@ -36,7 +36,7 @@ export function unsetCurrentInstance() {
|
||||
currentInstance = null
|
||||
}
|
||||
|
||||
export function useState(initial: any) {
|
||||
export function useState<T>(initial: T): [T, (newValue: T) => void] {
|
||||
if (!currentInstance) {
|
||||
throw new Error(
|
||||
`useState must be called in a function passed to withHooks.`
|
||||
@ -107,20 +107,20 @@ function injectEffect(
|
||||
: effect
|
||||
}
|
||||
|
||||
export function withHooks<T extends FunctionalComponent>(render: T): T {
|
||||
return {
|
||||
displayName: render.name,
|
||||
export function withHooks(render: FunctionalComponent): new () => Component {
|
||||
return class ComponentWithHooks extends Component {
|
||||
static displayName = render.name
|
||||
created() {
|
||||
hooksState.set(this._self, {
|
||||
hooksState.set((this as any)._self, {
|
||||
state: observable({}),
|
||||
effects: []
|
||||
})
|
||||
},
|
||||
}
|
||||
render(props: Data, slots: Slots, attrs: Data, parentVNode: VNode) {
|
||||
setCurrentInstance(this._self)
|
||||
setCurrentInstance((this as any)._self)
|
||||
const ret = render(props, slots, attrs, parentVNode)
|
||||
unsetCurrentInstance()
|
||||
return ret
|
||||
}
|
||||
} as any
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user