extend.spec.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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: any[] = []
  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() {
  91. return this.n
  92. }
  93. }
  94. })
  95. const B = A.extend({
  96. methods: {
  97. b() {
  98. return this.n + 1
  99. }
  100. }
  101. })
  102. const b = new B({
  103. data: { n: 0 },
  104. methods: {
  105. c() {
  106. return this.n + 2
  107. }
  108. }
  109. })
  110. expect(b.a()).toBe(0)
  111. expect(b.b()).toBe(1)
  112. expect(b.c()).toBe(2)
  113. })
  114. it('should merge assets', () => {
  115. const A = Vue.extend({
  116. components: {
  117. aa: {
  118. template: '<div>A</div>'
  119. }
  120. }
  121. })
  122. const B = A.extend({
  123. components: {
  124. bb: {
  125. template: '<div>B</div>'
  126. }
  127. }
  128. })
  129. const b = new B({
  130. template: '<div><aa></aa><bb></bb></div>'
  131. }).$mount()
  132. expect(b.$el.innerHTML).toBe('<div>A</div><div>B</div>')
  133. })
  134. it('caching', () => {
  135. const options = {
  136. template: '<div></div>'
  137. }
  138. const A = Vue.extend(options)
  139. const B = Vue.extend(options)
  140. expect(A).toBe(B)
  141. })
  142. // #4767
  143. it('extended options should use different identify from parent', () => {
  144. const A = Vue.extend({ computed: {} })
  145. const B = A.extend()
  146. B.options.computed.b = () => 'foo'
  147. expect(B.options.computed).not.toBe(A.options.computed)
  148. expect(A.options.computed.b).toBeUndefined()
  149. })
  150. })