Implement public API coverage

This patch:
- implements a basic public API coverage based on 'helper.tracePublicAPI' methods
- adds `npm run coverage` command which reports coverage after running all of the unit tests

References #50.
This commit is contained in:
JoelEinbinder 2017-07-27 16:16:37 -07:00 committed by Andrey Lushnikov
parent c26d2c8271
commit a2e0d27fb6
3 changed files with 44 additions and 4 deletions

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
/** @type {?Map<string, boolean>} */
let apiCoverage = null;
class Helper {
/**
* @param {function()|string} fun
@ -116,16 +118,21 @@ class Helper {
let className = classType.prototype.constructor.name;
className = className.substring(0, 1).toLowerCase() + className.substring(1);
const debug = require('debug')(`puppeteer:${className}`);
if (!debug.enabled)
if (!debug.enabled && !apiCoverage)
return;
for (let methodName of Reflect.ownKeys(classType.prototype)) {
const method = Reflect.get(classType.prototype, methodName);
if (methodName === 'constructor' || typeof methodName !== 'string' || methodName.startsWith('_') || typeof method !== 'function')
continue;
if (apiCoverage)
apiCoverage.set(`${className}.${methodName}`, false);
Reflect.set(classType.prototype, methodName, function(...args) {
let argsText = args.map(stringifyArgument).join(', ');
let callsite = `${className}.${methodName}(${argsText})`;
debug(callsite);
if (debug.enabled)
debug(callsite);
if (apiCoverage)
apiCoverage.set(`${className}.${methodName}`, true);
return method.call(this, ...args);
});
}
@ -163,6 +170,17 @@ class Helper {
listener.emitter.removeListener(listener.eventName, listener.handler);
listeners.splice(0, listeners.length);
}
/**
* @return {?Map<string, boolean>}
*/
static publicAPICoverage() {
return apiCoverage;
}
static recordPublicAPICoverage() {
apiCoverage = new Map();
}
}
module.exports = Helper;

View File

@ -11,10 +11,11 @@
"debug-unit": "DEBUG_TEST=true node --inspect-brk ./node_modules/.bin/jasmine test/test.js",
"test-phantom": "python third_party/phantomjs/test/run-tests.py",
"test-doclint": "jasmine utils/doclint/test/test.js",
"test": "npm run lint --silent && npm run unit && npm run test-phantom && npm run test-doclint",
"test": "npm run lint --silent && npm run coverage && npm run test-phantom && npm run test-doclint",
"install": "node install.js",
"lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run doc",
"doc": "node utils/doclint/cli.js"
"doc": "node utils/doclint/cli.js",
"coverage": "COVERAGE=true npm run unit"
},
"author": "The Chromium Authors",
"license": "SEE LICENSE IN LICENSE",

View File

@ -17,6 +17,9 @@
let fs = require('fs');
let rm = require('rimraf').sync;
let path = require('path');
let helper = require('../lib/helper');
if (process.env.COVERAGE)
helper.recordPublicAPICoverage();
let Browser = require('../lib/Browser');
let SimpleServer = require('./server/SimpleServer');
let GoldenUtils = require('./golden-utils');
@ -1345,6 +1348,24 @@ describe('Puppeteer', function() {
});
});
if (process.env.COVERAGE) {
describe('API', function(){
let coverage = helper.publicAPICoverage();
let disabled = new Set();
if (headless) {
disabled.add('dialog.accept');
disabled.add('dialog.dismiss');
} else {
disabled.add('page.pdf');
}
for (let method of coverage.keys()) {
(disabled.has(method) ? xit : it)(`public method '${method}' was tested`, SX(async function(){
expect(publicAPICoverage.get(method)).toBe(true);
}));
}
});
}
/**
* @param {!EventEmitter} emitter
* @param {string} eventName