Skip to content

Commit

Permalink
Merge pull request #792 from lamweili/refactor/test
Browse files Browse the repository at this point in the history
test: 100% coverage
  • Loading branch information
titanism authored Oct 3, 2022
2 parents 5543d67 + da1e842 commit b8c2e29
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 22 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
include:
- node-version: 10.x
test-on-old-node: 1
- node-version: 12.x
test-on-old-node: 1
- node-version: 14.x
- node-version: 16.x
- node-version: 18.x

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install Dependencies On Old Node ${{ matrix.node-version }}
if: ${{ matrix.test-on-old-node == '1' }}
run: node ci/remove-deps-4-old-node.js && yarn install --ignore-scripts
- name: Install Dependencies On Node ${{ matrix.node-version }}
if: ${{ matrix.test-on-old-node != '1' }}
run: yarn install
- run: npm test
- name: Coverage On Node ${{ matrix.node-version }}
run:
npm run coverage
22 changes: 22 additions & 0 deletions ci/remove-deps-4-old-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const fs = require('fs');
const path = require('path');
const package = require('../package.json');

const UNSUPPORT_DEPS_4_OLD = {
'eslint': undefined,
'mocha': '6.x'
};

const deps = Object.keys(UNSUPPORT_DEPS_4_OLD);
for (const item in package.devDependencies) {
if (deps.includes(item)) {
package.devDependencies[item] = UNSUPPORT_DEPS_4_OLD[item];
}
}

delete package.scripts.lint;

fs.writeFileSync(
path.join(__dirname, '../package.json'),
JSON.stringify(package, null, 2)
);
15 changes: 4 additions & 11 deletions lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ const Test = require('./test.js');
function TestAgent(app, options) {
if (!(this instanceof TestAgent)) return new TestAgent(app, options);
if (typeof app === 'function') app = http.createServer(app); // eslint-disable-line no-param-reassign
if (options) {
this._ca = options.ca;
this._key = options.key;
this._cert = options.cert;
}
Agent.call(this);
Agent.call(this, options);

This comment has been minimized.

Copy link
@titanism

titanism Oct 3, 2022

Author Collaborator

Are you sure _ca _key and _cert will still function as normal? This is breaking? @lamweili

This comment has been minimized.

Copy link
@lamweili

lamweili Oct 3, 2022

Contributor

In fact, it is currently broken. Only affects the HttpAgent portion:

  • Parent class: Agent from superagent
    • Child class: TestAgent from supertest

TestAgent only passes _ca, _key and _cert to Agent constructor.
That is dating back to superagent@3.0.0-alpha.1.

  • The _pfx is added to Agent (superagent@3.0.0-alpha.2)
    • TestAgent didn't have the _pfx feature.
  • The underscore prefix was removed in Agent (superagent@3.8.0-alpha.1)
    • TestAgent broke as it still passes underscored variables to Agent constructor.

At the moment, visionmedia/superagent/blob/master/src/node/agent.js#L33-53.


There is no need for TestAgent to map it (or every time the Agent changes, it has to be mirrored over).
TestAgent can pass the entire options object as-is to the Agent constructor. This is non-breaking.

this.app = app;
}

Expand All @@ -44,19 +39,17 @@ TestAgent.prototype.host = function(host) {
// override HTTP verb methods
methods.forEach(function(method) {
TestAgent.prototype[method] = function(url, fn) { // eslint-disable-line no-unused-vars
const req = new Test(this.app, method.toUpperCase(), url, this._host);
req.ca(this._ca);
req.cert(this._cert);
req.key(this._key);
const req = new Test(this.app, method.toUpperCase(), url);

if (this._host) {
req.set('host', this._host);
}

req.on('response', this._saveCookies.bind(this));
req.on('redirect', this._saveCookies.bind(this));
req.on('redirect', this._attachCookies.bind(this, req));
this._attachCookies(req);
this._setDefaults(req);
this._attachCookies(req);

return req;
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"scripts": {
"lint": "eslint lib/**/*.js test/**/*.js index.js",
"lint:fix": "eslint --fix lib/**/*.js test/**/*.js index.js",
"pretest": "npm run lint",
"pretest": "npm run lint --if-present",
"test": "nyc --reporter=html --reporter=text mocha --exit --require should --reporter spec --check-leaks",
"coverage": "nyc report --reporter=text-lcov | coveralls"
},
Expand Down
53 changes: 43 additions & 10 deletions test/supertest.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ function shouldIncludeStackWithThisFile(err) {
describe('request(url)', function () {
it('should be supported', function (done) {
const app = express();
let s;
let server;

app.get('/', function (req, res) {
res.send('hello');
});

s = app.listen(function () {
const url = 'http://localhost:' + s.address().port;
server = app.listen(function () {
const url = 'http://localhost:' + server.address().port;
request(url)
.get('/')
.expect('hello', done);
Expand All @@ -37,14 +37,14 @@ describe('request(url)', function () {
describe('.end(cb)', function () {
it('should set `this` to the test object when calling cb', function (done) {
const app = express();
let s;
let server;

app.get('/', function (req, res) {
res.send('hello');
});

s = app.listen(function () {
const url = 'http://localhost:' + s.address().port;
server = app.listen(function () {
const url = 'http://localhost:' + server.address().port;
const test = request(url).get('/');
test.end(function (err, res) {
this.should.eql(test);
Expand Down Expand Up @@ -80,7 +80,7 @@ describe('request(app)', function () {
res.send('hey');
});

server = app.listen(4000, function () {
server = app.listen(function () {
request(server)
.get('/')
.end(function (err, res) {
Expand All @@ -93,13 +93,15 @@ describe('request(app)', function () {

it('should work with remote server', function (done) {
const app = express();
let server;

app.get('/', function (req, res) {
res.send('hey');
});

app.listen(4001, function () {
request('http://localhost:4001')
server = app.listen(function () {
const url = 'http://localhost:' + server.address().port;
request(url)
.get('/')
.end(function (err, res) {
res.status.should.equal(200);
Expand Down Expand Up @@ -1269,7 +1271,7 @@ describe('request.get(url).query(vals) works as expected', function () {
});
});

it('handles unknown errors', function (done) {
it('handles unknown errors (err without res)', function (done) {
const app = express();

nock.disableNetConnect();
Expand All @@ -1285,6 +1287,8 @@ describe('request.get(url).query(vals) works as expected', function () {
// https://github.com/visionmedia/supertest/issues/352
.expect(200)
.end(function (err, res) {
should.exist(err);
should.not.exist(res);
err.should.be.an.instanceof(Error);
err.message.should.match(/Nock: Disallowed net connect/);
shouldIncludeStackWithThisFile(err);
Expand All @@ -1294,6 +1298,35 @@ describe('request.get(url).query(vals) works as expected', function () {
nock.restore();
});

// this scenario should never happen
// there shouldn't be any res if there is an err
// meant for test coverage for lib/test.js#169
// https://github.com/visionmedia/supertest/blob/5543d674cf9aa4547927ba6010d31d9474950dec/lib/test.js#L169
it('handles unknown errors (err with res)', function (done) {
const app = express();

app.get('/', function (req, res) {
res.status(200).send('OK');
});

const resError = new Error();
resError.status = 400;

const serverRes = { status: 200 };

request(app)
.get('/')
// private api
.assert(resError, serverRes, function (err, res) {
should.exist(err);
should.exist(res);
err.should.equal(resError);
res.should.equal(serverRes);
// close the server explicitly (as we are not using expect/end/then)
this.end(done);
});
});

it('should assert using promises', function (done) {
const app = express();

Expand Down

0 comments on commit b8c2e29

Please sign in to comment.