Skip to content

Commit

Permalink
Fix issue in propPathOr if default value is an object (#217)
Browse files Browse the repository at this point in the history
* Fix issue in propPathOr if default value is an object

In the previous implementation, if a property in the target is not found,
then the default value would be returned as the accumulator to the next
iteration of reduce. If the default value is an object, then it is
errantly traversed with the next property in the specified path.

* remove cross directory dependency

* make sure we don't return default if falsy value is found in object

* remove redundant conditional
  • Loading branch information
jonwhelan authored and evilsoft committed Feb 17, 2018
1 parent 95e8115 commit 78f6014
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
15 changes: 7 additions & 8 deletions src/helpers/propPathOr.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,25 @@ const isInteger = require('../core/isInteger')
const isNil= require('../core/isNil')
const isString = require('../core/isString')

const lift = (x, def) =>
isNil(x) ? def : x

// propPathOr : a -> [ String | Integer ] -> b -> c
function propPathOr(def, keys, target) {
if(!isArray(keys)) {
throw new TypeError('propPathOr: Array of strings or integers required for second argument')
}

if(isNil(target)) {
return def
}
const value = keys.reduce((target, key) => {
if (isNil(target)) {
return target
}

return keys.reduce((target, key) => {
if(!(isString(key) || isInteger(key))) {
throw new TypeError('propPathOr: Array of strings or integers required for second argument')
}

return lift(target[key], def)
return target[key]
}, target)

return isNil(value) ? def : value
}

module.exports = curry(propPathOr)
5 changes: 5 additions & 0 deletions src/helpers/propPathOr.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,10 @@ test('propPathOr function', t => {
t.equals(fn(null), def, 'returns the default value when data is null')
t.equals(fn(NaN), def, 'returns the default value when data is NaN')

const objDefault = { b: 1 }

t.equals(propPathOr(objDefault, [ 'a', 'b' ], { c: { b: 2 } }), objDefault, 'returns the default value when default is an object that has the same property as a nested property in target')
t.equals(propPathOr(1, [ 'a' ], { a: 0 } ), 0, 'returns found falsy value')

t.end()
})

0 comments on commit 78f6014

Please sign in to comment.