Comparing version 0.3.1 to 1.0.0
323
dottie.js
(function(undefined) { | ||
var root = this; | ||
var root = this; | ||
// Weird IE shit, objects do not have hasOwn, but the prototype does... | ||
var hasOwnProp = Object.prototype.hasOwnProperty; | ||
// Weird IE shit, objects do not have hasOwn, but the prototype does... | ||
var hasOwnProp = Object.prototype.hasOwnProperty; | ||
// Object cloning function, uses jQuery/Underscore/Object.create depending on what's available | ||
// Object cloning function, uses jQuery/Underscore/Object.create depending on what's available | ||
var clone = function (object) { | ||
if (typeof Object.hasOwnProperty !== 'undefined') { | ||
var target = {}; | ||
for (var i in object) { | ||
if (hasOwnProp.call(object, i)) { | ||
target[i] = object[i]; | ||
} | ||
} | ||
return target; | ||
} | ||
if (typeof jQuery !== 'undefined') { | ||
return jQuery.extend({}, object); | ||
} | ||
if (typeof _ !== 'undefined') { | ||
return _.extend({}, object); | ||
} | ||
}; | ||
var clone = function (object) { | ||
if (typeof Object.hasOwnProperty !== 'undefined') { | ||
var target = {}; | ||
for (var i in object) { | ||
if (hasOwnProp.call(object, i)) { | ||
target[i] = object[i]; | ||
} | ||
} | ||
return target; | ||
} | ||
if (typeof jQuery !== 'undefined') { | ||
return jQuery.extend({}, object); | ||
} | ||
if (typeof _ !== 'undefined') { | ||
return _.extend({}, object); | ||
} | ||
}; | ||
var Dottie = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var Dottie = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
if (args.length == 2) { | ||
return Dottie.find.apply(this, args); | ||
} | ||
return Dottie.transform.apply(this, args); | ||
}; | ||
if (args.length == 2) { | ||
return Dottie.find.apply(this, args); | ||
} | ||
return Dottie.transform.apply(this, args); | ||
}; | ||
// Legacy syntax, changed syntax to have get/set be similar in arg order | ||
Dottie.find = function(path, object) { | ||
return Dottie.get(object, path); | ||
}; | ||
// Legacy syntax, changed syntax to have get/set be similar in arg order | ||
Dottie.find = function(path, object) { | ||
return Dottie.get(object, path); | ||
}; | ||
// Dottie memoization flag | ||
Dottie.memoizePath = true; | ||
var memoized = {}; | ||
// Dottie memoization flag | ||
Dottie.memoizePath = true; | ||
var memoized = {}; | ||
// Traverse object according to path, return value if found - Return undefined if destination is unreachable | ||
Dottie.get = function(object, path, defaultVal) { | ||
if ((object === undefined) || (object === null)) return defaultVal; | ||
// Traverse object according to path, return value if found - Return undefined if destination is unreachable | ||
Dottie.get = function(object, path, defaultVal) { | ||
if ((object === undefined) || (object === null)) return defaultVal; | ||
var names; | ||
var names; | ||
if (typeof path === "string") { | ||
if (Dottie.memoizePath) { | ||
if (memoized[path]) { | ||
names = memoized[path].slice(0); | ||
} else { | ||
names = path.split('.').reverse(); | ||
memoized[path] = names.slice(0); | ||
} | ||
} else { | ||
names = path.split('.').reverse(); | ||
} | ||
} else if (Array.isArray(path)) { | ||
names = path.reverse(); | ||
} | ||
if (typeof path === "string") { | ||
if (Dottie.memoizePath) { | ||
if (memoized[path]) { | ||
names = memoized[path].slice(0); | ||
} else { | ||
names = path.split('.').reverse(); | ||
memoized[path] = names.slice(0); | ||
} | ||
} else { | ||
names = path.split('.').reverse(); | ||
} | ||
} else if (Array.isArray(path)) { | ||
names = path.reverse(); | ||
} | ||
while (names.length && (object = object[names.pop()]) !== undefined && object !== null); | ||
while (names.length && (object = object[names.pop()]) !== undefined && object !== null); | ||
// Handle cases where accessing a childprop of a null value | ||
if (object === null && names.length) object = undefined; | ||
// Handle cases where accessing a childprop of a null value | ||
if (object === null && names.length) object = undefined; | ||
return (object === undefined ? defaultVal : object); | ||
}; | ||
return (object === undefined ? defaultVal : object); | ||
}; | ||
Dottie.exists = function(object, path) { | ||
return Dottie.get(object, path) !== undefined; | ||
}; | ||
// Set nested value | ||
Dottie.set = function(object, path, value) { | ||
var pieces = Array.isArray(path) ? path : path.split('.'), current = object, piece, length = pieces.length; | ||
// Set nested value | ||
Dottie.set = function(object, path, value, options) { | ||
var pieces = Array.isArray(path) ? path : path.split('.'), current = object, piece, length = pieces.length; | ||
for (var index = 0; index < length; index++) { | ||
piece = pieces[index]; | ||
if (!hasOwnProp.call(current, piece) || current[piece] === undefined) { | ||
current[piece] = {}; | ||
} | ||
if (typeof current !== 'object') { | ||
throw new Error('Parent is not an object.'); | ||
} | ||
if (typeof current !== 'object') throw new Error('Target key is not suitable for a nested value (it is either not undefined or not an object)'); | ||
for (var index = 0; index < length; index++) { | ||
piece = pieces[index]; | ||
if (index == (length - 1)) { | ||
current[piece] = value; | ||
} else { | ||
current = current[piece]; | ||
} | ||
} | ||
// Create namespace (object) where none exists. | ||
// If `force === true`, bruteforce the path without throwing errors. | ||
if (!hasOwnProp.call(current, piece) || current[piece] === undefined || (typeof current[piece] !== 'object' && options && options.force === true)) { | ||
current[piece] = {}; | ||
} | ||
current[piece] = value; | ||
}; | ||
if (index == (length - 1)) { | ||
// Set final value | ||
current[piece] = value; | ||
} else { | ||
// We do not overwrite existing path pieces by default | ||
if (typeof current[piece] !== 'object') { | ||
throw new Error('Target key "' + piece + '" is not suitable for a nested value. (It is in use as non-object. Set `force` to `true` to override.)'); | ||
} | ||
// Set default nested value | ||
Dottie['default'] = function(object, path, value) { | ||
if (Dottie.get(object, path) === undefined) { | ||
Dottie.set(object, path, value); | ||
} | ||
}; | ||
// Traverse next in path | ||
current = current[piece]; | ||
} | ||
} | ||
// Transform unnested object with .-seperated keys into a nested object. | ||
Dottie.transform = function Dottie$transformfunction(object, options) { | ||
if (Array.isArray(object)) { | ||
return object.map(function(o) { | ||
return Dottie.transform(o, options); | ||
}); | ||
} | ||
// Is there any case when this is relevant? It's also the last line in the above for-loop | ||
current[piece] = value; | ||
}; | ||
options = options || {}; | ||
options.delimiter = options.delimiter || '.'; | ||
// Set default nested value | ||
Dottie['default'] = function(object, path, value) { | ||
if (Dottie.get(object, path) === undefined) { | ||
Dottie.set(object, path, value); | ||
} | ||
}; | ||
var pieces, | ||
piecesLength, | ||
piece, | ||
current, | ||
transformed = {}, | ||
key, | ||
keys = Object.keys(object), | ||
length = keys.length, | ||
i; | ||
// Transform unnested object with .-seperated keys into a nested object. | ||
Dottie.transform = function Dottie$transformfunction(object, options) { | ||
if (Array.isArray(object)) { | ||
return object.map(function(o) { | ||
return Dottie.transform(o, options); | ||
}); | ||
} | ||
for (i = 0; i < length; i++) { | ||
key = keys[i]; | ||
options = options || {}; | ||
options.delimiter = options.delimiter || '.'; | ||
if (key.indexOf(options.delimiter) !== -1) { | ||
pieces = key.split(options.delimiter); | ||
piecesLength = pieces.length; | ||
current = transformed; | ||
var pieces | ||
, piecesLength | ||
, piece | ||
, current | ||
, transformed = {} | ||
, key | ||
, keys = Object.keys(object) | ||
, length = keys.length | ||
, i; | ||
for (var index = 0; index < piecesLength; index++) { | ||
piece = pieces[index]; | ||
if (index != (piecesLength - 1) && !current.hasOwnProperty(piece)) { | ||
current[piece] = {}; | ||
} | ||
for (i = 0; i < length; i++) { | ||
key = keys[i]; | ||
if (index == (piecesLength - 1)) { | ||
current[piece] = object[key]; | ||
} | ||
if (key.indexOf(options.delimiter) !== -1) { | ||
pieces = key.split(options.delimiter); | ||
piecesLength = pieces.length; | ||
current = transformed; | ||
current = current[piece]; | ||
if (current === null) { | ||
break; | ||
} | ||
} | ||
} else { | ||
transformed[key] = object[key]; | ||
} | ||
} | ||
for (var index = 0; index < piecesLength; index++) { | ||
piece = pieces[index]; | ||
if (index != (piecesLength - 1) && !current.hasOwnProperty(piece)) { | ||
current[piece] = {}; | ||
} | ||
return transformed; | ||
}; | ||
if (index == (piecesLength - 1)) { | ||
current[piece] = object[key]; | ||
} | ||
Dottie.flatten = function(object, seperator) { | ||
if (typeof seperator === "undefined") seperator = '.'; | ||
var flattened = {}, | ||
current, | ||
nested; | ||
current = current[piece]; | ||
if (current === null) { | ||
break; | ||
} | ||
} | ||
} else { | ||
transformed[key] = object[key]; | ||
} | ||
} | ||
for (var key in object) { | ||
if (hasOwnProp.call(object, key)) { | ||
current = object[key]; | ||
if (Object.prototype.toString.call(current) === "[object Object]") { | ||
nested = Dottie.flatten(current, seperator); | ||
return transformed; | ||
}; | ||
for (var _key in nested) { | ||
flattened[key+seperator+_key] = nested[_key]; | ||
} | ||
} else { | ||
flattened[key] = current; | ||
} | ||
} | ||
} | ||
Dottie.flatten = function(object, seperator) { | ||
if (typeof seperator === "undefined") seperator = '.'; | ||
var flattened = {} | ||
, current | ||
, nested; | ||
return flattened; | ||
}; | ||
for (var key in object) { | ||
if (hasOwnProp.call(object, key)) { | ||
current = object[key]; | ||
if (Object.prototype.toString.call(current) === "[object Object]") { | ||
nested = Dottie.flatten(current, seperator); | ||
if (typeof module !== 'undefined' && module.exports) { | ||
exports = module.exports = Dottie; | ||
} else { | ||
root['Dottie'] = Dottie; | ||
root['Dot'] = Dottie; //BC | ||
for (var _key in nested) { | ||
flattened[key+seperator+_key] = nested[_key]; | ||
} | ||
} else { | ||
flattened[key] = current; | ||
} | ||
} | ||
} | ||
if (typeof define === "function") { | ||
define([], function () { return Dottie; }); | ||
} | ||
} | ||
return flattened; | ||
}; | ||
if (typeof module !== 'undefined' && module.exports) { | ||
exports = module.exports = Dottie; | ||
} else { | ||
root['Dottie'] = Dottie; | ||
root['Dot'] = Dottie; //BC | ||
if (typeof define === "function") { | ||
define([], function () { return Dottie; }); | ||
} | ||
} | ||
})(); |
{ | ||
"name": "dottie", | ||
"version": "0.3.1", | ||
"version": "1.0.0", | ||
"devDependencies": { | ||
@@ -10,3 +10,3 @@ "benchmark": "^1.0.0", | ||
}, | ||
"description": "Object traversing/manipulation util", | ||
"description": "Fast and save object nested object access and manipulation in JavaScript", | ||
"author": "Mick Hansen <maker@mhansen.io>", | ||
@@ -13,0 +13,0 @@ "repository": { |
[![Build Status](https://travis-ci.org/mickhansen/dottie.js.png)](https://travis-ci.org/mickhansen/dottie.js.png) | ||
Dottie helps you easily (and with sacrificing too much performance) look up and play with nested keys in objects, without them throwing up in your face. | ||
## Install | ||
@@ -36,2 +38,5 @@ npm install dottie | ||
dottie.set(values, ['some.dot.included', 'value'], someValue); | ||
dottie.set(values, 'some.nested.object', someValue, { | ||
force: true // force overwrite defined non-object keys into objects if needed | ||
}); | ||
``` | ||
@@ -38,0 +43,0 @@ |
@@ -1,19 +0,19 @@ | ||
var expect = require("expect.js"), | ||
dottie = require('../dottie'); | ||
var expect = require("expect.js") | ||
, dottie = require('../dottie'); | ||
describe("dottie.find", function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baz' | ||
}, | ||
'zoo': 'lander' | ||
}; | ||
var data = { | ||
'foo': { | ||
'bar': 'baz' | ||
}, | ||
'zoo': 'lander' | ||
}; | ||
it("should get first-level values", function () { | ||
expect(dottie.find('zoo', data)).to.equal('lander'); | ||
}); | ||
it("should get first-level values", function () { | ||
expect(dottie.find('zoo', data)).to.equal('lander'); | ||
}); | ||
it("should get nested-level values", function () { | ||
expect(dottie.find('foo.bar', data)).to.equal('baz'); | ||
}); | ||
it("should get nested-level values", function () { | ||
expect(dottie.find('foo.bar', data)).to.equal('baz'); | ||
}); | ||
}); |
@@ -1,40 +0,40 @@ | ||
var expect = require("expect.js"), | ||
dottie = require('../dottie'); | ||
var expect = require("expect.js") | ||
, dottie = require('../dottie'); | ||
describe("dottie.flatten", function () { | ||
it('should handle a basic nested structure without arrays', function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baa', | ||
'baz': { | ||
'foo': 'bar' | ||
} | ||
}, | ||
'bar': 'baz' | ||
}; | ||
it('should handle a basic nested structure without arrays', function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baa', | ||
'baz': { | ||
'foo': 'bar' | ||
} | ||
}, | ||
'bar': 'baz' | ||
}; | ||
expect(dottie.flatten(data)).to.eql({ | ||
'foo.bar': 'baa', | ||
'foo.baz.foo': 'bar', | ||
'bar': 'baz' | ||
}); | ||
}); | ||
expect(dottie.flatten(data)).to.eql({ | ||
'foo.bar': 'baa', | ||
'foo.baz.foo': 'bar', | ||
'bar': 'baz' | ||
}); | ||
}); | ||
it('should be possible to define your own seperator', function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baa', | ||
'baz': { | ||
'foo': 'bar' | ||
} | ||
}, | ||
'bar': 'baz' | ||
}; | ||
it('should be possible to define your own seperator', function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baa', | ||
'baz': { | ||
'foo': 'bar' | ||
} | ||
}, | ||
'bar': 'baz' | ||
}; | ||
expect(dottie.flatten(data, '_')).to.eql({ | ||
'foo_bar': 'baa', | ||
'foo_baz_foo': 'bar', | ||
'bar': 'baz' | ||
}); | ||
}); | ||
expect(dottie.flatten(data, '_')).to.eql({ | ||
'foo_bar': 'baa', | ||
'foo_baz_foo': 'bar', | ||
'bar': 'baz' | ||
}); | ||
}); | ||
}); |
@@ -1,103 +0,103 @@ | ||
var expect = require("expect.js"), | ||
dottie = require('../dottie'); | ||
var expect = require("expect.js") | ||
, dottie = require('../dottie'); | ||
/* If people modify the array prototype Dottie should not be affected */ | ||
Array.prototype.getByName = function(name) { | ||
for (var i = 0, len = this.length; i < len; i++) { | ||
if (typeof this[i] != "object") continue; | ||
if (this[i].name === name) return this[i]; | ||
} | ||
for (var i = 0, len = this.length; i < len; i++) { | ||
if (typeof this[i] != "object") continue; | ||
if (this[i].name === name) return this[i]; | ||
} | ||
}; | ||
Array.prototype.getByType = function(type) { | ||
var newvalues = []; | ||
for (var i = 0, len = this.length; i < len; i++) { | ||
if (typeof this[i] != "object") continue; | ||
if (this[i].type === type) newvalues.push(this[i]); | ||
} | ||
if (newvalues.length <= 0) newvalues = undefined; | ||
return newvalues; | ||
var newvalues = []; | ||
for (var i = 0, len = this.length; i < len; i++) { | ||
if (typeof this[i] != "object") continue; | ||
if (this[i].type === type) newvalues.push(this[i]); | ||
} | ||
if (newvalues.length <= 0) newvalues = undefined; | ||
return newvalues; | ||
}; | ||
describe("dottie.get", function () { | ||
var flags = { | ||
memoizePath: [false, true] | ||
}; | ||
var flags = { | ||
memoizePath: [false, true] | ||
}; | ||
var data = { | ||
'foo': { | ||
'bar': 'baz' | ||
}, | ||
'zoo': 'lander', | ||
'false': { | ||
'value': false | ||
}, | ||
'null': { | ||
'value': null | ||
}, | ||
'nullvalue': null, | ||
'nested.dot': { | ||
'key': 'value' | ||
} | ||
}; | ||
var data = { | ||
'foo': { | ||
'bar': 'baz' | ||
}, | ||
'zoo': 'lander', | ||
'false': { | ||
'value': false | ||
}, | ||
'null': { | ||
'value': null | ||
}, | ||
'nullvalue': null, | ||
'nested.dot': { | ||
'key': 'value' | ||
} | ||
}; | ||
Object.keys(flags).forEach(function (flag) { | ||
flags[flag].forEach(function (value) { | ||
describe(flag+': '+value, function () { | ||
beforeEach(function () { | ||
dottie[flag] = value; | ||
}); | ||
Object.keys(flags).forEach(function (flag) { | ||
flags[flag].forEach(function (value) { | ||
describe(flag+': '+value, function () { | ||
beforeEach(function () { | ||
dottie[flag] = value; | ||
}); | ||
it('should return undefined if value is undefined', function () { | ||
expect(dottie.get(undefined, 'foo')).to.equal(undefined); | ||
expect(dottie.get(undefined, 'foo')).to.equal(undefined); | ||
}); | ||
it('should return undefined if value is undefined', function () { | ||
expect(dottie.get(undefined, 'foo')).to.equal(undefined); | ||
expect(dottie.get(undefined, 'foo')).to.equal(undefined); | ||
}); | ||
it("should get first-level values", function () { | ||
expect(dottie.get(data, 'zoo')).to.equal('lander'); | ||
expect(dottie.get(data, 'zoo')).to.equal('lander'); | ||
}); | ||
it("should get first-level values", function () { | ||
expect(dottie.get(data, 'zoo')).to.equal('lander'); | ||
expect(dottie.get(data, 'zoo')).to.equal('lander'); | ||
}); | ||
it("should get nested-level values", function () { | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
}); | ||
it("should get nested-level values", function () { | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
}); | ||
it("should get nested-level values multiple times", function () { | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
}); | ||
it("should get nested-level values multiple times", function () { | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
expect(dottie.get(data, 'foo.bar')).to.equal('baz'); | ||
}); | ||
it("should return undefined if not found", function () { | ||
expect(dottie.get(data, 'foo.zoo.lander')).to.equal(undefined); | ||
}); | ||
it("should return undefined if not found", function () { | ||
expect(dottie.get(data, 'foo.zoo.lander')).to.equal(undefined); | ||
}); | ||
it("should return false values properly", function () { | ||
expect(dottie.get(data, 'false.value')).to.equal(false); | ||
}); | ||
it("should return false values properly", function () { | ||
expect(dottie.get(data, 'false.value')).to.equal(false); | ||
}); | ||
it("should return the default value passed in if not found", function() { | ||
expect(dottie.get(data, 'foo.zoo.lander', 'novalue')).to.equal('novalue'); | ||
}); | ||
it("should return the default value passed in if not found", function() { | ||
expect(dottie.get(data, 'foo.zoo.lander', 'novalue')).to.equal('novalue'); | ||
}); | ||
it("should return null of the value is null and not undefined", function() { | ||
expect(dottie.get(data, 'null.value')).to.equal(null); | ||
}); | ||
it("should return null of the value is null and not undefined", function() { | ||
expect(dottie.get(data, 'null.value')).to.equal(null); | ||
}); | ||
it("should return undefined if accessing a child property of a null value", function () { | ||
expect(dottie.get(data, 'nullvalue.childProp')).to.equal(undefined); | ||
expect(dottie.get(data, 'null.value.childProp')).to.equal(undefined); | ||
}); | ||
it("should return undefined if accessing a child property of a null value", function () { | ||
expect(dottie.get(data, 'nullvalue.childProp')).to.equal(undefined); | ||
expect(dottie.get(data, 'null.value.childProp')).to.equal(undefined); | ||
}); | ||
it("should return undefined if accessing a child property of a string value", function () { | ||
expect(dottie.get(data, 'foo.bar.baz.yapa')).to.equal(undefined); | ||
}); | ||
it("should return undefined if accessing a child property of a string value", function () { | ||
expect(dottie.get(data, 'foo.bar.baz.yapa')).to.equal(undefined); | ||
}); | ||
it('should get nested values with keys that have dots', function () { | ||
expect(dottie.get(data, ['nested.dot', 'key'])).to.equal('value'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should get nested values with keys that have dots', function () { | ||
expect(dottie.get(data, ['nested.dot', 'key'])).to.equal('value'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -1,41 +0,48 @@ | ||
var expect = require("expect.js"), | ||
dottie = require('../dottie'); | ||
var expect = require("expect.js") | ||
, dottie = require('../dottie'); | ||
describe("dottie.set", function () { | ||
var data = { | ||
'foo': { | ||
'bar': 'baa' | ||
} | ||
}; | ||
var data = { | ||
'foo': { | ||
'bar': 'baa' | ||
} | ||
}; | ||
it("should set nested values on existing structure", function () { | ||
dottie.set(data, 'foo.bar', 'baz'); | ||
expect(data.foo.bar).to.equal('baz'); | ||
}); | ||
it("should set nested values on existing structure", function () { | ||
dottie.set(data, 'foo.bar', 'baz'); | ||
expect(data.foo.bar).to.equal('baz'); | ||
}); | ||
it("should create nested structure if not existing", function () { | ||
dottie.set(data, 'level1.level2', 'foo'); | ||
expect(data.level1.level2).to.equal('foo'); | ||
expect(typeof data.level1).to.equal('object'); | ||
}); | ||
it("should create nested structure if not existing", function () { | ||
dottie.set(data, 'level1.level2', 'foo'); | ||
expect(data.level1.level2).to.equal('foo'); | ||
expect(typeof data.level1).to.equal('object'); | ||
}); | ||
it("should handle setting a nested value on an undefined value (should convert undefined to object)", function () { | ||
var data = { | ||
'values': undefined | ||
}; | ||
it("should handle setting a nested value on an undefined value (should convert undefined to object)", function () { | ||
var data = { | ||
'values': undefined | ||
}; | ||
dottie.set(data, 'values.level1', 'foo'); | ||
expect(data.values.level1).to.equal('foo'); | ||
}); | ||
dottie.set(data, 'values.level1', 'foo'); | ||
expect(data.values.level1).to.equal('foo'); | ||
}); | ||
it('should be able to set with an array path', function () { | ||
dottie.set(data, ['some.dot.containing', 'value'], 'razzamataz'); | ||
expect(data['some.dot.containing'].value).to.equal('razzamataz'); | ||
}); | ||
it('should be able to set with an array path', function () { | ||
dottie.set(data, ['some.dot.containing', 'value'], 'razzamataz'); | ||
expect(data['some.dot.containing'].value).to.equal('razzamataz'); | ||
}); | ||
it("should throw error when setting a nested value on an existing key with a non-object value", function() { | ||
expect(function () { | ||
dottie.set(data, 'foo.bar.baz', 'someValue'); | ||
}).to.throwError(); | ||
}); | ||
it("should throw error when setting a nested value on an existing key with a non-object value", function() { | ||
expect(function () { | ||
dottie.set(data, 'foo.bar.baz', 'someValue'); | ||
}).to.throwError(); | ||
}); | ||
it('should overwrite a nested non-object value on force: true', function () { | ||
dottie.set(data, 'foo.bar.baz', 'someValue', { | ||
force: true | ||
}); | ||
expect(data.foo.bar.baz).to.equal('someValue'); | ||
}); | ||
}); |
@@ -1,3 +0,3 @@ | ||
var expect = require("expect.js"), | ||
dottie = require('../dottie'); | ||
var expect = require("expect.js") | ||
, dottie = require('../dottie'); | ||
@@ -23,127 +23,127 @@ /* If people modify the array prototype Dottie should not be affected */ | ||
describe("dottie.transform", function () { | ||
it("should create a properly nested object from a basic dottie notated set of keys", function () { | ||
var values = { | ||
'user.name': 'John Doe', | ||
'user.email': 'jd@foobar.com', | ||
'user.location.country': 'Zanzibar', | ||
'user.location.city': 'Zanzibar City' | ||
}; | ||
it("should create a properly nested object from a basic dottie notated set of keys", function () { | ||
var values = { | ||
'user.name': 'John Doe', | ||
'user.email': 'jd@foobar.com', | ||
'user.location.country': 'Zanzibar', | ||
'user.location.city': 'Zanzibar City' | ||
}; | ||
var transformed = dottie.transform(values); | ||
var transformed = dottie.transform(values); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
}); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
}); | ||
it("should be able to handle a mixture of nested properties and dottie notated set of keys", function () { | ||
var values = { | ||
user: { | ||
name: 'John Doe' | ||
}, | ||
'user.email': 'jd@foobar.com', | ||
'user.location.country': 'Zanzibar', | ||
'user.location.city': 'Zanzibar City', | ||
'project.title': 'dottie' | ||
}; | ||
it("should be able to handle a mixture of nested properties and dottie notated set of keys", function () { | ||
var values = { | ||
user: { | ||
name: 'John Doe' | ||
}, | ||
'user.email': 'jd@foobar.com', | ||
'user.location.country': 'Zanzibar', | ||
'user.location.city': 'Zanzibar City', | ||
'project.title': 'dottie' | ||
}; | ||
var transformed = dottie.transform(values); | ||
var transformed = dottie.transform(values); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.project).not.to.be(undefined); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.project).not.to.be(undefined); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.project).to.be.an('object'); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.project).to.be.an('object'); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
expect(transformed.project.title).to.equal('dottie'); | ||
}); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
expect(transformed.project.title).to.equal('dottie'); | ||
}); | ||
it("should be able to handle base level properties together with nested", function () { | ||
var values = { | ||
'customer.name': 'John Doe', | ||
'customer.age': 15, | ||
'client': 'Lolcat' | ||
}; | ||
it("should be able to handle base level properties together with nested", function () { | ||
var values = { | ||
'customer.name': 'John Doe', | ||
'customer.age': 15, | ||
'client': 'Lolcat' | ||
}; | ||
var transformed = dottie.transform(values); | ||
var transformed = dottie.transform(values); | ||
expect(transformed.client).not.to.be(undefined); | ||
expect(transformed.hasOwnProperty('client')).to.be.ok(); // Ensure that the property is actually on the object itself, not on the prototype. | ||
expect(transformed.customer).not.to.be(undefined); | ||
expect(transformed.client).not.to.be(undefined); | ||
expect(transformed.hasOwnProperty('client')).to.be.ok(); // Ensure that the property is actually on the object itself, not on the prototype. | ||
expect(transformed.customer).not.to.be(undefined); | ||
expect(transformed.customer).to.be.an('object'); | ||
expect(transformed.customer).to.be.an('object'); | ||
expect(transformed.client).to.equal('Lolcat'); | ||
expect(transformed.customer.name).to.equal('John Doe'); | ||
expect(transformed.customer.age).to.equal(15); | ||
}); | ||
expect(transformed.client).to.equal('Lolcat'); | ||
expect(transformed.customer.name).to.equal('John Doe'); | ||
expect(transformed.customer.age).to.equal(15); | ||
}); | ||
it("should be able to handle null valued properties, not assigning nested level objects", function() { | ||
var values = { | ||
'section.id': 20, | ||
'section.layout': null, | ||
'section.layout.id': null, | ||
'section.layout.name': null | ||
}; | ||
it("should be able to handle null valued properties, not assigning nested level objects", function() { | ||
var values = { | ||
'section.id': 20, | ||
'section.layout': null, | ||
'section.layout.id': null, | ||
'section.layout.name': null | ||
}; | ||
var transformed = dottie.transform(values); | ||
var transformed = dottie.transform(values); | ||
expect(transformed.section.layout).to.be(null); | ||
expect(transformed['section.layout.id']).to.be(undefined); | ||
expect(transformed['section.layout.name']).to.be(undefined); | ||
}); | ||
expect(transformed.section.layout).to.be(null); | ||
expect(transformed['section.layout.id']).to.be(undefined); | ||
expect(transformed['section.layout.name']).to.be(undefined); | ||
}); | ||
it("supports arrays", function () { | ||
var values = [ | ||
{ | ||
'customer.name': 'John Doe', | ||
'customer.age': 15, | ||
'client': 'Lolcat' | ||
}, | ||
{ | ||
'client.name': 'John Doe', | ||
'client.age': 15, | ||
'customer': 'Lolcat' | ||
} | ||
]; | ||
it("supports arrays", function () { | ||
var values = [ | ||
{ | ||
'customer.name': 'John Doe', | ||
'customer.age': 15, | ||
'client': 'Lolcat' | ||
}, | ||
{ | ||
'client.name': 'John Doe', | ||
'client.age': 15, | ||
'customer': 'Lolcat' | ||
} | ||
]; | ||
var transformed = dottie.transform(values); | ||
expect(transformed[0].customer.name).to.equal('John Doe'); | ||
expect(transformed[1].client.name).to.equal('John Doe'); | ||
}); | ||
var transformed = dottie.transform(values); | ||
expect(transformed[0].customer.name).to.equal('John Doe'); | ||
expect(transformed[1].client.name).to.equal('John Doe'); | ||
}); | ||
it("supports custom delimiters", function () { | ||
var values = { | ||
user: { | ||
name: 'John Doe' | ||
}, | ||
'user_email': 'jd@foobar.com', | ||
'user_location_country': 'Zanzibar', | ||
'user_location_city': 'Zanzibar City', | ||
'project_title': 'dottie' | ||
}; | ||
it("supports custom delimiters", function () { | ||
var values = { | ||
user: { | ||
name: 'John Doe' | ||
}, | ||
'user_email': 'jd@foobar.com', | ||
'user_location_country': 'Zanzibar', | ||
'user_location_city': 'Zanzibar City', | ||
'project_title': 'dottie' | ||
}; | ||
var transformed = dottie.transform(values, { delimiter: '_' }); | ||
var transformed = dottie.transform(values, { delimiter: '_' }); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.project).not.to.be(undefined); | ||
expect(transformed.user).not.to.be(undefined); | ||
expect(transformed.user.location).not.to.be(undefined); | ||
expect(transformed.project).not.to.be(undefined); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.project).to.be.an('object'); | ||
expect(transformed.user).to.be.an('object'); | ||
expect(transformed.user.location).to.be.an('object'); | ||
expect(transformed.project).to.be.an('object'); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
expect(transformed.project.title).to.equal('dottie'); | ||
}); | ||
expect(transformed.user.email).to.equal('jd@foobar.com'); | ||
expect(transformed.user.location.city).to.equal('Zanzibar City'); | ||
expect(transformed.project.title).to.equal('dottie'); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
21986
515
1
95