state_spec.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. var Vue = require('src')
  2. var _ = require('src/util')
  3. describe('Instance state initialization', function () {
  4. it('should warn data functions that do not return an object', function () {
  5. new Vue({
  6. data: function () {}
  7. })
  8. expect('should return an object').toHaveBeenWarned()
  9. })
  10. it('should initialize data once per strat', function () {
  11. var spyOncePerStrat = jasmine.createSpy('called once per strat')
  12. const VM = Vue.extend({
  13. data: function () {
  14. spyOncePerStrat()
  15. return {
  16. result: 'false'
  17. }
  18. }
  19. })
  20. new VM({
  21. data: function () {
  22. spyOncePerStrat()
  23. return {
  24. result: 'true'
  25. }
  26. }
  27. })
  28. expect(spyOncePerStrat.calls.count()).toBe(2)
  29. })
  30. describe('data proxy', function () {
  31. var data = {
  32. a: 0,
  33. b: 0
  34. }
  35. var vm = new Vue({
  36. data: data
  37. })
  38. it('initial', function () {
  39. expect(vm.a).toBe(data.a)
  40. expect(vm.b).toBe(data.b)
  41. })
  42. it('vm => data', function () {
  43. vm.a = 1
  44. expect(data.a).toBe(1)
  45. expect(vm.a).toBe(data.a)
  46. })
  47. it('data => vm', function () {
  48. data.b = 2
  49. expect(vm.b).toBe(2)
  50. expect(vm.b).toBe(data.b)
  51. })
  52. })
  53. describe('$data', function () {
  54. it('should initialize props', function () {
  55. var vm = new Vue({
  56. el: document.createElement('div'),
  57. props: ['c']
  58. })
  59. expect(_.hasOwn(vm, 'c')).toBe(true)
  60. })
  61. it('external prop should overwrite default value', function () {
  62. var el = document.createElement('div')
  63. el.setAttribute('v-bind:c', '2')
  64. el.textContent = '{{c}}'
  65. var vm = new Vue({
  66. el: el,
  67. props: ['c'],
  68. data: {
  69. c: 1
  70. }
  71. })
  72. expect(vm.c).toBe(2)
  73. expect(el.textContent).toBe('2')
  74. })
  75. it('props should be available in data() and create()', function () {
  76. var el = document.createElement('div')
  77. el.setAttribute(':c', '2')
  78. var vm = new Vue({
  79. el: el,
  80. props: ['c'],
  81. data: function () {
  82. expect(this.c).toBe(2)
  83. return {
  84. d: this.c + 1
  85. }
  86. },
  87. created: function () {
  88. expect(this.c).toBe(2)
  89. }
  90. })
  91. expect(vm.d).toBe(3)
  92. })
  93. it('replace $data', function () {
  94. var vm = new Vue({
  95. data: {
  96. a: 1
  97. }
  98. })
  99. vm.$data = { b: 2 }
  100. // proxy new key
  101. expect(vm.b).toBe(2)
  102. // unproxy old key that's no longer present
  103. expect(_.hasOwn(vm, 'a')).toBe(false)
  104. })
  105. })
  106. describe('computed', function () {
  107. var spyE = jasmine.createSpy('computed e')
  108. var spyF = jasmine.createSpy('cached computed f')
  109. var spyCachedWatcher = jasmine.createSpy('cached computed watcher')
  110. var Test = Vue.extend({
  111. computed: {
  112. // uncached
  113. c: {
  114. cache: false,
  115. get: function () {
  116. return this.a + this.b
  117. }
  118. },
  119. // with setter
  120. d: {
  121. get: function () {
  122. return this.a + this.b
  123. },
  124. set: function (newVal) {
  125. var vals = newVal.split(' ')
  126. this.a = vals[0]
  127. this.b = vals[1]
  128. }
  129. },
  130. // chained computed
  131. e: function () {
  132. return this.c + 'e'
  133. },
  134. // cached
  135. f: {
  136. get: function () {
  137. spyF()
  138. return this.ff
  139. }
  140. },
  141. // chained cached
  142. g: function () {
  143. return this.f + 1
  144. },
  145. // another cached, for watcher test
  146. h: {
  147. get: function () {
  148. return this.hh
  149. }
  150. }
  151. }
  152. })
  153. var vm = new Test({
  154. data: {
  155. a: 'a',
  156. b: 'b',
  157. ff: 0,
  158. hh: 0
  159. },
  160. watch: {
  161. e: spyE,
  162. h: spyCachedWatcher
  163. }
  164. })
  165. it('get', function () {
  166. expect(vm.c).toBe('ab')
  167. expect(vm.d).toBe('ab')
  168. expect(vm.e).toBe('abe')
  169. })
  170. it('set', function (done) {
  171. vm.c = 123 // should do nothing
  172. vm.d = 'c d'
  173. expect(vm.a).toBe('c')
  174. expect(vm.b).toBe('d')
  175. expect(vm.c).toBe('cd')
  176. expect(vm.d).toBe('cd')
  177. expect(vm.e).toBe('cde')
  178. Vue.nextTick(function () {
  179. expect(spyE).toHaveBeenCalledWith('cde', 'abe')
  180. done()
  181. })
  182. })
  183. it('cached computed', function () {
  184. expect(spyF).not.toHaveBeenCalled()
  185. var f = vm.f
  186. var g = vm.g
  187. expect(spyF.calls.count()).toBe(1)
  188. expect(f).toBe(0)
  189. expect(g).toBe(1)
  190. // get again
  191. f = vm.f
  192. g = vm.g
  193. // should not be evaluated again
  194. expect(spyF.calls.count()).toBe(1)
  195. expect(f).toBe(0)
  196. expect(g).toBe(1)
  197. // update dep
  198. vm.ff = 1
  199. f = vm.f
  200. g = vm.g
  201. expect(spyF.calls.count()).toBe(2)
  202. expect(f).toBe(1)
  203. expect(g).toBe(2)
  204. })
  205. it('watching cached computed', function (done) {
  206. expect(spyCachedWatcher).not.toHaveBeenCalled()
  207. vm.hh = 2
  208. Vue.nextTick(function () {
  209. expect(spyCachedWatcher).toHaveBeenCalledWith(2, 0)
  210. done()
  211. })
  212. })
  213. it('same definition object bound to different instance', function () {
  214. var vm = new Test({
  215. data: {
  216. a: 'A',
  217. b: 'B'
  218. }
  219. })
  220. expect(vm.c).toBe('AB')
  221. expect(vm.d).toBe('AB')
  222. vm.d = 'C D'
  223. expect(vm.a).toBe('C')
  224. expect(vm.b).toBe('D')
  225. expect(vm.c).toBe('CD')
  226. expect(vm.d).toBe('CD')
  227. expect(vm.e).toBe('CDe')
  228. })
  229. })
  230. describe('methods', function () {
  231. it('should work and have correct context', function () {
  232. var vm = new Vue({
  233. data: {
  234. a: 1
  235. },
  236. methods: {
  237. test: function () {
  238. expect(this instanceof Vue).toBe(true)
  239. return this.a
  240. }
  241. }
  242. })
  243. expect(vm.test()).toBe(1)
  244. })
  245. })
  246. describe('meta', function () {
  247. var vm = new Vue({
  248. _meta: {
  249. $index: 0,
  250. $value: 'test'
  251. }
  252. })
  253. it('should define metas only on vm', function () {
  254. expect(vm.$index).toBe(0)
  255. expect(vm.$value).toBe('test')
  256. expect('$index' in vm.$data).toBe(false)
  257. expect('$value' in vm.$data).toBe(false)
  258. })
  259. })
  260. })