UNPKG

20 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>Document</title>
8 <link href="https://unpkg.com/mocha@4.0.1/mocha.css" rel="stylesheet" />
9 <link rel="stylesheet" href="/test/styles.css">
10</head>
11<body>
12 <nav onclick="location.pathname='/test/index.html'">
13 <h1>Mocha Tests - Composi Component Class</h1>
14 </nav>
15 <section>
16 <div id="mocha"></div>
17 <div id="messages"></div>
18 <div id="fixtures"></div>
19 <div id="hide-tests">
20 <div id='h1-test'></div>
21 <div id="list1-test"></div>
22 <div id="list2-test"></div>
23 <div id="list3-test"></div>
24 <div id="boolean-props"></div>
25 </div>
26 </section>
27
28 <script src='/dist/composi.js'></script>
29 <script src="https://unpkg.com/mocha@4.0.1/mocha.js"></script>
30 <script src="https://unpkg.com/chai@4.1.2/chai.js"></script>
31 <script>mocha.setup('bdd')</script>
32 <script>
33
34 const {h, Component} = composi
35 let should = chai.should()
36 let expect = chai.expect
37 let assert = chai.assert
38
39 describe('Create Component Instance', function() {
40 let componentDidMount = false;
41 const h1 = new Component({
42 render: data => h('h1', {style: {backgroundColor: '#000', color: '#fff'}}, `Hello, ${data}!`),
43 container: '#h1-test',
44 componentDidMount: () => {componentDidMount = true}
45 })
46 h1.update('World')
47 const h1El = document.querySelector('#h1-test h1')
48
49 it('Component container should be "#h1-test"', function() {
50 expect(h1.container.id).to.equal('h1-test')
51 })
52 it('Component element should exist', function() {
53 should.exist(h1.element)
54 })
55 it('Component element should be "h1"', function() {
56 expect(h1.element.nodeName).to.equal('H1')
57 })
58 it("Component render function should be \"data => h('h1', {style: {backgroundColor: '#000', color: '#fff'}}, `Hello, ${data}!`)\"", function() {
59 expect(h1.render.toString()).to.equal("data => h('h1', {style: {backgroundColor: '#000', color: '#fff'}}, `Hello, ${data}!`)")
60 })
61 it('Component lifecycle method "componentDidMount" should have run', function() {
62 expect(componentDidMount).to.equal(true)
63 })
64 it('Element created by component should be "h1"', function() {
65 expect(h1El.nodeName).to.equal('H1')
66 })
67 it('H1 element content should be "Hello, World!"', function() {
68 expect(h1El.textContent.trim()).to.equal('Hello, World!')
69 })
70 it('H1 element background color should be "#000"', function() {
71 expect(h1El.style.backgroundColor).to.equal('rgb(0, 0, 0)')
72 })
73 it('H1 element color should be "#fff"', function() {
74 expect(h1El.style.color).to.equal('rgb(255, 255, 255)')
75 })
76 it('Running update method on component with new data, H1 content should be "Hello, Joe Bodoni!"', function(done) {
77 setTimeout(function() {
78 h1.update('Joe Bodoni')
79 expect(h1El.textContent.trim()).to.equal('Hello, Joe Bodoni!')
80 },1000)
81 done()
82 })
83 })
84
85 describe('Create Extended Component without State', function() {
86 let componentDidMount = false;
87 class List extends Component {
88 render(data) {
89 return h('ul', {class:'list'},
90 data.map(item => h('li', {}, item))
91 )
92 }
93 componentDidMount() {
94 componentDidMount = true
95 }
96 }
97 const list = new List({
98 container: '#list1-test'
99 })
100 window.list = list
101 list.update(['Apples', 'Oranges', 'Bananas'])
102
103 it('Component mounted property should be true', function() {
104 expect(list.mounted).to.equal(true)
105 })
106 it('Component lifecycle method "componentDidMount" should have run', function() {
107 expect(componentDidMount).to.equal(true)
108 })
109 it('Component container should be "#list1-test"', function() {
110 expect(list.container.id).to.equal('list1-test')
111 })
112 it('Component element should be "ul"', function() {
113 expect(list.element.nodeName).to.equal('UL')
114 })
115 it('Component selector should be "#list1-test"', function() {
116 expect(list.selector).to.equal('#list1-test')
117 })
118 it('Component should have no state', function() {
119 expect(list.state).to.equal(undefined)
120 })
121 let listEl = document.querySelector('#list1-test ul')
122 it('Element created by component should be "ul"', function() {
123 expect(listEl.nodeName).to.equal('UL')
124 })
125 it('Element should have class of "list"', function() {
126 expect(listEl.className).to.equal('list')
127 })
128 it('Element should have three childen', function() {
129 expect(listEl.children).to.have.lengthOf(3)
130 })
131 it('First list item should contain "Apples"', function() {
132 expect(listEl.children[0].textContent.trim()).to.equal('Apples')
133 })
134 it('Last list item should contain "Bananas"', function() {
135 expect(listEl.children[2].textContent.trim()).to.equal('Bananas')
136 })
137 it('On update, list should have four children', function(done) {
138 setTimeout(function() {
139 list.update(['Apples', 'Oranges', 'Bananas', 'Grapes'])
140 expect(listEl.children).to.have.lengthOf(4)
141 }, 1000)
142 done()
143 })
144 it('On update, last list item should contain "Grapes"', function(done) {
145 setTimeout(function() {
146 expect(listEl.children[3].textContent.trim()).to.equal('Grapes')
147 }, 1000)
148 done()
149 })
150 it('On unmount, list should be removed from DOM', function(done) {
151 setTimeout(function() {
152 list.unmount()
153 const container = document.querySelector('#list1-test')
154 listEl = document.querySelector('#list1-test ul')
155 should.not.exist(listEl)
156 expect(container.children).to.have.lengthOf(0)
157 }, 1000)
158 done()
159 })
160 })
161
162 describe('Create Extended Component with State', function() {
163 let componentWillMount = false
164 let componentDidMount = false
165 let componentWillUpdate = false
166 let componentDidUpdate = false
167 let componentWillUnmount = false
168 const veggies = ['Potatoes', 'Tomatoes', 'Carrots', 'Peas']
169 class List extends Component {
170 constructor(props) {
171 super(props)
172 this.container = '#list2-test'
173 this.state = veggies
174 }
175 render(data) {
176 return h('ul', {class:'list'},
177 data.map(item => h('li', {title:item}, item))
178 )
179 }
180 componentWillMount() {
181 componentWillMount = true
182 }
183 componentDidMount() {
184 componentDidMount = true
185 }
186 componentWillUpdate() {
187 componentWillUpdate = true
188 }
189 componentDidUpdate() {
190 componentDidUpdate = true
191 }
192 componentWillUnmount() {
193 componentWillUnmount = true
194 }
195 }
196 const list2 = new List()
197 window.list2 = list2
198 let listEl
199 setTimeout(() => {
200 listEl = document.querySelector('#list2-test ul')
201 }, 100)
202
203 it('Component lifecycle method "componentDidMount" should run before component is created', function(done) {
204 setTimeout(() => {
205 expect(componentWillMount).to.equal(true)
206 }, 100)
207 done()
208 })
209 it('Component should mount when instantiated because it has state', function() {
210 const listEl = document.querySelector('#list1-test ul')
211 should.exist(listEl)
212 })
213 it('Component lifecycle method "componentDidMount" should have run', function(done) {
214 setTimeout(function() {
215 expect(componentDidMount).to.equal(true)
216 }, 100)
217 done()
218 })
219 it('Component mounted property should be true', function(done) {
220 setTimeout(() => {
221 expect(list2.mounted).to.equal(true)
222 }, 100)
223 done()
224 })
225 it('Component container should be "#list2-test"', function(done) {
226 setTimeout(function() {
227 expect(list2.container.id).to.equal('list2-test')
228 }, 100)
229 done()
230 })
231 it('Component element should be "ul"', function(done) {
232 setTimeout(function() {
233 expect(list2.element.nodeName).to.equal('UL')
234 }, 100)
235 done()
236 })
237 it('Component selector should be "#list2-test"', function(done) {
238 setTimeout(function() {
239 expect(list2.selector).to.equal('#list2-test')
240 }, 100)
241 done()
242 })
243 it('Component should have state', function(done) {
244 setTimeout(function() {
245 should.exist(list2.state)
246 }, 100)
247 done()
248 })
249 it('Component state show have 4 items', function(done) {
250 setTimeout(function() {
251 expect(list2.state).to.have.lengthOf(4)
252 }, 100)
253 done()
254 })
255 it('Component state should equal "Potatoes Tomatoes Carrots Peas"', function(done) {
256 setTimeout(function() {
257 expect(list2.state.join(' ')).to.equal("Potatoes Tomatoes Carrots Peas")
258 }, 100)
259 done()
260 })
261 it('Element created by component should be "ul"', function(done) {
262 setTimeout(function() {
263 expect(listEl.nodeName).to.equal('UL')
264 }, 100)
265 done()
266 })
267 it('Element should have class of "list"', function(done) {
268 setTimeout(function() {
269 expect(listEl.className).to.equal('list')
270 }, 100)
271 done()
272 })
273 it('Element should have three childen', function(done) {
274 setTimeout(function() {
275 expect(listEl.children).to.have.lengthOf(4)
276 }, 100)
277 done()
278 })
279 it('First list item should contain "Potatoes"', function(done) {
280 setTimeout(function() {
281 expect(listEl.children[0].textContent.trim()).to.equal('Potatoes')
282 }, 100)
283 done()
284 })
285 it('Last list item should contain "Peas"', function(done) {
286 setTimeout(function() {
287 expect(listEl.children[3].textContent.trim()).to.equal('Peas')
288 }, 100)
289 done()
290 })
291 it('List items should have title attribute', function(done) {
292 setTimeout(function() {
293 const items = Array.prototype.slice.apply(listEl.children)
294 items.map((item, idx) => {
295 should.exist(item.title)
296 expect(item.title).to.equal(veggies[idx])
297 })
298 }, 100)
299 done()
300 })
301
302
303 it('On update, list should have four children', function(done) {
304 setTimeout(function() {
305 list2.setState('Onions', list2.state.length)
306 expect(listEl.children).to.have.lengthOf(4)
307 }, 300)
308 done()
309 })
310 it('On update, last list item should contain "Onions"', function(done) {
311 setTimeout(function() {
312 expect(listEl.children[4].textContent.trim()).to.equal('Onions')
313 }, 400)
314 done()
315 })
316
317
318
319 it('Component lifecycle methods "componentWillUpdate" and "componentDidUpdate" should run when component state is updated', function(done) {
320 setTimeout(function(){
321 list2.setState('Lettuce', list2.state.length)
322 setTimeout(() => {
323 expect(componentWillUpdate).to.equal(true)
324 expect(componentDidUpdate).to.equal(true)
325 expect(list2.state[5]).to.equal('Lettuce')
326 }, 1000)
327 }, 1100)
328 done()
329 })
330
331 it('On unmount, "componentWillUnmount" lifecyle method should run and list should be removed from DOM', function(done) {
332 setTimeout(function() {
333 list2.unmount()
334 const container = document.querySelector('#list1-test')
335 listEl = document.querySelector('#list2-test ul')
336 expect(componentWillUnmount).to.equal(true)
337 should.not.exist(listEl)
338 expect(container.children).to.have.lengthOf(0)
339 }, 3000)
340 done()
341 })
342
343 })
344
345 describe('Use property dangerouslySetInnerHTML on element to set props using innerHTML without encoding.', function() {
346
347 class Div extends Component {
348 constructor(props) {
349 super(props)
350 this.container = '#list3-test'
351 this.state = true
352 }
353 render(data) {
354 return h(
355 'div',
356 {dangerouslySetInnerHTML: '<div id="dangerous-div">This was set dangerously!</div>'}
357 )
358 }
359 componentDidMount() {
360 console.log(this.element.children[0].id)
361 }
362 }
363 const testDiv = new Div()
364
365 it('Test div should have one child', function(done) {
366 setTimeout(() => {
367 expect(testDiv.element.children.length).to.equal(1)
368 }, 100)
369 done()
370 })
371 it('Test div child should have id of "dangerous-div"', function(done) {
372 setTimeout(() => {
373 expect(testDiv.element.children[0].id).to.equal('dangerous-div')
374 }, 100)
375 done()
376 })
377 it('Test div child should have content of "This was set dangerously!"', function(done) {
378 setTimeout(() => {
379 expect(testDiv.element.children[0].textContent.trim()).to.equal('This was set dangerously!')
380 }, 100)
381 done()
382 })
383 })
384
385 describe('Set properties with boolean values', function() {
386 // #boolean-props
387 class BooleanPropsTest extends Component {
388 render() {
389 return (
390 h('div',
391 {},
392 [
393 h('p', {}, [h('button', {id: 'btn-1', disabled: false})]),
394 h('p', {}, [h('button', {id: 'btn-2', disabled: 'false'})]),
395 h('p', {}, [h('button', {id: 'btn-3', disabled: true})]),
396 h('p', {}, [h('button', {id: 'btn-4', disabled: 'true'})]),
397 h('p', {}, [h('button', {id: 'btn-5', disabled: 1})]),
398 h('p', {}, [h('button', {id: 'btn-6', disabled: '1'})]),
399 h('p', {}, [h('button', {id: 'btn-7', disabled: -1})]),
400 h('p', {}, [h('button', {id: 'btn-8', disabled: '-1'})]),
401 h('p', {}, [h('button', {id: 'btn-9', disabled: 0})]),
402 h('p', {}, [h('button', {id: 'btn-10', disabled: '0'})]),
403 h('p', {class: 'boolean-test', translate: true}),
404 h('p', {class: 'boolean-test', translate: 'true'}),
405 h('p', {class: 'boolean-test', translate: false}),
406 h('p', {class: 'boolean-test', translate: 'false'}),
407 h('p', {class: 'boolean-test', translate: 'yes'}),
408 h('p', {class: 'boolean-test', translate: 'no'}),
409 h('p', {}, [h('input', {class: 'input', autocomplete: 'on'})]),
410 h('p', {}, [h('input', {class: 'input', autocomplete: 'off'})])
411 ])
412 )
413 }
414 componentDidMount() {
415 this.buttons = this.element.querySelectorAll('button')
416 this.booleanTests = this.element.querySelectorAll('.boolean-test')
417 this.inputTests = this.element.querySelectorAll('.input')
418 }
419 }
420 let buttons
421 const booleanPropsTest = new BooleanPropsTest({
422 container: '#boolean-props',
423 state: true
424 })
425 window.booleanPropsTest = booleanPropsTest
426
427 // Disabled tests:
428 it('Button set to "disabled={false}" should not be disabled', function(done) {
429 setTimeout(() => {
430 const prop = booleanPropsTest.buttons[0].disabled
431 expect(prop).to.be.false
432 }, 1000)
433 done()
434 })
435
436 it('Button set to "disabled=\"false\" should not be disabled', function(done) {
437 setTimeout(() => {
438 const prop = booleanPropsTest.buttons[1].disabled
439 expect(prop).to.be.false
440 }, 1000)
441 done()
442 })
443
444 it('Button set to "disabled={true}" should be disabled', function(done) {
445 setTimeout(() => {
446 const prop = booleanPropsTest.buttons[2].disabled
447 expect(prop).to.be.true
448 }, 1000)
449 done()
450 })
451
452 it('Button set to "disabled=\"true\" should be disabled', function(done) {
453 setTimeout(() => {
454 const prop = booleanPropsTest.buttons[3].disabled
455 expect(prop).to.be.true
456 }, 1000)
457 done()
458 })
459 it('Button set to "disabled={1} should be disabled', function(done) {
460 setTimeout(() => {
461 const prop = booleanPropsTest.buttons[4].disabled
462 expect(prop).to.be.true
463 }, 1000)
464 done()
465 })
466 it('Button set to "disabled=\"1\" should be disabled', function(done) {
467 setTimeout(() => {
468 const prop = booleanPropsTest.buttons[5].disabled
469 expect(prop).to.be.true
470 }, 1000)
471 done()
472 })
473 it('Button set to "disabled={-1} should be disabled', function(done) {
474 setTimeout(() => {
475 const prop = booleanPropsTest.buttons[6].disabled
476 expect(prop).to.be.true
477 }, 1000)
478 done()
479 })
480 it('Button set to "disabled=\"-1\" should be disabled', function(done) {
481 setTimeout(() => {
482 const prop = booleanPropsTest.buttons[7].disabled
483 expect(prop).to.be.true
484 }, 1000)
485 done()
486 })
487 it('Button set to "disabled={0} should not be disabled', function(done) {
488 setTimeout(() => {
489 const prop = booleanPropsTest.buttons[8].disabled
490 expect(prop).to.be.false
491 }, 1000)
492 done()
493 })
494 it('Button set to "disabled=\"0\" should be disabled', function(done) {
495 setTimeout(() => {
496 const prop = booleanPropsTest.buttons[9].disabled
497 expect(prop).to.be.true
498 }, 1000)
499 done()
500 })
501
502 // Translate tests:
503 it('Paragraph set to "translate={true} should be true', function(done) {
504 setTimeout(() => {
505 const prop = booleanPropsTest.booleanTests[0].translate
506 expect(prop).to.be.true
507 }, 1000)
508 done()
509 })
510 it('Paragraph set to "translate=\"true\" should be true', function(done) {
511 setTimeout(() => {
512 const prop = booleanPropsTest.booleanTests[1].translate
513 expect(prop).to.be.true
514 }, 1000)
515 done()
516 })
517 it('Paragraph set to "translate={false} should be false', function(done) {
518 setTimeout(() => {
519 const prop = booleanPropsTest.booleanTests[2].translate
520 assert.isOk(prop)
521 }, 1000)
522 done()
523 })
524 it('Paragraph set to "translate=\"false\" should be false', function(done) {
525 setTimeout(() => {
526 const prop = booleanPropsTest.booleanTests[3].translate
527 assert.isOk(prop)
528 }, 1000)
529 done()
530 })
531 it('Paragraph set to "translate=\"on\" should be true', function(done) {
532 setTimeout(() => {
533 const prop = booleanPropsTest.booleanTests[4].translate
534 assert.isOk(prop)
535 }, 1000)
536 done()
537 })
538 it('Paragraph set to "translate=\"off\" should be false', function(done) {
539 setTimeout(() => {
540 const prop = booleanPropsTest.booleanTests[5].translate
541 assert.isNotOk(prop)
542 }, 1000)
543 done()
544 })
545
546
547 // Autocomplete Tests
548 it('Paragraph set to "autocomplete=\"on\" should be true', function(done) {
549 setTimeout(() => {
550 const prop = booleanPropsTest.inputTests[0].autocomplete
551 assert.isOk(prop)
552 }, 1000)
553 done()
554 })
555 it('Paragraph set to "autocomplete=\"off\" should be false', function(done) {
556 setTimeout(() => {
557 const prop = booleanPropsTest.inputTests[1].autocomplete
558 expect(prop).to.equal('off')
559 }, 1000)
560 done()
561 })
562
563
564 })
565
566
567
568 mocha.run()
569 </script>
570</body>
571</html>
\No newline at end of file