瀏覽代碼

feat(runtime-test): triggerEvent

Evan You 7 年之前
父節點
當前提交
665cd8e3d9

+ 26 - 1
packages/runtime-test/__tests__/testRenderer.spec.ts

@@ -11,7 +11,9 @@ import {
   nextTick,
   observable,
   resetOps,
-  serialize
+  serialize,
+  renderIntsance,
+  triggerEvent
 } from '../src'
 
 describe('test renderer', () => {
@@ -152,4 +154,27 @@ describe('test renderer', () => {
 </div>`
     )
   })
+
+  it('should be able to trigger events', async () => {
+    class App extends Component {
+      count = 0
+      inc() {
+        this.count++
+      }
+      render() {
+        return h(
+          'div',
+          {
+            onClick: this.inc
+          },
+          this.count
+        )
+      }
+    }
+    const app = renderIntsance(App)
+    triggerEvent(app.$el, 'click')
+    expect(app.count).toBe(1)
+    await nextTick()
+    expect(serialize(app.$el)).toBe(`<div>1</div>`)
+  })
 })

+ 1 - 0
packages/runtime-test/src/index.ts

@@ -34,5 +34,6 @@ export function renderIntsance<T extends Component>(
 }
 
 export { serialize } from './serialize'
+export { triggerEvent } from './triggerEvent'
 export * from './nodeOps'
 export * from '@vue/runtime-core'

+ 3 - 1
packages/runtime-test/src/nodeOps.ts

@@ -10,6 +10,7 @@ export interface TestElement {
   tag: string
   children: TestNode[]
   props: Record<string, any>
+  eventListeners: Record<string, Function | Function[]> | null
 }
 
 export interface TestText {
@@ -68,7 +69,8 @@ function createElement(tag: string): TestElement {
     tag,
     children: [],
     props: {},
-    parentNode: null
+    parentNode: null,
+    eventListeners: null
   }
   logNodeOp({
     type: NodeOpTypes.CREATE,

+ 5 - 0
packages/runtime-test/src/patchData.ts

@@ -1,4 +1,5 @@
 import { TestElement, logNodeOp, NodeOpTypes } from './nodeOps'
+import { isOn } from '@vue/shared'
 
 export function patchData(
   el: TestElement,
@@ -14,4 +15,8 @@ export function patchData(
     propNextValue: nextValue
   })
   el.props[key] = nextValue
+  if (isOn(key)) {
+    const event = key.slice(2).toLowerCase()
+    ;(el.eventListeners || (el.eventListeners = {}))[event] = nextValue
+  }
 }

+ 2 - 1
packages/runtime-test/src/serialize.ts

@@ -1,4 +1,5 @@
 import { TestElement, TestNode, NodeTypes, TestText } from './nodeOps'
+import { isOn } from '@vue/shared'
 
 export function serialize(
   node: TestNode,
@@ -19,7 +20,7 @@ function serializeElement(
 ): string {
   const props = Object.keys(node.props)
     .map(key => {
-      return `${key}=${JSON.stringify(node.props[key])}`
+      return isOn(key) ? `` : `${key}=${JSON.stringify(node.props[key])}`
     })
     .join(' ')
   const newLine = indent ? `\n` : ``

+ 21 - 0
packages/runtime-test/src/triggerEvent.ts

@@ -0,0 +1,21 @@
+import { TestElement } from './nodeOps'
+
+export function triggerEvent(
+  el: TestElement,
+  event: string,
+  payload: any[] = []
+) {
+  const { eventListeners } = el
+  if (eventListeners) {
+    const listener = eventListeners[event]
+    if (listener) {
+      if (Array.isArray(listener)) {
+        for (let i = 0; i < listener.length; i++) {
+          listener[i](...payload)
+        }
+      } else {
+        listener(...payload)
+      }
+    }
+  }
+}