UNPKG

22.7 kBMarkdownView Raw
1# chai-enzyme
2
3[![npm version](https://img.shields.io/npm/v/chai-enzyme.svg)](https://www.npmjs.com/package/chai-enzyme) [![License](https://img.shields.io/npm/l/chai-enzyme.svg)](https://www.npmjs.com/package/chai-enzyme) [![Build Status](https://travis-ci.org/producthunt/chai-enzyme.svg)](https://travis-ci.org/producthunt/chai-enzyme)
4
5[Chai.js](https://github.com/chaijs/chai) assertions for [enzyme](https://github.com/airbnb/enzyme/).
6
7## Table of Contents
8
9 1. [Installation](#installation)
10 1. [Setup](#setup)
11 1. [Debug output in assertion exceptions](#debug-output-in-assertion-exceptions)
12 1. [Assertions](#assertions)
13 1. [`checked()`](#checked)
14 1. [`className(str)`](#classnamestr)
15 1. [`contain(nodeOrNodes)`](#containnodeornodes)
16 1. [`containMatchingElement(node)`](#containmatchingelementnode)
17 1. [`descendants(selector)`](#descendantsselector)
18 1. [`exactly()`](#exactly)
19 1. [`disabled()`](#disabled)
20 1. [`blank()`](#blank)
21 1. [`present()`](#present)
22 1. [`html(str)`](#htmlstr)
23 1. [`id(str)`](#idstr)
24 1. [`match(selector)`](#matchselector)
25 1. [`ref(key)`](#refkey)
26 1. [`selected()`](#selected)
27 1. [`tagName(str)`](#tagnamestr)
28 1. [`text(str)`](#textstr)
29 1. [`type(func)`](#typefunc)
30 1. [`value(str)`](#valuestr)
31 1. [`attr(key, [val])`](#attrkey-val)
32 1. [`data(key, [val])`](#datakey-val)
33 1. [`style(key, [val])`](#stylekey-val)
34 1. [`state(key, [val])`](#statekey-val)
35 1. [`prop(key, [val])`](#propkey-val)
36 1. [`props(key, [val])`](#propskey-val)
37 1. [Development](#development)
38 1. [Contributing](#contributing)
39 1. [License](#license)
40
41## Installation
42
43`chai-enzyme` depends on:
44
45```js
46"peerDependencies": {
47 "chai": "^3.0.0 || ^4.0.0",
48 "cheerio": "0.19.x || 0.20.x || 0.22.x || ^1.0.0-0",
49 "enzyme": "^2.7.0 || ^3.0.0",
50 "react": "^0.14.0 || ^15.0.0-0 || ^16.0.0-0",
51 "react-dom": "^0.14.0 || ^15.0.0-0 || ^16.0.0-0"
52}
53```
54
55`cheerio` is already a dependency of `enzyme`, so most probably you will not have
56to install it manually
57
58```
59$ npm install chai-enzyme --save-dev
60```
61
62## Setup
63
64```js
65import chai from 'chai'
66import chaiEnzyme from 'chai-enzyme'
67
68chai.use(chaiEnzyme()) // Note the invocation at the end
69```
70
71## Debug output in assertion exceptions
72
73You can also provide a custom debug function that can print useful information
74about the `wrapper` that you are using.
75
76The default one that chai-enzyme comes with, will pretty print the HTML of the
77wrapper under test.
78
79```shell
80 1) #text (text) (shallow): passes when the actual matches the expected:
81 AssertionError: expected <Fixture /> to have text 'Test test', but it has 'Test'
82
83 ---------- this is where the debug output starts ----------
84
85 HTML:
86
87 <span id="child">Test</span>
88
89 ---------- this is where the debug output ends ----------
90```
91
92Here is how you can implement and configure one for yourself:
93
94```js
95function myAwesomeDebug (wrapper) {
96 let html = wrapper.html()
97 // do something cool with the html
98 return html
99}
100
101chai.use(chaiEnzyme(myAwesomeDebug))
102```
103
104## Assertions
105
106It's important to know that all assertions are registered with Chai's `overwrite*`
107methods and therefore this plugin can work next to other Chai.js plugins that have
108similar assertions, such as [chai-jquery](https://github.com/chaijs/chai-jquery).
109
110At the beginning of each assertion, we verify if the provided object is a
111`ShallowWrapper`, `ReactWrapper` or a `cheerio` object and if not we delegate
112to the next assertion that responds to the given method.
113
114Note that not all assertions work with every rendering strategy.
115
116If you are wondering what rendering mechanism to use when, refer to [enzyme's
117documentation](https://github.com/airbnb/enzyme).
118
119#### `checked()`
120
121| render | mount | shallow |
122| -------|-------|-------- |
123| yes | yes | yes |
124
125
126Assert that the given wrapper is checked:
127
128```js
129import React from 'react'
130import {mount, render, shallow} from 'enzyme'
131
132class Fixture extends React.Component {
133 render () {
134 return (
135 <div>
136 <input id='checked' defaultChecked />
137 <input id='not' defaultChecked={false} />
138 </div>
139 )
140 }
141}
142
143const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
144
145expect(wrapper.find('#checked')).to.be.checked()
146expect(wrapper.find('#not')).to.not.be.checked()
147```
148
149#### `className(str)`
150
151| render | mount | shallow |
152| -------|-------|-------- |
153| yes | yes | yes |
154
155
156Assert that the wrapper has a given class:
157
158```js
159import React from 'react'
160import {mount, render, shallow} from 'enzyme'
161
162class Fixture extends React.Component {
163 render () {
164 return (
165 <div className='root top'>
166 <span className='child bottom'>test</span>
167 </div>
168 )
169 }
170}
171
172const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
173
174expect(wrapper.find('span')).to.have.className('child')
175expect(wrapper.find('span')).to.not.have.className('root')
176```
177
178#### `contain(nodeOrNodes)`
179
180| render | mount | shallow |
181| -------|-------|-------- |
182| no | yes | yes |
183
184
185Assert that the wrapper contains a given node or array of nodes:
186
187```js
188import React from 'react'
189import {mount, render, shallow} from 'enzyme'
190import PropTypes from 'prop-types';
191
192class User extends React.Component {
193 render () {
194 return (
195 <span>User {this.props.index}</span>
196 )
197 }
198}
199
200User.propTypes = {
201 index: PropTypes.number.isRequired
202}
203
204class Fixture extends React.Component {
205 render () {
206 return (
207 <div>
208 <ul>
209 <li><User index={1} /></li>
210 <li>
211 <User index={2} />
212 <User index={3} />
213 </li>
214 </ul>
215 </div>
216 )
217 }
218}
219
220const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
221
222expect(wrapper).to.contain(<User index={1} />)
223expect(wrapper).to.contain([<User index={2} />, <User index={3} />])
224expect(wrapper).to.not.contain(<User index={3} />)
225```
226
227#### `containMatchingElement(node)`
228
229| render | mount | shallow |
230| -------|-------|-------- |
231| no | yes | yes |
232
233
234Assert that the wrapper contains a matching given node:
235
236```js
237import React from 'react'
238import {mount, render, shallow} from 'enzyme'
239import PropTypes from 'prop-types';
240
241class User extends React.Component {
242 render () {
243 return (
244 <span>User {this.props.index} {this.props.name}</span>
245 )
246 }
247}
248
249User.propTypes = {
250 index: PropTypes.number,
251 name: PropTypes.string.isRequired
252}
253
254class Fixture extends React.Component {
255 render () {
256 return (
257 <div>
258 <ul>
259 <li><User index={1} name='John' /></li>
260 <li><User index={2} name='Doe' /></li>
261 </ul>
262 </div>
263 )
264 }
265}
266
267const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
268
269expect(wrapper).to.containMatchingElement(<User name='John' />)
270expect(wrapper).to.not.containMatchingElement(<User name='Conor' />)
271```
272
273#### `descendants(selector)`
274
275| render | mount | shallow |
276| -------|-------|-------- |
277| yes | yes | yes |
278
279
280Assert that the wrapper contains a descendant matching the given selector:
281
282```js
283import React from 'react'
284import {mount, render, shallow} from 'enzyme'
285
286class User extends React.Component {
287 render () {
288 return (
289 <span>User</span>
290 )
291 }
292}
293
294class Fixture extends React.Component {
295 render () {
296 return (
297 <div id='root'>
298 <User />
299 </div>
300 )
301 }
302}
303
304const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
305
306expect(wrapper).to.have.descendants('#root')
307expect(wrapper).to.have.descendants(User)
308
309expect(wrapper).to.not.have.descendants('#root1')
310```
311
312#### `exactly()`
313
314| render | mount | shallow |
315| -------|-------|-------- |
316| yes | yes | yes |
317
318
319Assert that the wrapper contains an exact amount of descendants matching the given selector:
320
321```js
322import React from 'react'
323import {mount, render, shallow} from 'enzyme'
324
325class Fixture extends React.Component {
326 render () {
327 return (
328 <div id='root'>
329 <span id='child'>
330 <span class='item'></span>
331 <span class='item'></span>
332 </span>
333 </div>
334 )
335 }
336}
337
338const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
339
340expect(wrapper).to.have.exactly(2).descendants('.item')
341```
342
343#### `disabled()`
344
345| render | mount | shallow |
346| -------|-------|-------- |
347| yes | yes | yes |
348
349
350Assert that the given wrapper is disabled:
351
352```js
353import React from 'react'
354import {mount, render, shallow} from 'enzyme'
355
356class Fixture extends React.Component {
357 render () {
358 return (
359 <div>
360 <input id='disabled' disabled />
361 <input id='not' />
362 </div>
363 )
364 }
365}
366
367const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
368
369expect(wrapper.find('#disabled')).to.be.disabled()
370expect(wrapper.find('#not')).to.not.be.disabled()
371```
372
373#### `blank()`
374
375| render | mount | shallow |
376| -------|-------|-------- |
377| yes | yes | yes |
378
379
380Assert that the given wrapper is empty:
381
382```js
383import React from 'react'
384import {mount, render, shallow} from 'enzyme'
385
386class Fixture extends React.Component {
387 render () {
388 return (
389 <div id='parent'>
390 <div id='child'>
391 </div>
392 </div>
393 )
394 }
395}
396
397const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
398
399expect(wrapper.find('#child')).to.be.blank()
400expect(wrapper.find('#parent')).to.not.be.blank()
401
402expect(wrapper.find('#child')).to.be.empty // an alias
403expect(wrapper.find('#parent')).to.not.be.empty // an alias
404
405class NullFixture extends React.Component {
406 render () {
407 return null
408 }
409}
410
411const nullWrapper = mount(<NullFixture />) // mount/render/shallow when applicable
412
413expect(nullWrapper).to.be.blank()
414expect(nullWrapper).to.be.empty // an alias
415```
416
417#### `present()`
418
419| render | mount | shallow |
420| -------|-------|-------- |
421| yes | yes | yes |
422
423
424Assert that the given wrapper exists:
425
426```js
427import React from 'react'
428import {mount, render, shallow} from 'enzyme'
429
430class Fixture extends React.Component {
431 render () {
432 return (
433 <div id='parent'></div>
434 )
435 }
436}
437
438const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
439
440expect(wrapper.find('#parent')).to.be.present()
441expect(wrapper.find('#parent')).to.exist // an alias
442
443class NullFixture extends React.Component {
444 render () {
445 return null
446 }
447}
448
449const nullWrapper = mount(<NullFixture />) // mount/render/shallow when applicable
450
451expect(nullWrapper).to.be.present()
452expect(nullWrapper).to.exist // an alias
453```
454
455#### `html(str)`
456
457| render | mount | shallow |
458| -------|-------|-------- |
459| yes | yes | yes |
460
461
462Assert that the wrapper has given html:
463
464```js
465import React from 'react'
466import {mount, render, shallow} from 'enzyme'
467
468class Fixture extends React.Component {
469 render () {
470 return (
471 <div id='root'>
472 <span id='child'>Test</span>
473 </div>
474 )
475 }
476}
477
478const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
479
480expect(wrapper.find('#child')).to.have.html('<span id="child">Test</span>')
481
482expect(wrapper.find('#child')).to.not.have.html('<span id="child">Test 1</span>')
483
484expect(wrapper.find('#child')).to.have.html().match(/Test/)
485```
486
487#### `id(str)`
488
489| render | mount | shallow |
490| -------|-------|-------- |
491| yes | yes | yes |
492
493
494Assert that the wrapper has given ID attribute:
495
496```js
497import React from 'react'
498import {mount, render, shallow} from 'enzyme'
499
500class Fixture extends React.Component {
501 render () {
502 return (
503 <div id='root'>
504 <span id='child'>test</span>
505 </div>
506 )
507 }
508}
509
510const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
511
512expect(wrapper).to.have.id('root')
513expect(wrapper).to.not.have.id('child')
514```
515
516#### `match(selector)`
517
518| render | mount | shallow |
519| -------|-------|-------- |
520| yes | yes | yes |
521
522
523Assert that the wrapper matches given selector:
524
525```js
526import React from 'react'
527import {mount, render, shallow} from 'enzyme'
528
529class Fixture extends React.Component {
530 render () {
531 return (
532 <div id='root'>
533 <span id='child'>test</span>
534 </div>
535 )
536 }
537}
538
539const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
540
541expect(wrapper.find('span')).to.match('#child')
542expect(wrapper.find('#root')).to.not.match('#child')
543```
544
545#### `ref(key)`
546
547| render | mount | shallow |
548| -------|-------|-------- |
549| no | yes | no |
550
551```js
552import React from 'react'
553import {mount, render, shallow} from 'enzyme'
554
555class Fixture extends React.Component {
556 render () {
557 return (
558 <div>
559 <input ref='test' />
560 </div>
561 )
562 }
563}
564
565const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
566
567expect(wrapper).to.have.ref('test')
568expect(wrapper).to.have.ref('random')
569```
570
571#### `selected()`
572
573| render | mount | shallow |
574| -------|-------|-------- |
575| yes | yes | no |
576
577
578Assert that the given wrapper is selected:
579
580```js
581import React from 'react'
582import {mount, render, shallow} from 'enzyme'
583
584class Fixture extends React.Component {
585 render () {
586 return (
587 <select defaultValue='test1'>
588 <option id='test1' value='test1'>Test 1</option>
589 <option id='test2' value='test2'>Test 1</option>
590 </select>
591 )
592 }
593}
594
595const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
596
597expect(wrapper.find('#test1')).to.be.selected()
598expect(wrapper.find('#test2')).to.not.be.selected()
599```
600
601#### `tagName(str)`
602
603| render | mount | shallow |
604| -------|-------|-------- |
605| yes | yes | yes |
606
607
608Assert that the given wrapper has the tag name:
609
610```js
611import React from 'react'
612import {mount, render, shallow} from 'enzyme'
613
614class Fixture extends React.Component {
615 render () {
616 return (
617 <div>
618 <span />
619 </div>
620 )
621 }
622}
623
624const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
625
626expect(wrapper).to.have.tagName('div')
627expect(wrapper.find('span')).to.have.tagName('span')
628
629expect(wrapper).to.not.have.tagName('a')
630expect(wrapper.find('span')).to.not.have.tagName('a')
631```
632
633#### `text(str)`
634
635| render | mount | shallow |
636| -------|-------|-------- |
637| yes | yes | yes |
638
639
640Assert that the given wrapper has the supplied text:
641
642```js
643import React from 'react'
644import {mount, render, shallow} from 'enzyme'
645
646class Fixture extends React.Component {
647 render () {
648 return (
649 <div id='root'>
650 <span id='child'>Test</span>
651 </div>
652 )
653 }
654}
655
656const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
657
658expect(wrapper.find('#child')).to.have.text('Test')
659
660expect(wrapper.find('#child')).to.contain.text('Te')
661expect(wrapper.find('#child')).to.include.text('Te') // include is an alias of contain
662
663expect(wrapper.find('#child')).to.not.have.text('Other text')
664expect(wrapper.find('#child')).to.not.include.text('Other text') // include is an alias of contain
665
666expect(wrapper.find('#child')).to.have.text().match(/Test/)
667```
668
669#### `type(func)`
670
671| render | mount | shallow |
672| -------|-------|-------- |
673| no | yes | yes |
674
675
676Assert that the given wrapper has a given type:
677
678```js
679import React from 'react'
680import {shallow} from 'enzyme'
681
682class Foo extends React.Component {
683 render () {
684 return (
685 <div>Foo</div>
686 )
687 }
688}
689
690class Bar extends React.Component {
691 render () {
692 return (
693 <div>Bar</div>
694 )
695 }
696}
697
698class Fixture extends React.Component {
699 render () {
700 return (
701 <Foo />
702 )
703 }
704}
705
706const shallowWrapper = shallow(<Fixture />)
707const mountWrapper = mount(<Fixture />)
708
709expect(shallowWrapper).to.have.type(Foo)
710expect(shallowWrapper).to.not.have.type(Bar)
711
712expect(mountWrapper).to.have.type(Fixture)
713expect(mountWrapper).to.not.have.type(Bar)
714```
715
716#### `value(str)`
717
718| render | mount | shallow |
719| -------|-------|-------- |
720| yes | yes | yes |
721
722
723Assert that the given wrapper has given value:
724
725```js
726import React from 'react'
727import {mount, render, shallow} from 'enzyme'
728
729class Fixture extends React.Component {
730 render () {
731 return (
732 <div>
733 <input defaultValue='test' />
734 </div>
735 )
736 }
737}
738
739const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
740
741expect(wrapper.find('input')).to.have.value('test')
742expect(wrapper.find('input')).to.not.have.value('other')
743```
744
745#### `attr(key, [val])`
746
747| render | mount | shallow |
748| -------|-------|-------- |
749| yes | yes | yes |
750
751
752Assert that the wrapper has given attribute [with value]:
753
754```js
755import React from 'react'
756import {mount, render, shallow} from 'enzyme'
757
758class Fixture extends React.Component {
759 render () {
760 return (
761 <div id='root'>
762 <span id='child'>test</span>
763 </div>
764 )
765 }
766}
767
768const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
769
770expect(wrapper.find('span')).to.have.attr('id')
771expect(wrapper).to.not.have.attr('disabled')
772
773expect(wrapper).to.have.attr('id', 'root')
774expect(wrapper).to.not.have.attr('id', 'invalid')
775
776expect(wrapper).to.have.attr('id').equal('root')
777```
778
779#### `data(key, [val])`
780
781| render | mount | shallow |
782| -------|-------|-------- |
783| yes | yes | yes |
784
785
786Assert that the wrapper has a given data attribute [with value]:
787
788```js
789import React from 'react'
790import {mount, render, shallow} from 'enzyme'
791
792class Fixture extends React.Component {
793 render () {
794 return (
795 <div data-name='root'>
796 <span data-name='child'>test</span>
797 </div>
798 )
799 }
800}
801
802const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
803
804expect(wrapper).to.have.data('name')
805expect(wrapper).to.not.have.data('random')
806
807expect(wrapper).to.have.data('name', 'root')
808expect(wrapper).to.not.have.data('name', 'invalid')
809
810expect(wrapper).to.have.data('name').equal('root')
811```
812
813#### `style(key, [val])`
814
815| render | mount | shallow |
816| -------|-------|-------- |
817| yes | yes | yes |
818
819
820Assert that the wrapper has given style:
821
822```js
823import React from 'react'
824import {mount, render, shallow} from 'enzyme'
825
826class Fixture extends React.Component {
827 render () {
828 return (
829 <div style={{ border: 1 }}>
830 <span style={{ color: 'red' }}>test</span>
831 </div>
832 )
833 }
834}
835
836const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
837
838expect(wrapper).to.have.style('border')
839expect(wrapper).to.not.have.style('color')
840expect(wrapper).to.have.style('margin-top') // do not use camelCase keys as you would do in your React component
841
842expect(wrapper).to.have.style('border', '1px')
843expect(wrapper).to.not.have.style('border', '2px')
844
845expect(wrapper).to.have.style('border').equal('1px')
846```
847
848#### `state(key, [val])`
849
850| render | mount | shallow |
851| -------|-------|-------- |
852| no | yes | yes |
853
854
855Assert that the wrapper has given state [with value]:
856
857```js
858import React from 'react'
859import {mount, render, shallow} from 'enzyme'
860
861class Fixture extends React.Component {
862 constructor () {
863 super()
864 this.state = { foo: 'bar' }
865 }
866
867 render () {
868 return (
869 <div id='root'>
870 </div>
871 )
872 }
873}
874
875const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
876
877expect(wrapper).to.have.state('foo')
878expect(wrapper).to.not.have.state('bar')
879
880
881expect(wrapper).to.have.state('foo', 'bar')
882expect(wrapper).to.not.have.state('foo', 'baz')
883
884expect(wrapper).to.have.state('foo').equal('bar')
885```
886
887
888#### `prop(key, [val])`
889
890| render | mount | shallow |
891| -------|-------|-------- |
892| no | yes | yes |
893
894Assert that the wrapper has given prop [with value]:
895
896```js
897import React from 'react'
898import {mount, render, shallow} from 'enzyme'
899import PropTypes from 'prop-types';
900
901class User extends React.Component {
902 render () {
903 return (
904 <span>User {this.props.index}</span>
905 )
906 }
907}
908
909User.propTypes = {
910 index: PropTypes.number.isRequired
911}
912
913class Fixture extends React.Component {
914 render () {
915 return (
916 <div>
917 <ul>
918 <li><User index={1} user={{name: 'Jane'}} /></li>
919 <li><User index={2} /></li>
920 </ul>
921 </div>
922 )
923 }
924}
925
926const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
927
928expect(wrapper.find(User).first()).to.have.prop('index')
929expect(wrapper.find(User).first()).to.not.have.prop('invalid')
930
931
932expect(wrapper.find(User).first()).to.have.prop('index', 1)
933expect(wrapper.find(User).first()).to.not.have.prop('index', 2)
934
935expect(wrapper.find(User).first()).to.have.prop('index').equal(1)
936expect(wrapper.find(User).first()).to.have.prop('user').deep.equal({name: 'Jane'})
937```
938
939#### `props(key, [val])`
940
941| render | mount | shallow |
942| -------|-------|-------- |
943| no | yes | yes |
944
945Assert that the wrapper has given set of props [with values]:
946
947```js
948import React from 'react'
949import {mount, render, shallow} from 'enzyme'
950import PropTypes from 'prop-types';
951
952class User extends React.Component {
953 render () {
954 return (
955 <span>User {this.props.index}</span>
956 )
957 }
958}
959
960User.propTypes = {
961 index: PropTypes.number.isRequired
962}
963
964class Fixture extends React.Component {
965 render () {
966 return (
967 <div>
968 <ul>
969 <li><User index={1} user={{name: 'Jane'}} /></li>
970 <li><User index={2} /></li>
971 </ul>
972 </div>
973 )
974 }
975}
976
977const wrapper = mount(<Fixture />) // mount/render/shallow when applicable
978
979expect(wrapper.find(User).first()).to.have.props([ 'index', 'user' ])
980expect(wrapper.find(User).first()).to.not.have.props([ 'invalid' ])
981
982
983expect(wrapper.find(User).first()).to.have.props({ index: 1 })
984expect(wrapper.find(User).first()).to.not.have.props({ index: 2 })
985
986expect(wrapper.find(User).first()).to.have.props([ 'index', 'user' ]).deep.equal([ 1, { name: 'Jane' } ])
987```
988
989## Development
990
991#### Setup
992
993```shell
994$ git clone <this repo>
995$ cd chai-enzyme
996$ npm install
997```
998
999#### Tests
1000
1001Linters:
1002
1003```shell
1004$ npm run test:lint
1005```
1006
1007Tests:
1008
1009```shell
1010$ npm run test:unit
1011```
1012
1013All:
1014
1015```shell
1016$ npm test
1017```
1018
1019## Contributing
1020
1021We want to make this assertion library as robust and complete as possible. If
1022you think that there are missing features/assertions, please open a GitHub issue or even
1023better - a PR.
1024
1025Bug reports and pull requests are welcome on GitHub. This project is intended to be a
1026safe, welcoming space for collaboration, and contributors are expected to adhere
1027to the [Contributor Covenant](http://contributor-covenant.org/) code of conduct.
1028
1029## License
1030
1031[![Product Hunt](http://i.imgur.com/dtAr7wC.png)](https://www.producthunt.com)
1032
1033```
1034 _________________
1035< The MIT License >
1036 -----------------
1037 \ ^__^
1038 \ (oo)\_______
1039 (__)\ )\/\
1040 ||----w |
1041 || ||
1042```