expect(true).to.be.true;
In this code, all the 'to', 'be', 'true' seems to be an attribute of the object response from 'expect(true)'.
How can these attributes work so that they can raise an exception?
You can check the source code:
[ 'to', 'be', 'been'
, 'is', 'and', 'has', 'have'
, 'with', 'that', 'which', 'at'
, 'of', 'same', 'but', 'does' ].forEach(function (chain) {
Assertion.addProperty(chain);
});
and there is a addProperty
in utils
:
https://github.com/chaijs/chai/blob/master/lib/chai/utils/addProperty.js
With this you can chain the properties infinitely like: .to.be.to.to.to.be.equal()
Let's create a simpler demonstration:
Assume that you have an assert
object, with the .true()
method
const assert = {
'true': function (v) {
return !!v
}
}
and you want to be able to chain .to
infinitely. Simply Use the defineProperty
to define our getter:
Object.defineProperty(assert, 'to', {
get() {
return assert
}
})
so now you can
assert.to.to.to.to.true(false)
working code: https://codepen.io/CodinCat/pen/LLzBEX?editors=0012
I've added another more complex example here: https://codepen.io/CodinCat/pen/dRVjXL?editors=0012
In this example you can see that there is some behaviors in the .true
property.
We store the value from expect()
in the internal __expectObj
and the __value
property, and then verify it in the getter of .true
. So you can
expect(false).to.to.to.to.true