observer_spec.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /**
  2. * Test data observation.
  3. */
  4. var Observer = require('../../src/observe/observer')
  5. // internal emitter has fixed 3 arguments
  6. // so we need to fill up the assetions with undefined
  7. var u = undefined
  8. Observer.pathDelimiter = '.'
  9. describe('Observer', function () {
  10. var spy
  11. beforeEach(function () {
  12. spy = jasmine.createSpy('observer')
  13. })
  14. it('get', function () {
  15. Observer.emitGet = true
  16. var obj = {
  17. a: 1,
  18. b: {
  19. c: 2
  20. }
  21. }
  22. var ob = Observer.create(obj)
  23. ob.on('get', spy)
  24. var t = obj.a
  25. expect(spy).toHaveBeenCalledWith('a', u, u)
  26. expect(spy.callCount).toBe(1)
  27. t = obj.b.c
  28. expect(spy).toHaveBeenCalledWith('b', u, u)
  29. expect(spy).toHaveBeenCalledWith('b.c', u, u)
  30. expect(spy.callCount).toBe(3)
  31. Observer.emitGet = false
  32. })
  33. it('set', function () {
  34. var obj = {
  35. a: 1,
  36. b: {
  37. c: 2
  38. }
  39. }
  40. var ob = Observer.create(obj)
  41. ob.on('set', spy)
  42. obj.a = 3
  43. expect(spy).toHaveBeenCalledWith('a', 3, u)
  44. expect(spy.callCount).toBe(1)
  45. obj.b.c = 4
  46. expect(spy).toHaveBeenCalledWith('b.c', 4, u)
  47. expect(spy.callCount).toBe(2)
  48. // swap set
  49. var newB = { c: 5 }
  50. obj.b = newB
  51. expect(spy).toHaveBeenCalledWith('b', newB, u)
  52. expect(spy.callCount).toBe(3)
  53. // same value set should not emit events
  54. obj.a = 3
  55. expect(spy.callCount).toBe(3)
  56. })
  57. it('ignore prefix', function () {
  58. var obj = {
  59. _test: 123,
  60. $test: 234
  61. }
  62. var ob = Observer.create(obj)
  63. ob.on('set', spy)
  64. obj._test = 234
  65. obj.$test = 345
  66. expect(spy.callCount).toBe(0)
  67. })
  68. it('ignore accessors', function () {
  69. var obj = {
  70. a: 123,
  71. get b () {
  72. return this.a
  73. }
  74. }
  75. var ob = Observer.create(obj)
  76. obj.a = 234
  77. expect(obj.b).toBe(234)
  78. })
  79. it('array get', function () {
  80. Observer.emitGet = true
  81. var obj = {
  82. arr: [{a:1}, {a:2}]
  83. }
  84. var ob = Observer.create(obj)
  85. ob.on('get', spy)
  86. var t = obj.arr[0].a
  87. expect(spy).toHaveBeenCalledWith('arr', u, u)
  88. expect(spy).toHaveBeenCalledWith('arr.0.a', u, u)
  89. expect(spy.callCount).toBe(2)
  90. Observer.emitGet = false
  91. })
  92. it('array set', function () {
  93. var obj = {
  94. arr: [{a:1}, {a:2}]
  95. }
  96. var ob = Observer.create(obj)
  97. ob.on('set', spy)
  98. obj.arr[0].a = 2
  99. expect(spy).toHaveBeenCalledWith('arr.0.a', 2, u)
  100. // set events after mutation
  101. obj.arr.reverse()
  102. obj.arr[0].a = 3
  103. expect(spy).toHaveBeenCalledWith('arr.0.a', 3, u)
  104. })
  105. it('array push', function () {
  106. var arr = [{a:1}, {a:2}]
  107. var ob = Observer.create(arr)
  108. ob.on('mutate', spy)
  109. arr.push({a:3})
  110. expect(spy.mostRecentCall.args[0]).toBe('')
  111. expect(spy.mostRecentCall.args[1]).toBe(arr)
  112. var mutation = spy.mostRecentCall.args[2]
  113. expect(mutation).toBeDefined()
  114. expect(mutation.method).toBe('push')
  115. expect(mutation.index).toBe(2)
  116. expect(mutation.removed.length).toBe(0)
  117. expect(mutation.inserted.length).toBe(1)
  118. expect(mutation.inserted[0]).toBe(arr[2])
  119. // test index update after mutation
  120. ob.on('set', spy)
  121. arr[2].a = 4
  122. expect(spy).toHaveBeenCalledWith('2.a', 4, u)
  123. })
  124. it('array pop', function () {
  125. var arr = [{a:1}, {a:2}]
  126. var popped = arr[1]
  127. var ob = Observer.create(arr)
  128. ob.on('mutate', spy)
  129. arr.pop()
  130. expect(spy.mostRecentCall.args[0]).toBe('')
  131. expect(spy.mostRecentCall.args[1]).toBe(arr)
  132. var mutation = spy.mostRecentCall.args[2]
  133. expect(mutation).toBeDefined()
  134. expect(mutation.method).toBe('pop')
  135. expect(mutation.index).toBe(1)
  136. expect(mutation.inserted.length).toBe(0)
  137. expect(mutation.removed.length).toBe(1)
  138. expect(mutation.removed[0]).toBe(popped)
  139. })
  140. it('array shift', function () {
  141. var arr = [{a:1}, {a:2}]
  142. var shifted = arr[0]
  143. var ob = Observer.create(arr)
  144. ob.on('mutate', spy)
  145. arr.shift()
  146. expect(spy.mostRecentCall.args[0]).toBe('')
  147. expect(spy.mostRecentCall.args[1]).toBe(arr)
  148. var mutation = spy.mostRecentCall.args[2]
  149. expect(mutation).toBeDefined()
  150. expect(mutation.method).toBe('shift')
  151. expect(mutation.index).toBe(0)
  152. expect(mutation.inserted.length).toBe(0)
  153. expect(mutation.removed.length).toBe(1)
  154. expect(mutation.removed[0]).toBe(shifted)
  155. // test index update after mutation
  156. ob.on('set', spy)
  157. arr[0].a = 4
  158. expect(spy).toHaveBeenCalledWith('0.a', 4, u)
  159. })
  160. it('array unshift', function () {
  161. var arr = [{a:1}, {a:2}]
  162. var unshifted = {a:3}
  163. var ob = Observer.create(arr)
  164. ob.on('mutate', spy)
  165. arr.unshift(unshifted)
  166. expect(spy.mostRecentCall.args[0]).toBe('')
  167. expect(spy.mostRecentCall.args[1]).toBe(arr)
  168. var mutation = spy.mostRecentCall.args[2]
  169. expect(mutation).toBeDefined()
  170. expect(mutation.method).toBe('unshift')
  171. expect(mutation.index).toBe(0)
  172. expect(mutation.removed.length).toBe(0)
  173. expect(mutation.inserted.length).toBe(1)
  174. expect(mutation.inserted[0]).toBe(unshifted)
  175. // test index update after mutation
  176. ob.on('set', spy)
  177. arr[1].a = 4
  178. expect(spy).toHaveBeenCalledWith('1.a', 4, u)
  179. })
  180. it('array splice', function () {
  181. var arr = [{a:1}, {a:2}]
  182. var inserted = {a:3}
  183. var removed = arr[1]
  184. var ob = Observer.create(arr)
  185. ob.on('mutate', spy)
  186. arr.splice(1, 1, inserted)
  187. expect(spy.mostRecentCall.args[0]).toBe('')
  188. expect(spy.mostRecentCall.args[1]).toBe(arr)
  189. var mutation = spy.mostRecentCall.args[2]
  190. expect(mutation).toBeDefined()
  191. expect(mutation.method).toBe('splice')
  192. expect(mutation.index).toBe(1)
  193. expect(mutation.removed.length).toBe(1)
  194. expect(mutation.inserted.length).toBe(1)
  195. expect(mutation.removed[0]).toBe(removed)
  196. expect(mutation.inserted[0]).toBe(inserted)
  197. // test index update after mutation
  198. ob.on('set', spy)
  199. arr[1].a = 4
  200. expect(spy).toHaveBeenCalledWith('1.a', 4, u)
  201. })
  202. it('array sort', function () {
  203. var arr = [{a:1}, {a:2}]
  204. var ob = Observer.create(arr)
  205. ob.on('mutate', spy)
  206. arr.sort(function (a, b) {
  207. return a.a < b.a ? 1 : -1
  208. })
  209. expect(spy.mostRecentCall.args[0]).toBe('')
  210. expect(spy.mostRecentCall.args[1]).toBe(arr)
  211. var mutation = spy.mostRecentCall.args[2]
  212. expect(mutation).toBeDefined()
  213. expect(mutation.method).toBe('sort')
  214. expect(mutation.index).toBeUndefined()
  215. expect(mutation.removed.length).toBe(0)
  216. expect(mutation.inserted.length).toBe(0)
  217. // test index update after mutation
  218. ob.on('set', spy)
  219. arr[1].a = 4
  220. expect(spy).toHaveBeenCalledWith('1.a', 4, u)
  221. })
  222. it('array reverse', function () {
  223. var arr = [{a:1}, {a:2}]
  224. var ob = Observer.create(arr)
  225. ob.on('mutate', spy)
  226. arr.reverse()
  227. expect(spy.mostRecentCall.args[0]).toBe('')
  228. expect(spy.mostRecentCall.args[1]).toBe(arr)
  229. var mutation = spy.mostRecentCall.args[2]
  230. expect(mutation).toBeDefined()
  231. expect(mutation.method).toBe('reverse')
  232. expect(mutation.index).toBeUndefined()
  233. expect(mutation.removed.length).toBe(0)
  234. expect(mutation.inserted.length).toBe(0)
  235. // test index update after mutation
  236. ob.on('set', spy)
  237. arr[1].a = 4
  238. expect(spy).toHaveBeenCalledWith('1.a', 4, u)
  239. })
  240. it('object.$add', function () {
  241. var obj = {a:{b:1}}
  242. var ob = Observer.create(obj)
  243. ob.on('add', spy)
  244. // add event
  245. var add = {d:2}
  246. obj.a.$add('c', add)
  247. expect(spy).toHaveBeenCalledWith('a.c', add, u)
  248. // check if add object is properly observed
  249. ob.on('set', spy)
  250. obj.a.c.d = 3
  251. expect(spy).toHaveBeenCalledWith('a.c.d', 3, u)
  252. })
  253. it('object.$delete', function () {
  254. var obj = {a:{b:1}}
  255. var ob = Observer.create(obj)
  256. ob.on('delete', spy)
  257. obj.a.$delete('b')
  258. expect(spy).toHaveBeenCalledWith('a.b', u, u)
  259. })
  260. it('array.$set', function () {
  261. var arr = [{a:1}, {a:2}]
  262. var ob = Observer.create(arr)
  263. ob.on('mutate', spy)
  264. var inserted = {a:3}
  265. var removed = arr[1]
  266. arr.$set(1, inserted)
  267. expect(spy.mostRecentCall.args[0]).toBe('')
  268. expect(spy.mostRecentCall.args[1]).toBe(arr)
  269. var mutation = spy.mostRecentCall.args[2]
  270. expect(mutation).toBeDefined()
  271. expect(mutation.method).toBe('splice')
  272. expect(mutation.index).toBe(1)
  273. expect(mutation.removed.length).toBe(1)
  274. expect(mutation.inserted.length).toBe(1)
  275. expect(mutation.removed[0]).toBe(removed)
  276. expect(mutation.inserted[0]).toBe(inserted)
  277. ob.on('set', spy)
  278. arr[1].a = 4
  279. expect(spy).toHaveBeenCalledWith('1.a', 4, u)
  280. })
  281. it('array.$remove', function () {
  282. var arr = [{a:1}, {a:2}]
  283. var ob = Observer.create(arr)
  284. ob.on('mutate', spy)
  285. var removed = arr.$remove(0)
  286. expect(spy.mostRecentCall.args[0]).toBe('')
  287. expect(spy.mostRecentCall.args[1]).toBe(arr)
  288. var mutation = spy.mostRecentCall.args[2]
  289. expect(mutation).toBeDefined()
  290. expect(mutation.method).toBe('splice')
  291. expect(mutation.index).toBe(0)
  292. expect(mutation.removed.length).toBe(1)
  293. expect(mutation.inserted.length).toBe(0)
  294. expect(mutation.removed[0]).toBe(removed)
  295. ob.on('set', spy)
  296. arr[0].a = 3
  297. expect(spy).toHaveBeenCalledWith('0.a', 3, u)
  298. })
  299. })