mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
test: add mustCallAtLeast
PR-URL: https://github.com/nodejs/node/pull/12935 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
46e773c5db
commit
fccc0bf6e6
@ -182,9 +182,9 @@ Gets IP of localhost
|
||||
|
||||
Array of IPV6 hosts.
|
||||
|
||||
### mustCall([fn][, expected])
|
||||
* fn [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
|
||||
* expected [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1
|
||||
### mustCall([fn][, exact])
|
||||
* `fn` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) default = `common.noop`
|
||||
* `exact` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1
|
||||
* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
|
||||
|
||||
Returns a function that calls `fn`. If the returned function has not been called
|
||||
@ -193,6 +193,17 @@ fail.
|
||||
|
||||
If `fn` is not provided, `common.noop` will be used.
|
||||
|
||||
### mustCallAtLeast([fn][, minimum])
|
||||
* `fn` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) default = `common.noop`
|
||||
* `minimum` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1
|
||||
* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
|
||||
|
||||
Returns a function that calls `fn`. If the returned function has not been called
|
||||
at least `minimum` number of times when the test is complete, then the test will
|
||||
fail.
|
||||
|
||||
If `fn` is not provided, `common.noop` will be used.
|
||||
|
||||
### nodeProcessAborted(exitCode, signal)
|
||||
* `exitCode` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type)
|
||||
* `signal` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)
|
||||
|
@ -459,13 +459,19 @@ function runCallChecks(exitCode) {
|
||||
if (exitCode !== 0) return;
|
||||
|
||||
const failed = mustCallChecks.filter(function(context) {
|
||||
return context.actual !== context.expected;
|
||||
if ('minimum' in context) {
|
||||
context.messageSegment = `at least ${context.minimum}`;
|
||||
return context.actual < context.minimum;
|
||||
} else {
|
||||
context.messageSegment = `exactly ${context.exact}`;
|
||||
return context.actual !== context.exact;
|
||||
}
|
||||
});
|
||||
|
||||
failed.forEach(function(context) {
|
||||
console.log('Mismatched %s function calls. Expected %d, actual %d.',
|
||||
console.log('Mismatched %s function calls. Expected %s, actual %d.',
|
||||
context.name,
|
||||
context.expected,
|
||||
context.messageSegment,
|
||||
context.actual);
|
||||
console.log(context.stack.split('\n').slice(2).join('\n'));
|
||||
});
|
||||
@ -473,22 +479,29 @@ function runCallChecks(exitCode) {
|
||||
if (failed.length) process.exit(1);
|
||||
}
|
||||
|
||||
exports.mustCall = function(fn, exact) {
|
||||
return _mustCallInner(fn, exact, 'exact');
|
||||
};
|
||||
|
||||
exports.mustCall = function(fn, expected) {
|
||||
exports.mustCallAtLeast = function(fn, minimum) {
|
||||
return _mustCallInner(fn, minimum, 'minimum');
|
||||
};
|
||||
|
||||
function _mustCallInner(fn, criteria, field) {
|
||||
if (typeof fn === 'number') {
|
||||
expected = fn;
|
||||
criteria = fn;
|
||||
fn = noop;
|
||||
} else if (fn === undefined) {
|
||||
fn = noop;
|
||||
}
|
||||
|
||||
if (expected === undefined)
|
||||
expected = 1;
|
||||
else if (typeof expected !== 'number')
|
||||
throw new TypeError(`Invalid expected value: ${expected}`);
|
||||
if (criteria === undefined)
|
||||
criteria = 1;
|
||||
else if (typeof criteria !== 'number')
|
||||
throw new TypeError(`Invalid ${field} value: ${criteria}`);
|
||||
|
||||
const context = {
|
||||
expected: expected,
|
||||
[field]: criteria,
|
||||
actual: 0,
|
||||
stack: (new Error()).stack,
|
||||
name: fn.name || '<anonymous>'
|
||||
@ -503,7 +516,7 @@ exports.mustCall = function(fn, expected) {
|
||||
context.actual++;
|
||||
return fn.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
exports.hasMultiLocalhost = function hasMultiLocalhost() {
|
||||
const TCP = process.binding('tcp_wrap').TCP;
|
||||
|
3
test/fixtures/failmustcall1.js
vendored
Normal file
3
test/fixtures/failmustcall1.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
const common = require('../common');
|
||||
const f = common.mustCall( () => {}, 2);
|
||||
f();
|
3
test/fixtures/failmustcall2.js
vendored
Normal file
3
test/fixtures/failmustcall2.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
const common = require('../common');
|
||||
const f = common.mustCallAtLeast(() => {}, 2);
|
||||
f();
|
@ -22,7 +22,8 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
const {join} = require('path');
|
||||
const {execFile} = require('child_process');
|
||||
|
||||
// test for leaked global detection
|
||||
global.gc = 42; // Not a valid global unless --expose_gc is set.
|
||||
@ -33,12 +34,15 @@ delete global.gc;
|
||||
// common.mustCall() tests
|
||||
assert.throws(function() {
|
||||
common.mustCall(function() {}, 'foo');
|
||||
}, /^TypeError: Invalid expected value: foo$/);
|
||||
}, /^TypeError: Invalid exact value: foo$/);
|
||||
|
||||
assert.throws(function() {
|
||||
common.mustCall(function() {}, /foo/);
|
||||
}, /^TypeError: Invalid expected value: \/foo\/$/);
|
||||
}, /^TypeError: Invalid exact value: \/foo\/$/);
|
||||
|
||||
assert.throws(function() {
|
||||
common.mustCallAtLeast(function() {}, /foo/);
|
||||
}, /^TypeError: Invalid minimum value: \/foo\/$/);
|
||||
|
||||
// assert.fail() tests
|
||||
assert.throws(
|
||||
@ -47,3 +51,40 @@ assert.throws(
|
||||
code: 'ERR_ASSERTION',
|
||||
message: /^fhqwhgads$/
|
||||
}));
|
||||
|
||||
const fnOnce = common.mustCall(() => {});
|
||||
fnOnce();
|
||||
const fnTwice = common.mustCall(() => {}, 2);
|
||||
fnTwice();
|
||||
fnTwice();
|
||||
const fnAtLeast1Called1 = common.mustCallAtLeast(() => {}, 1);
|
||||
fnAtLeast1Called1();
|
||||
const fnAtLeast1Called2 = common.mustCallAtLeast(() => {}, 1);
|
||||
fnAtLeast1Called2();
|
||||
fnAtLeast1Called2();
|
||||
const fnAtLeast2Called2 = common.mustCallAtLeast(() => {}, 2);
|
||||
fnAtLeast2Called2();
|
||||
fnAtLeast2Called2();
|
||||
const fnAtLeast2Called3 = common.mustCallAtLeast(() => {}, 2);
|
||||
fnAtLeast2Called3();
|
||||
fnAtLeast2Called3();
|
||||
fnAtLeast2Called3();
|
||||
|
||||
const failFixtures = [
|
||||
[
|
||||
join(common.fixturesDir, 'failmustcall1.js'),
|
||||
'Mismatched <anonymous> function calls. Expected exactly 2, actual 1.'
|
||||
], [
|
||||
join(common.fixturesDir, 'failmustcall2.js'),
|
||||
'Mismatched <anonymous> function calls. Expected at least 2, actual 1.'
|
||||
]
|
||||
];
|
||||
for (const p of failFixtures) {
|
||||
const [file, expected] = p;
|
||||
execFile(process.argv[0], [file], common.mustCall((ex, stdout, stderr) => {
|
||||
assert.ok(ex);
|
||||
assert.strictEqual(stderr, '');
|
||||
const firstLine = stdout.split('\n').shift();
|
||||
assert.strictEqual(firstLine, expected);
|
||||
}));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user