Skip to content

Commit

Permalink
Added promise support for library (#140)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
alexbjorlig committed Feb 10, 2021
1 parent 39af582 commit d73f838
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 38 deletions.
6 changes: 2 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
"parserOptions": {
"ecmaVersion": 2017
},
"env": {
"es6": true
}
"env": {
"mocha": true,
"node": true
"node": true,
"es6": true
},
"globals": {
"expect": true,
Expand Down
78 changes: 45 additions & 33 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,55 @@ var _ = require('lodash');
* @param {Boolean} options.semanticTypes enable semantic type detection (default: false)
* @param {Boolean} options.storeValues enable storing of values (default: true)
*
* @param {Function} fn Callback which will be passed `(err, schema)`
* @param {Function} callback Callback which will be passed `(err, schema)`
* @return {Promise} You can await promise, or use callback if provided.
*/
module.exports = function(docs, options, fn) {
// shift parameters if no options are specified
if (_.isUndefined(options) || _.isFunction(options) && _.isUndefined(fn)) {
fn = options;
options = {};
}
module.exports = function(docs, options, callback) {
const promise = new Promise((resolve, reject) => {
// shift parameters if no options are specified
if (_.isUndefined(options) || (_.isFunction(options) && _.isUndefined(callback))) {
callback = options;
options = {};
}

var src;
// MongoDB Cursors
if (docs.stream && typeof docs.stream === 'function') {
src = docs.stream();
// Streams
} else if (docs.pipe && typeof docs.pipe === 'function') {
src = docs;
// Arrays
} else if (_.isArray(docs)) {
src = es.readArray(docs);
} else {
reject(new Error(
'Unknown input type for `docs`. Must be an array, ' +
'stream or MongoDB Cursor.'
));
return;
}

var result;

src
.pipe(stream(options))
.on('data', function(data) {
result = data;
})
.on('error', function(err) {
reject(err);
})
.on('end', function() {
resolve(result);
});
});

var src;
// MongoDB Cursors
if (docs.stream && typeof docs.stream === 'function') {
src = docs.stream();
// Streams
} else if (docs.pipe && typeof docs.pipe === 'function') {
src = docs;
// Arrays
} else if (_.isArray(docs)) {
src = es.readArray(docs);
} else {
fn(new Error('Unknown input type for `docs`. Must be an array, '
+ 'stream or MongoDB Cursor.'));
return;
if (callback && typeof callback === 'function') {
promise.then(callback.bind(null, null), callback);
}

var result;

src.pipe(stream(options))
.on('data', function(data) {
result = data;
})
.on('error', function(err) {
fn(err);
})
.on('end', function() {
fn(null, result);
});
return promise;
};

module.exports.stream = stream;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"start": "zuul --local 3001 --open -- test/*.test.js",
"test": "mocha",
"ci": "./node_modules/istanbul/lib/cli.js cover _mocha -- -R spec ./test/*.test.js",
"check": "mongodb-js-precommit"
"check": "mongodb-js-precommit",
"lint": "eslint lib test examples --fix"
},
"precommit": [
"check"
Expand Down
64 changes: 64 additions & 0 deletions test/promise-or-callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
var getSchema = require('../');
var assert = require('assert');
var _ = require('lodash');

describe('getSchema should return promise', function() {
var docs = [
{ foo: 'bar'},
{ country: 'Croatia'},
{ country: 'Croatia'},
{ country: 'England'},
];

it('Check if return value is a promise', () => {
var result = getSchema(docs);
assert.strictEqual(result instanceof Promise, true);
});

it('Check that promise returns expected schema', async() => {
const result = await getSchema(docs);
const fieldNames = result.fields.map(v => v.name);
assert.deepStrictEqual(fieldNames, ['country', 'foo']);
});

describe('Check callback and promise return the same thing; success', () => {
let promiseResponse;
let callbackResponse;

before((done) => {
getSchema(docs).then((result) => {
promiseResponse = result;
});
getSchema(docs, (err, callbackResult) => {
if (err) {
throw err;
}
callbackResponse = callbackResult;
done();
});
});

it('Using callback and promise should return the same thing', () => {
assert(_.isEqual(promiseResponse, callbackResponse));
});
});

describe('Check callback and promise return the same thing; failure', () => {
let promiseErrMessage;
let callbackErrMessage;

before((done) => {
getSchema({foo: 'bar'}, (err) => {
getSchema({foo: 'bar'}).catch(error => {
promiseErrMessage = error.message;
});
callbackErrMessage = err.message;
done();
});
});

it('Using callback and promise should give same err message', () => {
assert.strictEqual(promiseErrMessage, callbackErrMessage);
});
});
});

0 comments on commit d73f838

Please sign in to comment.