| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /*!
- * 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: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,
- 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`.
- * * Literal dots and brackets (not delimiter) must be backslash-escaped.
- *
- * @param {String} path
- * @returns {Object} parsed
- * @api private
- */
- function parsePath (path) {
- var str = path.replace(/([^\\])\[/g, '$1.[')
- , 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.replace(/\\([.\[\]])/g, '$1') };
- });
- }
- /*!
- * ## _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;
- }
|