scope_spec.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. var Vue = require('../../../../src/vue')
  2. describe('Instance Scope', function () {
  3. describe('data proxy', function () {
  4. var data = {
  5. a: 0,
  6. b: 0
  7. }
  8. var vm = new Vue({
  9. data: data
  10. })
  11. it('initial', function () {
  12. expect(vm.a).toBe(data.a)
  13. expect(vm.b).toBe(data.b)
  14. })
  15. it('vm => data', function () {
  16. vm.a = 1
  17. expect(data.a).toBe(1)
  18. expect(vm.a).toBe(data.a)
  19. })
  20. it('data => vm', function () {
  21. data.b = 2
  22. expect(vm.b).toBe(2)
  23. expect(vm.b).toBe(data.b)
  24. })
  25. })
  26. describe('$data', function () {
  27. it('should initialize props', function () {
  28. var vm = new Vue({
  29. el: document.createElement('div'),
  30. props: ['c']
  31. })
  32. expect(vm.hasOwnProperty('c')).toBe(true)
  33. })
  34. it('should use default prop value if prop not provided', function () {
  35. var vm = new Vue({
  36. el: document.createElement('div'),
  37. props: ['c'],
  38. data: {
  39. c: 1
  40. }
  41. })
  42. expect(vm.c).toBe(1)
  43. })
  44. it('external prop should overwrite default value', function () {
  45. var el = document.createElement('div')
  46. el.setAttribute('c', '2')
  47. el.textContent = '{{c}}'
  48. var vm = new Vue({
  49. el: el,
  50. props: ['c'],
  51. data: {
  52. c: 1
  53. }
  54. })
  55. expect(vm.c).toBe(2)
  56. expect(el.textContent).toBe('2')
  57. })
  58. it('props should be available in data() and create()', function () {
  59. var el = document.createElement('div')
  60. el.setAttribute('c', '2')
  61. var vm = new Vue({
  62. el: el,
  63. props: ['c'],
  64. data: function () {
  65. expect(this.c).toBe(2)
  66. expect(this._data.c).toBe(2)
  67. return {
  68. d: this.c + 1
  69. }
  70. },
  71. created: function () {
  72. expect(this.c).toBe(2)
  73. expect(this._data.c).toBe(2)
  74. }
  75. })
  76. expect(vm.d).toBe(3)
  77. })
  78. it('replace $data', function () {
  79. var vm = new Vue({
  80. data: {
  81. a: 1
  82. }
  83. })
  84. vm.$data = { b: 2 }
  85. // proxy new key
  86. expect(vm.b).toBe(2)
  87. // unproxy old key that's no longer present
  88. expect(vm.hasOwnProperty('a')).toBe(false)
  89. })
  90. it('replace $data and handle props', function () {
  91. var el = document.createElement('div')
  92. var vm = new Vue({
  93. el: el,
  94. template: '<test a="{{a}}" b="{{*b}}" c="{{@c}}"></test>',
  95. data: {
  96. a: 1,
  97. b: 2,
  98. c: 3
  99. },
  100. components: {
  101. test: {
  102. props: ['a', 'b', 'c', 'd'],
  103. data: function () {
  104. return {
  105. a: null // should be overwritten
  106. }
  107. }
  108. }
  109. }
  110. })
  111. var child = vm.$children[0]
  112. expect(child.a).toBe(1)
  113. expect(child.b).toBe(2)
  114. expect(child.c).toBe(3)
  115. // test new data without prop fields:
  116. // should just copy
  117. child.$data = {}
  118. expect(child.a).toBe(1)
  119. expect(child.b).toBe(2)
  120. expect(child.c).toBe(3)
  121. // test new data with value:
  122. child.$data = {
  123. a: 2, // one-way
  124. b: 3, // one-time
  125. c: 4 // two-way
  126. }
  127. expect(child.a).toBe(2)
  128. expect(child.b).toBe(3)
  129. expect(child.c).toBe(4)
  130. // assert parent state
  131. // one-way
  132. expect(vm.a).toBe(1)
  133. // one-time
  134. expect(vm.b).toBe(2)
  135. // two-way
  136. expect(vm.c).toBe(4)
  137. })
  138. })
  139. describe('computed', function () {
  140. var spyE = jasmine.createSpy('computed e')
  141. var spyF = jasmine.createSpy('cached computed f')
  142. var spyCachedWatcher = jasmine.createSpy('cached computed watcher')
  143. var Test = Vue.extend({
  144. computed: {
  145. c: function () {
  146. return this.a + this.b
  147. },
  148. d: {
  149. get: function () {
  150. return this.a + this.b
  151. },
  152. set: function (newVal) {
  153. var vals = newVal.split(' ')
  154. this.a = vals[0]
  155. this.b = vals[1]
  156. }
  157. },
  158. // chained computed
  159. e: function () {
  160. return this.c + 'e'
  161. },
  162. // cached
  163. f: {
  164. get: function () {
  165. spyF()
  166. return this.ff
  167. }
  168. },
  169. // chained cached
  170. g: function () {
  171. return this.f + 1
  172. },
  173. // another cached, for watcher test
  174. h: {
  175. get: function () {
  176. return this.hh
  177. }
  178. }
  179. }
  180. })
  181. var vm = new Test({
  182. data: {
  183. a: 'a',
  184. b: 'b',
  185. ff: 0,
  186. hh: 0
  187. },
  188. watch: {
  189. e: spyE,
  190. h: spyCachedWatcher
  191. }
  192. })
  193. it('get', function () {
  194. expect(vm.c).toBe('ab')
  195. expect(vm.d).toBe('ab')
  196. expect(vm.e).toBe('abe')
  197. })
  198. it('set', function (done) {
  199. vm.c = 123 // should do nothing
  200. vm.d = 'c d'
  201. expect(vm.a).toBe('c')
  202. expect(vm.b).toBe('d')
  203. expect(vm.c).toBe('cd')
  204. expect(vm.d).toBe('cd')
  205. expect(vm.e).toBe('cde')
  206. Vue.nextTick(function () {
  207. expect(spyE).toHaveBeenCalledWith('cde', 'abe')
  208. done()
  209. })
  210. })
  211. it('inherit', function (done) {
  212. var child = vm.$addChild({
  213. inherit: true
  214. })
  215. expect(child.c).toBe('cd')
  216. child.d = 'e f'
  217. expect(vm.a).toBe('e')
  218. expect(vm.b).toBe('f')
  219. expect(vm.c).toBe('ef')
  220. expect(vm.d).toBe('ef')
  221. expect(vm.e).toBe('efe')
  222. expect(child.a).toBe('e')
  223. expect(child.b).toBe('f')
  224. expect(child.c).toBe('ef')
  225. expect(child.d).toBe('ef')
  226. expect(vm.e).toBe('efe')
  227. Vue.nextTick(function () {
  228. expect(spyE).toHaveBeenCalledWith('efe', 'cde')
  229. done()
  230. })
  231. })
  232. it('cached computed', function () {
  233. expect(spyF).not.toHaveBeenCalled()
  234. var f = vm.f
  235. var g = vm.g
  236. expect(spyF.calls.count()).toBe(1)
  237. expect(f).toBe(0)
  238. expect(g).toBe(1)
  239. // get again
  240. f = vm.f
  241. g = vm.g
  242. // should not be evaluated again
  243. expect(spyF.calls.count()).toBe(1)
  244. expect(f).toBe(0)
  245. expect(g).toBe(1)
  246. // update dep
  247. vm.ff = 1
  248. f = vm.f
  249. g = vm.g
  250. expect(spyF.calls.count()).toBe(2)
  251. expect(f).toBe(1)
  252. expect(g).toBe(2)
  253. })
  254. it('watching cached computed', function (done) {
  255. expect(spyCachedWatcher).not.toHaveBeenCalled()
  256. vm.hh = 2
  257. Vue.nextTick(function () {
  258. expect(spyCachedWatcher).toHaveBeenCalledWith(2, 0)
  259. done()
  260. })
  261. })
  262. it('same definition object bound to different instance', function () {
  263. var vm = new Test({
  264. data: {
  265. a: 'A',
  266. b: 'B'
  267. }
  268. })
  269. expect(vm.c).toBe('AB')
  270. expect(vm.d).toBe('AB')
  271. vm.d = 'C D'
  272. expect(vm.a).toBe('C')
  273. expect(vm.b).toBe('D')
  274. expect(vm.c).toBe('CD')
  275. expect(vm.d).toBe('CD')
  276. expect(vm.e).toBe('CDe')
  277. })
  278. it('disable cache', function () {
  279. var external = { b: 'B' }
  280. var vm = new Vue({
  281. data: {
  282. a: 'A'
  283. },
  284. computed: {
  285. test: {
  286. cache: false,
  287. get: function () {
  288. return this.a + external.b
  289. }
  290. }
  291. }
  292. })
  293. expect(vm.test).toBe('AB')
  294. external.b = 'C'
  295. expect(vm.test).toBe('AC')
  296. })
  297. })
  298. describe('methods', function () {
  299. it('should work and have correct context', function () {
  300. var vm = new Vue({
  301. data: {
  302. a: 1
  303. },
  304. methods: {
  305. test: function () {
  306. expect(this instanceof Vue).toBe(true)
  307. return this.a
  308. }
  309. }
  310. })
  311. expect(vm.test()).toBe(1)
  312. var child = vm.$addChild({
  313. inherit: true
  314. })
  315. expect(child.test()).toBe(1)
  316. })
  317. })
  318. describe('meta', function () {
  319. var vm = new Vue({
  320. _meta: {
  321. $index: 0,
  322. $value: 'test'
  323. }
  324. })
  325. it('should define metas only on vm', function () {
  326. expect(vm.$index).toBe(0)
  327. expect(vm.$value).toBe('test')
  328. expect('$index' in vm.$data).toBe(false)
  329. expect('$value' in vm.$data).toBe(false)
  330. })
  331. })
  332. })