]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: test ops logging for test renderer
authorEvan You <yyx990803@gmail.com>
Mon, 1 Oct 2018 20:42:53 +0000 (16:42 -0400)
committerEvan You <yyx990803@gmail.com>
Mon, 1 Oct 2018 20:42:53 +0000 (16:42 -0400)
packages/core/src/componentComputed.ts
packages/renderer-test/__tests__/testRenderer.spec.ts
packages/renderer-test/src/index.ts
packages/renderer-test/src/nodeOps.ts
packages/renderer-test/src/patchData.ts [new file with mode: 0644]

index bf8ddca496895d16e0ebb2a2a3231aaed76e16c7..2a00fe9e469e304da29dbd4fff8d3a7f1ea6bf38 100644 (file)
@@ -49,7 +49,9 @@ export function initializeComputed(
     {},
     {
       get(_, key: any) {
-        return handles[key]()
+        if (handles.hasOwnProperty(key)) {
+          return handles[key]()
+        }
       }
       // TODO should be readonly
     }
index 3974388fb7fb9c872adbfa2625cb8c7ca5f6b52a..20936dc9259f3bfca3eb427d8a80057f34a5aff4 100644 (file)
@@ -5,19 +5,30 @@ import {
   nodeOps,
   NodeTypes,
   TestElement,
-  TestText
+  TestText,
+  dumpOps,
+  NodeOpTypes,
+  nextTick,
+  observable,
+  resetOps
 } from '../src'
 
 describe('test renderer', () => {
   it('should work', () => {
     class App extends Component {
+      data() {
+        return {
+          id: 'test',
+          text: 'hello'
+        }
+      }
       render() {
         return h(
           'div',
           {
-            id: 'test'
+            id: this.id
           },
-          'hello'
+          this.text
         )
       }
     }
@@ -36,7 +47,85 @@ describe('test renderer', () => {
     expect(text.text).toBe('hello')
   })
 
-  it('should record ops', () => {
-    // TODO
+  it('should record ops', async () => {
+    const state = observable({
+      id: 'test',
+      text: 'hello'
+    })
+
+    class App extends Component {
+      render() {
+        return h(
+          'div',
+          {
+            id: state.id
+          },
+          state.text
+        )
+      }
+    }
+    const root = nodeOps.createElement('div')
+
+    resetOps()
+    render(h(App), root)
+    const ops = dumpOps()
+
+    expect(ops.length).toBe(5)
+
+    expect(ops[0]).toEqual({
+      type: NodeOpTypes.CREATE,
+      nodeType: NodeTypes.ELEMENT,
+      tag: 'div',
+      targetNode: root.children[0]
+    })
+
+    expect(ops[1]).toEqual({
+      type: NodeOpTypes.PATCH,
+      targetNode: root.children[0],
+      propKey: 'id',
+      propPrevValue: null,
+      propNextValue: 'test'
+    })
+
+    expect(ops[2]).toEqual({
+      type: NodeOpTypes.CREATE,
+      nodeType: NodeTypes.TEXT,
+      text: 'hello',
+      targetNode: (root.children[0] as TestElement).children[0]
+    })
+
+    expect(ops[3]).toEqual({
+      type: NodeOpTypes.APPEND,
+      targetNode: (root.children[0] as TestElement).children[0],
+      parentNode: root.children[0]
+    })
+
+    expect(ops[4]).toEqual({
+      type: NodeOpTypes.APPEND,
+      targetNode: root.children[0],
+      parentNode: root
+    })
+
+    // test update ops
+    state.id = 'foo'
+    state.text = 'bar'
+    await nextTick()
+
+    const updateOps = dumpOps()
+    expect(updateOps.length).toBe(2)
+
+    expect(updateOps[0]).toEqual({
+      type: NodeOpTypes.PATCH,
+      targetNode: root.children[0],
+      propKey: 'id',
+      propPrevValue: 'test',
+      propNextValue: 'foo'
+    })
+
+    expect(updateOps[1]).toEqual({
+      type: NodeOpTypes.SET_TEXT,
+      targetNode: (root.children[0] as TestElement).children[0],
+      text: 'bar'
+    })
   })
 })
index 2c8f648c42c676cc3cfa294feea8cade5a057b33..6436f98b1fab2b6749de3f7f7c877e878822a63c 100644 (file)
@@ -1,14 +1,6 @@
 import { createRenderer, VNode } from '@vue/core'
 import { nodeOps, TestElement } from './nodeOps'
-
-function patchData(
-  el: TestElement,
-  key: string,
-  prevValue: any,
-  nextValue: any
-) {
-  el.props[key] = nextValue
-}
+import { patchData } from './patchData'
 
 const { render: _render } = createRenderer({
   nodeOps,
index 05b4c508caa56eb4bed85ac42440b80634e054de..f36eadea7a943370ed81abbcfc8b6ac3f3e3c75d 100644 (file)
@@ -21,57 +21,44 @@ export interface TestText {
 
 export type TestNode = TestElement | TestText
 
-const enum OpTypes {
+export const enum NodeOpTypes {
   CREATE = 'create',
   INSERT = 'insert',
   APPEND = 'append',
   REMOVE = 'remove',
   SET_TEXT = 'setText',
   CLEAR = 'clearContent',
-  NEXT_SIBLING = 'nextSibling',
-  PARENT_NODE = 'parentNode'
+  PATCH = 'patch'
 }
 
-interface Op {
-  type: OpTypes
+export interface NodeOp {
+  type: NodeOpTypes
   nodeType?: NodeTypes
   tag?: string
   text?: string
   targetNode?: TestNode
   parentNode?: TestElement
   refNode?: TestNode
+  propKey?: string
+  propPrevValue?: any
+  propNextValue?: any
 }
 
 let nodeId: number = 0
-let isRecording: boolean = false
-let recordedOps: Op[] = []
+let recordedNodeOps: NodeOp[] = []
 
-function logOp(op: Op) {
-  if (isRecording) {
-    recordedOps.push(op)
-  }
+export function logNodeOp(op: NodeOp) {
+  recordedNodeOps.push(op)
 }
 
-export function startRecordingOps() {
-  if (!isRecording) {
-    isRecording = true
-    recordedOps = []
-  } else {
-    throw new Error(
-      '`startRecordingOps` called when there is already an active session.'
-    )
-  }
+export function resetOps() {
+  recordedNodeOps = []
 }
 
-export function dumpOps(): Op[] {
-  if (!isRecording) {
-    throw new Error(
-      '`dumpOps` called without a recording session. ' +
-        'Call `startRecordingOps` first to start a session.'
-    )
-  }
-  isRecording = false
-  return recordedOps.slice()
+export function dumpOps(): NodeOp[] {
+  const ops = recordedNodeOps.slice()
+  resetOps()
+  return ops
 }
 
 function createElement(tag: string): TestElement {
@@ -83,8 +70,8 @@ function createElement(tag: string): TestElement {
     props: {},
     parentNode: null
   }
-  logOp({
-    type: OpTypes.CREATE,
+  logNodeOp({
+    type: NodeOpTypes.CREATE,
     nodeType: NodeTypes.ELEMENT,
     targetNode: node,
     tag
@@ -99,8 +86,8 @@ function createText(text: string): TestText {
     text,
     parentNode: null
   }
-  logOp({
-    type: OpTypes.CREATE,
+  logNodeOp({
+    type: NodeOpTypes.CREATE,
     nodeType: NodeTypes.TEXT,
     targetNode: node,
     text
@@ -109,8 +96,8 @@ function createText(text: string): TestText {
 }
 
 function setText(node: TestText, text: string) {
-  logOp({
-    type: OpTypes.SET_TEXT,
+  logNodeOp({
+    type: NodeOpTypes.SET_TEXT,
     targetNode: node,
     text
   })
@@ -118,8 +105,8 @@ function setText(node: TestText, text: string) {
 }
 
 function appendChild(parent: TestElement, child: TestNode) {
-  logOp({
-    type: OpTypes.APPEND,
+  logNodeOp({
+    type: NodeOpTypes.APPEND,
     targetNode: child,
     parentNode: parent
   })
@@ -140,8 +127,8 @@ function insertBefore(parent: TestElement, child: TestNode, ref: TestNode) {
     console.error('parent: ', parent)
     throw new Error('ref is not a child of parent')
   }
-  logOp({
-    type: OpTypes.INSERT,
+  logNodeOp({
+    type: NodeOpTypes.INSERT,
     targetNode: child,
     parentNode: parent,
     refNode: ref
@@ -160,8 +147,8 @@ function replaceChild(
 }
 
 function removeChild(parent: TestElement, child: TestNode) {
-  logOp({
-    type: OpTypes.REMOVE,
+  logNodeOp({
+    type: NodeOpTypes.REMOVE,
     targetNode: child,
     parentNode: parent
   })
@@ -177,8 +164,8 @@ function removeChild(parent: TestElement, child: TestNode) {
 }
 
 function clearContent(node: TestNode) {
-  logOp({
-    type: OpTypes.CLEAR,
+  logNodeOp({
+    type: NodeOpTypes.CLEAR,
     targetNode: node
   })
   if (node.type === NodeTypes.ELEMENT) {
@@ -192,18 +179,10 @@ function clearContent(node: TestNode) {
 }
 
 function parentNode(node: TestNode): TestElement | null {
-  logOp({
-    type: OpTypes.PARENT_NODE,
-    targetNode: node
-  })
   return node.parentNode
 }
 
 function nextSibling(node: TestNode): TestNode | null {
-  logOp({
-    type: OpTypes.NEXT_SIBLING,
-    targetNode: node
-  })
   const parent = node.parentNode
   if (!parent) {
     return null
@@ -229,3 +208,5 @@ export const nodeOps = {
   nextSibling,
   querySelector
 }
+
+export function patchData() {}
diff --git a/packages/renderer-test/src/patchData.ts b/packages/renderer-test/src/patchData.ts
new file mode 100644 (file)
index 0000000..7f635af
--- /dev/null
@@ -0,0 +1,17 @@
+import { TestElement, logNodeOp, NodeOpTypes } from './nodeOps'
+
+export function patchData(
+  el: TestElement,
+  key: string,
+  prevValue: any,
+  nextValue: any
+) {
+  logNodeOp({
+    type: NodeOpTypes.PATCH,
+    targetNode: el,
+    propKey: key,
+    propPrevValue: prevValue,
+    propNextValue: nextValue
+  })
+  el.props[key] = nextValue
+}