Skip to content
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

Use jest and node-fetch for tests #926

Closed
wants to merge 17 commits into from

Conversation

PlasmaPower
Copy link
Contributor

Resolves #703. One test (currently set to skip) is tied to #848. I'll make the change to unskip it on the PR last to get merged.

@codecov
Copy link

codecov bot commented Mar 2, 2017

Codecov Report

Merging #926 into master will not change coverage.
The diff coverage is 100%.

@@          Coverage Diff           @@
##           master   #926    +/-   ##
======================================
  Coverage     100%   100%            
======================================
  Files           4      6     +2     
  Lines         431    367    -64     
  Branches      103      0   -103     
======================================
- Hits          431    367    -64
Impacted Files Coverage Δ
test/helpers/request.js 100% <100%> (ø)
lib/response.js 100% <0%> (ø)
lib/context.js 100% <0%> (ø)
lib/request.js 100% <0%> (ø)
lib/application.js 100% <0%> (ø)
test/helpers/context.js 100% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ebed04f...033a5ef. Read the comment docs.

@PlasmaPower
Copy link
Contributor Author

Hmm... the travis error is very confusing to me. Can anyone replicate it locally?

The denoted file+line is just });. Also, there's no combination of request and done in any test, as the error would suggest. There's also never a circumstance where request(...).get would be accessed.

@PlasmaPower
Copy link
Contributor Author

Oh, that's because the tests were preformed on a rebase, and new tests have been added. I'll fix that.

@PlasmaPower
Copy link
Contributor Author

Rebased. Not sure why Travis is taking some time to run, but it should work when it does.

@fengmk2
Copy link
Member

fengmk2 commented Mar 2, 2017

-1

No, we use supertest for a long time and it work great for me.
I don't see any good reason change to use node-fetch.

@PlasmaPower
Copy link
Contributor Author

PlasmaPower commented Mar 2, 2017

@fengmk2 Supertest is:

  • no longer maintained Edit: no longer the case
  • based on callbacks not promises Edit: now possible with .end()
  • without a good way to test for the absence of headers

I think that we need to switch at some point in time without a doubt. I'd much prefer to switch now than later.

@PlasmaPower
Copy link
Contributor Author

Also, I can't see any advantage of supertest over node-fetch. I've already done all the work to switch, and in some cases the code clearly gets simpler, so why not?

@PlasmaPower
Copy link
Contributor Author

Travis has passed.

@dougwilson
Copy link
Contributor

R.I.P. Travis

@magicdawn
Copy link

supertest is extend from superagent. and superagent has faux Promise support since v1.3.0
https://github.com/visionmedia/superagent/blob/v1.3.0/lib/node/index.js#L1027

-1 on node-fetch. fetch always reminds that's GET 😂

});

it('should output deprecation message for generator functions', () => {
const warningPromise = eventToPromise(process, 'deprecation')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use promise here is strange, I'd like to use the original syntax

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the original syntax, the asserts for the result of the request were run after the test has finished. I don't know if they would be ignored or result in a strange error, but I do know that it wouldn't work properly. I can return it to its original syntax and remove the request asserts though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of another use of eventToPromise, I can switch this back.

@PlasmaPower
Copy link
Contributor Author

PlasmaPower commented Mar 2, 2017

Ah, I see. I wasn't aware that superagent was updated. However, I still don't like using supertest, as once again it is unmaintained. Edit: no longer the case.

If we'd like to explicitly specify GET, then I can add that to the wrapper API. However, I still support node-fetch as the base.


done();
});
const res = await request(app, '/');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use supertest@3 with promise support is much better than node-fetch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into it, it does have a new maintainer, so my point there isn't valid. However, I still prefer the syntax of node-fetch. May I ask why you prefer supertest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I'd like to point out that for the specific test you've commented on using node-fetch is significantly cleaner (12 lines to 3 lines).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using supertest way

return request(app)
  .get('/')
  .expect(204)
  .expect(res => {
    assert(res.headers['set-cookie'].join(';').match(/^name=/));
  });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming even if we switch back to supertest we'd keep expect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think we should stick with supertest@3. fewer changes and it works fine

@PlasmaPower
Copy link
Contributor Author

PlasmaPower commented Mar 2, 2017

Sorry for switching to node-fetch without asking first, I thought the consensus was once we had async/await we should move away from supertest.

@PlasmaPower
Copy link
Contributor Author

One other thing about my node-fetch wrapper: it automatically closes the HTTP server, so the Jest process will exit after finishing the tests (not the case with our current supertest usage).

@fengmk2
Copy link
Member

fengmk2 commented Mar 2, 2017

without a good way to test for the absence of headers

We can send a pull request to supertest then make it happen.

request(app1.listen())
.get('/')
.expect(204, done);
return request(app1, '/').then(res => expect(res.status).toBe(204));
Copy link
Member

@fengmk2 fengmk2 Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this equal to supertest

return request(app1)
  .get('/')
  .expect(204);

Copy link
Contributor Author

@PlasmaPower PlasmaPower Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if Jest would recognize it as a Promise, given that it isn't true Promise, it just has .then and .catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like jest does recognize it as a promise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anything with a .then() method is a true promise ;)

@PlasmaPower
Copy link
Contributor Author

The one thing I realized supertest has going for it is that it's error messages are more relevant to the context of the assertion.

At this point, I think supertest is acceptable. I'm still not sure it's better though.

Copy link

@gdams gdams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, It will be really useful to not have to use make anymore as this will fix all the issues with AIX

.travis.yml Outdated
- make test-travis
- make bench
- npm run lint
- jest --coverage
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be worth having an npm script for coverage (so you could donpm run coverage)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that would be very helpful, I think npm test --coverage is good enough.

Copy link

@gibfahn gibfahn Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's helpful for people who are new to the module, if all the basic testing commands are npm run scripts, then you can just instantly work out what the testing commands are.

How do you know to run npm test --coverage?

package.json Outdated
@@ -4,7 +4,8 @@
"description": "Koa web app framework",
"main": "lib/application.js",
"scripts": {
"test": "make test"
"test": "jest",
"lint": "./node_modules/.bin/eslint benchmarks lib test"
Copy link

@gibfahn gibfahn Mar 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just do "lint": "eslint benchmarks lib test" (npm should be able to work out where eslint is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, we also don't want to use a global eslint even if it exists (plugins).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npm run prepends ./node_modules/.bin to the $PATH, so it will use the local eslint even if it's also installed globally.

You can test it by adding "tmp": "echo $PATH", to the package.json.

npm run docs

@PlasmaPower
Copy link
Contributor Author

@gibfahn Good points. I've added those, except I chose npm run test-cov instead of npm run coverage as that's what we previously had.

package.json Outdated
"test": "make test"
"test": "jest",
"test-cov": "jest --coverage",
"lint": "./node_modules/.bin/eslint benchmarks lib test"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you miss committing the lint change? I see it in the commit message 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, oops! Fixed.

@PlasmaPower PlasmaPower force-pushed the jest-tests branch 2 times, most recently from 9fda81a to a5ad829 Compare March 7, 2017 16:22
@PlasmaPower
Copy link
Contributor Author

Hmm, that Travis failure is very odd. Retrying.

@PlasmaPower
Copy link
Contributor Author

That time it passed. Given that it was a syntax error I'm not sure it was caused by jest. I'll investigate further if it occurs again.

@PlasmaPower
Copy link
Contributor Author

The test relying on #848 is proving to be a bit more difficult than thought. I'll look into it later today.

@PlasmaPower PlasmaPower force-pushed the jest-tests branch 2 times, most recently from 57fc767 to 28fa978 Compare March 8, 2017 16:48
@PlasmaPower
Copy link
Contributor Author

Okay I've updated the socket.writable test (depends on app.callback returning a promise). It's maybe a bit too complicated, but it should be fairly secure against future changes.

done();
});
const res = await request(server, '/');
expect(res.status).toBe(404);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I like using expect. anyone else prefer we use node's assert?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It comes with jest, so I figured that's what we'd use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert +1, don't like expect either, maybe we can try power-assert later, it has the same API with node's assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm since we've managed to avoid transformations thus far, I'm not sure we'd want to add one. However, I agree that it'd be very useful.

request(app.listen())
.get('/')
.expect('.keys required for signed cookies', done);
const text = await (await request(app, '/')).text();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol. I always try to only do 1 async action per line. gets crazy like this otherwise

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I probably should've split that up.

@jonathanong
Copy link
Member

my opinions:

  • stick to supertest@3 instead of node-fetch, which seems to be the consensus
  • use assert instead of expect, which I don't really care about

@PlasmaPower
Copy link
Contributor Author

OK, I'll open a new PR with those changes later today hopefully.

@jonathanong
Copy link
Member

@PlasmaPower thanks for all your work!!!

@PlasmaPower
Copy link
Contributor Author

I'm leaning towards a custom supertest wrapper, as we also need to shutdown the server. Is that okay?

Also, for now, I think I'll implement header not existing tests through that wrapper, then maybe make a PR to supertest in the future.

@PlasmaPower
Copy link
Contributor Author

I haven't had much time to work on this, if anyone wants to pick it up feel free.

@gillesdemey gillesdemey mentioned this pull request May 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants