Przeglądaj źródła

test: fix script setup helpers tests

Evan You 4 lat temu
rodzic
commit
ac853ff4ab

+ 29 - 17
packages/runtime-core/__tests__/apiSetupHelpers.spec.ts

@@ -5,7 +5,12 @@ import {
   render,
   SetupContext
 } from '@vue/runtime-test'
-import { defineEmits, defineProps, useContext } from '../src/apiSetupHelpers'
+import {
+  defineEmits,
+  defineProps,
+  useAttrs,
+  useSlots
+} from '../src/apiSetupHelpers'
 
 describe('SFC <script setup> helpers', () => {
   test('should warn runtime usage', () => {
@@ -16,34 +21,41 @@ describe('SFC <script setup> helpers', () => {
     expect(`defineEmits() is a compiler-hint`).toHaveBeenWarned()
   })
 
-  test('useContext (no args)', () => {
-    let ctx: SetupContext | undefined
+  test('useSlots / useAttrs (no args)', () => {
+    let slots: SetupContext['slots'] | undefined
+    let attrs: SetupContext['attrs'] | undefined
     const Comp = {
       setup() {
-        ctx = useContext()
+        slots = useSlots()
+        attrs = useAttrs()
         return () => {}
       }
     }
-    render(h(Comp), nodeOps.createElement('div'))
-    expect(ctx).toMatchObject({
-      attrs: {},
-      slots: {}
-    })
-    expect(typeof ctx!.emit).toBe('function')
+    const passedAttrs = { id: 'foo' }
+    const passedSlots = {
+      default: () => {},
+      x: () => {}
+    }
+    render(h(Comp, passedAttrs, passedSlots), nodeOps.createElement('div'))
+    expect(typeof slots!.default).toBe('function')
+    expect(typeof slots!.x).toBe('function')
+    expect(attrs).toMatchObject(passedAttrs)
   })
 
-  test('useContext (with args)', () => {
+  test('useSlots / useAttrs (with args)', () => {
+    let slots: SetupContext['slots'] | undefined
+    let attrs: SetupContext['attrs'] | undefined
     let ctx: SetupContext | undefined
-    let ctxArg: SetupContext | undefined
     const Comp = defineComponent({
-      setup(_, _ctxArg) {
-        ctx = useContext()
-        ctxArg = _ctxArg
+      setup(_, _ctx) {
+        slots = useSlots()
+        attrs = useAttrs()
+        ctx = _ctx
         return () => {}
       }
     })
     render(h(Comp), nodeOps.createElement('div'))
-    expect(ctx).toBeDefined()
-    expect(ctx).toBe(ctxArg)
+    expect(slots).toBe(ctx!.slots)
+    expect(attrs).toBe(ctx!.attrs)
   })
 })

+ 6 - 2
packages/runtime-core/src/apiSetupHelpers.ts

@@ -71,6 +71,10 @@ export function useContext(): SetupContext {
         `next minor release. Use \`useSlots()\` and \`useAttrs()\` instead.`
     )
   }
+  return getContext()
+}
+
+function getContext(): SetupContext {
   const i = getCurrentInstance()!
   if (__DEV__ && !i) {
     warn(`useContext() called without active instance.`)
@@ -79,9 +83,9 @@ export function useContext(): SetupContext {
 }
 
 export function useSlots(): SetupContext['slots'] {
-  return useContext().slots
+  return getContext().slots
 }
 
 export function useAttrs(): SetupContext['attrs'] {
-  return useContext().attrs
+  return getContext().attrs
 }

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

@@ -841,11 +841,14 @@ export function createSetupContext(
   }
 
   if (__DEV__) {
+    let attrs: Data
     // We use getters in dev in case libs like test-utils overwrite instance
     // properties (overwrites should not be done in prod)
     return Object.freeze({
       get attrs() {
-        return new Proxy(instance.attrs, attrDevProxyHandlers)
+        return (
+          attrs || (attrs = new Proxy(instance.attrs, attrDevProxyHandlers))
+        )
       },
       get slots() {
         return shallowReadonly(instance.slots)