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?
ASSERT: Fails fast, aborting the current function. EXPECT: Continues after the failure.
You can use deep-equal-in-any-order plugin. Chai plugin to match objects and arrays deep equality with arrays (including nested ones) being in any order. It works in a similar way as deep. equal but it doesn't check the order of the arrays (at any level of nested objects and arrays).
Notice: either return or notify(done) must be used with promise assertions. This can be a slight departure from the existing format of assertions being used on a project or by a team. Those other assertions are likely synchronous and thus do not require special handling.
Chai is such an assertion library, which provides certain interfaces to implement assertions for any JavaScript-based framework. Chai's interfaces are broadly classified into two: TDD styles and BDD styles.
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
Take a look at the source of chai Assertion but the tl;dr is that Chai implements its own chainable methods on its assert library. However, special keywords are simply syntactic sugar as in the code below shows. Literally they are just properties that are added and can be chained but nothing truly is defined:
/** * ### Language Chains * * The following are provided as chainable getters to improve the readability * of your assertions. * * **Chains** * * - to * - be * - been * - is * - that * - which * - and * - has * - have * - with * - at * - of * - same * - but * - does * * @name language chains * @namespace BDD * @api public */ [ 'to', 'be', 'been' , 'is', 'and', 'has', 'have' , 'with', 'that', 'which', 'at' , 'of', 'same', 'but', 'does' ].forEach(function (chain) { Assertion.addProperty(chain); });
From there what it actually looks for are keywords it specifically defines. So one example is the keyword .to.be.true
it will look at true
as defined in the code snippet below
/** * ### .true * * Asserts that the target is strictly (`===`) equal to `true`. * * expect(true).to.be.true; * * Add `.not` earlier in the chain to negate `.true`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `true`. * * expect(false).to.be.false; // Recommended * expect(false).to.not.be.true; // Not recommended * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.true; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(false, 'nooo why fail??').to.be.true; * * @name true * @namespace BDD * @api public */ Assertion.addProperty('true', function () { this.assert( true === flag(this, 'object') , 'expected #{this} to be true' , 'expected #{this} to be false' , flag(this, 'negate') ? false : true ); });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With