-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Introduce a lint rule to report error when testing promises. If a exp… #42
Introduce a lint rule to report error when testing promises. If a exp… #42
Conversation
CI is failing because of non-semantic commit message. See http://karma-runner.github.io/2.0/dev/git-commit-msg.html |
'function() { /*fulfillment*/}, ' + | ||
'function() { /*rejection*/ expect(someThing).toEqual(true)})})', | ||
|
||
'it("it1", function() { return somePromise.then()})', |
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.
can you add assertions that await
is ok without return
?
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 will work on that.
I will work on fixing non-semantic commit message. |
introduce a lint rule to report error when testing promises. If a expectation is added inside a then or catch block of promise then as per jest docs, it is mandatory to return that promise for succesfull execution of that expectation. This rule will report all such expectations where promise is not returned.
63da944
to
da393e0
Compare
@SimenB I have done the semantic commit message fix and a new commit to allow await expressions without return statement |
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.
Needs docs
@SimenB doc changes done! Please review the same. Also did some sanity on a project which uses promises and jest. Found one bug with nested then or catch, added unit test & fixed 😊 |
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 ran this against Jest's code base, and there are a couple of false positives.
- arrow shorthand: https://github.com/facebook/jest/blob/3ffc99e02d4b1ecad9d0f5ec2e228bddc8e7210b/packages/jest-runtime/src/__tests__/runtime_module_directories.test.js#L57-L66
- There are many cases here where it doesn't warn even though the tests use the same pattern. Why?
- A promise which is created, but only returned at a later time: https://github.com/facebook/jest/blob/3ffc99e02d4b1ecad9d0f5ec2e228bddc8e7210b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js#L103-L134
@SimenB thanks for that feedback! I will work on that. |
@SimenB When i tried to run the rule against jest, the rule was not running at all, I believe following was the cause, In line no 21 of .eslintrc.js in jest code base, it says to check only .md files, I.e. To summarize I did following steps to test this rule agains jest code base,
Here is the output,
Let me know your thoughts, we may need to add |
To test the rule in the Jest repo, you have to add the rule here: https://github.com/facebook/jest/blob/c799a0251d84a7e0c04d98e7d921a5a0e707c72f/packages/eslint-config-fb-strict/index.js#L50-L52 |
@SimenB Thanks, I will test the rule that way. On other hand , I don't find the previousaly mentioned false positives in the output posted in my previous comment. Do you find that as the expectated output is or something is missing in that. |
They are in your paste, in particular
and
|
I was being dumb, two failing test cases which should be valid pushed |
6f02ae9
to
d1416c2
Compare
d1416c2
to
5b25a69
Compare
` | ||
it('shorthand arrow', () => | ||
something().then(value => { | ||
expect(() => { |
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.
this passes if I add return
before expect
(which is not needed)
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 will work on 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.
There are two more similar cases,
- Where expect is inside a block,
test('invalid return', () => {
const promise = something().then(value => {
{ expect(value).toBe('red'); }
});
});
- Where expect is inside another method,
test('invalid return', () => {
const promise = something().then(value => {
anotherMethod(); //this method contains the expect stament
});
});
I have already added this limitation(#>2) in the PR description. I think these are rare scenarios, the first one may not occur at all. As mentioned earlier in the PR description, I think they are good to have
can be done in next enhancement to this rule.
If this scenarios are must to have
, then I am happy to implement in this PR itself.
'it("it1", function() { Promise.resolve().then(' + | ||
'function() { /*fulfillment*/ expect(someThing).toEqual(true)}, ' + | ||
'function() { /*rejection*/ expect(someThing).toEqual(true)})})', | ||
errors: [ |
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.
why is this 2 errors? It should just be one, there is only a single promise 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 will fix that.
Another false positive is if I use the test('callback in handler', done => {
something().then(value => {
expect(value).toBe('red');
done();
});
}); This shouldn't warn, but it's also weird usage of promises, so I think we should just not warn here. (if it's easy to solve, please do so) |
Yes I will do that. I think, this rule should just ignore processing if the test function have done parameter. Also i verified, the name of parameter can be anything not necessary to be named as done only.
Verification of done getting called is not required, the test will fail if the function signature has done param, and test does not call it. |
@SimenB below feedback are fixed,
|
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.
This is great, thank you!
Ran it on the jest code base, and it actually found an error! jestjs/jest#5336 Great job! |
…ectation is added inside a then or catch block of promise then as per jest docs, it is mandatory to return that promise for succesfull execution of that expectation. This rull will report all such expectations where promise is not returned.
Summary
Implements #41
As jest user I work on a project that heavily uses promises and jest is our tool to write tests. We were aware that as per jest docs, it is required to return a promise, if you want to test some thing in its fulfillment or rejection block.
If you do not return that promise and write some exceptions in its then or catch block. Then that test will always be green, as the expectation in then or catch block is never executed. If you return that promise then the expectation will be executed and tests will be red or green depending on the actual result of that expectation.
In this situation it becomes very important to make sure that,
a) You make that test red before making it green for the final push. Which will assure that the exception is getting executed.
As human, we may forget to do that and hence this lint rule will be helpful.
Test plan
Limitations