]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: basic tests for hooks
authorEvan You <yyx990803@gmail.com>
Sun, 28 Oct 2018 21:45:53 +0000 (17:45 -0400)
committerEvan You <yyx990803@gmail.com>
Sun, 28 Oct 2018 21:45:53 +0000 (17:45 -0400)
packages/runtime-core/__tests__/hooks.spec.ts [new file with mode: 0644]
packages/runtime-core/src/optional/hooks.ts

diff --git a/packages/runtime-core/__tests__/hooks.spec.ts b/packages/runtime-core/__tests__/hooks.spec.ts
new file mode 100644 (file)
index 0000000..51ccd39
--- /dev/null
@@ -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
+  })
+})
index 9303613df6ed9ba9c0cfd71944b92b1daf76c094..c195c2c765d484a44c3256f544e1fd701c31e111 100644 (file)
@@ -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
+  }
 }