| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  | import Vue from 'vue' | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  | import { hasSymbol } from 'core/util/env' | 
					
						
							| 
									
										
										
										
											2017-10-12 22:57:02 +08:00
										 |  |  | import testObjectOption from '../../../helpers/test-object-option' | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('Options props', () => { | 
					
						
							| 
									
										
										
										
											2017-10-12 22:57:02 +08:00
										 |  |  |   testObjectOption('props') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   it('array syntax', done => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         b: 'bar' | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2016-06-18 02:03:19 +08:00
										 |  |  |       template: '<test v-bind:b="b" ref="child"></test>', | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: ['b'], | 
					
						
							|  |  |  |           template: '<div>{{b}}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.innerHTML).toBe('bar') | 
					
						
							|  |  |  |     vm.b = 'baz' | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(vm.$el.innerHTML).toBe('baz') | 
					
						
							|  |  |  |       vm.$refs.child.b = 'qux' | 
					
						
							|  |  |  |     }).then(() => { | 
					
						
							|  |  |  |       expect(vm.$el.innerHTML).toBe('qux') | 
					
						
							| 
									
										
										
										
											2016-06-02 09:50:00 +08:00
										 |  |  |       expect('Avoid mutating a prop directly').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('object syntax', done => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         b: 'bar' | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2016-06-18 02:03:19 +08:00
										 |  |  |       template: '<test v-bind:b="b" ref="child"></test>', | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: { b: String }, | 
					
						
							|  |  |  |           template: '<div>{{b}}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.innerHTML).toBe('bar') | 
					
						
							|  |  |  |     vm.b = 'baz' | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(vm.$el.innerHTML).toBe('baz') | 
					
						
							|  |  |  |       vm.$refs.child.b = 'qux' | 
					
						
							|  |  |  |     }).then(() => { | 
					
						
							|  |  |  |       expect(vm.$el.innerHTML).toBe('qux') | 
					
						
							| 
									
										
										
										
											2016-06-02 09:50:00 +08:00
										 |  |  |       expect('Avoid mutating a prop directly').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('warn mixed syntax', () => { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       props: [{ b: String }] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     expect('props must be strings when using array syntax').toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('default values', () => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         b: undefined | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       template: '<test :b="b"></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             a: { | 
					
						
							|  |  |  |               default: 'A' // absent
 | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             b: { | 
					
						
							|  |  |  |               default: 'B' // undefined
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           template: '<div>{{a}}{{b}}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.textContent).toBe('AB') | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('default value reactivity', done => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       props: { | 
					
						
							|  |  |  |         a: { | 
					
						
							|  |  |  |           default: () => ({ b: 1 }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       propsData: { | 
					
						
							|  |  |  |         a: undefined | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       template: '<div>{{ a.b }}</div>' | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.textContent).toBe('1') | 
					
						
							|  |  |  |     vm.a.b = 2 | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(vm.$el.textContent).toBe('2') | 
					
						
							|  |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-15 02:40:57 +08:00
										 |  |  |   it('default value Function', () => { | 
					
						
							|  |  |  |     const func = () => 132 | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       props: { | 
					
						
							|  |  |  |         a: { | 
					
						
							|  |  |  |           type: Function, | 
					
						
							|  |  |  |           default: func | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       propsData: { | 
					
						
							|  |  |  |         a: undefined | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     expect(vm.a).toBe(func) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   it('warn object/array default values', () => { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       props: { | 
					
						
							|  |  |  |         a: { | 
					
						
							|  |  |  |           default: { b: 1 } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       propsData: { | 
					
						
							|  |  |  |         a: undefined | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     expect('Props with type Object/Array must use a factory function').toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('warn missing required', () => { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       template: '<test></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: { a: { required: true }}, | 
					
						
							|  |  |  |           template: '<div>{{a}}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect('Missing required prop: "a"').toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('assertions', () => { | 
					
						
							|  |  |  |     function makeInstance (value, type, validator, required) { | 
					
						
							|  |  |  |       return new Vue({ | 
					
						
							|  |  |  |         template: '<test :test="val"></test>', | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           val: value | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         components: { | 
					
						
							|  |  |  |           test: { | 
					
						
							|  |  |  |             template: '<div></div>', | 
					
						
							|  |  |  |             props: { | 
					
						
							|  |  |  |               test: { | 
					
						
							|  |  |  |                 type, | 
					
						
							|  |  |  |                 validator, | 
					
						
							|  |  |  |                 required | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }).$mount() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('string', () => { | 
					
						
							|  |  |  |       makeInstance('hello', String) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(123, String) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('number', () => { | 
					
						
							|  |  |  |       makeInstance(123, Number) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance('123', Number) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected Number with value 123, got String with value "123"').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('number & boolean', () => { | 
					
						
							|  |  |  |       makeInstance(123, Number) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       makeInstance(false, Number) | 
					
						
							|  |  |  |       expect('Expected Number, got Boolean with value false').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('string & boolean', () => { | 
					
						
							|  |  |  |       makeInstance('hello', String) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       makeInstance(true, String) | 
					
						
							|  |  |  |       expect('Expected String, got Boolean with value true').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('boolean', () => { | 
					
						
							|  |  |  |       makeInstance(true, Boolean) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance('123', Boolean) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected Boolean, got String with value "123"').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('function', () => { | 
					
						
							|  |  |  |       makeInstance(() => {}, Function) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(123, Function) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected Function, got Number with value 123').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('object', () => { | 
					
						
							|  |  |  |       makeInstance({}, Object) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance([], Object) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected Object, got Array').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('array', () => { | 
					
						
							|  |  |  |       makeInstance([], Array) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance({}, Array) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected Array, got Object').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-06 04:23:53 +08:00
										 |  |  |     it('primitive wrapper objects', () => { | 
					
						
							|  |  |  |       /* eslint-disable no-new-wrappers */ | 
					
						
							|  |  |  |       makeInstance(new String('s'), String) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2017-09-06 04:23:53 +08:00
										 |  |  |       makeInstance(new Number(1), Number) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2017-09-06 04:23:53 +08:00
										 |  |  |       makeInstance(new Boolean(true), Boolean) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2017-09-06 04:23:53 +08:00
										 |  |  |       /* eslint-enable no-new-wrappers */ | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  |     if (hasSymbol) { | 
					
						
							|  |  |  |       it('symbol', () => { | 
					
						
							|  |  |  |         makeInstance(Symbol('foo'), Symbol) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |         expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  |         makeInstance({}, Symbol) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |         expect('Expected Symbol, got Object').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2020-09-21 18:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('warns when expected an explicable type but Symbol was provided', () => { | 
					
						
							|  |  |  |         makeInstance(Symbol('foo'), String) | 
					
						
							|  |  |  |         expect('Expected String, got Symbol').toHaveBeenWarned() | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('warns when expected an explicable type but Symbol was provided', () => { | 
					
						
							|  |  |  |         makeInstance(Symbol('foo'), [String, Number]) | 
					
						
							|  |  |  |         expect('Expected String, Number, got Symbol').toHaveBeenWarned() | 
					
						
							|  |  |  |       }) | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 17:41:10 +08:00
										 |  |  |     if (typeof BigInt !== 'undefined') { | 
					
						
							|  |  |  |       /* global BigInt */ | 
					
						
							|  |  |  |       it('bigint', () => { | 
					
						
							|  |  |  |         makeInstance(BigInt(100), BigInt) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |         expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2021-03-30 17:41:10 +08:00
										 |  |  |         makeInstance({}, BigInt) | 
					
						
							|  |  |  |         expect('Expected BigInt, got Object').toHaveBeenWarned() | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-10 20:36:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     it('custom constructor', () => { | 
					
						
							|  |  |  |       function Class () {} | 
					
						
							|  |  |  |       makeInstance(new Class(), Class) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance({}, Class) | 
					
						
							|  |  |  |       expect('type check failed').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('multiple types', () => { | 
					
						
							|  |  |  |       makeInstance([], [Array, Number, Boolean]) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance({}, [Array, Number, Boolean]) | 
					
						
							|  |  |  |       expect('Expected Array, Number, Boolean, got Object').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('custom validator', () => { | 
					
						
							|  |  |  |       makeInstance(123, null, v => v === 123) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(123, null, v => v === 234) | 
					
						
							|  |  |  |       expect('custom validator check failed').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('type check + custom validator', () => { | 
					
						
							|  |  |  |       makeInstance(123, Number, v => v === 123) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(123, Number, v => v === 234) | 
					
						
							|  |  |  |       expect('custom validator check failed').toHaveBeenWarned() | 
					
						
							|  |  |  |       makeInstance(123, String, v => v === 123) | 
					
						
							| 
									
										
										
										
											2018-08-17 22:40:46 +08:00
										 |  |  |       expect('Expected String with value "123", got Number with value 123').toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('multiple types + custom validator', () => { | 
					
						
							|  |  |  |       makeInstance(123, [Number, String, Boolean], v => v === 123) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(123, [Number, String, Boolean], v => v === 234) | 
					
						
							|  |  |  |       expect('custom validator check failed').toHaveBeenWarned() | 
					
						
							|  |  |  |       makeInstance(123, [String, Boolean], v => v === 123) | 
					
						
							|  |  |  |       expect('Expected String, Boolean').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('optional with type + null/undefined', () => { | 
					
						
							|  |  |  |       makeInstance(undefined, String) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       makeInstance(null, String) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('required with type + null/undefined', () => { | 
					
						
							|  |  |  |       makeInstance(undefined, String, null, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(1) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       expect('Expected String').toHaveBeenWarned() | 
					
						
							|  |  |  |       makeInstance(null, Boolean, null, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(2) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       expect('Expected Boolean').toHaveBeenWarned() | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('optional prop of any type (type: true or prop: true)', () => { | 
					
						
							|  |  |  |       makeInstance(1, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  |       makeInstance('any', true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  |       makeInstance({}, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  |       makeInstance(undefined, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  |       makeInstance(null, true) | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-09-10 13:12:06 +08:00
										 |  |  |     }) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-14 22:14:14 +08:00
										 |  |  |   it('should work with v-bind', () => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       template: `<test v-bind="{ a: 1, b: 2 }"></test>`, | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: ['a', 'b'], | 
					
						
							|  |  |  |           template: '<div>{{ a }} {{ b }}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.textContent).toBe('1 2') | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   it('should warn data fields already defined as a prop', () => { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       template: '<test a="1"></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           data: function () { | 
					
						
							|  |  |  |             return { a: 123 } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             a: null | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect('already declared as a prop').toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-18 22:09:27 +08:00
										 |  |  |   it('should warn methods already defined as a prop', () => { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       template: '<test a="1"></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             a: null | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           methods: { | 
					
						
							|  |  |  |             a () { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							| 
									
										
										
										
											2017-09-02 06:34:10 +08:00
										 |  |  |     expect(`Method "a" has already been defined as a prop`).toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2017-02-18 22:09:27 +08:00
										 |  |  |     expect(`Avoid mutating a prop directly`).toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   it('treat boolean props properly', () => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							| 
									
										
										
										
											2016-06-18 02:03:19 +08:00
										 |  |  |       template: '<comp ref="child" prop-a prop-b="prop-b"></comp>', | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |       components: { | 
					
						
							|  |  |  |         comp: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             propA: Boolean, | 
					
						
							|  |  |  |             propB: Boolean, | 
					
						
							|  |  |  |             propC: Boolean | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$refs.child.propA).toBe(true) | 
					
						
							|  |  |  |     expect(vm.$refs.child.propB).toBe(true) | 
					
						
							|  |  |  |     expect(vm.$refs.child.propC).toBe(false) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should respect default value of a Boolean prop', function () { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       template: '<test></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             prop: { | 
					
						
							|  |  |  |               type: Boolean, | 
					
						
							|  |  |  |               default: true | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           template: '<div>{{prop}}</div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$el.textContent).toBe('true') | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('non reactive values passed down as prop should not be converted', done => { | 
					
						
							|  |  |  |     const a = Object.freeze({ | 
					
						
							|  |  |  |       nested: { | 
					
						
							|  |  |  |         msg: 'hello' | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     const parent = new Vue({ | 
					
						
							|  |  |  |       template: '<comp :a="a.nested"></comp>', | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         a: a | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         comp: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           props: ['a'] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     const child = parent.$children[0] | 
					
						
							|  |  |  |     expect(child.a.msg).toBe('hello') | 
					
						
							|  |  |  |     expect(child.a.__ob__).toBeUndefined() // should not be converted
 | 
					
						
							|  |  |  |     parent.a = Object.freeze({ | 
					
						
							|  |  |  |       nested: { | 
					
						
							|  |  |  |         msg: 'yo' | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(child.a.msg).toBe('yo') | 
					
						
							|  |  |  |       expect(child.a.__ob__).toBeUndefined() | 
					
						
							|  |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not warn for non-required, absent prop', function () { | 
					
						
							|  |  |  |     new Vue({ | 
					
						
							|  |  |  |       template: '<test></test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             prop: { | 
					
						
							|  |  |  |               type: String | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |     expect(console.error.mock.calls.length).toBe(0) | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  |   }) | 
					
						
							| 
									
										
										
										
											2016-08-16 05:47:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // #3453
 | 
					
						
							|  |  |  |   it('should not fire watcher on object/array props when parent re-renders', done => { | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |     const spy = vi.fn() | 
					
						
							| 
									
										
										
										
											2016-08-16 05:47:01 +08:00
										 |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         arr: [] | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       template: '<test :prop="arr">hi</test>', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           props: ['prop'], | 
					
						
							|  |  |  |           watch: { | 
					
						
							|  |  |  |             prop: spy | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           template: '<div><slot></slot></div>' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     vm.$forceUpdate() | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(spy).not.toHaveBeenCalled() | 
					
						
							|  |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2016-11-05 10:49:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // #4090
 | 
					
						
							| 
									
										
										
										
											2017-03-06 16:50:49 +08:00
										 |  |  |   it('should not trigger watcher on default value', done => { | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |     const spy = vi.fn() | 
					
						
							| 
									
										
										
										
											2016-11-05 10:49:30 +08:00
										 |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       template: `<test :value="a" :test="b"></test>`, | 
					
						
							|  |  |  |       data: { | 
					
						
							|  |  |  |         a: 1, | 
					
						
							|  |  |  |         b: undefined | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           template: '<div>{{ value }}</div>', | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             value: { type: Number }, | 
					
						
							|  |  |  |             test: { | 
					
						
							|  |  |  |               type: Object, | 
					
						
							|  |  |  |               default: () => ({}) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           watch: { | 
					
						
							|  |  |  |             test: spy | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vm.a++ | 
					
						
							|  |  |  |     waitForUpdate(() => { | 
					
						
							|  |  |  |       expect(spy).not.toHaveBeenCalled() | 
					
						
							|  |  |  |       vm.b = {} | 
					
						
							|  |  |  |     }).then(() => { | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(spy.mock.calls.length).toBe(1) | 
					
						
							| 
									
										
										
										
											2016-11-05 10:49:30 +08:00
										 |  |  |     }).then(() => { | 
					
						
							|  |  |  |       vm.b = undefined | 
					
						
							|  |  |  |     }).then(() => { | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(spy.mock.calls.length).toBe(2) | 
					
						
							| 
									
										
										
										
											2016-11-05 10:49:30 +08:00
										 |  |  |       vm.a++ | 
					
						
							|  |  |  |     }).then(() => { | 
					
						
							| 
									
										
										
										
											2022-05-20 07:56:02 +08:00
										 |  |  |       expect(spy.mock.calls.length).toBe(2) | 
					
						
							| 
									
										
										
										
											2016-11-05 10:49:30 +08:00
										 |  |  |     }).then(done) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2016-11-19 01:13:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('warn reserved props', () => { | 
					
						
							| 
									
										
										
										
											2017-10-05 05:31:58 +08:00
										 |  |  |     const specialAttrs = ['key', 'ref', 'slot', 'is', 'slot-scope'] | 
					
						
							| 
									
										
										
										
											2016-11-19 01:13:12 +08:00
										 |  |  |     new Vue({ | 
					
						
							| 
									
										
										
										
											2017-06-16 21:08:37 +08:00
										 |  |  |       props: specialAttrs | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     specialAttrs.forEach(attr => { | 
					
						
							|  |  |  |       expect(`"${attr}" is a reserved attribute`).toHaveBeenWarned() | 
					
						
							| 
									
										
										
										
											2016-11-19 01:13:12 +08:00
										 |  |  |     }) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2018-03-10 03:46:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should consider order when casting [Boolean, String] multi-type props', () => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       template: '<test ref="test" booleanOrString stringOrBoolean />', | 
					
						
							|  |  |  |       components: { | 
					
						
							|  |  |  |         test: { | 
					
						
							|  |  |  |           template: '<div></div>', | 
					
						
							|  |  |  |           props: { | 
					
						
							|  |  |  |             booleanOrString: [Boolean, String], | 
					
						
							|  |  |  |             stringOrBoolean: [String, Boolean] | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect(vm.$refs.test.$props.booleanOrString).toBe(true) | 
					
						
							|  |  |  |     expect(vm.$refs.test.$props.stringOrBoolean).toBe('') | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2021-03-30 17:38:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should warn when a prop type is not a constructor', () => { | 
					
						
							|  |  |  |     const vm = new Vue({ | 
					
						
							|  |  |  |       template: '<div>{{a}}</div>', | 
					
						
							|  |  |  |       props: { | 
					
						
							|  |  |  |         a: { | 
					
						
							|  |  |  |           type: 'String', | 
					
						
							|  |  |  |           default: 'test' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }).$mount() | 
					
						
							|  |  |  |     expect( | 
					
						
							|  |  |  |       'Invalid prop type: "String" is not a constructor' | 
					
						
							|  |  |  |     ).toHaveBeenWarned() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-01 03:15:01 +08:00
										 |  |  | }) |