2
0

node.spec.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. import {
  2. compileAndStringify,
  3. prepareRuntime,
  4. resetRuntime,
  5. createInstance,
  6. syncPromise,
  7. checkRefresh
  8. } from '../helpers/index'
  9. describe('node in render function', () => {
  10. let runtime
  11. beforeAll(() => {
  12. runtime = prepareRuntime()
  13. })
  14. afterAll(() => {
  15. resetRuntime()
  16. runtime = null
  17. })
  18. it('should be generated', () => {
  19. const instance = createInstance(runtime, `
  20. new Vue({
  21. render: function (createElement) {
  22. return createElement('div', {}, [
  23. createElement('text', { attrs: { value: 'Hello' }}, [])
  24. ])
  25. },
  26. el: "body"
  27. })
  28. `)
  29. expect(instance.getRealRoot()).toEqual({
  30. type: 'div',
  31. children: [
  32. { type: 'text', attr: { value: 'Hello' }}
  33. ]
  34. })
  35. })
  36. it('should be generated with all types of text', () => {
  37. const instance = createInstance(runtime, `
  38. new Vue({
  39. render: function (createElement) {
  40. return createElement('div', {}, [
  41. createElement('text', { attrs: { value: 'Hello' }}, []),
  42. 'World',
  43. createElement('text', {}, ['Weex'])
  44. ])
  45. },
  46. el: "body"
  47. })
  48. `)
  49. expect(instance.getRealRoot()).toEqual({
  50. type: 'div',
  51. children: [
  52. { type: 'text', attr: { value: 'Hello' }},
  53. { type: 'text', attr: { value: 'World' }},
  54. { type: 'text', attr: { value: 'Weex' }}
  55. ]
  56. })
  57. })
  58. it('should be generated with comments', () => {
  59. // todo
  60. })
  61. it('should be generated with module diff', (done) => {
  62. const instance = createInstance(runtime, `
  63. new Vue({
  64. data: {
  65. counter: 0
  66. },
  67. methods: {
  68. foo: function () {}
  69. },
  70. render: function (createElement) {
  71. switch (this.counter) {
  72. case 1:
  73. return createElement('div', {}, [
  74. createElement('text', { attrs: { value: 'World' }}, [])
  75. ])
  76. case 2:
  77. return createElement('div', {}, [
  78. createElement('text', { attrs: { value: 'World' }, style: { fontSize: 100 }}, [])
  79. ])
  80. case 3:
  81. return createElement('div', {}, [
  82. createElement('text', {
  83. attrs: { value: 'World' },
  84. style: { fontSize: 100 },
  85. on: { click: this.foo }
  86. }, [])
  87. ])
  88. case 4:
  89. return createElement('div', {}, [
  90. createElement('text', {
  91. attrs: { value: 'Weex' },
  92. style: { color: '#ff0000' }
  93. }, [])
  94. ])
  95. default:
  96. return createElement('div', {}, [
  97. createElement('text', { attrs: { value: 'Hello' }}, [])
  98. ])
  99. }
  100. },
  101. el: "body"
  102. })
  103. `)
  104. expect(instance.getRealRoot()).toEqual({
  105. type: 'div',
  106. children: [
  107. { type: 'text', attr: { value: 'Hello' }}
  108. ]
  109. })
  110. syncPromise([
  111. checkRefresh(instance, { counter: 1 }, result => {
  112. expect(result).toEqual({
  113. type: 'div',
  114. children: [
  115. { type: 'text', attr: { value: 'World' }}
  116. ]
  117. })
  118. }),
  119. checkRefresh(instance, { counter: 2 }, result => {
  120. expect(result).toEqual({
  121. type: 'div',
  122. children: [
  123. { type: 'text', attr: { value: 'World' }, style: { fontSize: 100 }}
  124. ]
  125. })
  126. }),
  127. checkRefresh(instance, { counter: 3 }, result => {
  128. expect(result).toEqual({
  129. type: 'div',
  130. children: [
  131. { type: 'text', attr: { value: 'World' }, style: { fontSize: 100 }, event: ['click'] }
  132. ]
  133. })
  134. }),
  135. checkRefresh(instance, { counter: 4 }, result => {
  136. expect(result).toEqual({
  137. type: 'div',
  138. children: [
  139. { type: 'text', attr: { value: 'Weex' }, style: { fontSize: '', color: '#ff0000' }}
  140. ]
  141. })
  142. done()
  143. })
  144. ])
  145. })
  146. it('should be generated with sub components', () => {
  147. const instance = createInstance(runtime, `
  148. new Vue({
  149. render: function (createElement) {
  150. return createElement('div', {}, [
  151. createElement('text', { attrs: { value: 'Hello' }}, []),
  152. createElement('foo', { props: { x: 'Weex' }})
  153. ])
  154. },
  155. components: {
  156. foo: {
  157. props: {
  158. x: { default: 'World' }
  159. },
  160. render: function (createElement) {
  161. return createElement('text', { attrs: { value: this.x }}, [])
  162. }
  163. }
  164. },
  165. el: "body"
  166. })
  167. `)
  168. expect(instance.getRealRoot()).toEqual({
  169. type: 'div',
  170. children: [
  171. { type: 'text', attr: { value: 'Hello' }},
  172. { type: 'text', attr: { value: 'Weex' }}
  173. ]
  174. })
  175. })
  176. it('should be generated with if/for diff', (done) => {
  177. const { render, staticRenderFns } = compileAndStringify(`
  178. <div>
  179. <text v-for="item in list" v-if="item.x">{{item.v}}</text>
  180. </div>
  181. `)
  182. const instance = createInstance(runtime, `
  183. new Vue({
  184. data: {
  185. list: [
  186. { v: 'Hello', x: true },
  187. { v: 'World', x: false },
  188. { v: 'Weex', x: true }
  189. ]
  190. },
  191. computed: {
  192. x: {
  193. get: function () { return 0 },
  194. set: function (v) {
  195. switch (v) {
  196. case 1:
  197. this.list[1].x = true
  198. break
  199. case 2:
  200. this.list.push({ v: 'v-if' })
  201. break
  202. case 3:
  203. this.list.push({ v: 'v-for', x: true })
  204. break
  205. case 4:
  206. this.list.splice(1, 2)
  207. break
  208. }
  209. }
  210. }
  211. },
  212. render: ${render},
  213. staticRenderFns: ${staticRenderFns},
  214. el: "body"
  215. })
  216. `)
  217. expect(instance.getRealRoot()).toEqual({
  218. type: 'div',
  219. children: [
  220. { type: 'text', attr: { value: 'Hello' }},
  221. { type: 'text', attr: { value: 'Weex' }}
  222. ]
  223. })
  224. syncPromise([
  225. checkRefresh(instance, { x: 1 }, result => {
  226. expect(result).toEqual({
  227. type: 'div',
  228. children: [
  229. { type: 'text', attr: { value: 'Hello' }},
  230. { type: 'text', attr: { value: 'World' }},
  231. { type: 'text', attr: { value: 'Weex' }}
  232. ]
  233. })
  234. }),
  235. checkRefresh(instance, { x: 2 }, result => {
  236. expect(result).toEqual({
  237. type: 'div',
  238. children: [
  239. { type: 'text', attr: { value: 'Hello' }},
  240. { type: 'text', attr: { value: 'World' }},
  241. { type: 'text', attr: { value: 'Weex' }}
  242. ]
  243. })
  244. }),
  245. checkRefresh(instance, { x: 3 }, result => {
  246. expect(result).toEqual({
  247. type: 'div',
  248. children: [
  249. { type: 'text', attr: { value: 'Hello' }},
  250. { type: 'text', attr: { value: 'World' }},
  251. { type: 'text', attr: { value: 'Weex' }},
  252. { type: 'text', attr: { value: 'v-for' }}
  253. ]
  254. })
  255. }),
  256. checkRefresh(instance, { x: 4 }, result => {
  257. expect(result).toEqual({
  258. type: 'div',
  259. children: [
  260. { type: 'text', attr: { value: 'Hello' }},
  261. { type: 'text', attr: { value: 'v-for' }}
  262. ]
  263. })
  264. done()
  265. })
  266. ])
  267. })
  268. it('should be generated with node structure diff', (done) => {
  269. const instance = createInstance(runtime, `
  270. new Vue({
  271. data: {
  272. counter: 0
  273. },
  274. render: function (createElement) {
  275. switch (this.counter) {
  276. case 1:
  277. return createElement('div', {}, [
  278. createElement('text', { attrs: { value: 'Hello' }}, []),
  279. createElement('text', { attrs: { value: 'World' }}, [])
  280. ])
  281. case 2:
  282. return createElement('div', {}, [
  283. createElement('text', { attrs: { value: 'Hello' }}, []),
  284. createElement('text', { attrs: { value: 'World' }}, []),
  285. createElement('text', { attrs: { value: 'Weex' }}, [])
  286. ])
  287. case 3:
  288. return createElement('div', {}, [
  289. createElement('text', { attrs: { value: 'Hello' }}, []),
  290. createElement('text', { attrs: { value: 'Weex' }}, [])
  291. ])
  292. case 4:
  293. return createElement('div', {}, [
  294. createElement('text', { attrs: { value: 'Weex' }}, [])
  295. ])
  296. case 5:
  297. return createElement('div', {}, [
  298. createElement('text', { attrs: { value: 'Hello' }}, []),
  299. createElement('text', { attrs: { value: 'Weex' }}, [])
  300. ])
  301. case 6:
  302. return createElement('div', {}, [
  303. createElement('input', { attrs: { value: 'Hello' }}, []),
  304. createElement('text', { attrs: { value: 'Weex' }}, [])
  305. ])
  306. default:
  307. return createElement('div', {}, [
  308. createElement('text', { attrs: { value: 'Hello' }}, []),
  309. ])
  310. }
  311. },
  312. el: "body"
  313. })
  314. `)
  315. expect(instance.getRealRoot()).toEqual({
  316. type: 'div',
  317. children: [
  318. { type: 'text', attr: { value: 'Hello' }}
  319. ]
  320. })
  321. syncPromise([
  322. checkRefresh(instance, { counter: 1 }, result => {
  323. expect(result).toEqual({
  324. type: 'div',
  325. children: [
  326. { type: 'text', attr: { value: 'Hello' }},
  327. { type: 'text', attr: { value: 'World' }}
  328. ]
  329. })
  330. }),
  331. checkRefresh(instance, { counter: 2 }, result => {
  332. expect(result).toEqual({
  333. type: 'div',
  334. children: [
  335. { type: 'text', attr: { value: 'Hello' }},
  336. { type: 'text', attr: { value: 'World' }},
  337. { type: 'text', attr: { value: 'Weex' }}
  338. ]
  339. })
  340. }),
  341. checkRefresh(instance, { counter: 3 }, result => {
  342. expect(result).toEqual({
  343. type: 'div',
  344. children: [
  345. { type: 'text', attr: { value: 'Hello' }},
  346. { type: 'text', attr: { value: 'Weex' }}
  347. ]
  348. })
  349. }),
  350. checkRefresh(instance, { counter: 4 }, result => {
  351. expect(result).toEqual({
  352. type: 'div',
  353. children: [
  354. { type: 'text', attr: { value: 'Weex' }}
  355. ]
  356. })
  357. }),
  358. checkRefresh(instance, { counter: 5 }, result => {
  359. expect(result).toEqual({
  360. type: 'div',
  361. children: [
  362. { type: 'text', attr: { value: 'Hello' }},
  363. { type: 'text', attr: { value: 'Weex' }}
  364. ]
  365. })
  366. }),
  367. checkRefresh(instance, { counter: 6 }, result => {
  368. expect(result).toEqual({
  369. type: 'div',
  370. children: [
  371. { type: 'input', attr: { value: 'Hello' }},
  372. { type: 'text', attr: { value: 'Weex' }}
  373. ]
  374. })
  375. done()
  376. })
  377. ])
  378. })
  379. it('should be generated with component diff', (done) => {
  380. const instance = createInstance(runtime, `
  381. new Vue({
  382. data: {
  383. counter: 0
  384. },
  385. components: {
  386. foo: {
  387. props: { a: { default: '1' }, b: { default: '2' }},
  388. render: function (createElement) {
  389. return createElement('text', { attrs: { value: this.a + '-' + this.b }}, [])
  390. }
  391. },
  392. bar: {
  393. render: function (createElement) {
  394. return createElement('text', { attrs: { value: 'Bar' }, style: { fontSize: 100 }})
  395. }
  396. },
  397. baz: {
  398. render: function (createElement) {
  399. return createElement('image', { attrs: { src: 'http://example.com/favicon.ico' }})
  400. }
  401. }
  402. },
  403. render: function (createElement) {
  404. switch (this.counter) {
  405. case 1:
  406. return createElement('div', {}, [
  407. createElement('foo', { props: { a: '111', b: '222' }}, [])
  408. ])
  409. case 2:
  410. return createElement('div', {}, [
  411. createElement('foo', {}, [])
  412. ])
  413. case 3:
  414. return createElement('div', {}, [
  415. createElement('bar', {}, [])
  416. ])
  417. case 4:
  418. return createElement('div', {}, [
  419. createElement('baz', {}, [])
  420. ])
  421. case 5:
  422. return createElement('div', {}, [
  423. createElement('foo', {}, []),
  424. createElement('bar', {}, []),
  425. createElement('baz', {}, [])
  426. ])
  427. default:
  428. return createElement('div', {}, [
  429. createElement('foo', { props: { a: '111' }}, [])
  430. ])
  431. }
  432. },
  433. el: "body"
  434. })
  435. `)
  436. expect(instance.getRealRoot()).toEqual({
  437. type: 'div',
  438. children: [
  439. { type: 'text', attr: { value: '111-2' }}
  440. ]
  441. })
  442. syncPromise([
  443. checkRefresh(instance, { counter: 1 }, result => {
  444. expect(result).toEqual({
  445. type: 'div',
  446. children: [
  447. { type: 'text', attr: { value: '111-222' }}
  448. ]
  449. })
  450. }),
  451. checkRefresh(instance, { counter: 2 }, result => {
  452. expect(result).toEqual({
  453. type: 'div',
  454. children: [
  455. { type: 'text', attr: { value: '1-2' }}
  456. ]
  457. })
  458. }),
  459. checkRefresh(instance, { counter: 3 }, result => {
  460. expect(result).toEqual({
  461. type: 'div',
  462. children: [
  463. { type: 'text', attr: { value: 'Bar' }, style: { fontSize: 100 }}
  464. ]
  465. })
  466. }),
  467. checkRefresh(instance, { counter: 4 }, result => {
  468. expect(result).toEqual({
  469. type: 'div',
  470. children: [
  471. { type: 'image', attr: { src: 'http://example.com/favicon.ico' }}
  472. ]
  473. })
  474. }),
  475. checkRefresh(instance, { counter: 5 }, result => {
  476. expect(result).toEqual({
  477. type: 'div',
  478. children: [
  479. { type: 'text', attr: { value: '1-2' }},
  480. { type: 'text', attr: { value: 'Bar' }, style: { fontSize: 100 }},
  481. { type: 'image', attr: { src: 'http://example.com/favicon.ico' }}
  482. ]
  483. })
  484. done()
  485. })
  486. ])
  487. })
  488. })