testRuntime.spec.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import {
  2. h,
  3. render,
  4. nodeOps,
  5. NodeTypes,
  6. TestElement,
  7. TestText,
  8. ref,
  9. reactive,
  10. dumpOps,
  11. resetOps,
  12. NodeOpTypes,
  13. nextTick,
  14. serialize,
  15. triggerEvent
  16. } from '../src'
  17. describe('test renderer', () => {
  18. it('should work', () => {
  19. const root = nodeOps.createElement('div')
  20. render(
  21. h(
  22. 'div',
  23. {
  24. id: 'test'
  25. },
  26. 'hello'
  27. ),
  28. root
  29. )
  30. expect(root.children.length).toBe(1)
  31. const el = root.children[0] as TestElement
  32. expect(el.type).toBe(NodeTypes.ELEMENT)
  33. expect(el.props.id).toBe('test')
  34. expect(el.children.length).toBe(1)
  35. const text = el.children[0] as TestText
  36. expect(text.type).toBe(NodeTypes.TEXT)
  37. expect(text.text).toBe('hello')
  38. })
  39. it('should record ops', async () => {
  40. const state = reactive({
  41. id: 'test',
  42. text: 'hello'
  43. })
  44. const App = {
  45. render() {
  46. return h(
  47. 'div',
  48. {
  49. id: state.id
  50. },
  51. state.text
  52. )
  53. }
  54. }
  55. const root = nodeOps.createElement('div')
  56. resetOps()
  57. render(h(App), root)
  58. const ops = dumpOps()
  59. expect(ops.length).toBe(4)
  60. expect(ops[0]).toEqual({
  61. type: NodeOpTypes.CREATE,
  62. nodeType: NodeTypes.ELEMENT,
  63. tag: 'div',
  64. targetNode: root.children[0]
  65. })
  66. expect(ops[1]).toEqual({
  67. type: NodeOpTypes.PATCH,
  68. targetNode: root.children[0],
  69. propKey: 'id',
  70. propPrevValue: null,
  71. propNextValue: 'test'
  72. })
  73. expect(ops[2]).toEqual({
  74. type: NodeOpTypes.SET_ELEMENT_TEXT,
  75. text: 'hello',
  76. targetNode: root.children[0]
  77. })
  78. expect(ops[3]).toEqual({
  79. type: NodeOpTypes.INSERT,
  80. targetNode: root.children[0],
  81. parentNode: root,
  82. refNode: null
  83. })
  84. // test update ops
  85. state.id = 'foo'
  86. state.text = 'bar'
  87. await nextTick()
  88. const updateOps = dumpOps()
  89. expect(updateOps.length).toBe(2)
  90. expect(updateOps[0]).toEqual({
  91. type: NodeOpTypes.PATCH,
  92. targetNode: root.children[0],
  93. propKey: 'id',
  94. propPrevValue: 'test',
  95. propNextValue: 'foo'
  96. })
  97. expect(updateOps[1]).toEqual({
  98. type: NodeOpTypes.SET_ELEMENT_TEXT,
  99. targetNode: root.children[0],
  100. text: 'bar'
  101. })
  102. })
  103. it('should be able to serialize nodes', () => {
  104. const App = {
  105. render() {
  106. return h(
  107. 'div',
  108. {
  109. id: 'test'
  110. },
  111. [h('span', 'foo'), 'hello']
  112. )
  113. }
  114. }
  115. const root = nodeOps.createElement('div')
  116. render(h(App), root)
  117. expect(serialize(root)).toEqual(
  118. `<div><div id="test"><span>foo</span>hello</div></div>`
  119. )
  120. // indented output
  121. expect(serialize(root, 2)).toEqual(
  122. `<div>
  123. <div id="test">
  124. <span>
  125. foo
  126. </span>
  127. hello
  128. </div>
  129. </div>`
  130. )
  131. })
  132. it('should be able to trigger events', async () => {
  133. const count = ref(0)
  134. const App = () => {
  135. return h(
  136. 'span',
  137. {
  138. onClick: () => {
  139. count.value++
  140. }
  141. },
  142. count.value
  143. )
  144. }
  145. const root = nodeOps.createElement('div')
  146. render(h(App), root)
  147. triggerEvent(root.children[0] as TestElement, 'click')
  148. expect(count.value).toBe(1)
  149. await nextTick()
  150. expect(serialize(root)).toBe(`<div><span>1</span></div>`)
  151. })
  152. })