"rollup-plugin-terser": "^2.0.2",
"rollup-plugin-typescript2": "^0.17.0",
"ts-jest": "^23.10.0",
- "typescript": "^3.1.3",
+ "typescript": "^3.5.0",
"yorkie": "^2.0.0"
}
}
// never been tracked
return
}
- const effects = new Set()
- const computedRunners = new Set()
+ const effects: Set<ReactiveEffect> = new Set()
+ const computedRunners: Set<ReactiveEffect> = new Set()
if (type === OperationTypes.CLEAR) {
// collection being cleared, trigger all effects for target
depsMap.forEach(dep => {
--- /dev/null
+import { createComponent } from '../src/component'
+import { value } from '@vue/observer'
+
+test('createComponent type inference', () => {
+ const MyComponent = createComponent({
+ props: {
+ a: Number,
+ b: {
+ type: String
+ }
+ },
+ setup(props) {
+ props.a * 2
+ props.b.slice()
+ return {
+ c: value(1),
+ d: {
+ e: value('hi')
+ }
+ }
+ },
+ render({ state, props }) {
+ state.c * 2
+ state.d.e.slice()
+ props.a * 2
+ props.b.slice()
+ this.a * 2
+ this.b.slice()
+ this.c * 2
+ this.d.e.slice()
+ }
+ })
+ MyComponent // avoid unused
+ // rename this file to .tsx to test TSX props inference
+ // ;(<MyComponent a={1} b="foo"/>)
+})
+++ /dev/null
-import {
- Component,
- observable,
- h,
- nextTick,
- KeepAlive,
- ComponentPropsOptions,
- ComponentWatchOptions
-} from '@vue/runtime-core'
-import { createInstance, renderInstance } from '@vue/runtime-test'
-
-describe('class inheritance', () => {
- it('should merge data', () => {
- class Base extends Component {
- foo = 1
- data() {
- return {
- bar: 2
- }
- }
- }
-
- class Child extends Base {
- foo: number
- bar: number
- baz: number
- qux: number = 4
-
- data(): any {
- return {
- baz: 3
- }
- }
- }
-
- const child = createInstance(Child)
-
- expect(child.foo).toBe(1)
- expect(child.bar).toBe(2)
- expect(child.baz).toBe(3)
- expect(child.qux).toBe(4)
- })
-
- it('should merge props', () => {
- class Base extends Component {
- static props: ComponentPropsOptions = {
- foo: Number
- }
- }
-
- class Child extends Base {
- foo: number
- bar: number
- $props: { foo: number; bar: number }
- static props: ComponentPropsOptions = {
- bar: Number
- }
- }
-
- const child = createInstance(Child, {
- foo: 1,
- bar: 2
- })
-
- expect(child.foo).toBe(1)
- expect(child.bar).toBe(2)
- expect(child.$props.foo).toBe(1)
- expect(child.$props.bar).toBe(2)
- })
-
- it('should merge lifecycle hooks', async () => {
- const calls: string[] = []
- const state = observable({ ok: true })
-
- class Base extends Component {
- beforeCreate() {
- calls.push('base beforeCreate')
- }
- created() {
- calls.push('base created')
- }
- beforeMount() {
- calls.push('base beforeMount')
- }
- mounted() {
- calls.push('base mounted')
- }
- beforeUpdate() {
- calls.push('base beforeUpdate')
- }
- updated() {
- calls.push('base updated')
- }
- beforeUnmount() {
- calls.push('base beforeUnmount')
- }
- unmounted() {
- calls.push('base unmounted')
- }
- }
-
- class Child extends Base {
- beforeCreate() {
- calls.push('child beforeCreate')
- }
- created() {
- calls.push('child created')
- }
- beforeMount() {
- calls.push('child beforeMount')
- }
- mounted() {
- calls.push('child mounted')
- }
- beforeUpdate() {
- calls.push('child beforeUpdate')
- }
- updated() {
- calls.push('child updated')
- }
- beforeUnmount() {
- calls.push('child beforeUnmount')
- }
- unmounted() {
- calls.push('child unmounted')
- }
- render() {
- return state.ok ? 'foo' : 'bar'
- }
- }
-
- class Container extends Component {
- show = true
- render() {
- return this.show ? h(Child) : null
- }
- }
-
- const container = await renderInstance(Container)
- expect(calls).toEqual([
- 'base beforeCreate',
- 'child beforeCreate',
- 'base created',
- 'child created',
- 'base beforeMount',
- 'child beforeMount',
- 'base mounted',
- 'child mounted'
- ])
-
- calls.length = 0
- state.ok = false
- await nextTick()
- expect(calls).toEqual([
- 'base beforeUpdate',
- 'child beforeUpdate',
- 'base updated',
- 'child updated'
- ])
-
- calls.length = 0
- container.show = false
- await nextTick()
- expect(calls).toEqual([
- 'base beforeUnmount',
- 'child beforeUnmount',
- 'base unmounted',
- 'child unmounted'
- ])
- })
-
- it('should merge lifecycle hooks (activated/deactivated)', async () => {
- const calls: string[] = []
-
- class Base extends Component {
- activated() {
- calls.push('base activated')
- }
- deactivated() {
- calls.push('base deactivated')
- }
- }
-
- class Child extends Base {
- activated() {
- calls.push('child activated')
- }
- deactivated() {
- calls.push('child deactivated')
- }
- render() {
- return 'foo'
- }
- }
-
- class Container extends Component {
- ok = true
- render() {
- return h(KeepAlive, this.ok ? h(Child) : null)
- }
- }
-
- const container = await renderInstance(Container)
- expect(container.$el.text).toBe('foo')
-
- container.ok = false
- await nextTick()
- expect(container.$el.text).toBe('')
- expect(calls).toEqual(['base deactivated', 'child deactivated'])
-
- calls.length = 0
- container.ok = true
- await nextTick()
- expect(container.$el.text).toBe('foo')
- expect(calls).toEqual(['base activated', 'child activated'])
- })
-
- it('should merge watchers', async () => {
- const fooCallback = jest.fn()
- const barCallback = jest.fn()
-
- class Base extends Component {
- static watch: ComponentWatchOptions = {
- foo: fooCallback
- }
- }
-
- class Child extends Base {
- foo = 1
- bar = 2
- static watch: ComponentWatchOptions = {
- bar: barCallback
- }
- }
-
- const child = createInstance(Child)
- child.foo = 2
- await nextTick()
- expect(fooCallback).toHaveBeenCalledWith(2, 1)
- child.bar = 3
- await nextTick()
- expect(barCallback).toHaveBeenCalledWith(3, 2)
- })
-
- it('should inherit methods', () => {
- const fooCallback = jest.fn()
- const barCallback = jest.fn()
-
- class Base extends Component {
- foo() {
- fooCallback()
- }
- }
-
- class Child extends Base {
- bar() {
- barCallback()
- }
- }
-
- const child = createInstance(Child)
- child.foo()
- child.bar()
- expect(fooCallback).toHaveBeenCalled()
- expect(barCallback).toHaveBeenCalled()
- })
-
- it('should inherit computed properties', () => {
- class Base extends Component {
- a = 1
- get foo() {
- return this.a + 1
- }
- }
-
- class Child extends Base {
- b = 1
- get bar() {
- return this.b + this.foo + 1
- }
- }
-
- const child = createInstance(Child)
- expect(child.foo).toBe(2)
- expect(child.bar).toBe(4)
-
- child.a = 2
- expect(child.foo).toBe(3)
- expect(child.bar).toBe(5)
- })
-})
+++ /dev/null
-import { h, Component, memoize, nextTick } from '../src'
-import { renderInstance, serialize } from '@vue/runtime-test'
-
-describe('memoize', () => {
- it('should work', async () => {
- class App extends Component {
- count = 1
- render() {
- return h('div', [
- this.count,
- this.count % 2
- ? memoize(() => h('div', `A` + this.count), this, 0)
- : null,
- memoize(() => h('div', `B` + this.count), this, 1)
- ])
- }
- }
-
- const app = await renderInstance(App)
- expect(serialize(app.$el)).toBe(`<div>1<div>A1</div><div>B1</div></div>`)
-
- app.count++
- await nextTick()
- expect(serialize(app.$el)).toBe(`<div>2<div>B1</div></div>`)
-
- app.count++
- await nextTick()
- // test remounting a memoized tree
- expect(serialize(app.$el)).toBe(`<div>3<div>A1</div><div>B1</div></div>`)
- })
-
- it('should invalidate based on keys', async () => {
- class App extends Component {
- foo = 1
- bar = 1
- render() {
- return memoize(() => h('div', this.foo + this.bar), this, 0, [this.bar])
- }
- }
-
- const app = await renderInstance(App)
- expect(serialize(app.$el)).toBe(`<div>2</div>`)
-
- app.foo++
- await nextTick()
- // should not update
- expect(serialize(app.$el)).toBe(`<div>2</div>`)
-
- app.bar++
- await nextTick()
- // should update now
- expect(serialize(app.$el)).toBe(`<div>4</div>`)
- })
-})
+++ /dev/null
-import { Component, ComponentClass, mixins } from '@vue/runtime-core'
-import { createInstance } from '@vue/runtime-test'
-import { prop } from '@vue/decorators'
-
-const calls: string[] = []
-
-beforeEach(() => {
- calls.length = 0
-})
-
-class ClassMixinA extends Component<{ p1: string }, { d11: number }> {
- // props
- @prop
- p1: string
- // data
- d1 = 1
- data() {
- return {
- d11: 2
- }
- }
-
- // computed
- get c1() {
- return this.d1 + this.$data.d11
- }
-
- // lifecycle
- created() {
- calls.push('created from mixin A')
- }
-
- // methods
- foo() {
- return this.d1
- }
-}
-
-class ClassMixinB extends Component<{ p2: string }, { d21: number }> {
- // props
- static props = {
- p2: String
- }
-
- // data
- d2 = 1
- data() {
- return {
- d21: 2
- }
- }
-
- get c2() {
- return this.d2 + this.$data.d21
- }
-
- // lifecycle
- created() {
- calls.push('created from mixin B')
- }
-
- // methods
- bar() {
- return this.d2
- }
-}
-
-const ObjectMixinA = {
- props: {
- p1: String
- },
- data() {
- return {
- d1: 1,
- d11: 2
- }
- },
- computed: {
- c1() {
- return this.d1 + this.d11
- }
- },
- created() {
- calls.push('created from mixin A')
- },
- methods: {
- foo() {
- return this.d1
- }
- }
-}
-
-const ObjectMixinB = {
- props: {
- p2: String
- },
- data() {
- return {
- d2: 1,
- d21: 2
- }
- },
- computed: {
- c2() {
- return this.d2 + this.d21
- }
- },
- created() {
- calls.push('created from mixin B')
- },
- methods: {
- bar() {
- return this.d2
- }
- }
-}
-
-function assertMixins(Test: any) {
- const instance = createInstance(Test, {
- p1: '1',
- p2: '2',
- p3: '3'
- }) as any
-
- // data
- expect(instance.d1).toBe(1)
- expect(instance.d11).toBe(2)
- expect(instance.d2).toBe(1)
- expect(instance.d21).toBe(2)
- expect(instance.d3).toBe(1)
- expect(instance.d31).toBe(2)
-
- // props
- expect(instance.p1).toBe('1')
- expect(instance.p2).toBe('2')
- expect(instance.p3).toBe('3')
- expect(instance.$props.p1).toBe('1')
- expect(instance.$props.p2).toBe('2')
- expect(instance.$props.p3).toBe('3')
-
- // computed
- expect(instance.c1).toBe(3)
- expect(instance.c2).toBe(3)
- expect(instance.c3).toBe(3)
-
- // lifecycle
- expect(calls).toEqual([
- 'created from mixin A',
- 'created from mixin B',
- 'created from Test'
- ])
-
- // methods
- expect(instance.foo()).toBe(1)
- expect(instance.bar()).toBe(1)
- expect(instance.baz()).toBe(1)
-}
-
-describe('mixins', () => {
- it('should work with classes', () => {
- class Test extends mixins(ClassMixinA, ClassMixinB)<
- { p3: string },
- { d31: number }
- > {
- static props = {
- p3: String
- }
-
- d3 = 1
- data(): any {
- return {
- d31: 2
- }
- }
-
- get c3() {
- return this.d3 + this.d31
- }
-
- created() {
- calls.push('created from Test')
- }
-
- baz() {
- return this.d3
- }
- }
-
- const instance = createInstance(Test, {
- p1: '1',
- p2: '2',
- p3: '3'
- })
-
- // we duplicate the assertions because they serve as type tests as well
-
- // data
- expect(instance.d1).toBe(1)
- expect(instance.$data.d11).toBe(2)
- expect(instance.d2).toBe(1)
- expect(instance.$data.d21).toBe(2)
- expect(instance.d3).toBe(1)
- expect(instance.d31).toBe(2)
-
- // props
- expect(instance.p1).toBe('1')
- expect(instance.$props.p2).toBe('2')
- expect(instance.p3).toBe('3')
- expect(instance.$props.p1).toBe('1')
- expect(instance.$props.p2).toBe('2')
- expect(instance.$props.p3).toBe('3')
-
- // computed
- expect(instance.c1).toBe(3)
- expect(instance.c2).toBe(3)
- expect(instance.c3).toBe(3)
-
- // lifecycle
- expect(calls).toEqual([
- 'created from mixin A',
- 'created from mixin B',
- 'created from Test'
- ])
-
- // methods
- expect(instance.foo()).toBe(1)
- expect(instance.bar()).toBe(1)
- expect(instance.baz()).toBe(1)
- })
-
- it('should work with objects', () => {
- class Test extends ((mixins as any)(
- ObjectMixinA,
- ObjectMixinB
- ) as ComponentClass)<{ p3: string }, { d31: number }> {
- static props = {
- p3: String
- }
-
- d3 = 1
- data(): any {
- return {
- d31: 2
- }
- }
-
- get c3() {
- return this.d3 + this.$data.d31
- }
-
- created() {
- calls.push('created from Test')
- }
-
- baz() {
- return this.d3
- }
- }
-
- assertMixins(Test)
- })
-
- it('should work with a mix of objects and classes', () => {
- class Test extends ((mixins as any)(
- ClassMixinA,
- ObjectMixinB
- ) as ComponentClass)<{ p3: string }, { d31: number }> {
- static props = {
- p3: String
- }
-
- d3 = 1
- data(): any {
- return {
- d31: 2
- }
- }
-
- get c3() {
- return this.d3 + this.$data.d31
- }
-
- created() {
- calls.push('created from Test')
- }
-
- baz() {
- return this.d3
- }
- }
-
- assertMixins(Test)
- })
-})
+++ /dev/null
-import {
- h,
- Component,
- observable,
- nextTick,
- renderInstance
-} from '@vue/runtime-test'
-
-describe('Parent chain management', () => {
- it('should have correct $parent / $root / $children', async () => {
- let child: any
- let grandChildren: any[] = []
-
- const state = observable({ ok: true })
-
- class Parent extends Component {
- render() {
- return h(Child)
- }
- }
-
- class Child extends Component {
- created() {
- child = this
- }
- render() {
- return [state.ok ? h(GrandChild) : null, h(GrandChild)]
- }
- }
-
- class GrandChild extends Component {
- created() {
- grandChildren.push(this)
- }
- unmounted() {
- grandChildren.splice(grandChildren.indexOf(this), 1)
- }
- render() {
- return h('div')
- }
- }
-
- const parent = await renderInstance(Parent)
-
- expect(child.$parent).toBe(parent)
- expect(child.$root).toBe(parent)
-
- grandChildren.forEach(grandChild => {
- expect(grandChild.$parent).toBe(child)
- expect(grandChild.$root).toBe(parent)
- })
-
- expect(parent.$children).toEqual([child])
- expect(grandChildren.length).toBe(2)
- expect(child.$children).toEqual(grandChildren)
-
- state.ok = false
- await nextTick()
- expect(grandChildren.length).toBe(1)
- expect(child.$children).toEqual(grandChildren)
- })
-
- it('should have correct $parent / $root w/ functional component in between', async () => {
- let child: any
- let grandChildren: any[] = []
-
- const state = observable({ ok: true })
-
- class Parent extends Component {
- render() {
- return h(FunctionalChild)
- }
- }
-
- const FunctionalChild = () => h(Child)
-
- class Child extends Component {
- created() {
- child = this
- }
- render() {
- return [
- state.ok ? h(FunctionalGrandChild) : null,
- h(FunctionalGrandChild)
- ]
- }
- }
-
- const FunctionalGrandChild = () => h(GrandChild)
-
- class GrandChild extends Component {
- created() {
- grandChildren.push(this)
- }
- unmounted() {
- grandChildren.splice(grandChildren.indexOf(this), 1)
- }
- render() {}
- }
-
- const parent = await renderInstance(Parent)
-
- expect(child.$parent).toBe(parent)
- expect(child.$root).toBe(parent)
-
- grandChildren.forEach(grandChild => {
- expect(grandChild.$parent).toBe(child)
- expect(grandChild.$root).toBe(parent)
- })
-
- expect(parent.$children).toEqual([child])
- expect(grandChildren.length).toBe(2)
- expect(child.$children).toEqual(grandChildren)
-
- state.ok = false
- await nextTick()
- expect(grandChildren.length).toBe(1)
- expect(child.$children).toEqual(grandChildren)
- })
-})
declare namespace JSX {
interface Element {}
interface ElementClass {
- render(props: any, slots: any, attrs: any): any
+ $props: {}
}
interface ElementAttributesProperty {
$props: {}
},
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/runtime-core#readme",
"dependencies": {
- "@vue/observer": "3.0.0-alpha.1",
- "@vue/scheduler": "3.0.0-alpha.1"
+ "@vue/observer": "3.0.0-alpha.1"
}
}
declare namespace JSX {
interface Element {}
interface ElementClass {
- render(props: any, slots: any, attrs: any): any
+ $props: {}
}
interface ElementAttributesProperty {
$props: {}
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typescript@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
- integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==
+typescript@^3.5.0:
+ version "3.5.1"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202"
+ integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==
uglify-js@^3.1.4:
version "3.4.9"