test: fix script setup helpers tests

This commit is contained in:
Evan You 2021-06-23 10:31:32 -04:00
parent 075889ebfc
commit ac853ff4ab
3 changed files with 39 additions and 20 deletions

View File

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

View File

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

View File

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