extend.spec.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 merge methods', () => {
  70. const A = Vue.extend({
  71. methods: {
  72. a () { return this.n }
  73. }
  74. })
  75. const B = A.extend({
  76. methods: {
  77. b () { return this.n + 1 }
  78. }
  79. })
  80. const b = new B({
  81. data: { n: 0 },
  82. methods: {
  83. c () { return this.n + 2 }
  84. }
  85. })
  86. expect(b.a()).toBe(0)
  87. expect(b.b()).toBe(1)
  88. expect(b.c()).toBe(2)
  89. })
  90. it('should merge assets', () => {
  91. const A = Vue.extend({
  92. components: {
  93. aa: {
  94. template: '<div>A</div>'
  95. }
  96. }
  97. })
  98. const B = A.extend({
  99. components: {
  100. bb: {
  101. template: '<div>B</div>'
  102. }
  103. }
  104. })
  105. const b = new B({
  106. template: '<div><aa></aa><bb></bb></div>'
  107. }).$mount()
  108. expect(b.$el.innerHTML).toBe('<div>A</div><div>B</div>')
  109. })
  110. it('caching', () => {
  111. const options = {
  112. template: '<div></div>'
  113. }
  114. const A = Vue.extend(options)
  115. const B = Vue.extend(options)
  116. expect(A).toBe(B)
  117. })
  118. // #4767
  119. it('extended options should use different identify from parent', () => {
  120. const A = Vue.extend({ computed: {}})
  121. const B = A.extend()
  122. B.options.computed.b = () => 'foo'
  123. expect(B.options.computed).not.toBe(A.options.computed)
  124. expect(A.options.computed.b).toBeUndefined()
  125. })
  126. })