extend.spec.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import Vue from 'vue'
  2. describe('Global API: extend', () => {
  3. it('should correctly merge options', () => {
  4. const Test = Vue.extend({
  5. name: 'test',
  6. a: 1,
  7. b: 2
  8. })
  9. expect(Test.options.a).toBe(1)
  10. expect(Test.options.b).toBe(2)
  11. expect(Test.super).toBe(Vue)
  12. const t = new Test({
  13. a: 2
  14. })
  15. expect(t.$options.a).toBe(2)
  16. expect(t.$options.b).toBe(2)
  17. // inheritance
  18. const Test2 = Test.extend({
  19. a: 2
  20. })
  21. expect(Test2.options.a).toBe(2)
  22. expect(Test2.options.b).toBe(2)
  23. const t2 = new Test2({
  24. a: 3
  25. })
  26. expect(t2.$options.a).toBe(3)
  27. expect(t2.$options.b).toBe(2)
  28. })
  29. it('should warn invalid names', () => {
  30. Vue.extend({ name: '123' })
  31. expect('Invalid component name: "123"').toHaveBeenWarned()
  32. Vue.extend({ name: '_fesf' })
  33. expect('Invalid component name: "_fesf"').toHaveBeenWarned()
  34. Vue.extend({ name: 'Some App' })
  35. expect('Invalid component name: "Some App"').toHaveBeenWarned()
  36. })
  37. it('should work when used as components', () => {
  38. const foo = Vue.extend({
  39. template: '<span>foo</span>'
  40. })
  41. const bar = Vue.extend({
  42. template: '<span>bar</span>'
  43. })
  44. const vm = new Vue({
  45. template: '<div><foo></foo><bar></bar></div>',
  46. components: { foo, bar }
  47. }).$mount()
  48. expect(vm.$el.innerHTML).toBe('<span>foo</span><span>bar</span>')
  49. })
  50. it('should merge lifecycle hooks', () => {
  51. const calls = []
  52. const A = Vue.extend({
  53. created () {
  54. calls.push(1)
  55. }
  56. })
  57. const B = A.extend({
  58. created () {
  59. calls.push(2)
  60. }
  61. })
  62. new B({
  63. created () {
  64. calls.push(3)
  65. }
  66. })
  67. expect(calls).toEqual([1, 2, 3])
  68. })
  69. it('should not merge nested mixins created with Vue.extend', () => {
  70. const A = Vue.extend({
  71. created: () => {}
  72. })
  73. const B = Vue.extend({
  74. mixins: [A],
  75. created: () => {}
  76. })
  77. const C = Vue.extend({
  78. extends: B,
  79. created: () => {}
  80. })
  81. const D = Vue.extend({
  82. mixins: [C],
  83. created: () => {}
  84. })
  85. expect(D.options.created.length).toBe(4)
  86. })
  87. it('should merge methods', () => {
  88. const A = Vue.extend({
  89. methods: {
  90. a () { return this.n }
  91. }
  92. })
  93. const B = A.extend({
  94. methods: {
  95. b () { return this.n + 1 }
  96. }
  97. })
  98. const b = new B({
  99. data: { n: 0 },
  100. methods: {
  101. c () { return this.n + 2 }
  102. }
  103. })
  104. expect(b.a()).toBe(0)
  105. expect(b.b()).toBe(1)
  106. expect(b.c()).toBe(2)
  107. })
  108. it('should merge assets', () => {
  109. const A = Vue.extend({
  110. components: {
  111. aa: {
  112. template: '<div>A</div>'
  113. }
  114. }
  115. })
  116. const B = A.extend({
  117. components: {
  118. bb: {
  119. template: '<div>B</div>'
  120. }
  121. }
  122. })
  123. const b = new B({
  124. template: '<div><aa></aa><bb></bb></div>'
  125. }).$mount()
  126. expect(b.$el.innerHTML).toBe('<div>A</div><div>B</div>')
  127. })
  128. it('caching', () => {
  129. const options = {
  130. template: '<div></div>'
  131. }
  132. const A = Vue.extend(options)
  133. const B = Vue.extend(options)
  134. expect(A).toBe(B)
  135. })
  136. // #4767
  137. it('extended options should use different identify from parent', () => {
  138. const A = Vue.extend({ computed: {}})
  139. const B = A.extend()
  140. B.options.computed.b = () => 'foo'
  141. expect(B.options.computed).not.toBe(A.options.computed)
  142. expect(A.options.computed.b).toBeUndefined()
  143. })
  144. })