Skip to content

Commit

Permalink
Renamed getWithPath to getPathIn
Browse files Browse the repository at this point in the history
Added `getPath`
  • Loading branch information
ascartabelli committed Apr 2, 2016
1 parent 7b6a84e commit f4880b4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
57 changes: 46 additions & 11 deletions src/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ var _valuesFrom = _curry(function (getKeys, obj) {
* @category Object
* @param {Function} predicate - The predicate to test the object properties
* @param {String} message - The error message
* @param {String[]} keyPaths - The array of property names, or {@link module:lamb.getWithPath|paths}, to test.
* @param {String[]} keyPaths - The array of property names, or {@link module:lamb.getPathIn|paths}, to test.
* @param {String} [pathSeparator="."]
* @returns {Array<String, String[]>} An error in the form <code>["message", ["propertyA", "propertyB"]]</code> or an empty array.
*/
function checker (predicate, message, keyPaths, pathSeparator) {
return function (obj) {
var getValues = partial(getWithPath, obj, _, pathSeparator);
var getValues = partial(getPathIn, obj, _, pathSeparator);
return predicate.apply(obj, keyPaths.map(getValues)) ? [] : [message, keyPaths];
};
}
Expand Down Expand Up @@ -151,7 +151,8 @@ function fromPairs (pairsList) {
*
* @memberof module:lamb
* @category Object
* @see {@link module:lamb.getKey|getKey}, {@link module:lamb.getWithPath|getWithPath}
* @see {@link module:lamb.getKey|getKey}
* @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}
* @param {Object} obj
* @param {String} key
* @returns {*}
Expand All @@ -173,13 +174,45 @@ function getIn (obj, key) {
*
* @memberof module:lamb
* @category Object
* @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getWithPath|getWithPath}
* @see {@link module:lamb.getIn|getIn}
* @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}
* @function
* @param {String} key
* @returns {Function}
*/
var getKey = _curry(getIn, 2, true);

/**
* Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given
* path and separator, expecting the object to act upon.
* @example
* var user = {
* name: "John",
* surname: "Doe",
* login: {
* "user.name": "jdoe",
* password: "abc123"
* }
* };
*
* var getPwd = _.getPath("login.password");
* var getUsername = _.getPath("login/user.name", "/");
*
* getPwd(user) // => "abc123";
* getUsername(user) // => "jdoe"
*
* @memberof module:lamb
* @category Object
* @see {@link module:lamb.getPathIn|getPathIn}
* @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}
* @param {String} path
* @param {String} [separator="."]
* @returns {Function}
*/
function getPath (path, separator) {
return partial(getPathIn, _, path, separator);
}

/**
* Gets a nested property value from an object using the given path.<br/>
* The path is a string with property names separated by dots by default, but
Expand All @@ -195,22 +228,23 @@ var getKey = _curry(getIn, 2, true);
* };
*
* // same as _.getIn if no path is involved
* _.getWithPath(user, "name") // => "John"
* _.getPathIn(user, "name") // => "John"
*
* _.getWithPath(user, "login.password") // => "abc123";
* _.getWithPath(user, "login/user.name", "/") // => "jdoe"
* _.getWithPath(user, "name.foo") // => undefined
* _.getWithPath(user, "name.foo.bar") // => throws a TypeError
* _.getPathIn(user, "login.password") // => "abc123";
* _.getPathIn(user, "login/user.name", "/") // => "jdoe"
* _.getPathIn(user, "name.foo") // => undefined
* _.getPathIn(user, "name.foo.bar") // => throws a TypeError
*
* @memberof module:lamb
* @category Object
* @see {@link module:lamb.getPath|getPath}
* @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}
* @param {Object|ArrayLike} obj
* @param {String} path
* @param {String} [separator="."]
* @returns {*}
*/
function getWithPath (obj, path, separator) {
function getPathIn (obj, path, separator) {
return path.split(separator || ".").reduce(getIn, obj);
}

Expand Down Expand Up @@ -749,7 +783,8 @@ lamb.enumerables = enumerables;
lamb.fromPairs = fromPairs;
lamb.getIn = getIn;
lamb.getKey = getKey;
lamb.getWithPath = getWithPath;
lamb.getPath = getPath;
lamb.getPathIn = getPathIn;
lamb.has = has;
lamb.hasKey = hasKey;
lamb.hasKeyValue = hasKeyValue;
Expand Down
29 changes: 19 additions & 10 deletions test/spec/objectSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,40 @@ describe("lamb.object", function () {
});
});

describe("getWithPath", function () {
describe("getPath / getPathIn", function () {
var obj = {a: 2, b: {a: 3, b: [4, 5], c: "foo"}, "c.d" : {"e.f": 6}};

it("should retrieve a nested object property using the supplied path", function () {
expect(lamb.getWithPath(obj, "a")).toBe(2);
expect(lamb.getWithPath(obj, "b.a")).toBe(3);
expect(lamb.getWithPath(obj, "b.b")).toBe(obj.b.b);
expect(lamb.getPath("a")(obj)).toBe(2);
expect(lamb.getPath("b.a")(obj)).toBe(3);
expect(lamb.getPath("b.b")(obj)).toBe(obj.b.b);
expect(lamb.getPathIn(obj, "a")).toBe(2);
expect(lamb.getPathIn(obj, "b.a")).toBe(3);
expect(lamb.getPathIn(obj, "b.b")).toBe(obj.b.b);
});

it("should be able to retrieve values from arrays and array-like objects", function () {
expect(lamb.getWithPath(obj, "b.b.0")).toBe(4);
expect(lamb.getWithPath(obj, "b.c.0")).toBe("f");
expect(lamb.getPath("b.b.0")(obj)).toBe(4);
expect(lamb.getPath("b.c.0")(obj)).toBe("f");
expect(lamb.getPathIn(obj, "b.b.0")).toBe(4);
expect(lamb.getPathIn(obj, "b.c.0")).toBe("f");
});

it("should accept a custom path separator", function () {
expect(lamb.getWithPath(obj, "b->b->0", "->")).toBe(4);
expect(lamb.getWithPath(obj, "c.d/e.f", "/")).toBe(6);
expect(lamb.getPath("b->b->0", "->")(obj)).toBe(4);
expect(lamb.getPath("c.d/e.f", "/")(obj)).toBe(6);
expect(lamb.getPathIn(obj, "b->b->0", "->")).toBe(4);
expect(lamb.getPathIn(obj, "c.d/e.f", "/")).toBe(6);
});

it("should return undefined for a unknown property in an existent object", function () {
expect(lamb.getWithPath(obj, "b.a.z")).toBeUndefined();
expect(lamb.getPath("b.a.z")(obj)).toBeUndefined();
expect(lamb.getPathIn(obj, "b.a.z")).toBeUndefined();
});

it("should throw an error if a non existent object is requested in the path", function () {
expect(function () {lamb.getWithPath(obj, "b.z.a")}).toThrow();
expect(function () {lamb.getPath("b.z.a")(obj)}).toThrow();
expect(function () {lamb.getPathIn(obj, "b.z.a")}).toThrow();
});
});

Expand Down

0 comments on commit f4880b4

Please sign in to comment.