-
-
Notifications
You must be signed in to change notification settings - Fork 701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
addMethod returns a new assertion with flags copied over instead of this #642
addMethod returns a new assertion with flags copied over instead of this #642
Conversation
Here are the tests I thought were right for this. |
|
||
// If it is, calling length on it should return an assertion, not a function | ||
var anAssertion = expect([1, 2, 3]).to.be.an.instanceof(Array); | ||
expect(anAssertion.length).to.be.an.instanceof(assertionConstructor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add some assertions that feature the an
keyword, and also feature the length
keyword, similar to the original issue.
expect([1, 2, 3]).to.be.an.instanceOf(Array).and.to.have.length.below(1000)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well thought @keithamus.
This fix appears to work with the expression you posted, but I went to the issue to test other examples and this appears to fail:
expect(my_object).to.have.a.deep.property("foo.bar").that.is.an("array").with.a.length.of.at.least(1);
The reason is the same you explained on the issue, we are getting back an assert
function instead of an Assertion
object.
I'll take a further look at this to find the exact reason.
Thanks again for your feedback, it was really useful 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @lucasfcosta thanks for doing that, and also awesome work adding some more tests and discovering another issue 😄
It looks like in that case, the .a.
part turns the Assertion into a function, from which it doesn't recover. To wit:
> chai.expect({foo: [1,2,3]}).to
Assertion {
__flags:
{ ssfi: [Function: addProperty],
object: { foo: [Object] },
message: undefined } }
> chai.expect({foo: [1,2,3]}).to.have
Assertion {
__flags:
{ ssfi: [Function: addProperty],
object: { foo: [Object] },
message: undefined } }
> chai.expect({foo: [1,2,3]}).to.have.a
[Function: assert]
> chai.expect({foo: [1,2,3]}).to.have.a.deep
[Function: assert]
Luckily, it looks like the fix will be pretty much the same thing. L44 of addProperty has the same ternary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT: Please ignore this comment and just read this.
Ah, that makes sense.
Thanks for the insight here.
I was also doing some research on this too, shouldn't we create another assertion and transfer flags to it instead of returning this
?
I'm not sure this is needed, I will do some further experiments with this, but it may be good to prevent further errors related to this.
Well, I've done some further studies on this and I've discovered that the explanation for why this ( We've got this line into our What I've done on this PR partially solves our problem because when we return a How we could solve this:This would be a very, very easy fix if we could just do: Unfortunately this is not available on all browsers because the Being able to delete Currently we can only solve this for some cases, like the ones described above, in which we return a For NowFor now, I will just do the changes we've talked about on On the current commits I improved the tests for both I hope I was clear, but if I wasn't don't be afraid to ask. |
4fa4847
to
5223164
Compare
5223164
to
8f8f186
Compare
Hey @lucasfcosta thanks for the awesome deep dive! Here's my commentary on this:
This is because According to Kangax (here is the name is configurable test and here is the length is configurable test), Edge, Firefox, Chrome and Node (4 & 5) support this, but older browsers (IE<=11, older Android versions not using Chrome, all Safaris including iOS) do not.
Older IEs and Safari are basically immovable at this point. Its disappointing but it is what it is. Fixing this by ensuring we don't end up returning functions in the chain, as you've done in this PR - is useful of its own merit. If we looked at deleting the properties ( |
@keithamus thanks for the info on the I totally agree with you when you say that consistent behaviour is preferable, that's why this PR has only non-breaking and consistent changes, but, as I said, there's no way to solve chaining This partially solves the problem, but it's still (in my opinion) better than nothing. What do you think about it? Thanks for your feedback and for your help, without you this PR wouldn't have been possible 😄 |
LGTM 😄 |
addMethod returns a new assertion with flags copied over instead of this
@@ -39,6 +40,10 @@ module.exports = function (ctx, name, method) { | |||
if (old_ssfi && config.includeStack === false) | |||
flag(this, 'ssfi', ctx[name]); | |||
var result = method.apply(this, arguments); | |||
return result === undefined ? this : result; | |||
|
|||
var newAssertion = new chai.Assertion(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting ReferenceError: chai is not defined
thrown here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this problem has been shadowed by global.chai = require('../..');
in all tests...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks @Turbo87. Fancy making a PR for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, I see you already have 🎉 👍
This aims to solve #562.
Special thanks to @keithamus for the whole idea here, I just made some minor adjustments.
This PR should include:
addMethod
returning anew Assertion
with flags copied overI'm currently writing the tests and I'm not sure if they're complete enough.
I was thinking about testing chaining some assertions as described on #562, testing the type of their return and if methods are really returning a new Assertion with the flags which should have been copied. Is this enough? If not, what else should be verified?
EDIT: This needs a review, please see this. I'll take a further look at it.