merge-option_spec.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. var _ = require('../../../../src/util')
  2. var Vue = require('../../../../src/vue')
  3. var merge = require('../../../../src/util/merge-option')
  4. describe('Util - Option merging', function () {
  5. it('default strat', function () {
  6. // child undefined
  7. var res = merge({replace:true}, {}).replace
  8. expect(res).toBe(true)
  9. // child overwrite
  10. res = merge({replace:true}, {replace:false}).replace
  11. expect(res).toBe(false)
  12. })
  13. it('hooks & paramAttributes', function () {
  14. var fn1 = function () {}
  15. var fn2 = function () {}
  16. var res
  17. // parent undefined
  18. res = merge({}, {created: fn1}).created
  19. expect(Array.isArray(res)).toBe(true)
  20. expect(res.length).toBe(1)
  21. expect(res[0]).toBe(fn1)
  22. // child undefined
  23. res = merge({created: [fn1]}, {}).created
  24. expect(Array.isArray(res)).toBe(true)
  25. expect(res.length).toBe(1)
  26. expect(res[0]).toBe(fn1)
  27. // both defined
  28. res = merge({created: [fn1]}, {created: fn2}).created
  29. expect(Array.isArray(res)).toBe(true)
  30. expect(res.length).toBe(2)
  31. expect(res[0]).toBe(fn1)
  32. expect(res[1]).toBe(fn2)
  33. // both arrays
  34. res = merge({paramAttributes: [1]}, {paramAttributes: [2]}).paramAttributes
  35. expect(Array.isArray(res)).toBe(true)
  36. expect(res.length).toBe(2)
  37. expect(res[0]).toBe(1)
  38. expect(res[1]).toBe(2)
  39. })
  40. it('events', function () {
  41. // no parent
  42. res = merge({}, {events:1})
  43. expect(res.events).toBe(1)
  44. // no child
  45. res = merge({events:1}, {})
  46. expect(res.events).toBe(1)
  47. var fn1 = function () {}
  48. var fn2 = function () {}
  49. var fn3 = function () {}
  50. var parent = {
  51. events: {
  52. 'fn1': [fn1, fn2],
  53. 'fn2': fn2
  54. }
  55. }
  56. var child = {
  57. events: {
  58. 'fn1': fn3,
  59. 'fn2': fn3,
  60. 'fn3': fn3
  61. }
  62. }
  63. var res = merge(parent, child).events
  64. assertRes(res.fn1, [fn1, fn2, fn3])
  65. assertRes(res.fn2, [fn2, fn3])
  66. assertRes(res.fn3, [fn3])
  67. function assertRes (res, expected) {
  68. expect(Array.isArray(res)).toBe(true)
  69. expect(res.length).toBe(expected.length)
  70. var i = expected.length
  71. while (i--) {
  72. expect(res[i]).toBe(expected[i])
  73. }
  74. }
  75. })
  76. it('normal object hashes', function () {
  77. var fn1 = function () {}
  78. var fn2 = function () {}
  79. var res
  80. // parent undefined
  81. res = merge({}, {methods: {test: fn1}}).methods
  82. expect(res.test).toBe(fn1)
  83. // child undefined
  84. res = merge({methods: {test: fn1}}, {}).methods
  85. expect(res.test).toBe(fn1)
  86. // both defined
  87. var parent = {methods: {test: fn1}}
  88. res = merge(parent, {methods: {test2: fn2}}).methods
  89. expect(res.test).toBe(fn1)
  90. expect(res.test2).toBe(fn2)
  91. })
  92. it('assets', function () {
  93. var asset1 = {}
  94. var asset2 = {}
  95. var asset3 = {}
  96. var asset4 = {}
  97. var asset5 = {}
  98. var res = merge(
  99. { directives: { a: asset1 }},
  100. { directives: { b: asset2 }}
  101. ).directives
  102. expect(res.a).toBe(asset1)
  103. expect(res.b).toBe(asset2)
  104. // vm asset merge should do tree-way merge
  105. var proto = { d: asset5 }
  106. var parent = { directives: Object.create(proto) }
  107. parent.directives.a = asset1
  108. parent.directives.b = asset4
  109. res = merge(
  110. parent,
  111. { directives: { b: asset2 }},
  112. {
  113. $parent: {
  114. $options: {
  115. directives: { c: asset3 }
  116. }
  117. }
  118. },
  119. 'directives'
  120. ).directives
  121. expect(res.a).toBe(asset1)
  122. // child should overwrite parent
  123. expect(res.b).toBe(asset2)
  124. expect(res.c).toBe(asset3)
  125. // should not copy parent prototype properties
  126. expect(res.d).toBeUndefined()
  127. })
  128. it('guard components', function () {
  129. var res = merge({}, {
  130. components: {
  131. a: { template: 'hi' }
  132. }
  133. })
  134. expect(typeof res.components.a).toBe('function')
  135. expect(res.components.a.options.name).toBe('a')
  136. expect(res.components.a.super).toBe(Vue)
  137. })
  138. it('should ignore non-function el & data in class merge', function () {
  139. var res = merge({}, {el:1, data:2})
  140. expect(res.el).toBeUndefined()
  141. expect(res.data).toBeUndefined()
  142. })
  143. it('class el merge', function () {
  144. function fn1 () {}
  145. function fn2 () {}
  146. var res = merge({el:fn1}, {el:fn2})
  147. expect(res.el).toBe(fn2)
  148. })
  149. it('class data merge', function () {
  150. function fn1 () {
  151. return { a: 1, c: 4, d: { e: 1 } }
  152. }
  153. function fn2 () {
  154. return { a: 2, b: 3, d: { f: 2 } }
  155. }
  156. // both present
  157. var res = merge({data:fn1}, {data:fn2}).data()
  158. expect(res.a).toBe(2)
  159. expect(res.b).toBe(3)
  160. expect(res.c).toBe(4)
  161. expect(res.d.e).toBe(1)
  162. expect(res.d.f).toBe(2)
  163. // only parent
  164. res = merge({data:fn1}, {}).data()
  165. expect(res.a).toBe(1)
  166. expect(res.b).toBeUndefined()
  167. expect(res.c).toBe(4)
  168. expect(res.d.e).toBe(1)
  169. expect(res.d.f).toBeUndefined()
  170. })
  171. it('instanace el merge', function () {
  172. var vm = {} // mock vm presence
  173. function fn1 () {
  174. expect(this).toBe(vm)
  175. return 1
  176. }
  177. function fn2 () {
  178. expect(this).toBe(vm)
  179. return 2
  180. }
  181. // both functions
  182. var res = merge({el:fn1}, {el:fn2}, vm)
  183. expect(res.el).toBe(2)
  184. // direct instance el
  185. res = merge({el:fn1}, {el:2}, vm)
  186. expect(res.el).toBe(2)
  187. // no parent
  188. res = merge({}, {el:2}, vm)
  189. expect(res.el).toBe(2)
  190. // no child
  191. res = merge({el:fn1}, {}, vm)
  192. expect(res.el).toBe(1)
  193. })
  194. it('instance data merge with no instance data', function () {
  195. var res = merge(
  196. {data: function () {
  197. return { a: 1}
  198. }},
  199. {}, // no instance data
  200. {} // mock vm presence
  201. )
  202. expect(res.data.a).toBe(1)
  203. })
  204. it('instance data merge with default data function', function () {
  205. var vm = {} // mock vm presence
  206. var res = merge(
  207. // component default
  208. { data: function () {
  209. expect(this).toBe(vm)
  210. return {
  211. a: 1,
  212. b: 2
  213. }
  214. }},
  215. { data: { a: 2 }}, // instance data
  216. vm
  217. )
  218. expect(res.data.a).toBe(2)
  219. expect(res.data.b).toBe(2)
  220. })
  221. it('already observed instance data merge with default data', function () {
  222. var Observer = require('../../../../src/observer')
  223. var instanceData = { a: 123 }
  224. // observe it
  225. Observer.create(instanceData)
  226. var res = merge(
  227. {
  228. data: function () { return { b: 234} }
  229. },
  230. {
  231. data: instanceData
  232. },
  233. {}
  234. )
  235. expect(res.data.a).toBe(123)
  236. expect(res.data.b).toBe(234)
  237. expect(Object.getOwnPropertyDescriptor(res.data, 'b').get).toBeTruthy()
  238. })
  239. it('mixins', function () {
  240. var a = {}, b = {}, c = {}, d = {}
  241. var f1 = function () {}
  242. var f2 = function () {}
  243. var f3 = function () {}
  244. var f4 = function () {}
  245. var mixinA = { a: 1, directives: { a: a }, created: f2 }
  246. var mixinB = { b: 1, directives: { b: b }, created: f3 }
  247. var res = merge(
  248. { a: 2, directives: { c: c }, created: [f1] },
  249. { directives: { d: d }, mixins: [mixinA, mixinB], created: f4 }
  250. )
  251. expect(res.a).toBe(1)
  252. expect(res.b).toBe(1)
  253. expect(res.directives.a).toBe(a)
  254. expect(res.directives.b).toBe(b)
  255. expect(res.directives.c).toBe(c)
  256. expect(res.directives.d).toBe(d)
  257. expect(res.created[0]).toBe(f1)
  258. expect(res.created[1]).toBe(f2)
  259. expect(res.created[2]).toBe(f3)
  260. expect(res.created[3]).toBe(f4)
  261. })
  262. })