2
0

compiler-options.spec.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import Vue from 'vue'
  2. import { compile } from 'entries/web-compiler'
  3. import { getAndRemoveAttr } from 'compiler/helpers'
  4. describe('compile options', () => {
  5. it('should be compiled', () => {
  6. const { render, staticRenderFns, errors } = compile(`
  7. <div>
  8. <input type="text" v-model="msg" required max="8" v-validate:field1.group1.group2>
  9. </div>
  10. `, {
  11. directives: {
  12. validate (el, dir) {
  13. if (dir.name === 'validate' && dir.arg) {
  14. el.validate = {
  15. field: dir.arg,
  16. groups: dir.modifiers ? Object.keys(dir.modifiers) : []
  17. }
  18. }
  19. }
  20. },
  21. modules: [{
  22. transformNode (el) {
  23. el.validators = el.validators || []
  24. const validators = ['required', 'min', 'max', 'pattern', 'maxlength', 'minlength']
  25. validators.forEach(name => {
  26. const rule = getAndRemoveAttr(el, name)
  27. if (rule !== undefined) {
  28. el.validators.push({ name, rule })
  29. }
  30. })
  31. },
  32. genData (el) {
  33. let data = ''
  34. if (el.validate) {
  35. data += `validate:${JSON.stringify(el.validate)},`
  36. }
  37. if (el.validators) {
  38. data += `validators:${JSON.stringify(el.validators)},`
  39. }
  40. return data
  41. },
  42. transformCode (el, code) {
  43. // check
  44. if (!el.validate || !el.validators) {
  45. return code
  46. }
  47. // setup validation result props
  48. const result = { dirty: false } // define something other prop
  49. el.validators.forEach(validator => {
  50. result[validator.name] = null
  51. })
  52. // generate code
  53. return `_h('validate',{props:{
  54. field:${JSON.stringify(el.validate.field)},
  55. groups:${JSON.stringify(el.validate.groups)},
  56. validators:${JSON.stringify(el.validators)},
  57. result:${JSON.stringify(result)},
  58. child:${code}}
  59. })`
  60. }
  61. }]
  62. })
  63. expect(render).not.toBeUndefined()
  64. expect(staticRenderFns).toEqual([])
  65. expect(errors).toEqual([])
  66. const renderFn = new Function(render)
  67. const vm = new Vue({
  68. data: {
  69. msg: 'hello'
  70. },
  71. components: {
  72. validate: {
  73. props: ['field', 'groups', 'validators', 'result', 'child'],
  74. render (h) {
  75. return this.child
  76. },
  77. computed: {
  78. valid () {
  79. let ret = true
  80. for (let i = 0; i > this.validators.length; i++) {
  81. const { name } = this.validators[i]
  82. if (!this.result[name]) {
  83. ret = false
  84. break
  85. }
  86. }
  87. return ret
  88. }
  89. },
  90. mounted () {
  91. // initialize validation
  92. const value = this.$el.value
  93. this.validators.forEach(validator => {
  94. const ret = this[validator.name](value, validator.rule)
  95. this.result[validator.name] = ret
  96. })
  97. },
  98. methods: {
  99. // something validators logic
  100. required (val) {
  101. return val.length > 0
  102. },
  103. max (val, rule) {
  104. return !(parseInt(val, 10) > parseInt(rule, 10))
  105. }
  106. }
  107. }
  108. },
  109. render: renderFn,
  110. staticRenderFns
  111. }).$mount()
  112. expect(vm.$el.innerHTML).toBe('<input type="text">')
  113. expect(vm.$children[0].valid).toBe(true)
  114. })
  115. it('should collect errors', () => {
  116. let compiled = compile('hello')
  117. expect(compiled.errors.length).toBe(1)
  118. expect(compiled.errors[0]).toContain('should contain exactly one root element')
  119. compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
  120. expect(compiled.errors.length).toBe(2)
  121. expect(compiled.errors[0]).toContain('invalid expression: v-if="a----"')
  122. expect(compiled.errors[1]).toContain('invalid expression: {{ b++++ }}')
  123. })
  124. })