فهرست منبع

wip: trying to make tests work

Evan You 7 سال پیش
والد
کامیت
ba571cda61

+ 9 - 9
packages/runtime-core/__tests__/fragment.spec.ts

@@ -16,14 +16,14 @@ import {
 } from '@vue/runtime-test'
 
 describe('Fragments', () => {
-  it('should allow returning multiple component root nodes', () => {
+  it('should allow returning multiple component root nodes', async () => {
     class App extends Component {
       render() {
         return [h('div', 'one'), 'two']
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
     expect(serialize(root)).toBe(`<div><div>one</div>two</div>`)
     expect(root.children.length).toBe(2)
     expect(root.children[0]).toMatchObject({
@@ -40,14 +40,14 @@ describe('Fragments', () => {
     })
   })
 
-  it('should be able to explicitly create fragments', () => {
+  it('should be able to explicitly create fragments', async () => {
     class App extends Component {
       render() {
         return h('div', [h(Fragment, [h('div', 'one'), 'two'])])
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
     const parent = root.children[0] as TestElement
     expect(serialize(parent)).toBe(`<div><div>one</div>two</div>`)
   })
@@ -65,7 +65,7 @@ describe('Fragments', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
 
     expect(serialize(root)).toBe(`<div><div>one</div>two</div>`)
 
@@ -84,7 +84,7 @@ describe('Fragments', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await await render(h(App), root)
 
     expect(serialize(root)).toBe(`<div><div>one</div>two</div>`)
 
@@ -103,7 +103,7 @@ describe('Fragments', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
 
     expect(serialize(root)).toBe(`<div><div>one</div><div>two</div></div>`)
 
@@ -138,7 +138,7 @@ describe('Fragments', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
     const parent = root.children[0] as TestElement
 
     expect(serialize(parent)).toBe(
@@ -179,7 +179,7 @@ describe('Fragments', () => {
     }
 
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
 
     expect(serialize(root)).toBe(
       `<div><div>outer</div><div>one</div><div>two</div></div>`

+ 2 - 1
packages/runtime-core/src/component.ts

@@ -109,7 +109,8 @@ export interface ComponentInstance<P = {}, D = {}>
 // actual implementation of the component
 class InternalComponent implements PublicInstanceMethods {
   get $el(): any {
-    return this.$vnode && this.$vnode.el
+    const el = this.$vnode && this.$vnode.el
+    return typeof el === 'function' ? (el as any)() : el
   }
 
   $vnode: VNode | null = null

+ 2 - 7
packages/runtime-core/src/createRenderer.ts

@@ -228,13 +228,9 @@ export function createRenderer(options: RendererOptions) {
       // kept-alive
       activateComponentInstance(vnode, container, endNode)
     } else {
-      if (__JSDOM__) {
+      queueJob(() => {
         mountComponentInstance(vnode, container, isSVG, endNode)
-      } else {
-        queueJob(() => {
-          mountComponentInstance(vnode, container, isSVG, endNode)
-        }, flushHooks)
-      }
+      }, flushHooks)
     }
   }
 
@@ -1441,7 +1437,6 @@ export function createRenderer(options: RendererOptions) {
       }
     }
     return nextTick(() => {
-      debugger
       return vnode && vnode.flags & VNodeFlags.COMPONENT_STATEFUL
         ? (vnode.children as ComponentInstance).$proxy
         : null

+ 5 - 5
packages/runtime-test/__tests__/testRuntime.spec.ts

@@ -17,7 +17,7 @@ import {
 } from '../src'
 
 describe('test renderer', () => {
-  it('should work', () => {
+  it('should work', async () => {
     class App extends Component {
       render() {
         return h(
@@ -30,7 +30,7 @@ describe('test renderer', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
 
     expect(root.children.length).toBe(1)
 
@@ -64,7 +64,7 @@ describe('test renderer', () => {
     const root = nodeOps.createElement('div')
 
     resetOps()
-    render(h(App), root)
+    await render(h(App), root)
     const ops = dumpOps()
 
     expect(ops.length).toBe(5)
@@ -126,7 +126,7 @@ describe('test renderer', () => {
     })
   })
 
-  it('should be able to serialize nodes', () => {
+  it('should be able to serialize nodes', async () => {
     class App extends Component {
       render() {
         return h(
@@ -139,7 +139,7 @@ describe('test renderer', () => {
       }
     }
     const root = nodeOps.createElement('div')
-    render(h(App), root)
+    await render(h(App), root)
     expect(serialize(root)).toEqual(
       `<div><div id="test"><span>foo</span>hello</div></div>`
     )

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

@@ -63,6 +63,9 @@ export function dumpOps(): NodeOp[] {
 }
 
 function createElement(tag: string): TestElement {
+  if (nodeId === 5) {
+    throw new Error('foo')
+  }
   const node: TestElement = {
     id: nodeId++,
     type: NodeTypes.ELEMENT,

+ 4 - 1
packages/scheduler/src/experimental.ts

@@ -61,7 +61,10 @@ export function nextTick<T>(fn?: () => T): Promise<T> {
         nextTickQueue.push(() => {
           resolve(fn ? fn() : undefined)
         })
-        pendingRejectors.push(reject)
+        pendingRejectors.push(err => {
+          if (fn) fn()
+          reject(err)
+        })
       } else {
         resolve(fn ? fn() : undefined)
       }

+ 27 - 21
packages/scheduler/src/patchNodeOps.ts

@@ -1,5 +1,6 @@
 import { NodeOps } from '@vue/runtime-core'
 import { nodeOps } from '../../runtime-dom/src/nodeOps'
+import { nodeOps as testNodeOps } from '../../runtime-test/src/nodeOps'
 
 export type Op = [Function, ...any[]]
 
@@ -14,27 +15,32 @@ const evaluate = (v: any) => {
 }
 
 // patch nodeOps to record operations without touching the DOM
-Object.keys(nodeOps).forEach((key: keyof NodeOps) => {
-  const original = nodeOps[key] as Function
-  if (key === 'querySelector') {
-    return
-  }
-  if (/create/.test(key)) {
-    nodeOps[key] = (...args: any[]) => {
-      let res: any
-      if (currentOps) {
-        return () => res || (res = original(...args))
-      } else {
-        return original(...args)
-      }
+function patchOps(nodeOps: NodeOps) {
+  Object.keys(nodeOps).forEach((key: keyof NodeOps) => {
+    const original = nodeOps[key] as Function
+    if (key === 'querySelector') {
+      return
     }
-  } else {
-    nodeOps[key] = (...args: any[]) => {
-      if (currentOps) {
-        currentOps.push([original, ...args.map(evaluate)])
-      } else {
-        original(...args)
+    if (/create/.test(key)) {
+      nodeOps[key] = (...args: any[]) => {
+        let res: any
+        if (currentOps) {
+          return () => res || (res = original(...args))
+        } else {
+          return original(...args)
+        }
+      }
+    } else {
+      nodeOps[key] = (...args: any[]) => {
+        if (currentOps) {
+          currentOps.push([original, ...args.map(evaluate)])
+        } else {
+          original(...args)
+        }
       }
     }
-  }
-})
+  })
+}
+
+patchOps(nodeOps)
+patchOps(testNodeOps)