Skip to content

Commit b188260

Browse files
committed
refactor(util): expose defineOperation for testing
1 parent 820fbb4 commit b188260

File tree

2 files changed

+70
-62
lines changed

2 files changed

+70
-62
lines changed

lib/kerberos.js

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const kerberos = require('bindings')('kerberos');
44
const KerberosClient = kerberos.KerberosClient;
55
const KerberosServer = kerberos.KerberosServer;
6+
const defineOperation = require('./util').defineOperation;
67

78
// GSS Flags
89
const GSS_C_DELEG_FLAG = 1;
@@ -20,67 +21,6 @@ const GSS_C_NO_OID = 0;
2021
const GSS_MECH_OID_KRB5 = 9;
2122
const GSS_MECH_OID_SPNEGO = 6;
2223

23-
function validateParameter(parameter, spec) {
24-
if (parameter == null) {
25-
throw new TypeError(`Required parameter \`${spec.name}\` missing`);
26-
}
27-
28-
if (spec.type && typeof parameter !== spec.type) {
29-
throw new TypeError(
30-
`Invalid type for parameter \`${spec.name}\`, expected \`${
31-
spec.type
32-
}\` but found \`${typeof parameter}\``
33-
);
34-
}
35-
}
36-
37-
/**
38-
* Monkey-patches an existing method to support parameter validation, as well
39-
* as adding support for returning Promises if callbacks are not provided.
40-
*
41-
* @private
42-
* @param {function} fn the function to override
43-
* @param {Array<Object>} paramDefs the definitions of each parameter to the function
44-
*/
45-
function defineOperation(fn, paramDefs) {
46-
return function() {
47-
const args = Array.prototype.slice.call(arguments);
48-
const params = [];
49-
for (let i = 0; i < paramDefs.length; ++i) {
50-
const def = paramDefs[i];
51-
let arg = args[i];
52-
53-
if (def.default && arg == null) arg = def.default;
54-
if (def.type === 'object' && def.default != null) {
55-
arg = Object.assign({}, def.default, arg);
56-
}
57-
58-
// special case to allow `options` to be optional
59-
if (def.name === 'options' && (typeof arg === 'function' || arg == null)) {
60-
arg = {};
61-
}
62-
63-
validateParameter(arg, paramDefs[i]);
64-
params.push(arg);
65-
}
66-
67-
const callback = arguments[arguments.length - 1];
68-
if (typeof callback !== 'function') {
69-
return new Promise((resolve, reject) => {
70-
params.push((err, response) => {
71-
if (err) return reject(err);
72-
resolve(response);
73-
});
74-
75-
fn.apply(this, params);
76-
});
77-
}
78-
79-
params.push(callback);
80-
fn.apply(this, params);
81-
};
82-
}
83-
8424
/**
8525
* @class KerberosClient
8626
*
@@ -147,7 +87,7 @@ KerberosClient.prototype.unwrap = defineOperation(KerberosClient.prototype.unwra
14787
* @kind function
14888
* @memberof KerberosServer
14989
* @param {string} challenge A string containing the base64-encoded client data
150-
* @param {function} callback
90+
* @param {function} [callback]
15191
* @return {Promise} returns Promise if no callback passed
15292
*/
15393
KerberosServer.prototype.step = defineOperation(KerberosServer.prototype.step, [

lib/util.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
function validateParameter(parameter, spec) {
4+
if (parameter == null && spec.required === false) {
5+
return;
6+
}
7+
8+
if (parameter == null) {
9+
throw new TypeError(`Required parameter \`${spec.name}\` missing`);
10+
}
11+
12+
if (spec.type && typeof parameter !== spec.type) {
13+
throw new TypeError(
14+
`Invalid type for parameter \`${spec.name}\`, expected \`${
15+
spec.type
16+
}\` but found \`${typeof parameter}\``
17+
);
18+
}
19+
}
20+
21+
/**
22+
* Monkey-patches an existing method to support parameter validation, as well
23+
* as adding support for returning Promises if callbacks are not provided.
24+
*
25+
* @private
26+
* @param {function} fn the function to override
27+
* @param {Array<Object>} paramDefs the definitions of each parameter to the function
28+
*/
29+
function defineOperation(fn, paramDefs) {
30+
return function() {
31+
const args = Array.prototype.slice.call(arguments);
32+
const params = [];
33+
for (let i = 0; i < paramDefs.length; ++i) {
34+
const def = paramDefs[i];
35+
let arg = args[i];
36+
37+
if (def.default && arg == null) arg = def.default;
38+
if (def.type === 'object' && def.default != null) {
39+
arg = Object.assign({}, def.default, arg);
40+
}
41+
42+
// special case to allow `options` to be optional
43+
if (def.name === 'options' && (typeof arg === 'function' || arg == null)) {
44+
arg = {};
45+
}
46+
47+
validateParameter(arg, paramDefs[i]);
48+
params.push(arg);
49+
}
50+
51+
const callback = params.pop();
52+
if (typeof callback !== 'function') {
53+
return new Promise((resolve, reject) => {
54+
params.push((err, response) => {
55+
if (err) return reject(err);
56+
resolve(response);
57+
});
58+
59+
fn.apply(this, params);
60+
});
61+
}
62+
63+
params.push(callback);
64+
fn.apply(this, params);
65+
};
66+
}
67+
68+
module.exports = { defineOperation, validateParameter };

0 commit comments

Comments
 (0)