-
-
Notifications
You must be signed in to change notification settings - Fork 698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix properties with undefined
value pass property assertion
#308
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
32826c0
Fix properties with `undefined` value pass property assertion
joshperry 7d466b2
Handle array indexing terminating paths
joshperry c4b0d18
Small unit test fix
joshperry 8cdb7b1
Refactor if statement out
joshperry 2d22f45
Refactor common functionality, document, test
joshperry dd51594
More unit tests for new utility functions
joshperry 414dea2
Fix typo
joshperry File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/*! | ||
* Chai - getPathInfo utility | ||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> | ||
* MIT Licensed | ||
*/ | ||
|
||
var hasProperty = require('./hasProperty'); | ||
|
||
/** | ||
* ### .getPathInfo(path, object) | ||
* | ||
* This allows the retrieval of property info in an | ||
* object given a string path. | ||
* | ||
* The path info consists of an object with the | ||
* following properties: | ||
* | ||
* * parent - The parent object of the property referenced by `path` | ||
* * name - The name of the final property, a number if it was an array indexer | ||
* * value - The value of the property, if it exists, otherwise `undefined` | ||
* * exists - Whether the property exists or not | ||
* | ||
* @param {String} path | ||
* @param {Object} object | ||
* @returns {Object} info | ||
* @name getPathInfo | ||
* @api public | ||
*/ | ||
|
||
module.exports = function getPathInfo(path, obj) { | ||
var parsed = parsePath(path), | ||
last = parsed[parsed.length - 1]; | ||
|
||
var info = { | ||
parent: _getPathValue(parsed, obj, parsed.length - 1), | ||
name: last.p || last.i, | ||
value: _getPathValue(parsed, obj), | ||
}; | ||
info.exists = hasProperty(info.name, info.parent); | ||
|
||
return info; | ||
}; | ||
|
||
|
||
/*! | ||
* ## parsePath(path) | ||
* | ||
* Helper function used to parse string object | ||
* paths. Use in conjunction with `_getPathValue`. | ||
* | ||
* var parsed = parsePath('myobject.property.subprop'); | ||
* | ||
* ### Paths: | ||
* | ||
* * Can be as near infinitely deep and nested | ||
* * Arrays are also valid using the formal `myobject.document[3].property`. | ||
* | ||
* @param {String} path | ||
* @returns {Object} parsed | ||
* @api private | ||
*/ | ||
|
||
function parsePath (path) { | ||
var str = path.replace(/\[/g, '.[') | ||
, parts = str.match(/(\\\.|[^.]+?)+/g); | ||
return parts.map(function (value) { | ||
var re = /\[(\d+)\]$/ | ||
, mArr = re.exec(value); | ||
if (mArr) return { i: parseFloat(mArr[1]) }; | ||
else return { p: value }; | ||
}); | ||
} | ||
|
||
|
||
/*! | ||
* ## _getPathValue(parsed, obj) | ||
* | ||
* Helper companion function for `.parsePath` that returns | ||
* the value located at the parsed address. | ||
* | ||
* var value = getPathValue(parsed, obj); | ||
* | ||
* @param {Object} parsed definition from `parsePath`. | ||
* @param {Object} object to search against | ||
* @param {Number} object to search against | ||
* @returns {Object|Undefined} value | ||
* @api private | ||
*/ | ||
|
||
function _getPathValue (parsed, obj, index) { | ||
var tmp = obj | ||
, res; | ||
|
||
index = (index === undefined ? parsed.length : index); | ||
|
||
for (var i = 0, l = index; i < l; i++) { | ||
var part = parsed[i]; | ||
if (tmp) { | ||
if ('undefined' !== typeof part.p) | ||
tmp = tmp[part.p]; | ||
else if ('undefined' !== typeof part.i) | ||
tmp = tmp[part.i]; | ||
if (i == (l - 1)) res = tmp; | ||
} else { | ||
res = undefined; | ||
} | ||
} | ||
return res; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/*! | ||
* Chai - hasProperty utility | ||
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> | ||
* MIT Licensed | ||
*/ | ||
|
||
var type = require('./type'); | ||
|
||
/** | ||
* ### .hasProperty(object, name) | ||
* | ||
* This allows checking whether an object has | ||
* named property or numeric array index. | ||
* | ||
* Basically does the same thing as the `in` | ||
* operator but works properly with natives | ||
* and null/undefined values. | ||
* | ||
* var obj = { | ||
* arr: ['a', 'b', 'c'] | ||
* , str: 'Hello' | ||
* } | ||
* | ||
* The following would be the results. | ||
* | ||
* hasProperty('str', obj); // true | ||
* hasProperty('constructor', obj); // true | ||
* hasProperty('bar', obj); // false | ||
* | ||
* hasProperty('length', obj.str); // true | ||
* hasProperty(1, obj.str); // true | ||
* hasProperty(5, obj.str); // false | ||
* | ||
* hasProperty('length', obj.arr); // true | ||
* hasProperty(2, obj.arr); // true | ||
* hasProperty(3, obj.arr); // false | ||
* | ||
* @param {Objuect} object | ||
* @param {String|Number} name | ||
* @returns {Boolean} whether it exists | ||
* @name getPathInfo | ||
* @api public | ||
*/ | ||
|
||
var literals = { | ||
'number': Number | ||
, 'string': String | ||
}; | ||
|
||
module.exports = function hasProperty(name, obj) { | ||
var ot = type(obj); | ||
|
||
// Bad Object, obviously no props at all | ||
if(ot === 'null' || ot === 'undefined') | ||
return false; | ||
|
||
// The `in` operator does not work with certain literals | ||
// box these before the check | ||
if(literals[ot] && typeof obj !== 'object') | ||
obj = new literals[ot](obj); | ||
|
||
return name in obj; | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, this looks much better!