state_spec.js 6.0 KB

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