UNPKG

14.1 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <meta http-equiv="X-UA-Compatible" content="ie=edge">
7 <title>Mount and Render</title>
8 <link href="https://unpkg.com/mocha@4.0.1/mocha.css" rel="stylesheet" />
9 <link rel="stylesheet" href="/test/styles.css">
10 <link rel="icon" type="image/png" href="/resources/favicon-16x16.png" sizes="16x16" />
11 <link rel="icon" type="image/png" href="/resources/favicon-32x32.png" sizes="32x32" />
12</head>
13<body>
14 <nav onclick="location.pathname='/test/index.html'">
15 <h1>Mocha Tests - Composi mount, render &amp; unmount Functions</h1>
16 </nav>
17 <section>
18 <div id="mocha"></div>
19 <div id="messages"></div>
20 <div id="fixtures"></div>
21 <div id="hide-tests">
22 <div id='h1-test'></div>
23 <div id="list-test"></div>
24 <div id="alert-test"></div>
25 <div id="render-test"></div>
26 <div id="unmount"></div>
27 <div id="lifecycle"></div>
28 <div id="hydrate">
29 <ul id="listToHydrate">
30 <li>One</li>
31 <li>Two</li>
32 </ul>
33 </div>
34 </div>
35 </section>
36
37 <script src="https://unpkg.com/mocha@4.0.1/mocha.js"></script>
38 <script src="https://unpkg.com/chai@4.1.2/chai.js"></script>
39 <script src='/dist/composi.js'></script>
40 <script>mocha.setup('bdd')</script>
41 <script>
42 const {h, mount, unmount, render} = composi
43 let expect = chai.expect
44
45 function H1(){
46 return h('h1', {id: 'title'}, 'The Title')
47 }
48
49 mount(H1(), '#h1-test')
50
51 function List() {
52 return h('ul', {class: 'list'},[
53 h('li', {}, 'one'),
54 h('li', {}, 'two'),
55 h('li', {}, 'three')
56 ])
57 }
58 mount(List(), '#list-test')
59
60 function Alert(message) {
61 return h('h2', {style: {color: 'red'}} , `Alert: ${message}!`)
62 }
63 mount(Alert('this is a message'), '#alert-test')
64
65 const things = [
66 {name: 'Apple', key: 101},
67 {name: 'Chair', key: 102},
68 {name: 'Horse', key: 103}
69 ]
70 function List2(data) {
71 return h(
72 'ul',
73 {},
74 data.map(item => h('li', {key: item.key}, item.name))
75 )
76 }
77 let vNode = List2(things)
78 let list2 = mount(List2(things), '#render-test')
79
80 setTimeout(() => {
81 things.push({name: 'Popcorn', key: 104})
82 vNode = List2(things)
83 list2 = render(List2(things), list2, '#render-test')
84 }, 3000)
85
86 describe('Create virtual node for list', function() {
87 it('virtual node should have three children', function() {
88 expect(vNode.children.length).to.equal(3)
89 })
90 it('virtual node children should equal "Apple", "Chair" and "Horse"', function() {
91 expect(vNode.children[0].children[0].type).to.equal('Apple')
92 expect(vNode.children[1].children[0].type).to.equal('Chair')
93 expect(vNode.children[2].children[0].type).to.equal('Horse')
94 })
95 it('virtual node children should have following keys: "101", "102", "103"', function() {
96 expect(vNode.children[0].key).to.equal(101)
97 expect(vNode.children[1].key).to.equal(102)
98 expect(vNode.children[2].key).to.equal(103)
99 })
100 })
101
102 describe("Mount h1", function() {
103 const title = document.querySelector('#title')
104 it('title should be "h1"', function() {
105 expect(title.nodeName).to.equal('H1')
106 });
107 it('title should have id equal to "title"', function() {
108 expect(title.id).to.equal('title')
109 })
110 it('title content should be "The Title"', function() {
111 expect(title.textContent).to.equal('The Title')
112 })
113 it('Mounted component element should have property "isMounted"', function() {
114 expect(title.isMounted).to.equal(true)
115 })
116 })
117 describe('Mount list', function() {
118 const list = document.querySelector('ul')
119 it('list should be of type "UL"', function() {
120 expect(list.nodeName).to.equal('UL')
121 })
122 it('list should have class of "list"', function() {
123 expect(list.className).to.equal('list')
124 })
125 it('list should have three children', function() {
126 expect(list.childNodes).to.have.lengthOf(3)
127 })
128 it('list item one should be type "LI"', function() {
129 expect(list.childNodes[0].nodeName).to.equal('LI')
130 })
131 it('list 1 item content should be "one"', function() {
132 expect(list.childNodes[0].textContent).to.equal('one')
133 })
134 it('list 2 item content should be "two"', function() {
135 expect(list.childNodes[1].textContent).to.equal('two')
136 })
137 it('list 3 item content should be "three"', function() {
138 expect(list.childNodes[2].textContent).to.equal('three')
139 })
140 })
141
142 describe('Mount alert', function() {
143 const alert = document.querySelector('h2')
144 it('alert should be of type "H2"', function() {
145 expect(alert.nodeName).to.equal('H2')
146 })
147 it('alert content should be "Alert: this is a message!"', function() {
148 expect(alert.textContent).to.equal("Alert: this is a message!")
149 })
150 it('alert should have style of "color: red"', function() {
151 expect(alert.style.color).to.equal('red')
152 })
153 })
154
155 describe('Hydrate existing DOM node using mount function', function() {
156 const listToHydrate = document.querySelector('#listToHydrate')
157 function hydrateTheList() {
158 return (
159 h(
160 'ul',
161 {
162 id: 'listToHydrate'
163 },
164 [
165 h(
166 'li',
167 {key: 101},
168 ['Apple']
169 ),
170 h(
171 'li',
172 {key: 102},
173 ['Orange']
174 ),
175 h(
176 'li',
177 {key: 103},
178 ['Banana']
179 )
180 ]
181 )
182 )
183 }
184
185 it('The list to hydrate should have an id of "listToHydrate"', function() {
186 expect(listToHydrate.id).to.equal('listToHydrate')
187 })
188
189 it('The list to hydrate should have two children', function() {
190 expect(listToHydrate.children.length).to.equal(2)
191 })
192
193 it('The list to hydrate should have children with content of "One" and "Two"', function() {
194 expect(listToHydrate.children[0].textContent).to.equal('One')
195 expect(listToHydrate.children[1].textContent).to.equal('Two')
196 })
197
198 it('The hydrated list should have three children', function(done) {
199 setTimeout(() => {
200 mount(hydrateTheList(), '#hydrate', '#listToHydrate')
201 const hydratedList = document.querySelector('#listToHydrate')
202 expect(hydratedList.children.length).to.equal(3)
203 }, 1500)
204 done()
205 })
206
207 it('The hydrated list should have and id of "hydratedList"', function(done) {
208 setTimeout(() => {
209 const hydratedList = document.querySelector('#listToHydrate')
210 expect(hydratedList.id).to.equal('listToHydrate')
211 }, 1000)
212 done()
213 })
214
215 it('The hydrated list should contain "Apple", "Orange", "Banana"', function(done) {
216 setTimeout(() => {
217 const hydratedList = document.querySelector('#listToHydrate')
218 expect(hydratedList.children[0].textContent).to.equal('Apple')
219 expect(hydratedList.children[1].textContent).to.equal('Orange')
220 expect(hydratedList.children[2].textContent).to.equal('Banana')
221 }, 2500)
222 done()
223 }, 2500)
224 })
225
226 describe('Mount list to update later', function() {
227 const list = document.querySelector('#render-test ul')
228
229 it('should have just three children', function() {
230 expect(list.children.length).to.equal(3)
231 })
232 it('list items should contain "Apple", "Chair" and "Horse"', function() {
233 expect(list.children[0].textContent).to.equal('Apple')
234 expect(list.children[1].textContent).to.equal('Chair')
235 expect(list.children[2].textContent).to.equal('Horse')
236 })
237
238 })
239
240 describe('Update list with render function', function() {
241 it('list virtual node should have four children', function(done) {
242 setTimeout(() => {
243 expect(vNode.children.length).to.equal(4)
244 }, 3000)
245 done()
246 })
247 it('list virtual node now have four items"', function(done) {
248 setTimeout(() => {
249 expect(vNode.children.length).to.equal(4)
250 }, 3000)
251 done()
252 })
253 const list = document.querySelector('#render-test ul')
254 it('virtual node children should be "Apple", "Chair", "Horse" and "Popcorn', function(done) {
255 setTimeout(() => {
256 expect(vNode.children[0].children[0].type).to.equal('Apple')
257 expect(vNode.children[1].children[0].type).to.equal('Chair')
258 expect(vNode.children[2].children[0].type).to.equal('Horse')
259 expect(vNode.children[3].children[0].type).to.equal('Popcorn')
260 }, 3000)
261 done()
262 })
263 it('virtual node children keys should be "101", "102", "103", "104"', function(done) {
264 setTimeout(() => {
265 expect(vNode.children[0].key).to.equal(101)
266 expect(vNode.children[1].key).to.equal(102)
267 expect(vNode.children[2].key).to.equal(103)
268 expect(vNode.children[3].key).to.equal(104)
269 }, 3000)
270 done()
271 })
272 it('DOM list should have four list items', function(done) {
273 setTimeout(() => {
274 expect(list.children.length).to.equal(4)
275 }, 3000)
276 done()
277 })
278 it('DOM list items should contain "Apple", "Chair", "Horse" and "Popcorn"', function(done) {
279 setTimeout(() => {
280 expect(list.children[0].textContent).to.equal('Apple')
281 expect(list.children[1].textContent).to.equal('Chair')
282 expect(list.children[2].textContent).to.equal('Horse')
283 expect(list.children[3].textContent).to.equal('Popcorn')
284 }, 3000)
285 done()
286 })
287 })
288
289 describe('Component should execute thee lifecycle hooks', function() {
290 let componentDidMount = false
291 let componentDidUpdate = false
292 let componentDidUnmount = false
293 let unmountedComponents = 0
294 function LifecycleTest(data) {
295 function testMount() {
296 componentDidMount = true
297 }
298 function testUpdate() {
299 componentDidUpdate = true
300 unmountedComponents += 1
301 }
302 function testUnmount(done, el) {
303 componentDidUnmount = true
304 done()
305 }
306 function listItems(items) {
307 console.log(items)
308 return items.map(item => h('li', {onunmount: (done, el) => testUnmount(done, el)}, item))
309 }
310 return (
311 h(
312 'ul',
313 {
314 onmount: () => {
315 testMount()
316 },
317 onupdate: () => {
318 testUpdate()
319 }
320 },
321 listItems(data)
322 )
323 )
324 }
325 let testComponent = mount(LifecycleTest([1,2]), '#lifecycle')
326
327 it('Functional component should execute "onmount" when it is mounted', function(done) {
328 setTimeout(() => {
329 expect(componentDidMount).to.be.true
330 expect(testComponent.children.length).to.equal(2)
331 }, 1000)
332 done()
333 })
334 it('Functional component should execute "onupdate" when it is updated', function(done) {
335 setTimeout(() => {
336 testComponent = render(LifecycleTest([1,2,3]), testComponent, '#lifecycle')
337 expect(componentDidUpdate).to.be.true
338 expect(testComponent.children.length).to.equal(3)
339 }, 1500)
340 done()
341 })
342 it('List component\'s list items should execute "onunmount" when they are deleted', function(done) {
343 setTimeout(() => {
344 testComponent = render(LifecycleTest([1]), testComponent, '#lifecycle')
345 expect(componentDidUnmount).to.be.true
346 expect(testComponent.children.length).to.equal(1)
347 expect(unmountedComponents).to.equal(2)
348 }, 2000)
349 done()
350 })
351 })
352
353 describe('Component should mount, unmount, mount again and update with render function', function() {
354 function MountTest(props) {
355 return (
356 h(
357 'p',
358 {
359 id: 'unmountBase',
360 },
361 props.message
362 )
363 )
364 }
365 let mountTest = mount(MountTest({ id: 'unmountBase', message: 'whatever'}), '#unmount')
366 let mountTestContainer = document.querySelector('#unmount')
367
368 it('Component should be mounted.', function() {
369 expect(mountTest.element.nodeType).to.equal(1)
370 expect(mountTest.element.id).to.equal('unmountBase')
371 expect(mountTest.element.isMounted).to.equal(true)
372 expect(mountTestContainer.textContent).to.equal('whatever')
373 })
374 it('Unmount should remove component from DOM', function(done) {
375 setTimeout(() => {
376 unmount(mountTest)
377 expect(mountTestContainer.children.length).to.equal(0)
378 expect(mountTest.element).to.equal(null)
379 }, 1000)
380 done()
381 })
382 it('Should be able to re-mount unmounted component', function(done) {
383 setTimeout(() => {
384 mountTest = mount(MountTest({ id: 'unmountBase', message: 'new message' }), '#unmount')
385 expect(mountTest.element.nodeType).to.equal(1)
386 expect(mountTest.element.id).to.equal('unmountBase')
387 expect(mountTest.element.isMounted).to.equal(true)
388 expect(mountTestContainer.textContent).to.equal('new message')
389 }, 2000)
390 done()
391 })
392 it('Should be able to use render to update re-mounted component', function (done) {
393 setTimeout(() => {
394 mountTest = render(MountTest({ id: 'unmountBase', message: 'updated message' }), mountTest, '#unmount')
395 expect(mountTestContainer.textContent).to.equal('updated message')
396 }, 3000)
397 done()
398 })
399 })
400 mocha.run()
401 </script>
402</body>
403</html>
\No newline at end of file