2020-01-24 04:05:38 +08:00
|
|
|
import { h, render, getCurrentInstance, nodeOps } from '@vue/runtime-test'
|
2020-01-22 22:29:35 +08:00
|
|
|
import { mockWarn } from '@vue/shared'
|
2019-10-10 22:02:55 +08:00
|
|
|
import { ComponentInternalInstance } from '../src/component'
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2019-10-10 22:02:55 +08:00
|
|
|
describe('component: proxy', () => {
|
|
|
|
mockWarn()
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2019-12-11 00:14:29 +08:00
|
|
|
test('data', () => {
|
2019-10-10 22:02:55 +08:00
|
|
|
let instance: ComponentInternalInstance
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
foo: 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instance = getCurrentInstance()!
|
|
|
|
instanceProxy = this
|
|
|
|
},
|
|
|
|
render() {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
2019-10-10 22:02:55 +08:00
|
|
|
expect(instanceProxy.foo).toBe(1)
|
|
|
|
instanceProxy.foo = 2
|
|
|
|
expect(instance!.data.foo).toBe(2)
|
|
|
|
})
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2019-12-11 00:14:29 +08:00
|
|
|
test('renderContext', () => {
|
2019-10-10 22:02:55 +08:00
|
|
|
let instance: ComponentInternalInstance
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
setup() {
|
|
|
|
return {
|
|
|
|
foo: 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instance = getCurrentInstance()!
|
|
|
|
instanceProxy = this
|
|
|
|
},
|
|
|
|
render() {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
2019-10-10 22:02:55 +08:00
|
|
|
expect(instanceProxy.foo).toBe(1)
|
|
|
|
instanceProxy.foo = 2
|
|
|
|
expect(instance!.renderContext.foo).toBe(2)
|
|
|
|
})
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2019-12-11 00:14:29 +08:00
|
|
|
test('propsProxy', () => {
|
2019-10-10 22:02:55 +08:00
|
|
|
let instance: ComponentInternalInstance
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
props: {
|
|
|
|
foo: {
|
|
|
|
type: Number,
|
|
|
|
default: 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return () => null
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instance = getCurrentInstance()!
|
|
|
|
instanceProxy = this
|
2019-10-10 02:03:21 +08:00
|
|
|
}
|
2019-10-10 22:02:55 +08:00
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
2019-10-10 22:02:55 +08:00
|
|
|
expect(instanceProxy.foo).toBe(1)
|
|
|
|
expect(instance!.propsProxy!.foo).toBe(1)
|
|
|
|
expect(() => (instanceProxy.foo = 2)).toThrow(TypeError)
|
|
|
|
expect(`Attempting to mutate prop "foo"`).toHaveBeenWarned()
|
|
|
|
})
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2020-01-28 03:30:00 +08:00
|
|
|
test('should not expose non-declared props', () => {
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
setup() {
|
|
|
|
return () => null
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instanceProxy = this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
render(h(Comp, { count: 1 }), nodeOps.createElement('div'))
|
|
|
|
expect('count' in instanceProxy).toBe(false)
|
|
|
|
})
|
|
|
|
|
2019-12-11 00:14:29 +08:00
|
|
|
test('public properties', () => {
|
2019-10-10 22:02:55 +08:00
|
|
|
let instance: ComponentInternalInstance
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
setup() {
|
|
|
|
return () => null
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instance = getCurrentInstance()!
|
|
|
|
instanceProxy = this
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
2019-10-10 22:02:55 +08:00
|
|
|
expect(instanceProxy.$data).toBe(instance!.data)
|
|
|
|
expect(instanceProxy.$props).toBe(instance!.propsProxy)
|
|
|
|
expect(instanceProxy.$attrs).toBe(instance!.attrs)
|
|
|
|
expect(instanceProxy.$slots).toBe(instance!.slots)
|
|
|
|
expect(instanceProxy.$refs).toBe(instance!.refs)
|
2020-04-06 06:39:22 +08:00
|
|
|
expect(instanceProxy.$parent).toBe(
|
|
|
|
instance!.parent && instance!.parent.proxy
|
|
|
|
)
|
|
|
|
expect(instanceProxy.$root).toBe(instance!.root.proxy)
|
2019-10-10 22:02:55 +08:00
|
|
|
expect(instanceProxy.$emit).toBe(instance!.emit)
|
|
|
|
expect(instanceProxy.$el).toBe(instance!.vnode.el)
|
|
|
|
expect(instanceProxy.$options).toBe(instance!.type)
|
|
|
|
expect(() => (instanceProxy.$data = {})).toThrow(TypeError)
|
|
|
|
expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned()
|
|
|
|
})
|
2019-10-10 02:03:21 +08:00
|
|
|
|
2019-12-11 00:14:29 +08:00
|
|
|
test('sink', async () => {
|
2019-10-10 22:02:55 +08:00
|
|
|
let instance: ComponentInternalInstance
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
setup() {
|
|
|
|
return () => null
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instance = getCurrentInstance()!
|
|
|
|
instanceProxy = this
|
2019-10-10 02:03:21 +08:00
|
|
|
}
|
2019-10-10 22:02:55 +08:00
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
2019-10-10 22:02:55 +08:00
|
|
|
instanceProxy.foo = 1
|
|
|
|
expect(instanceProxy.foo).toBe(1)
|
2019-10-30 10:28:38 +08:00
|
|
|
expect(instance!.sink.foo).toBe(1)
|
2019-10-10 02:03:21 +08:00
|
|
|
})
|
2019-12-11 00:14:29 +08:00
|
|
|
|
|
|
|
test('has check', () => {
|
|
|
|
let instanceProxy: any
|
|
|
|
const Comp = {
|
|
|
|
render() {},
|
|
|
|
props: {
|
|
|
|
msg: String
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
foo: 0
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setup() {
|
|
|
|
return {
|
|
|
|
bar: 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
instanceProxy = this
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 04:05:38 +08:00
|
|
|
render(h(Comp, { msg: 'hello' }), nodeOps.createElement('div'))
|
2019-12-11 00:14:29 +08:00
|
|
|
|
|
|
|
// props
|
|
|
|
expect('msg' in instanceProxy).toBe(true)
|
|
|
|
// data
|
|
|
|
expect('foo' in instanceProxy).toBe(true)
|
|
|
|
// renderContext
|
|
|
|
expect('bar' in instanceProxy).toBe(true)
|
|
|
|
// public properties
|
|
|
|
expect('$el' in instanceProxy).toBe(true)
|
|
|
|
|
|
|
|
// non-existent
|
|
|
|
expect('$foobar' in instanceProxy).toBe(false)
|
|
|
|
expect('baz' in instanceProxy).toBe(false)
|
|
|
|
|
|
|
|
// set non-existent (goes into sink)
|
|
|
|
instanceProxy.baz = 1
|
|
|
|
expect('baz' in instanceProxy).toBe(true)
|
2020-04-06 06:39:22 +08:00
|
|
|
|
|
|
|
// dev mode ownKeys check for console inspection
|
|
|
|
expect(Object.keys(instanceProxy)).toMatchObject([
|
|
|
|
'msg',
|
|
|
|
'bar',
|
|
|
|
'foo',
|
|
|
|
'baz'
|
|
|
|
])
|
2019-12-11 00:14:29 +08:00
|
|
|
})
|
2020-03-22 04:25:33 +08:00
|
|
|
|
|
|
|
// #864
|
|
|
|
test('should not warn declared but absent props', () => {
|
|
|
|
const Comp = {
|
|
|
|
props: ['test'],
|
|
|
|
render(this: any) {
|
|
|
|
return this.test
|
|
|
|
}
|
|
|
|
}
|
|
|
|
render(h(Comp), nodeOps.createElement('div'))
|
|
|
|
expect(
|
|
|
|
`was accessed during render but is not defined`
|
|
|
|
).not.toHaveBeenWarned()
|
|
|
|
})
|
2019-10-10 02:03:21 +08:00
|
|
|
})
|