Skip to content

Commit d73f838

Browse files
authoredFeb 10, 2021
Added promise support for library (#140)
* Added promise support for library Based on this excellent SO answer: https://stackoverflow.com/a/36838115/3694288 The objective is to make the library more available and easy to use. * Added linting check in package.json
1 parent 39af582 commit d73f838

File tree

4 files changed

+113
-38
lines changed

4 files changed

+113
-38
lines changed
 

‎.eslintrc

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
"parserOptions": {
33
"ecmaVersion": 2017
44
},
5-
"env": {
6-
"es6": true
7-
}
85
"env": {
96
"mocha": true,
10-
"node": true
7+
"node": true,
8+
"es6": true
119
},
1210
"globals": {
1311
"expect": true,

‎lib/index.js

+45-33
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,55 @@ var _ = require('lodash');
1414
* @param {Boolean} options.semanticTypes enable semantic type detection (default: false)
1515
* @param {Boolean} options.storeValues enable storing of values (default: true)
1616
*
17-
* @param {Function} fn Callback which will be passed `(err, schema)`
17+
* @param {Function} callback Callback which will be passed `(err, schema)`
18+
* @return {Promise} You can await promise, or use callback if provided.
1819
*/
19-
module.exports = function(docs, options, fn) {
20-
// shift parameters if no options are specified
21-
if (_.isUndefined(options) || _.isFunction(options) && _.isUndefined(fn)) {
22-
fn = options;
23-
options = {};
24-
}
20+
module.exports = function(docs, options, callback) {
21+
const promise = new Promise((resolve, reject) => {
22+
// shift parameters if no options are specified
23+
if (_.isUndefined(options) || (_.isFunction(options) && _.isUndefined(callback))) {
24+
callback = options;
25+
options = {};
26+
}
27+
28+
var src;
29+
// MongoDB Cursors
30+
if (docs.stream && typeof docs.stream === 'function') {
31+
src = docs.stream();
32+
// Streams
33+
} else if (docs.pipe && typeof docs.pipe === 'function') {
34+
src = docs;
35+
// Arrays
36+
} else if (_.isArray(docs)) {
37+
src = es.readArray(docs);
38+
} else {
39+
reject(new Error(
40+
'Unknown input type for `docs`. Must be an array, ' +
41+
'stream or MongoDB Cursor.'
42+
));
43+
return;
44+
}
45+
46+
var result;
47+
48+
src
49+
.pipe(stream(options))
50+
.on('data', function(data) {
51+
result = data;
52+
})
53+
.on('error', function(err) {
54+
reject(err);
55+
})
56+
.on('end', function() {
57+
resolve(result);
58+
});
59+
});
2560

26-
var src;
27-
// MongoDB Cursors
28-
if (docs.stream && typeof docs.stream === 'function') {
29-
src = docs.stream();
30-
// Streams
31-
} else if (docs.pipe && typeof docs.pipe === 'function') {
32-
src = docs;
33-
// Arrays
34-
} else if (_.isArray(docs)) {
35-
src = es.readArray(docs);
36-
} else {
37-
fn(new Error('Unknown input type for `docs`. Must be an array, '
38-
+ 'stream or MongoDB Cursor.'));
39-
return;
61+
if (callback && typeof callback === 'function') {
62+
promise.then(callback.bind(null, null), callback);
4063
}
4164

42-
var result;
43-
44-
src.pipe(stream(options))
45-
.on('data', function(data) {
46-
result = data;
47-
})
48-
.on('error', function(err) {
49-
fn(err);
50-
})
51-
.on('end', function() {
52-
fn(null, result);
53-
});
65+
return promise;
5466
};
5567

5668
module.exports.stream = stream;

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"start": "zuul --local 3001 --open -- test/*.test.js",
2020
"test": "mocha",
2121
"ci": "./node_modules/istanbul/lib/cli.js cover _mocha -- -R spec ./test/*.test.js",
22-
"check": "mongodb-js-precommit"
22+
"check": "mongodb-js-precommit",
23+
"lint": "eslint lib test examples --fix"
2324
},
2425
"precommit": [
2526
"check"

‎test/promise-or-callback.test.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
var getSchema = require('../');
2+
var assert = require('assert');
3+
var _ = require('lodash');
4+
5+
describe('getSchema should return promise', function() {
6+
var docs = [
7+
{ foo: 'bar'},
8+
{ country: 'Croatia'},
9+
{ country: 'Croatia'},
10+
{ country: 'England'},
11+
];
12+
13+
it('Check if return value is a promise', () => {
14+
var result = getSchema(docs);
15+
assert.strictEqual(result instanceof Promise, true);
16+
});
17+
18+
it('Check that promise returns expected schema', async() => {
19+
const result = await getSchema(docs);
20+
const fieldNames = result.fields.map(v => v.name);
21+
assert.deepStrictEqual(fieldNames, ['country', 'foo']);
22+
});
23+
24+
describe('Check callback and promise return the same thing; success', () => {
25+
let promiseResponse;
26+
let callbackResponse;
27+
28+
before((done) => {
29+
getSchema(docs).then((result) => {
30+
promiseResponse = result;
31+
});
32+
getSchema(docs, (err, callbackResult) => {
33+
if (err) {
34+
throw err;
35+
}
36+
callbackResponse = callbackResult;
37+
done();
38+
});
39+
});
40+
41+
it('Using callback and promise should return the same thing', () => {
42+
assert(_.isEqual(promiseResponse, callbackResponse));
43+
});
44+
});
45+
46+
describe('Check callback and promise return the same thing; failure', () => {
47+
let promiseErrMessage;
48+
let callbackErrMessage;
49+
50+
before((done) => {
51+
getSchema({foo: 'bar'}, (err) => {
52+
getSchema({foo: 'bar'}).catch(error => {
53+
promiseErrMessage = error.message;
54+
});
55+
callbackErrMessage = err.message;
56+
done();
57+
});
58+
});
59+
60+
it('Using callback and promise should give same err message', () => {
61+
assert.strictEqual(promiseErrMessage, callbackErrMessage);
62+
});
63+
});
64+
});

0 commit comments

Comments
 (0)
Please sign in to comment.