mixin.spec.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import Vue from 'vue'
  2. describe('Global API: mixin', () => {
  3. let options
  4. beforeEach(() => { options = Vue.options })
  5. afterEach(() => { Vue.options = options })
  6. it('should work', () => {
  7. const spy = jasmine.createSpy('global mixin')
  8. Vue.mixin({
  9. created () {
  10. spy(this.$options.myOption)
  11. }
  12. })
  13. new Vue({
  14. myOption: 'hello'
  15. })
  16. expect(spy).toHaveBeenCalledWith('hello')
  17. })
  18. it('should work for constructors created before mixin is applied', () => {
  19. const calls = []
  20. const Test = Vue.extend({
  21. name: 'test',
  22. beforeCreate () {
  23. calls.push(this.$options.myOption + ' local')
  24. }
  25. })
  26. Vue.mixin({
  27. beforeCreate () {
  28. calls.push(this.$options.myOption + ' global')
  29. }
  30. })
  31. expect(Test.options.name).toBe('test')
  32. new Test({
  33. myOption: 'hello'
  34. })
  35. expect(calls).toEqual(['hello global', 'hello local'])
  36. })
  37. // #3957
  38. it('should work for global props', () => {
  39. const Test = Vue.extend({
  40. template: `<div>{{ prop }}</div>`
  41. })
  42. Vue.mixin({
  43. props: ['prop']
  44. })
  45. // test child component
  46. const vm = new Vue({
  47. template: '<test prop="hi"></test>',
  48. components: { Test }
  49. }).$mount()
  50. expect(vm.$el.textContent).toBe('hi')
  51. })
  52. // vue-loader#433
  53. it('should not drop late-set render functions', () => {
  54. const Test = Vue.extend({})
  55. Test.options.render = h => h('div', 'hello')
  56. Vue.mixin({})
  57. const vm = new Vue({
  58. render: h => h(Test)
  59. }).$mount()
  60. expect(vm.$el.textContent).toBe('hello')
  61. })
  62. // #4266
  63. it('should not drop scopedId', () => {
  64. const Test = Vue.extend({})
  65. Test.options._scopeId = 'foo'
  66. Vue.mixin({})
  67. const vm = new Test({
  68. template: '<div><p>hi</p></div>'
  69. }).$mount()
  70. expect(vm.$el.children[0].hasAttribute('foo')).toBe(true)
  71. })
  72. // #4976
  73. it('should not drop late-attached custom options on existing constructors', () => {
  74. const baseSpy = jasmine.createSpy('base')
  75. const Base = Vue.extend({
  76. beforeCreate: baseSpy
  77. })
  78. const Test = Base.extend({})
  79. // Inject options later
  80. // vue-loader and vue-hot-reload-api are doing like this
  81. Test.options.computed = {
  82. $style: () => 123
  83. }
  84. const spy = jasmine.createSpy('late attached')
  85. Test.options.beforeCreate = Test.options.beforeCreate.concat(spy)
  86. // Update super constructor's options
  87. const mixinSpy = jasmine.createSpy('mixin')
  88. Vue.mixin({
  89. beforeCreate: mixinSpy
  90. })
  91. // mount the component
  92. const vm = new Test({
  93. template: '<div>{{ $style }}</div>'
  94. }).$mount()
  95. expect(spy.calls.count()).toBe(1)
  96. expect(baseSpy.calls.count()).toBe(1)
  97. expect(mixinSpy.calls.count()).toBe(1)
  98. expect(vm.$el.textContent).toBe('123')
  99. expect(vm.$style).toBe(123)
  100. // Should not be dropped
  101. expect(Test.options.computed.$style()).toBe(123)
  102. expect(Test.options.beforeCreate).toEqual([mixinSpy, baseSpy, spy])
  103. })
  104. })