Skip to content

Commit

Permalink
split reduce into reduce and inject
Browse files Browse the repository at this point in the history
  • Loading branch information
jdiamond committed Mar 16, 2013
1 parent aa231c2 commit 70f2e54
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 107 deletions.
94 changes: 57 additions & 37 deletions pointless.js
Expand Up @@ -131,37 +131,46 @@ P.map = P.binary(function(fn, _) {
return result;
});

P.reduce = function(_, fn, seed) {
var reduceError = 'Reduce of empty array with no initial value';

P.reduce = P.binary(function(fn, _) {
var result;
var seeded = arguments.length >= 3;
if (_.reduce) {
var ignoreIndex = function(previous, current) {
result = _.reduce(function(previous, current) {
return fn(previous, current);
};
result = seeded ? _.reduce(ignoreIndex, seed) : _.reduce(ignoreIndex);
});
} else if (P.isArrayLike(_)) {
var i = 0;
if (seeded) {
result = seed;
} else {
if (_.length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
i = 1;
result = _[0];
if (_.length === 0) {
throw new TypeError(reduceError);
}
var i = 1;
result = _[0];
for (var n = _.length; i < n; i++) {
result = fn(result, _[i]);
}
} else {
if (seeded) {
result = fn(seed, _);
} else {
result = _;
result = _;
}
return result;
});

P.inject = P.nary(3, function(fn, seed, _) {
var result;
if (_.inject) {
result = _.inject(function(previous, current) {
return fn(previous, current);
}, seed);
} else if (P.isArrayLike(_)) {
var i = 0;
result = seed;
for (var n = _.length; i < n; i++) {
result = fn(result, _[i]);
}
} else {
result = fn(seed, _);
}
return result;
};
});

P.each = function(_, fn) {
if (_.forEach) {
Expand Down Expand Up @@ -246,10 +255,15 @@ P.prototype.map = function(fn) {
return this.then(function(_) { return P.map(fn, _); });
};

P.prototype.reduce = function(fn, seed) {
var seeded = arguments.length === 2;
P.prototype.reduce = function(fn) {
return this.then(function(val) {
return P.reduce(fn, val);
});
};

P.prototype.inject = function(fn, seed) {
return this.then(function(val) {
return seeded ? P.reduce(val, fn, seed) : P.reduce(val, fn);
return P.inject(fn, seed, val);
});
};

Expand Down Expand Up @@ -359,23 +373,29 @@ Promise.prototype.then = function(fulfilled, rejected, progressed) {
);
};

Promise.prototype.reduce = function(fn, seed) {
var seeded = arguments.length === 2;
Promise.prototype.reduce = function(fn) {
return this.then(function(val) {
return seeded ? Q.when(seed)
.then(function(seed) {
return P.reduce(val, reducer, seed);
})
: P.reduce(val, reducer)
;
return P.reduce(function reducer(previous, current) {
return Q.when(previous)
.then(function(previous) {
return fn(previous, current);
});
}, val);
});
};

Promise.prototype.inject = function(fn, seed) {
return this.then(function(val) {
return Q.when(seed)
.then(function(seed) {
return P.inject(function(previous, current) {
return Q.when(previous)
.then(function(previous) {
return fn(previous, current);
});
}, seed, val);
});
});
function reducer(previous, current) {
return Q.when(previous)
.then(function(previous) {
return fn(previous, current);
}
);
}
};

P.Promise = Promise;
Expand Down
110 changes: 55 additions & 55 deletions test/promise-tests.js
Expand Up @@ -63,47 +63,65 @@ asyncTest('mixed map test', function() {
deferredNumber.resolve(2);
});

asyncTest('reduce number with seed', function() {
asyncTest('reduce number', function() {
var addSpy = sinon.spy(add);
P(12)
.eventually()
.reduce(addSpy, 1)
.reduce(addSpy)
.then(function(result) {
equal(result, 13);
equal(result, 12);
equal(addSpy.callCount, 0);
start();
});
});

asyncTest('reduce array of numbers', function() {
var addSpy = sinon.spy(add);
P([ 1, 2 ])
.eventually()
.reduce(addSpy)
.then(function(result) {
equal(result, 3);
equal(addSpy.callCount, 1);
deepEqual(addSpy.getCall(0).args, [ 1, 12 ]);
deepEqual(addSpy.getCall(0).args, [ 1, 2 ]);
start();
});
});

asyncTest('reduce number without seed', function() {
asyncTest('reduce empty array', function() {
var addSpy = sinon.spy(add);
P(12)
P([])
.eventually()
.reduce(addSpy)
.then(function(result) {
equal(result, 12);
ok(false);
start();
})
.fail(function(error) {
ok(error instanceof TypeError);
equal(addSpy.callCount, 0);
start();
});
});

asyncTest('reduce array of numbers with seed', function() {
asyncTest('reduce empty array-like', function() {
var addSpy = sinon.spy(add);
P([ 1, 2 ])
P(arrayLike())
.eventually()
.reduce(addSpy, 0)
.reduce(addSpy)
.then(function(result) {
equal(result, 3);
equal(addSpy.callCount, 2);
deepEqual(addSpy.getCall(0).args, [ 0, 1 ]);
deepEqual(addSpy.getCall(1).args, [ 1, 2 ]);
ok(false);
start();
})
.fail(function(error) {
ok(error instanceof TypeError);
equal(addSpy.callCount, 0);
start();
});
});

asyncTest('reduce array of numbers without seed', function() {
var addSpy = sinon.spy(add);
asyncTest('reduce array of numbers with function returning promise', function() {
var addSpy = sinon.spy(eventuallyAdd);
P([ 1, 2 ])
.eventually()
.reduce(addSpy)
Expand All @@ -115,67 +133,62 @@ asyncTest('reduce array of numbers without seed', function() {
});
});

asyncTest('reduce empty array with seed', function() {
asyncTest('inject number', function() {
var addSpy = sinon.spy(add);
P([])
P(12)
.eventually()
.reduce(addSpy, 12)
.inject(addSpy, 1)
.then(function(result) {
equal(result, 12);
equal(addSpy.callCount, 0);
equal(result, 13);
equal(addSpy.callCount, 1);
deepEqual(addSpy.getCall(0).args, [ 1, 12 ]);
start();
});
});

asyncTest('reduce empty array without seed', function() {
asyncTest('inject array of numbers', function() {
var addSpy = sinon.spy(add);
P([])
P([ 1, 2 ])
.eventually()
.reduce(addSpy)
.inject(addSpy, 0)
.then(function(result) {
ok(false);
start();
})
.fail(function(error) {
ok(error instanceof TypeError);
equal(addSpy.callCount, 0);
equal(result, 3);
equal(addSpy.callCount, 2);
deepEqual(addSpy.getCall(0).args, [ 0, 1 ]);
deepEqual(addSpy.getCall(1).args, [ 1, 2 ]);
start();
});
});

asyncTest('reduce empty array-like with seed', function() {
asyncTest('inject empty array', function() {
var addSpy = sinon.spy(add);
P(arrayLike())
P([])
.eventually()
.reduce(addSpy, 12)
.inject(addSpy, 12)
.then(function(result) {
equal(result, 12);
equal(addSpy.callCount, 0);
start();
});
});

asyncTest('reduce empty array-like without seed', function() {
asyncTest('inject empty array-like', function() {
var addSpy = sinon.spy(add);
P(arrayLike())
.eventually()
.reduce(addSpy)
.inject(addSpy, 12)
.then(function(result) {
ok(false);
start();
})
.fail(function(error) {
ok(error instanceof TypeError);
equal(result, 12);
equal(addSpy.callCount, 0);
start();
});
});

asyncTest('reduce array of numbers with seed and reducer returning promise', function() {
asyncTest('inject array of numbers with function returning promise', function() {
var addSpy = sinon.spy(eventuallyAdd);
P([ 1, 2 ])
.eventually()
.reduce(addSpy, 0)
.inject(addSpy, 0)
.then(function(result) {
equal(result, 3);
equal(addSpy.callCount, 2);
Expand All @@ -185,19 +198,6 @@ asyncTest('reduce array of numbers with seed and reducer returning promise', fun
});
});

asyncTest('reduce array of numbers without seed and reducer returning promise', function() {
var addSpy = sinon.spy(eventuallyAdd);
P([ 1, 2 ])
.eventually()
.reduce(addSpy)
.then(function(result) {
equal(result, 3);
equal(addSpy.callCount, 1);
deepEqual(addSpy.getCall(0).args, [ 1, 2 ]);
start();
});
});

function eventuallyExpect(expected) {
return function(actual) {
deepEqual(actual, expected);
Expand Down
41 changes: 26 additions & 15 deletions test/tests.js
Expand Up @@ -52,38 +52,49 @@ test('map array of objects with object', function() {
]);
});

test('reduce number with seed', function() {
equal(P(12).reduce(add, 1)._, 13);
});

test('reduce number without seed', function() {
test('reduce number', function() {
equal(P(12).reduce(add)._, 12);
});

test('reduce array of numbers', function() {
equal(P([ 1, 2 ]).reduce(add, 0)._, 3);
});

test('reduce array of numbers with no initial value', function() {
equal(P([ 1, 2 ]).reduce(add)._, 3);
});

test('reduce empty array with no initial value', function() {
test('reduce empty array', function() {
throws(function() { P([]).reduce(add); }, TypeError);
});

test('reduce array-like of numbers', function() {
equal(P(arrayLike(1, 2)).reduce(add, 0)._, 3);
});

test('reduce array-like of numbers with no initial value', function() {
equal(P(arrayLike(1, 2)).reduce(add)._, 3);
});

test('reduce empty array-like with no initial value', function() {
test('reduce empty array-like', function() {
throws(function() { P(arrayLike()).reduce(add); }, TypeError);
});

test('reduce returns partial', function() {
var adder = P.reduce(add);
equal(adder([ 1, 2 ]), 3);
});

test('inject number with seed', function() {
equal(P(12).inject(add, 1)._, 13);
});

test('inject array of numbers', function() {
equal(P([ 1, 2 ]).inject(add, 0)._, 3);
});

test('inject array-like of numbers', function() {
equal(P(arrayLike(1, 2)).inject(add, 0)._, 3);
});

test('inject returns partial', function() {
var adder = P.inject(add);
var adderTo3 = adder(3);
equal(adderTo3([ 1, 2 ]), 6);
});

test('each number', function() {
var add1Spy = sinon.spy(add1);
equal(P(12).each(add1Spy)._, 12);
Expand Down

0 comments on commit 70f2e54

Please sign in to comment.