Skip to content

Commit

Permalink
- apply and applyArgs now treat non-array-like values for the `ar…
Browse files Browse the repository at this point in the history
…gs` parameter as empty arrays

- Updated tests for `apply` and `applyArgs`
- `apply` and `applyArgs` now keep the predicate’s context
  • Loading branch information
ascartabelli committed Jun 21, 2016
1 parent c7e6bdd commit eaeec3c
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 17 deletions.
13 changes: 8 additions & 5 deletions dist/lamb.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.
* @author Andrea Scartabelli <andrea.scartabelli@gmail.com>
* @version 0.30.0-alpha.2
* @version 0.30.0-alpha.3
* @module lamb
* @license MIT
* @preserve
Expand All @@ -18,7 +18,7 @@
* @category Core
* @type String
*/
lamb._version = "0.30.0-alpha.2";
lamb._version = "0.30.0-alpha.3";

// alias used as a placeholder argument for partial application
var _ = lamb;
Expand Down Expand Up @@ -3138,7 +3138,7 @@
* @returns {*}
*/
function apply (fn, args) {
return fn.apply(fn, slice(args));
return fn.apply(this, slice(Object(args)));
}

/**
Expand All @@ -3153,11 +3153,14 @@
*
* @memberof module:lamb
* @category Function
* @function
* @param {ArrayLike} args
* @returns {Function}
*/
var applyArgs = _curry(apply, 2, true);
function applyArgs (args) {
return function (fn) {
return fn.apply(this, slice(Object(args)));
};
}

/**
* Builds a function that passes only the specified amount of arguments to the given function.<br/>
Expand Down
4 changes: 2 additions & 2 deletions dist/lamb.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lamb.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"coveralls": "gulp coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
},
"tonicExample": "var _ = require('lamb');",
"version": "0.30.0-alpha.2",
"version": "0.30.0-alpha.3",
"devDependencies": {
"coveralls": "^2.11.9",
"gulp": "^3.9.1",
Expand Down
9 changes: 6 additions & 3 deletions src/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function _curry (fn, arity, isRightCurry, isAutoCurry) {
* @returns {*}
*/
function apply (fn, args) {
return fn.apply(fn, slice(args));
return fn.apply(this, slice(Object(args)));
}

/**
Expand All @@ -50,11 +50,14 @@ function apply (fn, args) {
*
* @memberof module:lamb
* @category Function
* @function
* @param {ArrayLike} args
* @returns {Function}
*/
var applyArgs = _curry(apply, 2, true);
function applyArgs (args) {
return function (fn) {
return fn.apply(this, slice(Object(args)));
};
}

/**
* Builds a function that passes only the specified amount of arguments to the given function.<br/>
Expand Down
68 changes: 63 additions & 5 deletions test/spec/functionSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ var assert = sinon.assert;
var lamb = require("../../dist/lamb.js");

describe("lamb.function", function () {
function Foo (value) {
this.value = value;
}
Foo.prototype = {
value: 0,
bar: function (a, b) {
return (this.value + a) / b;
}
}


describe("apply", function () {
it("should apply the passed function to the given arguments", function () {
expect(lamb.apply(Math.max, [-1, 3, 2, 15, 7])).toBe(15);
Expand All @@ -14,13 +25,29 @@ describe("lamb.function", function () {
expect(lamb.apply(Math.max, "3412")).toBe(4);
});

it("should throw an error if no function is passed", function () {
expect(function () {lamb.apply({}, [])}).toThrow();
expect(function () {lamb.apply(null, [])}).toThrow();
it("should not alter the function's context", function () {
var obj = {value: 4, apply: lamb.apply};
expect(obj.apply(Foo.prototype.bar, [1, 2])).toBe(2.5);
});

it("should treat non-array-like values for the `args` parameter as empty arrays", function () {
var fooSpy = jasmine.createSpy("fooSpy");
var values = [null, void 0, {}, /foo/, NaN, true, new Date()];

for (var i = 0; i < values.length; i++) {
lamb.apply(fooSpy, values[i]);
expect(fooSpy.calls.argsFor(i).length).toBe(0);
}

lamb.apply(fooSpy);
expect(fooSpy.calls.argsFor(i).length).toBe(0);
expect(fooSpy.calls.count()).toBe(i + 1);
});

it("should throw an error if no arguments are passed", function () {
expect(function (){lamb.apply(function () {})}).toThrow();
it("should throw an exception if `fn` isn't a function", function () {
["foo", null, void 0, {}, [], /foo/, 1, NaN, true, new Date()].forEach(function (value) {
expect(function () { lamb.apply(value, []); }).toThrow();
});
});
});

Expand All @@ -33,6 +60,37 @@ describe("lamb.function", function () {
expect(applyArgsTo(lamb.filter)).toEqual([2, 4, 6]);
expect(applyArgsTo(lamb.map)).toEqual([false, true, false, true, false, true]);
});

it("should accept an array-like object", function () {
expect(lamb.applyArgs("3412")(Math.max)).toBe(4);
});

it("should not alter the function's context", function () {
var obj = {value: 4, baz: lamb.applyArgs([1, 2])};
expect(obj.baz(Foo.prototype.bar)).toBe(2.5);
});

it("should treat non-array-like values for the `args` parameter as empty arrays", function () {
var fooSpy = jasmine.createSpy("fooSpy");
var values = [null, void 0, {}, /foo/, NaN, true, new Date()];

for (var i = 0; i < values.length; i++) {
lamb.applyArgs(values[i])(fooSpy);
expect(fooSpy.calls.argsFor(i).length).toBe(0);
}

lamb.applyArgs()(fooSpy);
expect(fooSpy.calls.argsFor(i).length).toBe(0);
expect(fooSpy.calls.count()).toBe(i + 1);
});

it("should throw an exception if `fn` isn't a function", function () {
["foo", null, void 0, {}, [], /foo/, 1, NaN, true, new Date()].forEach(function (value) {
expect(function () { lamb.applyArgs([])(value); }).toThrow();
});

expect(lamb.applyArgs([])).toThrow();
});
});

describe("aritize", function () {
Expand Down

0 comments on commit eaeec3c

Please sign in to comment.