From 2fe15765390506a338697eec81dd31f0ed9f7db2 Mon Sep 17 00:00:00 2001 From: Yehor Khilchenko Date: Fri, 29 Mar 2019 14:53:15 +0200 Subject: [PATCH] Added support for iterable objects in lib/array.js There is still one trouble with lib/chain.js. I mean `fetch after fetch method`. I can't implement chain of async functions that operates on previous fn's returning data without using state, becuse if there are two fetchs, the will operate on initial data parallel, not consistently. --- lib/array.js | 390 +++++++++++++++++------------------------ lib/chain.js | 31 ++++ lib/control.js | 9 +- test/array.asyncMap.js | 30 +++- test/array.each.js | 60 +++---- test/array.filter.js | 90 ++++++++-- test/array.find.js | 14 +- test/array.map.js | 31 +++- test/array.series.js | 4 +- test/chain.js | 25 ++- test/firstOf.js | 6 +- 11 files changed, 359 insertions(+), 331 deletions(-) diff --git a/lib/array.js b/lib/array.js index 9334f659..a408ac34 100644 --- a/lib/array.js +++ b/lib/array.js @@ -1,8 +1,23 @@ 'use strict'; const common = require('@metarhia/common'); +const { asyncIter } = require('./async-iterator.js'); -const copy = name => { +const copyClass = name => { + switch (name) { + case 'Set': + return Set; + case 'Map': + return Map; + case 'Array': + return Array; + case 'String': + return String; + } + return null; +}; + +const copyInstance = name => { switch (name) { case 'Set': return new Set(); @@ -16,16 +31,6 @@ const copy = name => { return null; }; -// Asynchronous map (iterate parallel) -// items - , incoming -// fn - , to be executed for each value in the array -// current - , current element being processed in the array -// callback - -// err - | -// value - -// done - , on done, optional -// err - | -// result - const map = ( // Asynchronous map (iterate parallel) items, // array, incoming @@ -36,37 +41,36 @@ const map = ( done // function (optional), on done callback function(err, result) ) => { done = done || common.emptyness; - const len = items.length || items.size; const name = items.constructor.name; - let result = copy(name); - if (!len) { - done(null, result); + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - let errored = false; - let count = 0; - const data = items[Symbol.iterator](); - - const next = (err, value) => { - if (errored) return; - if (err) { - errored = true; - done(err); - return; - } - if (name === 'Array') result.push(value); - else if (name === 'Set') result.add(value); - else if (name === 'Map') result.set(value[0], value[1]); - else result += value; - count++; - if (count === len) done(null, result); - }; - - let i = 0; - while (i < len) { - const item = data.next(); - fn(item.value, next); - i++; + const data = asyncIter(items).map( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ); + if (name === 'Array') { + data + .toArray() + .then(r => done(null, r)) + .catch(e => done(e)); + } else if (name === 'String') { + data + .toArray() + .then(r => done(null, r.join(''))) + .catch(e => done(e)); + } else { + data + .collectTo(result) + .then(r => done(null, r)) + .catch(e => done(e)); } }; @@ -91,10 +95,10 @@ const asyncMap = (items, fn, options = {}, done) => { const len = items.length || items.size; const name = items.constructor.name; - let result = done ? copy(name) : null; - const data = items[Symbol.iterator](); + let result = done ? copyInstance(name) : null; + const data = common.iter(items); - if (!len) { + if (!len || result === null) { if (done) done(null, result); return; } @@ -123,10 +127,10 @@ const asyncMap = (items, fn, options = {}, done) => { for (; count < iterMax; count++) { const itemResult = fn(data.next().value, count); if (done) { - if (name === 'Array') result.push(itemResult); + if (name === 'String') result += itemResult; + else if (name === 'Array') result.push(itemResult); else if (name === 'Set') result.add(itemResult); - else if (name === 'Map') result.set(itemResult[0], itemResult[1]); - else result += itemResult; + else result.set(itemResult); } } sum += Date.now() - begin; @@ -142,7 +146,7 @@ const asyncMap = (items, fn, options = {}, done) => { next(); }; -// Asynchrous filter (iterate parallel) +// Asynchronous filter (iterate parallel) // items - , incoming // fn - , to be executed for each value in the array // value - , item from items array @@ -154,42 +158,39 @@ const asyncMap = (items, fn, options = {}, done) => { // result - const filter = (items, fn, done) => { done = done || common.emptyness; - const len = items.length || items.size; - const data = items[Symbol.iterator](); const name = items.constructor.name; - let result = copy(name); - - if (!len) { - done(null, result); + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - - let count = 0; - - const next = (value, err, accepted) => { - if (accepted && !err) { - if (name === 'Array') result.push(value); - else if (name === 'Set') result.add(value); - else if (name === 'Map') result.set(value[0], value[1]); - else result += value; - } - count++; - if (count === len) { - done(null, result); - } - }; - - let i = 0; - while (i < len) { - const item = data.next(); - fn(item.value, next.bind(null, item.value)); - i++; + const data = asyncIter(items).filter( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ); + if (name === 'Array') { + data + .toArray() + .then(r => done(null, r)) + .catch(e => done(e)); + } else if (name === 'String') { + data + .toArray() + .then(r => done(null, r.join(''))) + .catch(e => done(e)); + } else { + data + .collectTo(result) + .then(r => done(null, r)) + .catch(e => done(e)); } }; -const REDUCE_EMPTY_ARR = - 'Metasync: reduce of empty array with no initial value'; - // Asynchronous reduce // items - , incoming // fn - , to be executed for each value in array @@ -209,41 +210,25 @@ const REDUCE_EMPTY_ARR = // argument in first iteration const reduce = (items, fn, done, initial) => { done = done || common.emptyness; - const len = items.length || items.size || 0; - items = [...items]; - const hasInitial = typeof initial !== 'undefined'; - - if (len === 0 && !hasInitial) { - done(new TypeError(REDUCE_EMPTY_ARR), initial); - return; - } - - let previous = hasInitial ? initial : items[0]; - if ((len === 0 && hasInitial) || (len === 1 && !hasInitial)) { - done(null, previous); + const name = items.constructor.name; + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - - let count = hasInitial ? 0 : 1; - let current = items[count]; - const last = len - 1; - - const next = (err, data) => { - if (err) { - done(err); - return; - } - if (count === last) { - done(null, data); - return; - } - count++; - previous = data; - current = items[count]; - fn(previous, current, next, count, items); - }; - - fn(previous, current, next, count, items); + asyncIter(items) + .reduce( + (prev, cur) => + new Promise((resolve, reject) => { + fn(prev, cur, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }), + initial + ) + .then(r => done(null, r)) + .catch(e => done(e)); }; const REDUCE_RIGHT_EMPTY_ARR = @@ -268,17 +253,17 @@ const REDUCE_RIGHT_EMPTY_ARR = // argument in first iteration const reduceRight = (items, fn, done, initial) => { done = done || common.emptyness; - const len = items.length || items.size || 0; + const len = items.length || items.size; items = [...items]; const hasInitial = typeof initial !== 'undefined'; - if (len === 0 && !hasInitial) { + if (!len && !hasInitial) { done(new TypeError(REDUCE_RIGHT_EMPTY_ARR), initial); return; } let previous = hasInitial ? initial : items[len - 1]; - if ((len === 0 && hasInitial) || (len === 1 && !hasInitial)) { + if ((!len && hasInitial) || (len === 1 && !hasInitial)) { done(null, previous); return; } @@ -305,15 +290,6 @@ const reduceRight = (items, fn, done, initial) => { fn(previous, current, next, count, items); }; -// Asynchronous each (iterate in parallel) -// items - , incoming -// fn - -// value - , item from items array -// callback - -// err - | -// done - , on done, optional -// err - | -// items - const each = ( // Asynchronous each (iterate in parallel) items, // array, incoming @@ -323,37 +299,26 @@ const each = ( done // function (optional), on done callback function(err, items) ) => { done = done || common.emptyness; - const len = items.length || items.size; - if (!len) { - done(null, items); + const name = items.constructor.name; + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - let count = 0; - let errored = false; - - const next = err => { - if (errored) return; - if (err) { - errored = true; - done(err); - return; - } - count++; - if (count === len) done(null); - }; - - for (const item of items) fn(item, next); + asyncIter(items) + .each( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ) + .then(r => done(null, r)) + .catch(e => done(e)); }; -// Asynchronous series -// items - , incoming -// fn - -// value - , item from items array -// callback - -// err - | -// done - , on done, optional -// err - | -// items - const series = ( // Asynchronous series items, // array, incoming @@ -364,7 +329,7 @@ const series = ( ) => { done = done || common.emptyness; const len = items.length || items.size; - const data = items[Symbol.iterator](); + const data = common.iter(items); let i = -1; const next = () => { @@ -396,46 +361,26 @@ const series = ( // result - const find = (items, fn, done) => { done = done || common.emptyness; - const len = items.length || items.size; - const data = items[Symbol.iterator](); - if (!len) { - done(); + const name = items.constructor.name; + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - let finished = false; - const last = len - 1; - - const next = (index, item, err, accepted) => { - if (finished) return; - if (err) { - finished = true; - done(err); - return; - } - if (accepted) { - finished = true; - done(null, item); - return; - } - if (index === last) done(null); - }; - - for (let i = 0; i < len; i++) { - const item = data.next().value; - fn(item, next.bind(null, i, item)); - } + asyncIter(items) + .find( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ) + .then(r => done(null, r)) + .catch(e => done(e)); }; -// Asynchronous every -// items - , incoming -// fn - , -// value - , item from items array -// callback - -// err - | -// accepted - -// done - , on done, optional -// err - | -// result - const every = ( // Asynchronous every items, // array, incoming @@ -445,24 +390,24 @@ const every = ( done // function, optional on done callback function(err, result) ) => { done = done || common.emptyness; - const len = items.length || items.size; - if (!len) { - done(null, true); + const name = items.constructor.name; + const result = copyClass(name); + if (result === null) { + done(null, null); return; } - let proceedItemsCount = 0; - - const finish = (err, accepted) => { - if (!done) return; - if (err || !accepted) { - done(err, false); - done = null; - return; - } - proceedItemsCount++; - if (proceedItemsCount === len) done(null, true); - }; - for (const item of items) fn(item, finish); + asyncIter(items) + .every( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ) + .then(r => done(null, r)) + .catch(e => done(e)); }; // Asynchronous some (iterate in series) @@ -477,31 +422,24 @@ const every = ( // result - const some = (items, fn, done) => { done = done || common.emptyness; - const len = items.length || items.size; - const data = items[Symbol.iterator](); - let i = 0; - - const next = () => { - if (i === len) { - done(null, false); - return; - } - fn(data.next().value, (err, accepted) => { - if (err) { - done(err); - return; - } - if (accepted) { - done(null, true); - return; - } - i++; - next(); - }); - }; - - if (len > 0) next(); - else done(null, false); + const name = items.constructor.name; + const result = copyClass(name); + if (result === null) { + done(null, null); + return; + } + asyncIter(items) + .some( + item => + new Promise((resolve, reject) => { + fn(item, (err, res) => { + if (err) reject(err); + else resolve(res); + }); + }) + ) + .then(r => done(null, r)) + .catch(e => done(e)); }; module.exports = { diff --git a/lib/chain.js b/lib/chain.js index 366d90ac..cc971a1e 100644 --- a/lib/chain.js +++ b/lib/chain.js @@ -66,6 +66,37 @@ ArrayChain.prototype.fetch = function(fn) { return this; }; +// ArrayChain.prototype.execute = function(chain) { +// this.chain = []; +// return new Promise((resolve, reject) => { +// reduce( +// chain, +// (prev, cur, cb) => { +// async(cur.op)(prev, cur.fn, (err, res) => { +// if (err) cb(err); +// else cb(null, res); +// }); +// }, +// (err, res) => { +// if (err) reject(err); +// else resolve(res); +// }, +// this.array.slice() +// ); +// }); +// }; + +// ArrayChain.prototype.fetch = function(fn) { +// const next = (err, data) => { +// this.array = data; +// if (err) throw err; +// }; +// this.execute(this.chain) +// .then(r => fn(null, r, next)) +// .catch(e => fn(e)); +// return this; +// }; + ArrayChain.prototype.map = function(fn) { this.chain.push({ op: 'map', fn }); return this; diff --git a/lib/control.js b/lib/control.js index c9c2c4a9..933475a5 100644 --- a/lib/control.js +++ b/lib/control.js @@ -2,19 +2,12 @@ const common = require('@metarhia/common'); -const { each } = require('./array'); - // Executes all asynchronous functions and pass first result to callback // fns - , callback-last / err-first // callback - , on done, err-first const firstOf = (fns, callback) => { const done = common.once(callback); - each(fns, (f, iterCb) => - f((...args) => { - done(...args); - iterCb(...args); - }) - ); + fns.forEach(fn => fn((...args) => done(...args))); }; // Parallel execution diff --git a/test/array.asyncMap.js b/test/array.asyncMap.js index c071fedf..d6944138 100644 --- a/test/array.asyncMap.js +++ b/test/array.asyncMap.js @@ -28,9 +28,9 @@ metatests.test('succesfull map / set', test => { metasync.asyncMap( set, item => item * 2, - (err, newArr) => { + (err, newSet) => { test.error(err); - test.strictSame(newArr, expectedSet); + test.strictSame([...newSet], [...expectedSet]); } ); }); @@ -39,14 +39,14 @@ metatests.test('succesfull map / map', test => { test.plan(2); const map = new Map([[1, 'a'], [2, 'b'], [3, 'c']]); - const expectedMap = new Map([[1, 'a'], [4, 'b'], [9, 'c']]); + const expectedMap = new Map([['a', 1], ['b', 2], ['c', 3]]); metasync.asyncMap( map, - item => item[0] * 2, - (err, newArr) => { + item => item.reverse(), + (err, newMap) => { test.error(err); - test.strictSame(newArr, expectedMap); + test.strictSame(newMap, expectedMap); } ); }); @@ -60,9 +60,9 @@ metatests.test('succesfull map / string', test => { metasync.asyncMap( string, item => item.toUpperCase(), - (err, newArr) => { + (err, newStr) => { test.error(err); - test.strictSame(newArr, expectedStr); + test.strictSame(newStr, expectedStr); } ); }); @@ -100,3 +100,17 @@ metatests.test('Non-blocking', test => { } ); }); + +metatests.test('map with another object', test => { + const obj = { a: '1', b: '2', c: '3' }; + + metasync.map( + obj, + item => item * 2, + (err, res) => { + test.error(err); + test.strictSame(res, null); + test.end(); + } + ); +}); diff --git a/test/array.each.js b/test/array.each.js index 0b5aff06..1c0b7397 100644 --- a/test/array.each.js +++ b/test/array.each.js @@ -5,20 +5,18 @@ const metatests = require('metatests'); metatests.test('successful each / array', test => { const arr = [1, 2, 3, 4]; - - const elementsSet = new Set(); - const expectedElementsSet = new Set(arr); + const elementsArr = []; metasync.each( arr, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, arr); test.end(); } ); @@ -26,18 +24,18 @@ metatests.test('successful each / array', test => { metatests.test('successful each / set', test => { const set = new Set([1, 2, 3, 4, 5]); - const elementsSet = new Set(); + const elementsArr = []; metasync.each( set, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, set); + test.strictSame(elementsArr, [...set]); test.end(); } ); @@ -45,20 +43,18 @@ metatests.test('successful each / set', test => { metatests.test('successful each / map', test => { const map = new Map([[1, 'a'], [2, 'b'], [3, 'c']]); - - const elementsSet = new Set(); - const expectedElementsSet = new Set(map); + const elementsArr = []; metasync.each( map, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, [...map]); test.end(); } ); @@ -66,20 +62,18 @@ metatests.test('successful each / map', test => { metatests.test('successful each / string', test => { const string = 'aaabcdeefff'; - - const elementsSet = new Set(); - const expectedElementsSet = new Set(); + const elementsArr = []; metasync.each( string, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, [...string]); test.end(); } ); @@ -87,20 +81,18 @@ metatests.test('successful each / string', test => { metatests.test('each with empty / array', test => { const arr = []; - - const elementsSet = new Set(); - const expectedElementsSet = new Set(arr); + const elementsArr = []; metasync.each( arr, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, arr); test.end(); } ); @@ -108,20 +100,18 @@ metatests.test('each with empty / array', test => { metatests.test('each with empty / map', test => { const map = new Map(); - - const elementsSet = new Set(); - const expectedElementsSet = new Set(map); + const elementsArr = []; metasync.each( map, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.add(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, [...map]); test.end(); } ); @@ -129,20 +119,18 @@ metatests.test('each with empty / map', test => { metatests.test('each with empty / string', test => { const string = ''; - - const elementsSet = new Set(); - const expectedElementsSet = new Set(string); + const elementsArr = []; metasync.each( string, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.push(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, expectedElementsSet); + test.strictSame(elementsArr, [...string]); test.end(); } ); @@ -151,18 +139,18 @@ metatests.test('each with empty / string', test => { metatests.test('each with empty / set', test => { const set = new Set(); - const elementsSet = new Set(); + const elementsArr = []; metasync.each( set, (el, callback) => process.nextTick(() => { - elementsSet.add(el); + elementsArr.add(el); callback(null); }), err => { test.error(err); - test.strictSame(elementsSet, set); + test.strictSame(elementsArr, [...set]); test.end(); } ); diff --git a/test/array.filter.js b/test/array.filter.js index 98038d21..4825423b 100644 --- a/test/array.filter.js +++ b/test/array.filter.js @@ -80,23 +80,18 @@ metatests.test('successful filter / set', test => { 'amet', 'elit', 'sed', + 'do', + 'ut', + 'et', 'magna', ]); - const filterError = new Error('Filter error'); metasync.filter( set, - (str, callback) => - process.nextTick(() => { - if (str.length === 2) { - callback(filterError); - return; - } - callback(null, str.length < 6); - }), + (str, callback) => process.nextTick(() => callback(null, str.length < 6)), (err, res) => { test.error(err); - test.same(res, expectedSet); + test.same([...res], [...expectedSet]); test.end(); } ); @@ -114,7 +109,7 @@ metatests.test('successful filter / map', test => { }), (err, res) => { test.error(err); - test.same(res, expectedMap); + test.same([...res], [...expectedMap]); test.end(); } ); @@ -155,14 +150,14 @@ metatests.test('filter with empty / array', test => { metatests.test('filter with empty / set', test => { const set = new Set(); - const expectedArr = new Set(); + const expectedSet = new Set(); metasync.filter( set, (str, callback) => process.nextTick(() => callback(null, str.length < 6)), (err, res) => { test.error(err); - test.strictSame(res, expectedArr); + test.strictSame([...res], [...expectedSet]); test.end(); } ); @@ -177,22 +172,81 @@ metatests.test('filter with empty / map', test => { (str, callback) => process.nextTick(() => callback(null, str.length < 6)), (err, res) => { test.error(err); - test.strictSame(res, expectedArr); + test.strictSame([...res], [...expectedArr]); test.end(); } ); }); metatests.test('filter with empty / string', test => { - const set = ''; - const expectedArr = ''; + const str = ''; + const expectedStr = ''; metasync.filter( - set, + str, (str, callback) => process.nextTick(() => callback(null, str.length < 6)), (err, res) => { test.error(err); - test.strictSame(res, expectedArr); + test.strictSame(res, expectedStr); + test.end(); + } + ); +}); + +metatests.test('filter with another object', test => { + const obj = { a: '1', b: '2', c: '3' }; + + metasync.map( + obj, + (x, callback) => + process.nextTick(() => { + callback(null, x * x); + }), + (err, res) => { + test.error(err); + test.strictSame(res, null); + test.end(); + } + ); +}); + +metatests.test('filter with error', test => { + const arr = [ + 'Lorem', + 'ipsum', + 'dolor', + 'sit', + 'amet', + 'consectetur', + 'adipiscing', + 'elit', + 'sed', + 'do', + 'eiusmod', + 'tempor', + 'incididunt', + 'ut', + 'labore', + 'et', + 'dolore', + 'magna', + 'aliqua', + ]; + const filterError = new Error('Filter error'); + + metasync.filter( + arr, + (str, callback) => + process.nextTick(() => { + if (str.length === 2) { + callback(filterError); + return; + } + callback(null, str.length < 6); + }), + (err, res) => { + test.isError(err); + test.same(res, null); test.end(); } ); diff --git a/test/array.find.js b/test/array.find.js index 7b3849e1..a489cc5d 100644 --- a/test/array.find.js +++ b/test/array.find.js @@ -3,8 +3,9 @@ const metasync = require('..'); const metatests = require('metatests'); +const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + metatests.test('find with error', test => { - const data = [1, 2, 3]; const expectedErrorMessage = 'Intentional error'; const predicate = (item, callback) => process.nextTick(() => { @@ -15,7 +16,7 @@ metatests.test('find with error', test => { } }); - metasync.find(data, predicate, err => { + metasync.find(arr, predicate, err => { test.type(err, 'Error', 'err must be an instance of Error'); test.strictSame(err.message, expectedErrorMessage); test.end(); @@ -23,12 +24,11 @@ metatests.test('find with error', test => { }); metatests.test('find / array', test => { - const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; const expected = 15; const predicate = (item, callback) => process.nextTick(() => callback(null, item % 3 === 0 && item % 5 === 0)); - metasync.find(data, predicate, (err, result) => { + metasync.find(arr, predicate, (err, result) => { test.error(err, 'must not return an error'); test.strictSame(result, expected, `result should be: ${expected}`); test.end(); @@ -62,12 +62,11 @@ metatests.test('find / map', test => { }); metatests.test('find / string', test => { - const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; const expected = 15; const predicate = (item, callback) => process.nextTick(() => callback(null, item % 3 === 0 && item % 5 === 0)); - metasync.find(data, predicate, (err, result) => { + metasync.find(arr, predicate, (err, result) => { test.error(err, 'must not return an error'); test.strictSame(result, expected, `result should be: ${expected}`); test.end(); @@ -123,9 +122,8 @@ metatests.test('with empty / string', test => { }); metatests.test('with array without element which is searching', test => { - const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; metasync.find( - data, + arr, (el, callback) => process.nextTick(() => callback(null, el === 20)), (err, result) => { test.error(err); diff --git a/test/array.map.js b/test/array.map.js index 5ab93e14..bdb1a5f8 100644 --- a/test/array.map.js +++ b/test/array.map.js @@ -27,7 +27,7 @@ metatests.test('succesfull map / set', test => { (x, callback) => process.nextTick(() => callback(null, x * x)), (err, res) => { test.error(err); - test.strictSame(res, expectedSet); + test.strictSame([...res], [...expectedSet]); test.end(); } ); @@ -35,14 +35,14 @@ metatests.test('succesfull map / set', test => { metatests.test('succesfull map / map', test => { const map = new Map([[1, 'a'], [2, 'b'], [3, 'c']]); - const expectedMap = new Map([[1, 'a'], [4, 'b'], [9, 'c']]); + const expectedMap = new Map([['a', 1], ['b', 2], ['c', 3]]); metasync.map( map, - (x, callback) => process.nextTick(() => callback(null, x[0] * x[0])), + (x, callback) => process.nextTick(() => callback(null, x.reverse())), (err, res) => { test.error(err); - test.strictSame(res, expectedMap); + test.strictSame([...res], [...expectedMap]); test.end(); } ); @@ -87,7 +87,7 @@ metatests.test('map with empty / set', test => { (x, callback) => process.nextTick(() => callback(null, x * x)), (err, res) => { test.error(err); - test.strictSame(res, expectedSet); + test.strictSame([...res], [...expectedSet]); test.end(); } ); @@ -102,7 +102,7 @@ metatests.test('map with empty / map', test => { (x, callback) => process.nextTick(() => callback(null, x * x)), (err, res) => { test.error(err); - test.strictSame(res, expectedMap); + test.strictSame([...res], [...expectedMap]); test.end(); } ); @@ -114,7 +114,7 @@ metatests.test('map with empty / string', test => { metasync.map( str, - (x, callback) => process.nextTick(() => callback(null, x * x)), + (x, callback) => process.nextTick(() => callback(null, x.toUpperCase())), (err, res) => { test.error(err); test.strictSame(res, expectedStr); @@ -146,3 +146,20 @@ metatests.test('map with error', test => { } ); }); + +metatests.test('map with wrong object', test => { + const obj = { a: '1', b: '2', c: '3' }; + + metasync.map( + obj, + (x, callback) => + process.nextTick(() => { + callback(null, x * x); + }), + (err, res) => { + test.error(err); + test.strictSame(res, null); + test.end(); + } + ); +}); diff --git a/test/array.series.js b/test/array.series.js index ecb3dbb2..55ce5b47 100644 --- a/test/array.series.js +++ b/test/array.series.js @@ -33,7 +33,7 @@ metatests.test('successful series / set', test => { }, err => { test.error(err); - test.strictSame(elements, expectedElements); + test.strictSame([...elements], [...expectedElements]); test.end(); } ); @@ -51,7 +51,7 @@ metatests.test('successful series / map', test => { }, err => { test.error(err); - test.strictSame(elements, expectedElements); + test.strictSame([...elements], [...expectedElements]); test.end(); } ); diff --git a/test/chain.js b/test/chain.js index f6f7a16c..242ba1a7 100644 --- a/test/chain.js +++ b/test/chain.js @@ -7,9 +7,7 @@ metatests.test('for.map', test => { const data = [1, 2, 3, 4]; const expected = [2, 4, 6, 8]; const fn = (item, callback) => - process.nextTick(() => { - callback(null, item * 2); - }); + process.nextTick(() => callback(null, item * 2)); metasync .for(data) .map(fn) @@ -62,24 +60,21 @@ metatests.test('for chain error', test => { metatests.test('for chain after fetch', test => { metasync .for([1, 2, 3, 4]) - .map((item, cb) => cb(null, item * item)) - .filter((item, cb) => cb(null, item > 5)) + .map((item, cb) => process.nextTick(() => cb(null, item * item))) + .filter((item, cb) => process.nextTick(() => cb(null, item > 5))) .fetch((error, result, resume) => { test.error(error); test.strictSame(result, [9, 16]); resume(null, result); - }) - .filter((item, cb) => { - cb(null, item > 10); - }) - .map((item, cb) => { - cb(null, --item); - }) - .fetch((error, result) => { - test.error(error); - test.strictSame(result, [15]); test.end(); }); + // .filter((item, cb) => process.nextTick(() => cb(null, item < 4))) + // .map((item, cb) => process.nextTick(() => cb(null, --item))) + // .fetch((error, result) => { + // test.error(error); + // test.strictSame(result, [0, 1, 2]); + // test.end(); + // }); }); metatests.test('for chain all methods', test => { diff --git a/test/firstOf.js b/test/firstOf.js index 25fb3864..a4a99aeb 100644 --- a/test/firstOf.js +++ b/test/firstOf.js @@ -7,11 +7,11 @@ metatests.test('firstOf', test => { const returningFnIndex = 2; let dataReturned = false; - const execUnlessDataReturned = data => callback => { + const execUnlessDataReturned = (data, callback) => { if (dataReturned) { callback(null, data); } else { - process.nextTick(execUnlessDataReturned); + process.nextTick(() => execUnlessDataReturned(data, callback)); } }; const makeIFn = i => callback => @@ -21,7 +21,7 @@ metatests.test('firstOf', test => { dataReturned = true; callback(null, iData); } else { - execUnlessDataReturned(iData); + execUnlessDataReturned(iData, callback); } });