UNPKG

4.88 kBMarkdownView Raw
1dirty-chai
2==========
3Function form for terminating assertion properties.
4
5## Install
6```
7npm install dirty-chai --save-dev
8```
9## Usage
10
11`dirty-chai` is a chai [plugin](http://chaijs.com/plugins).
12
13```js
14var chai = require('chai');
15var dirtyChai = require('dirty-chai');
16var expect = chai.expect
17
18chai.use(dirtyChai);
19// ...
20expect(true).to.be.true();
21```
22
23## Custom Error Messages
24
25With this function form for terminating properties you can also provide custom error messages to show when the assertion fails. This works whether the assertion is somewhere mid-chain or at the end.
26
27```js
28expect(true).to.be.true.and.not.false('Reason: Paradox');
29expect(true).to.be.true('The fabric of logic has torn').and.not.false();
30```
31
32## Affected Assertions
33
34The following built-in assertions are modified by this plugin to now use the function-call form:
35
36* ok
37* true
38* false
39* null
40* undefined
41* exist
42* empty
43* arguments
44* Arguments
45
46## Caveats
47
48**Always terminate with a function**
49
50These forms can also be mixed, but the chain must always be terminated in the function form or assertions up to that point in the chain will not execute.
51
52```js
53expect(true).to.be.true.and.not.false();
54expect(true).to.be.true().and.not.false();
55```
56
57**Chaining length/arguments**
58
59This breaks both the `length` and `arguments` asserts when they are in the chain following any other assertion. To work around this limitation, do the `length` or `arguments` asserts first in the chain or just do multiple assertion statements.
60
61```js
62myArray.should.exist.and.should.have.length(3); // Error: length is not a function
63
64// Do two assert statements instead
65myArray.should.exist();
66myArray.should.have.length(3);
67```
68
69** use with chai-as-promised **
70
71If you're using chai-as-promised, you should `.use` chai-as-promised before dirty-chai:
72
73```js
74var chai = require("chai");
75var chaiAsPromised = require("chai-as-promised");
76var dirtyChai = require("dirty-chai");
77
78
79chai.use(chaiAsPromised);
80chai.use(dirtyChai);
81```
82
83## Plugin Assertions
84
85This plugin will also hook and convert any property assertions added by other Chai plugins. The only thing you need to do is make sure to load dirty-chai before any other plugins so that it can get its hooks in place before the other plugins are loaded.
86
87For example, if you load [sinon-chai](https://github.com/domenic/sinon-chai) after dirty-chai, all of its property assertions will now be method assertions.
88
89```js
90spy.should.have.been.called();
91spy.should.have.been.calledOnce();
92spy.should.have.been.calledTwice();
93```
94
95## Why?
96
97[Chai](https://github.com/chaijs/chai) is probably one of the most popular assertion libraries in the node. It has over 400 dependents and is downloaded almost 500,000/month.
98
99For stylistic reasons, Chai was designed so that any assertions that did not require parameters would simply assert on property access. This allowed those assertions to elide the empty parens that would be required if those assertions were methods.
100
101This design decision has a pretty big impact on how much trust you can place in your tests, especially if you don't adhere strictly to TDD's red-green-refactor flow. For a detailed descent into why, read [Beware of libraries that assert on property access](https://github.com/moll/js-must#asserting-on-property-access).
102
103There is also the problem of getting errors from linters like JSHint. If you are linting your test code, your linter will complain with an error something like "Expected an assignment or function call and instead saw an expression." Since the linter doesn't know about the property getter it assumes this line has no side-effects, and throws a warning in case you made a mistake.
104
105Squelching these errors is not a good solution as test code is getting to be just as important as, if not more than, production code. Catching syntactical errors in tests using static analysis is a great tool to help make sure that your tests are well-defined and free of typos.
106
107This plugin was written so that we can still take advantage of the large ecosystem of projects and plugins written with/for Chai, while still being able to trust your tests. It converts the built-in property assertions to method assertions, including any property assertions added by plugins.
108
109The list of affected assertions, and many assertions added by plugins, are property getters that assert immediately on access. Because of that, they were written to be used by terminating the assertion chain with a property access.
110
111```js
112expect(true).to.be.true;
113foo.should.be.ok;
114````
115
116A better option was to provide a function-call form for these assertions so that the code's intent is more clear and the linters stop complaining about something looking off. This form is added in addition to the existing property access form and does not impact existing test code.
117
118```js
119expect(true).to.be.true();
120foo.should.be.ok();
121```