var async = require('../lib'); var expect = require('chai').expect; var assert = require('assert'); describe("map", function() { function mapIteratee(call_order, x, callback) { setTimeout(function() { call_order.push(x); callback(null, x * 2); }, x * 25); } it('basic', function(done) { var call_order = []; async.map([1, 3, 2], mapIteratee.bind(this, call_order), function(err, results) { assert(err === null, err + " passed instead of 'null'"); expect(call_order).to.eql([1, 2, 3]); expect(results).to.eql([2, 6, 4]); done(); }); }); it('with reflect', function(done) { var call_order = []; async.map([1, 3, 2], async.reflect(function(item, cb) { setTimeout(function() { call_order.push(item); cb(null, item * 2); }, item * 25); }), function(err, results) { assert(err === null, err + " passed instead of 'null'"); expect(call_order).to.eql([1, 2, 3]); expect(results).to.eql([{ value: 2 }, { value: 6 }, { value: 4 }]); done(); }); }); it('error with reflect', function(done) { var call_order = []; async.map([-1, 1, 3, 2], async.reflect(function(item, cb) { setTimeout(function() { call_order.push(item); if (item < 0) { cb('number less then zero'); } else { cb(null, item * 2); } }, item * 25); }), function(err, results) { assert(err === null, err + " passed instead of 'null'"); expect(call_order).to.eql([-1, 1, 2, 3]); expect(results).to.eql([{ error: 'number less then zero' }, { value: 2 }, { value: 6 }, { value: 4 }]); done(); }); }); it('map original untouched', function(done) { var a = [1, 2, 3]; async.map(a, function(x, callback) { callback(null, x * 2); }, function(err, results) { expect(results).to.eql([2, 4, 6]); expect(a).to.eql([1, 2, 3]); done(); }); }); it('map without main callback', function(done) { var a = [1, 2, 3]; var r = []; async.map(a, function(x, callback) { r.push(x); var done_ = r.length == a.length; callback(null); if (done_) { expect(r).to.eql(a); done(); } }); }); it('map error', function(done) { async.map([1, 2, 3], function(x, callback) { callback('error'); }, function(err) { expect(err).to.equal('error'); }); setTimeout(done, 50); }); it('map undefined array', function(done) { async.map(undefined, function(x, callback) { callback(); }, function(err, result) { expect(err).to.equal(null); expect(result).to.eql([]); }); setTimeout(done, 50); }); it('map object', function(done) { async.map({ a: 1, b: 2, c: 3 }, function(val, callback) { callback(null, val * 2); }, function(err, result) { if (err) throw err; expect(Object.prototype.toString.call(result)).to.equal('[object Array]'); expect(result).to.contain(2); expect(result).to.contain(4); expect(result).to.contain(6); done(); }); }); it('mapSeries', function(done) { var call_order = []; async.mapSeries([1, 3, 2], mapIteratee.bind(this, call_order), function(err, results) { assert(err === null, err + " passed instead of 'null'"); expect(call_order).to.eql([1, 3, 2]); expect(results).to.eql([2, 6, 4]); done(); }); }); it('mapSeries error', function(done) { async.mapSeries([1, 2, 3], function(x, callback) { callback('error'); }, function(err) { expect(err).to.equal('error'); }); setTimeout(done, 50); }); it('mapSeries undefined array', function(done) { async.mapSeries(undefined, function(x, callback) { callback(); }, function(err, result) { expect(err).to.equal(null); expect(result).to.eql([]); }); setTimeout(done, 50); }); it('mapSeries object', function(done) { async.mapSeries({ a: 1, b: 2, c: 3 }, function(val, callback) { callback(null, val * 2); }, function(err, result) { if (err) throw err; expect(result).to.contain(2); expect(result).to.contain(4); expect(result).to.contain(6); done(); }); }); it('mapLimit', function(done) { var call_order = []; async.mapLimit([2, 4, 3], 2, mapIteratee.bind(this, call_order), function(err, results) { assert(err === null, err + " passed instead of 'null'"); expect(call_order).to.eql([2, 4, 3]); expect(results).to.eql([4, 8, 6]); done(); }); }); it('mapLimit empty array', function(done) { async.mapLimit([], 2, function(x, callback) { assert(false, 'iteratee should not be called'); callback(); }, function(err) { if (err) throw err; assert(true, 'should call callback'); }); setTimeout(done, 25); }); it('mapLimit undefined array', function(done) { async.mapLimit(undefined, 2, function(x, callback) { callback(); }, function(err, result) { expect(err).to.equal(null); expect(result).to.eql([]); }); setTimeout(done, 50); }); it('mapLimit limit exceeds size', function(done) { var call_order = []; async.mapLimit([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 20, mapIteratee.bind(this, call_order), function(err, results) { expect(call_order).to.eql([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); expect(results).to.eql([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]); done(); }); }); it('mapLimit limit equal size', function(done) { var call_order = []; async.mapLimit([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 10, mapIteratee.bind(this, call_order), function(err, results) { expect(call_order).to.eql([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); expect(results).to.eql([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]); done(); }); }); it('mapLimit zero limit', function(done) { async.mapLimit([0, 1, 2, 3, 4, 5], 0, function(x, callback) { assert(false, 'iteratee should not be called'); callback(); }, function(err, results) { expect(results).to.eql([]); assert(true, 'should call callback'); }); setTimeout(done, 25); }); it('mapLimit error', function(done) { var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; var call_order = []; async.mapLimit(arr, 3, function(x, callback) { call_order.push(x); if (x === 2) { callback('error'); } }, function(err) { expect(call_order).to.eql([0, 1, 2]); expect(err).to.equal('error'); }); setTimeout(done, 25); }); it('mapLimit does not continue replenishing after error', function(done) { var started = 0; var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; var delay = 10; var limit = 3; var maxTime = 10 * arr.length; async.mapLimit(arr, limit, function(x, callback) { started++; if (started === 3) { return callback(new Error("Test Error")); } setTimeout(function() { callback(); }, delay); }, function() {}); setTimeout(function() { expect(started).to.equal(3); done(); }, maxTime); }); it('map with Map', function(done) { if (typeof Map !== 'function') return done(); var map = new Map(); map.set(1, "a"); map.set(2, "b"); async.map(map, function(val, cb) { cb(null, val); }, function(err, result) { assert(Array.isArray(result), "map should return an array for an iterable"); done(); }); }); // Issue 1106 on github: https://github.com/caolan/async/issues/1106 it('map main callback is called only once', function(done) { async.map([1, 2], function(item, callback) { try { callback(item); } catch (exception) { expect(function() { callback(exception); }).to.throw(/already called/); done(); } }, function() { throw new Error(); }); }); });