utils.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. describe('Utils', function () {
  2. var utils = require('vue/src/utils'),
  3. config = require('vue/src/config')
  4. try {
  5. require('non-existent')
  6. } catch (e) {
  7. // testing require fail
  8. // for code coverage
  9. }
  10. describe('get', function () {
  11. it('should get value', function () {
  12. var obj = { a: { b: { c: 123 }}}
  13. assert.strictEqual(utils.get(obj, 'a.b.c'), 123)
  14. })
  15. it('should return undefined if path does not exist', function () {
  16. var obj = { a: {}}
  17. assert.strictEqual(utils.get(obj, 'a.b.c'), undefined)
  18. })
  19. })
  20. describe('set', function () {
  21. it('should set value', function () {
  22. var obj = { a: { b: { c: 0 }}}
  23. utils.set(obj, 'a.b.c', 123)
  24. assert.strictEqual(obj.a.b.c, 123)
  25. })
  26. it('should set even if path does not exist', function () {
  27. var obj = {}
  28. utils.set(obj, 'a.b.c', 123)
  29. assert.strictEqual(obj.a.b.c, 123)
  30. })
  31. })
  32. describe('hash', function () {
  33. it('should return an Object with null prototype', function () {
  34. var hash = utils.hash()
  35. assert.strictEqual(Object.getPrototypeOf(hash), null)
  36. })
  37. })
  38. describe('attr', function () {
  39. var el = document.createElement('div'),
  40. testAttr = 'transition',
  41. full = 'v-' + testAttr
  42. el.setAttribute (full, 'test')
  43. it('should append the prefix and return the attribute value', function () {
  44. var val = utils.attr(el, testAttr)
  45. assert.strictEqual(val, 'test')
  46. })
  47. it('should remove the attribute', function () {
  48. assert.notOk(el.hasAttribute(full))
  49. })
  50. it('should work with different prefix', function () {
  51. Vue.config({ prefix: 'test' })
  52. var el = document.createElement('div')
  53. el.setAttribute('test-' + testAttr, 'test')
  54. var val = utils.attr(el, testAttr)
  55. assert.strictEqual(val, 'test')
  56. assert.notOk(el.hasAttribute('test-' + testAttr))
  57. Vue.config({ prefix: 'v' })
  58. })
  59. })
  60. describe('defProtected', function () {
  61. it('should define a protected property', function () {
  62. var a = {}
  63. utils.defProtected(a, 'test', 1)
  64. var keys = []
  65. for (var key in a) {
  66. keys.push(key)
  67. }
  68. assert.strictEqual(keys.length, 0, 'inenumerable')
  69. assert.strictEqual(JSON.stringify(a), '{}', 'unstringifiable')
  70. a.test = 2
  71. assert.strictEqual(a.test, 1, 'unconfigurable')
  72. })
  73. it('should take enumerable option', function () {
  74. var a = {}
  75. utils.defProtected(a, 'test', 1, true)
  76. var keys = []
  77. for (var key in a) {
  78. keys.push(key)
  79. }
  80. assert.strictEqual(keys.length, 1, 'enumerable')
  81. assert.strictEqual(keys[0], 'test')
  82. assert.strictEqual(JSON.stringify(a), '{"test":1}', 'stringifiable')
  83. })
  84. })
  85. describe('typeOf', function () {
  86. it('should return correct type', function () {
  87. var tof = utils.typeOf
  88. assert.equal(tof({}), 'Object')
  89. assert.equal(tof([]), 'Array')
  90. assert.equal(tof(1), 'Number')
  91. assert.equal(tof(''), 'String')
  92. assert.equal(tof(true), 'Boolean')
  93. // phantomjs weirdness
  94. assert.ok(tof(null) === 'Null' || tof(null) === 'DOMWindow')
  95. assert.ok(tof(undefined) === 'Undefined' || tof(undefined) === 'DOMWindow')
  96. })
  97. })
  98. describe('toText', function () {
  99. var txt = utils.toText
  100. it('should do nothing for strings, numbers and booleans', function () {
  101. assert.strictEqual(txt('hihi'), 'hihi')
  102. assert.strictEqual(txt(123), 123)
  103. assert.strictEqual(txt(true), true)
  104. assert.strictEqual(txt(false), false)
  105. })
  106. it('should output empty string if value is not string or number', function () {
  107. assert.strictEqual(txt(undefined), '')
  108. assert.strictEqual(txt(null), '')
  109. assert.strictEqual(txt(NaN), '')
  110. })
  111. it('should stringify value if is object', function () {
  112. assert.strictEqual(txt({foo:"bar"}), '{"foo":"bar"}')
  113. })
  114. })
  115. describe('extend', function () {
  116. it('should extend the obj with extension obj', function () {
  117. var a = {a: 1}, b = {a: {}, b: 2}
  118. utils.extend(a, b)
  119. assert.strictEqual(a.a, b.a)
  120. assert.strictEqual(a.b, b.b)
  121. })
  122. it('should respect the protective option', function () {
  123. var a = {a: 1}, b = {a: {}, b: 2}
  124. utils.extend(a, b, true)
  125. assert.strictEqual(a.a, 1)
  126. assert.strictEqual(a.b, b.b)
  127. })
  128. it('should always return the extended object', function () {
  129. var a = {a: 1}, b = {a: {}, b: 2}
  130. assert.strictEqual(a, utils.extend(a, b))
  131. assert.strictEqual(a, utils.extend(a, undefined))
  132. })
  133. })
  134. describe('unique', function () {
  135. it('should filter an array with duplicates into unqiue ones', function () {
  136. var arr = [1, 2, 3, 1, 2, 3, 4, 5],
  137. res = utils.unique(arr),
  138. l = res.length
  139. assert.strictEqual(l, 5)
  140. while (l--) {
  141. assert.strictEqual(res[l], 5 - l)
  142. }
  143. })
  144. })
  145. describe('bind', function () {
  146. it('should bind the right context', function () {
  147. function test () {
  148. return this + 1
  149. }
  150. var bound = utils.bind(test, 2)
  151. assert.strictEqual(bound(), 3)
  152. })
  153. })
  154. describe('toFragment', function () {
  155. it('should convert a string tempalte to a documentFragment', function () {
  156. var template = '<div class="a">hi</div><p>ha</p>',
  157. frag = utils.toFragment(template)
  158. assert.ok(frag instanceof window.DocumentFragment)
  159. assert.equal(frag.querySelector('.a').textContent, 'hi')
  160. assert.equal(frag.querySelector('p').textContent, 'ha')
  161. })
  162. it('should also work if the string is an ID selector', function () {
  163. var id = 'utils-template-to-fragment',
  164. template = '<div class="a">hi</div><p>ha</p>',
  165. el = document.createElement('template')
  166. el.id = id
  167. el.innerHTML = template
  168. document.getElementById('test').appendChild(el)
  169. var frag = utils.toFragment('#' + id)
  170. assert.ok(frag instanceof window.DocumentFragment)
  171. assert.equal(frag.querySelector('.a').textContent, 'hi')
  172. assert.equal(frag.querySelector('p').textContent, 'ha')
  173. })
  174. })
  175. describe('toConstructor', function () {
  176. it('should convert an non-VM object to a VM constructor', function () {
  177. var a = { test: 1 },
  178. A = utils.toConstructor(a)
  179. assert.ok(A.prototype instanceof Vue)
  180. assert.strictEqual(A.options, a)
  181. })
  182. it('should return the argument if it is already a consutructor', function () {
  183. var A = utils.toConstructor(Vue)
  184. assert.strictEqual(A, Vue)
  185. })
  186. })
  187. describe('processOptions', function () {
  188. var options = {
  189. partials: {
  190. a: '#utils-template-to-fragment',
  191. b: '<div class="a">hi</div><p>ha</p>'
  192. },
  193. components: {
  194. a: { data: { data: 1 } },
  195. b: { data: { data: 2 } }
  196. },
  197. template: '<a>{{hi}}</a>'
  198. }
  199. it('should convert string partials to fragment nodes', function () {
  200. // call it here
  201. utils.processOptions(options)
  202. var partials = options.partials
  203. for (var key in partials) {
  204. var frag = partials[key]
  205. assert.ok(frag instanceof window.DocumentFragment)
  206. assert.equal(frag.querySelector('.a').textContent, 'hi')
  207. assert.equal(frag.querySelector('p').textContent, 'ha')
  208. }
  209. })
  210. it('should convert string template to fragment node', function () {
  211. assert.ok(options.template instanceof window.DocumentFragment)
  212. assert.equal(options.template.querySelector('a').textContent, '{{hi}}')
  213. })
  214. it('should convert plain object components & elements to constructors', function () {
  215. var components = options.components
  216. assert.ok(components.a.prototype instanceof Vue)
  217. assert.strictEqual(components.a.options.data.data, 1)
  218. assert.ok(components.b.prototype instanceof Vue)
  219. assert.strictEqual(components.b.options.data.data, 2)
  220. })
  221. })
  222. describe('log', function () {
  223. if (!window.console) return
  224. it('should only log in debug mode', function () {
  225. // overwrite log temporarily
  226. var oldLog = console.log,
  227. logged
  228. console.log = function (msg) {
  229. logged = msg
  230. }
  231. utils.log('123')
  232. assert.notOk(logged)
  233. config.debug = true
  234. utils.log('123')
  235. assert.strictEqual(logged, '123')
  236. // teardown
  237. config.debug = false
  238. console.log = oldLog
  239. })
  240. })
  241. describe('warn', function () {
  242. if (!window.console) return
  243. it('should only warn when not in silent mode', function () {
  244. config.silent = true
  245. var oldWarn = console.warn,
  246. warned
  247. console.warn = function (msg) {
  248. warned = msg
  249. }
  250. utils.warn('123')
  251. assert.notOk(warned)
  252. config.silent = false
  253. utils.warn('123')
  254. assert.strictEqual(warned, '123')
  255. console.warn = oldWarn
  256. })
  257. it('should also trace in debug mode', function () {
  258. config.silent = false
  259. config.debug = true
  260. var oldTrace = console.trace,
  261. oldWarn = console.warn,
  262. traced
  263. console.warn = function () {}
  264. console.trace = function () {
  265. traced = true
  266. }
  267. utils.warn('testing trace')
  268. assert.ok(traced)
  269. config.silent = true
  270. config.debug = false
  271. console.trace = oldTrace
  272. console.warn = oldWarn
  273. })
  274. })
  275. describe('addClass', function () {
  276. var el = document.createElement('div')
  277. it('should work', function () {
  278. utils.addClass(el, 'hihi')
  279. assert.strictEqual(el.className, 'hihi')
  280. utils.addClass(el, 'hi')
  281. assert.strictEqual(el.className, 'hihi hi')
  282. })
  283. it('should not add duplicate', function () {
  284. utils.addClass(el, 'hi')
  285. assert.strictEqual(el.className, 'hihi hi')
  286. })
  287. })
  288. describe('removeClass', function () {
  289. it('should work', function () {
  290. var el = document.createElement('div')
  291. el.className = 'hihi hi ha'
  292. utils.removeClass(el, 'hi')
  293. assert.strictEqual(el.className, 'hihi ha')
  294. utils.removeClass(el, 'ha')
  295. assert.strictEqual(el.className, 'hihi')
  296. })
  297. })
  298. })