Skip to content

Commit

Permalink
test: fix script setup helpers tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jun 23, 2021
1 parent 075889e commit ac853ff
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 20 deletions.
46 changes: 29 additions & 17 deletions packages/runtime-core/__tests__/apiSetupHelpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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)
})
})
8 changes: 6 additions & 2 deletions packages/runtime-core/src/apiSetupHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.`)
Expand All @@ -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
}
5 changes: 4 additions & 1 deletion packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit ac853ff

Please sign in to comment.