directive.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. var assert = require('assert'),
  2. Directive = require('../../src/directive'),
  3. directives = require('../../src/directives')
  4. describe('UNIT: Directive', function () {
  5. describe('.parse()', function () {
  6. it('should return null if directive name does not have correct prefix', function () {
  7. var d = Directive.parse('ds-test', 'abc')
  8. assert.ok(d === null)
  9. })
  10. it('should return null if directive is unknown', function () {
  11. var d = Directive.parse('sd-directive-that-does-not-exist', 'abc')
  12. assert.ok(d === null)
  13. })
  14. it('should return null if the expression is invalid', function () {
  15. var d = Directive.parse('sd-text', ''),
  16. e = Directive.parse('sd-text', ' '),
  17. f = Directive.parse('sd-text', '|'),
  18. g = Directive.parse('sd-text', ' | ')
  19. assert.ok(d === null, 'empty')
  20. assert.ok(e === null, 'spaces')
  21. assert.ok(f === null, 'single pipe')
  22. assert.ok(g === null, 'pipe with spaces')
  23. })
  24. it('should return an instance of Directive if args are good', function () {
  25. var d = Directive.parse('sd-text', 'abc')
  26. assert.ok(d instanceof Directive)
  27. })
  28. })
  29. describe('instantiation', function () {
  30. var test = function () {}
  31. directives.test = test
  32. var obj = {
  33. bind: function () {},
  34. update: function () {},
  35. unbind: function () {},
  36. custom: function () {}
  37. }
  38. directives.obj = obj
  39. it('should copy the definition as _update if the def is a function', function () {
  40. var d = Directive.parse('sd-test', 'abc')
  41. assert.ok(d._update === test)
  42. })
  43. it('should copy methods if the def is an object', function () {
  44. var d = Directive.parse('sd-obj', 'abc')
  45. assert.ok(d._update === obj.update, 'update should be copied as _update')
  46. assert.ok(d._unbind === obj.unbind, 'unbind should be copied as _unbind')
  47. assert.ok(d.bind === obj.bind)
  48. assert.ok(d.custom === obj.custom, 'should copy any custom methods')
  49. })
  50. it('should trim the expression', function () {
  51. var exp = ' fsfsef | fsef a ',
  52. d = Directive.parse('sd-text', exp)
  53. assert.ok(d.expression === exp.trim())
  54. })
  55. it('should extract correct argument', function () {
  56. var d = Directive.parse('sd-text', 'todo:todos'),
  57. e = Directive.parse('sd-text', 'todo:todos + abc'),
  58. f = Directive.parse('sd-text', 'todo:todos | fsf fsef')
  59. assert.ok(d.arg === 'todo', 'simple')
  60. assert.ok(e.arg === 'todo', 'expression')
  61. assert.ok(f.arg === 'todo', 'with filters')
  62. })
  63. it('should extract correct nesting info', function () {
  64. var d = Directive.parse('sd-text', 'abc'),
  65. e = Directive.parse('sd-text', '^abc'),
  66. f = Directive.parse('sd-text', '^^^abc'),
  67. g = Directive.parse('sd-text', '$abc')
  68. assert.ok(d.nesting === false && d.root === false && d.key === 'abc', 'no nesting')
  69. assert.ok(e.nesting === 1 && e.root === false && e.key === 'abc', '1 level')
  70. assert.ok(f.nesting === 3 && f.root === false && f.key === 'abc', '3 levels')
  71. assert.ok(g.root === true && g.nesting === false && g.key === 'abc', 'root')
  72. })
  73. it('should be able to determine whether the key is an expression', function () {
  74. var d = Directive.parse('sd-text', 'abc'),
  75. e = Directive.parse('sd-text', '!abc'),
  76. f = Directive.parse('sd-text', 'abc + bcd * 5 / 2'),
  77. g = Directive.parse('sd-text', 'abc && (bcd || eee)'),
  78. h = Directive.parse('sd-text', 'test(abc)')
  79. assert.ok(d.isExp === false)
  80. assert.ok(e.isExp, 'negation')
  81. assert.ok(f.isExp, 'math')
  82. assert.ok(g.isExp, 'logic')
  83. assert.ok(g.isExp, 'function invocation')
  84. })
  85. it('should have a filter prop of null if no filters are present', function () {
  86. var d = Directive.parse('sd-text', 'abc'),
  87. e = Directive.parse('sd-text', 'abc |'),
  88. f = Directive.parse('sd-text', 'abc ||'),
  89. g = Directive.parse('sd-text', 'abc | | '),
  90. h = Directive.parse('sd-text', 'abc | unknown | nothing at all | whaaat')
  91. assert.ok(d.filters === null)
  92. assert.ok(e.filters === null, 'single')
  93. assert.ok(f.filters === null, 'double')
  94. assert.ok(g.filters === null, 'with spaces')
  95. assert.ok(h.filters === null, 'with unknown filters')
  96. })
  97. it('should extract correct filters (single filter)', function () {
  98. var d = Directive.parse('sd-text', 'abc | uppercase'),
  99. f = d.filters[0]
  100. assert.ok(f.name === 'uppercase' && f.args === null)
  101. assert.ok(f.apply('test') === 'TEST')
  102. })
  103. it('should extract correct filters (single filter with args)', function () {
  104. var d = Directive.parse('sd-text', 'abc | pluralize item \'arg with spaces\''),
  105. f = d.filters[0]
  106. assert.ok(f.name === 'pluralize', 'name')
  107. assert.ok(f.args.length === 2, 'args length')
  108. assert.ok(f.args[0] === 'item' && f.args[1] === 'arg with spaces', 'args value')
  109. })
  110. it('should extract correct filters (multiple filters)', function () {
  111. // intentional double pipe
  112. var d = Directive.parse('sd-text', 'abc | uppercase | pluralize item || lowercase'),
  113. f1 = d.filters[0],
  114. f2 = d.filters[1],
  115. f3 = d.filters[2]
  116. assert.ok(d.filters.length === 3)
  117. assert.ok(f1.name === 'uppercase')
  118. assert.ok(f2.name === 'pluralize' && f2.args[0] === 'item')
  119. assert.ok(f3.name === 'lowercase')
  120. })
  121. })
  122. describe('.applyFilters()', function () {
  123. it('should work', function () {
  124. var d = Directive.parse('sd-text', 'abc | pluralize item | capitalize'),
  125. v = d.applyFilters(2)
  126. assert.ok(v === 'Items')
  127. })
  128. })
  129. describe('.apply()', function () {
  130. var test,
  131. applyTest = function (val) { test = val }
  132. directives.applyTest = applyTest
  133. it('should invole the _update function', function () {
  134. var d = Directive.parse('sd-applyTest', 'abc')
  135. d.apply(12345)
  136. assert.ok(test === 12345)
  137. })
  138. it('should apply the filter if there is any', function () {
  139. var d = Directive.parse('sd-applyTest', 'abc | currency £')
  140. d.apply(12345)
  141. assert.ok(test === '£123,45.00')
  142. })
  143. })
  144. describe('.update()', function () {
  145. var d = Directive.parse('sd-text', 'abc'),
  146. applied = false
  147. d.apply = function () {
  148. applied = true
  149. }
  150. it('should apply() for first time update, even if the value is undefined', function () {
  151. d.update(undefined, true)
  152. assert.ok(applied === true)
  153. })
  154. it('should apply() when a different value is given', function () {
  155. applied = false
  156. d.update(123)
  157. assert.ok(d.value === 123 && applied === true)
  158. })
  159. it('should not apply() if the value is the same', function () {
  160. applied = false
  161. d.update(123)
  162. assert.ok(!applied)
  163. })
  164. })
  165. describe('.refresh()', function () {
  166. var d = Directive.parse('sd-text', 'abc'),
  167. applied = false,
  168. el = 1, vm = 2,
  169. value = {
  170. get: function (ctx) {
  171. return ctx.el + ctx.vm
  172. }
  173. }
  174. d.el = el
  175. d.vm = vm
  176. d.apply = function () {
  177. applied = true
  178. }
  179. d.refresh(value)
  180. it('should set the value if value arg is given', function () {
  181. assert.ok(d.value === value)
  182. })
  183. it('should get its el&vm context and get correct computedValue', function () {
  184. assert.ok(d.computedValue === el + vm)
  185. })
  186. it('should call apply()', function () {
  187. assert.ok(applied)
  188. })
  189. it('should not call apply() if computedValue is the same', function () {
  190. applied = false
  191. d.refresh()
  192. assert.ok(!applied)
  193. })
  194. })
  195. describe('.unbind()', function () {
  196. var d = Directive.parse('sd-text', 'abc'),
  197. unbound = false,
  198. val
  199. d._unbind = function (v) {
  200. val = v
  201. unbound = true
  202. }
  203. it('should not work if it has no element yet', function () {
  204. d.unbind()
  205. assert.ok(unbound === false)
  206. })
  207. it('should call _unbind() if it has an element', function () {
  208. d.el = true
  209. d.unbind(true)
  210. assert.ok(unbound === true)
  211. // should not null everything unless it's an update
  212. assert.ok(d.el && d.vm)
  213. })
  214. it('should null everything if it\'s called for VM destruction', function () {
  215. d.unbind()
  216. assert.ok(d.el === null && d.vm === null && d.binding === null && d.compiler === null)
  217. })
  218. })
  219. })