dot-object 1.5.3 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dot-object might be problematic. Click here for more details.

package/CHANGELOG.md CHANGED
@@ -1,7 +1,19 @@
1
1
  # ChangeLog
2
2
 
3
+ ## 2018-10-26 Version 1.7.1
4
+ * [[`e1bb99c83e`](https://github.com/rhalff/dot-object/commit/e1bb99c83e)] - Fix isIndex numeric key matching. (Fixed by mrdivyansh #31)
5
+
6
+ ## 2017-09-20 Version 1.7.0
7
+ * let .dot and .object understand empty objects / arrays
8
+
9
+ ## 2017-07-27 Version 1.6.0
10
+ * implemented keepArray
11
+
12
+ ## 2016-09-29 Version 1.5.4
13
+ * update dist
14
+
3
15
  ## 2016-09-29, Version 1.5.3
4
- * Fix override bug in str()
16
+ * Fix override bug in str()
5
17
 
6
18
  ## 2016-08-04, Version 1.5.0
7
19
  * [[`a7e948f2fa`](https://github.com/rhalff/dot-object/commit/a7e948f2fa)] - Ensure we only process true Arrays and Objects. (Fixed by MechJosh0 #15)
package/README.md CHANGED
@@ -166,7 +166,7 @@ console.log(tgt);
166
166
  ```
167
167
 
168
168
  #### Pick/remove a value using dot notation:
169
- ```
169
+ ```js
170
170
  var dot = require('dot-object');
171
171
 
172
172
  var obj = {
@@ -327,9 +327,9 @@ Result:
327
327
  }
328
328
  ```
329
329
 
330
- ## Using a different seperator
330
+ ## Using a different separator
331
331
 
332
- If you do not like dot notation, you are free to specify a different seperator.
332
+ If you do not like dot notation, you are free to specify a different separator.
333
333
 
334
334
  ```javascript
335
335
  var Dot = require('dot-object');
package/bower.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "type": "git",
26
26
  "url": "git://github.com/rhalff/dot-object.git"
27
27
  },
28
- "version": "1.5.3",
28
+ "version": "1.7.0",
29
29
  "homepage": "https://github.com/rhalff/dot-object",
30
30
  "moduleType": [
31
31
  "amd",
@@ -31,7 +31,19 @@
31
31
  }
32
32
 
33
33
  function isIndex(k) {
34
- return /^\d+/.test(k)
34
+ return /^\d+$/.test(k)
35
+ }
36
+
37
+ function isObject(val) {
38
+ return Object.prototype.toString.call(val) === '[object Object]'
39
+ }
40
+
41
+ function isArrayOrObject(val) {
42
+ return Object(val) === val
43
+ }
44
+
45
+ function isEmptyObject(val) {
46
+ return Object.keys(val).length === 0
35
47
  }
36
48
 
37
49
  function parsePath(path, sep) {
@@ -41,17 +53,17 @@
41
53
  return path.split(sep)
42
54
  }
43
55
 
44
- function DotObject(seperator, override, useArray) {
56
+ function DotObject(separator, override, useArray) {
45
57
  if (!(this instanceof DotObject)) {
46
- return new DotObject(seperator, override, useArray)
58
+ return new DotObject(separator, override, useArray)
47
59
  }
48
60
 
49
- if (typeof seperator === 'undefined') seperator = '.'
50
61
  if (typeof override === 'undefined') override = false
51
62
  if (typeof useArray === 'undefined') useArray = true
52
- this.seperator = seperator
63
+ this.separator = separator || '.'
53
64
  this.override = override
54
65
  this.useArray = useArray
66
+ this.keepArray = false
55
67
 
56
68
  // contains touched arrays
57
69
  this.cleanup = []
@@ -72,21 +84,29 @@
72
84
  obj[k] = obj[k] ||
73
85
  (this.useArray && isIndex(a[0]) ? [] : {})
74
86
 
75
- if (obj[k] !== Object(obj[k])) {
87
+ if (!isArrayOrObject(obj[k])) {
76
88
  if (this.override) {
77
89
  obj[k] = {}
78
90
  } else {
79
- throw new Error(
80
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
81
- )
91
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
92
+ throw new Error(
93
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
94
+ )
95
+ }
96
+
97
+ return
82
98
  }
83
99
  }
84
100
 
85
101
  this._fill(a, obj[k], v, mod)
86
102
  } else {
87
103
  if (!this.override &&
88
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
89
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
104
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
105
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
106
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
107
+ }
108
+
109
+ return
90
110
  }
91
111
 
92
112
  obj[k] = _process(v, mod)
@@ -120,11 +140,11 @@
120
140
 
121
141
  Object.keys(obj).forEach(function(k) {
122
142
  var mod = mods === undefined ? null : mods[k]
123
- // normalize array notation.
124
- var ok = parsePath(k, self.seperator).join(self.seperator)
143
+ // normalize array notation.
144
+ var ok = parsePath(k, self.separator).join(self.separator)
125
145
 
126
- if (ok.indexOf(self.seperator) !== -1) {
127
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
146
+ if (ok.indexOf(self.separator) !== -1) {
147
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
128
148
  delete obj[k]
129
149
  } else if (self.override) {
130
150
  obj[k] = _process(obj[k], mod)
@@ -141,9 +161,9 @@
141
161
  * @param {Function|Array} mod optional modifier
142
162
  */
143
163
  DotObject.prototype.str = function(path, v, obj, mod) {
144
- if (path.indexOf(this.seperator) !== -1) {
145
- this._fill(path.split(this.seperator), obj, v, mod)
146
- } else if (this.override) {
164
+ if (path.indexOf(this.separator) !== -1) {
165
+ this._fill(path.split(this.separator), obj, v, mod)
166
+ } else if (!obj.hasOwnProperty(path) || this.override) {
147
167
  obj[path] = _process(v, mod)
148
168
  }
149
169
 
@@ -167,7 +187,7 @@
167
187
  var key
168
188
  var cp
169
189
 
170
- keys = parsePath(path, this.seperator)
190
+ keys = parsePath(path, this.separator)
171
191
  for (i = 0; i < keys.length; i++) {
172
192
  key = parseKey(keys[i], obj)
173
193
  if (obj && typeof obj === 'object' && key in obj) {
@@ -332,10 +352,6 @@
332
352
  return obj2
333
353
  }
334
354
 
335
- function isObject(val) {
336
- return Object.prototype.toString.call(val) === '[object Object]'
337
- }
338
-
339
355
  /**
340
356
  *
341
357
  * Set a property on an object using dot notation.
@@ -355,7 +371,7 @@
355
371
  if (typeof val === 'undefined') {
356
372
  return obj
357
373
  }
358
- keys = parsePath(path, this.seperator)
374
+ keys = parsePath(path, this.separator)
359
375
 
360
376
  for (i = 0; i < keys.length; i++) {
361
377
  key = keys[i]
@@ -444,10 +460,18 @@
444
460
  tgt = tgt || {}
445
461
  path = path || []
446
462
  Object.keys(obj).forEach(function(key) {
447
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
463
+ if (
464
+ (
465
+ isArrayOrObject(obj[key]) &&
466
+ (
467
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
468
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
469
+ )
470
+ )
471
+ ) {
448
472
  return this.dot(obj[key], tgt, path.concat(key))
449
473
  } else {
450
- tgt[path.concat(key).join(this.seperator)] = obj[key]
474
+ tgt[path.concat(key).join(this.separator)] = obj[key]
451
475
  }
452
476
  }.bind(this))
453
477
  return tgt
@@ -476,13 +500,16 @@
476
500
  })
477
501
  })
478
502
 
479
- Object.defineProperty(DotObject, 'useArray', {
480
- get: function() {
481
- return dotDefault.useArray
482
- },
483
- set: function(val) {
484
- dotDefault.useArray = val
485
- }
503
+ ;
504
+ ['useArray', 'keepArray'].forEach(function(prop) {
505
+ Object.defineProperty(DotObject, prop, {
506
+ get: function() {
507
+ return dotDefault[prop]
508
+ },
509
+ set: function(val) {
510
+ dotDefault[prop] = val
511
+ }
512
+ })
486
513
  })
487
514
 
488
515
  DotObject._process = _process
@@ -490,12 +517,12 @@
490
517
 
491
518
  if (typeof define === 'function' && define.amd) {
492
519
  define(function() {
493
- return DotObject;
494
- });
520
+ return DotObject
521
+ })
495
522
  } else if (typeof module != 'undefined' && module.exports) {
496
- module.exports = DotObject;
523
+ module.exports = DotObject
497
524
  } else {
498
- global[exportName] = DotObject;
525
+ global[exportName] = DotObject
499
526
  }
500
527
 
501
- })(this, 'DotObject');
528
+ })(this, 'DotObject')
@@ -1 +1 @@
1
- !function(t,e){"use strict";function r(t,e){var r,i;if("function"==typeof e)i=e(t),void 0!==i&&(t=i);else if(Array.isArray(e))for(r=0;r<e.length;r++)i=e[r](t),void 0!==i&&(t=i);return t}function i(t,e){return"-"===t[0]&&Array.isArray(e)&&/^-\d+$/.test(t)?e.length+parseInt(t,10):t}function n(t){return/^\d+/.test(t)}function o(t,e){return t.indexOf("[")>=0&&(t=t.replace(/\[/g,".").replace(/]/g,"")),t.split(e)}function s(t,e,r){return this instanceof s?("undefined"==typeof t&&(t="."),"undefined"==typeof e&&(e=!1),"undefined"==typeof r&&(r=!0),this.seperator=t,this.override=e,this.useArray=r,void(this.cleanup=[])):new s(t,e,r)}function c(t){return function(){return p[t].apply(p,arguments)}}function f(t){return"[object Object]"===Object.prototype.toString.call(t)}var p=new s(".",(!1),(!0));s.prototype._fill=function(t,e,i,o){var s=t.shift();if(t.length>0){if(e[s]=e[s]||(this.useArray&&n(t[0])?[]:{}),e[s]!==Object(e[s])){if(!this.override)throw new Error("Trying to redefine `"+s+"` which is a "+typeof e[s]);e[s]={}}this._fill(t,e[s],i,o)}else{if(!this.override&&e[s]===Object(e[s])&&Object.keys(e[s]).length)throw new Error("Trying to redefine non-empty obj['"+s+"']");e[s]=r(i,o)}},s.prototype.object=function(t,e){var i=this;return Object.keys(t).forEach(function(n){var s=void 0===e?null:e[n],c=o(n,i.seperator).join(i.seperator);c.indexOf(i.seperator)!==-1?(i._fill(c.split(i.seperator),t,t[n],s),delete t[n]):i.override&&(t[n]=r(t[n],s))}),t},s.prototype.str=function(t,e,i,n){return t.indexOf(this.seperator)!==-1?this._fill(t.split(this.seperator),i,e,n):this.override&&(i[t]=r(e,n)),i},s.prototype.pick=function(t,e,r){var n,s,c,f,p;for(s=o(t,this.seperator),n=0;n<s.length;n++){if(f=i(s[n],e),!(e&&"object"==typeof e&&f in e))return;if(n===s.length-1)return r?(c=e[f],delete e[f],Array.isArray(e)&&(p=s.slice(0,-1).join("."),this.cleanup.indexOf(p)===-1&&this.cleanup.push(p)),c):e[f];e=e[f]}return r&&Array.isArray(e)&&(e=e.filter(function(t){return void 0!==t})),e},s.prototype.remove=function(t,e){var r;if(this.cleanup=[],Array.isArray(t)){for(r=0;r<t.length;r++)this.pick(t[r],e,!0);return this._cleanup(e),e}return this.pick(t,e,!0)},s.prototype._cleanup=function(t){var e,r,i,n;if(this.cleanup.length){for(r=0;r<this.cleanup.length;r++)i=this.cleanup[r].split("."),n=i.splice(0,-1).join("."),e=n?this.pick(n,t):t,e=e[i[0]].filter(function(t){return void 0!==t}),this.set(this.cleanup[r],e,t);this.cleanup=[]}},s.prototype.del=s.prototype.remove,s.prototype.move=function(t,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(e,r(this.pick(t,i,!0),n),i,o):(o=n,this.set(e,this.pick(t,i,!0),i,o)),i},s.prototype.transfer=function(t,e,i,n,o,s){return"function"==typeof o||Array.isArray(o)?this.set(e,r(this.pick(t,i,!0),o),n,s):(s=o,this.set(e,this.pick(t,i,!0),n,s)),n},s.prototype.copy=function(t,e,i,n,o,s){return"function"==typeof o||Array.isArray(o)?this.set(e,r(JSON.parse(JSON.stringify(this.pick(t,i,!1))),o),n,s):(s=o,this.set(e,this.pick(t,i,!1),n,s)),n},s.prototype.set=function(t,e,r,i){var n,s,c,p;if("undefined"==typeof e)return r;for(c=o(t,this.seperator),n=0;n<c.length;n++){if(p=c[n],n===c.length-1)if(i&&f(e)&&f(r[p]))for(s in e)e.hasOwnProperty(s)&&(r[p][s]=e[s]);else if(i&&Array.isArray(r[p])&&Array.isArray(e))for(var u=0;u<e.length;u++)r[c[n]].push(e[u]);else r[p]=e;else r.hasOwnProperty(p)&&(f(r[p])||Array.isArray(r[p]))||(/^\d+$/.test(c[n+1])?r[p]=[]:r[p]={});r=r[p]}return r},s.prototype.transform=function(t,e,r){return e=e||{},r=r||{},Object.keys(t).forEach(function(i){this.set(t[i],this.pick(i,e),r)}.bind(this)),r},s.prototype.dot=function(t,e,r){return e=e||{},r=r||[],Object.keys(t).forEach(function(i){return Object(t[i])===t[i]&&"[object Object]"===Object.prototype.toString.call(t[i])||"[object Array]"===Object.prototype.toString.call(t[i])?this.dot(t[i],e,r.concat(i)):void(e[r.concat(i).join(this.seperator)]=t[i])}.bind(this)),e},s.pick=c("pick"),s.move=c("move"),s.transfer=c("transfer"),s.transform=c("transform"),s.copy=c("copy"),s.object=c("object"),s.str=c("str"),s.set=c("set"),s.del=s.remove=c("remove"),s.dot=c("dot"),["override","overwrite"].forEach(function(t){Object.defineProperty(s,t,{get:function(){return p.override},set:function(t){p.override=!!t}})}),Object.defineProperty(s,"useArray",{get:function(){return p.useArray},set:function(t){p.useArray=t}}),s._process=r,"function"==typeof define&&define.amd?define(function(){return s}):"undefined"!=typeof module&&module.exports?module.exports=s:t[e]=s}(this,"DotObject");
1
+ !function(t,r){"use strict";function s(t,r){var e,i;if("function"==typeof r)void 0!==(i=r(t))&&(t=i);else if(Array.isArray(r))for(e=0;e<r.length;e++)void 0!==(i=r[e](t))&&(t=i);return t}function c(t){return"[object Object]"===Object.prototype.toString.call(t)}function f(t){return Object(t)===t}function p(t){return 0===Object.keys(t).length}function a(t,r){return 0<=t.indexOf("[")&&(t=t.replace(/\[/g,".").replace(/]/g,"")),t.split(r)}function i(t,r,e){if(!(this instanceof i))return new i(t,r,e);void 0===r&&(r=!1),void 0===e&&(e=!0),this.separator=t||".",this.override=r,this.useArray=e,this.keepArray=!1,this.cleanup=[]}var e=new i(".",!1,!0);function n(t){return function(){return e[t].apply(e,arguments)}}i.prototype._fill=function(t,r,e,i){var n,o=t.shift();if(0<t.length){if(r[o]=r[o]||(this.useArray&&(n=t[0],/^\d+$/.test(n))?[]:{}),!f(r[o])){if(!this.override){if(!f(e)||!p(e))throw new Error("Trying to redefine `"+o+"` which is a "+typeof r[o]);return}r[o]={}}this._fill(t,r[o],e,i)}else{if(!this.override&&f(r[o])&&!p(r[o])){if(!f(e)||!p(e))throw new Error("Trying to redefine non-empty obj['"+o+"']");return}r[o]=s(e,i)}},i.prototype.object=function(i,n){var o=this;return Object.keys(i).forEach(function(t){var r=void 0===n?null:n[t],e=a(t,o.separator).join(o.separator);-1!==e.indexOf(o.separator)?(o._fill(e.split(o.separator),i,i[t],r),delete i[t]):o.override&&(i[t]=s(i[t],r))}),i},i.prototype.str=function(t,r,e,i){return-1!==t.indexOf(this.separator)?this._fill(t.split(this.separator),e,r,i):e.hasOwnProperty(t)&&!this.override||(e[t]=s(r,i)),e},i.prototype.pick=function(t,r,e){var i,n,o,s,f,p,c;for(n=a(t,this.separator),i=0;i<n.length;i++){if(p=n[i],c=r,s="-"===p[0]&&Array.isArray(c)&&/^-\d+$/.test(p)?c.length+parseInt(p,10):p,!(r&&"object"==typeof r&&s in r))return;if(i===n.length-1)return e?(o=r[s],delete r[s],Array.isArray(r)&&(f=n.slice(0,-1).join("."),-1===this.cleanup.indexOf(f)&&this.cleanup.push(f)),o):r[s];r=r[s]}return e&&Array.isArray(r)&&(r=r.filter(function(t){return void 0!==t})),r},i.prototype.remove=function(t,r){var e;if(this.cleanup=[],Array.isArray(t)){for(e=0;e<t.length;e++)this.pick(t[e],r,!0);return this._cleanup(r),r}return this.pick(t,r,!0)},i.prototype._cleanup=function(t){var r,e,i,n;if(this.cleanup.length){for(e=0;e<this.cleanup.length;e++)r=(r=(n=(i=this.cleanup[e].split(".")).splice(0,-1).join("."))?this.pick(n,t):t)[i[0]].filter(function(t){return void 0!==t}),this.set(this.cleanup[e],r,t);this.cleanup=[]}},i.prototype.del=i.prototype.remove,i.prototype.move=function(t,r,e,i,n){return"function"==typeof i||Array.isArray(i)?this.set(r,s(this.pick(t,e,!0),i),e,n):(n=i,this.set(r,this.pick(t,e,!0),e,n)),e},i.prototype.transfer=function(t,r,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(r,s(this.pick(t,e,!0),n),i,o):(o=n,this.set(r,this.pick(t,e,!0),i,o)),i},i.prototype.copy=function(t,r,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(r,s(JSON.parse(JSON.stringify(this.pick(t,e,!1))),n),i,o):(o=n,this.set(r,this.pick(t,e,!1),i,o)),i},i.prototype.set=function(t,r,e,i){var n,o,s,f;if(void 0===r)return e;for(s=a(t,this.separator),n=0;n<s.length;n++){if(f=s[n],n===s.length-1)if(i&&c(r)&&c(e[f]))for(o in r)r.hasOwnProperty(o)&&(e[f][o]=r[o]);else if(i&&Array.isArray(e[f])&&Array.isArray(r))for(var p=0;p<r.length;p++)e[s[n]].push(r[p]);else e[f]=r;else e.hasOwnProperty(f)&&(c(e[f])||Array.isArray(e[f]))||(/^\d+$/.test(s[n+1])?e[f]=[]:e[f]={});e=e[f]}return e},i.prototype.transform=function(r,e,i){return e=e||{},i=i||{},Object.keys(r).forEach(function(t){this.set(r[t],this.pick(t,e),i)}.bind(this)),i},i.prototype.dot=function(r,e,i){return e=e||{},i=i||[],Object.keys(r).forEach(function(t){if(f(r[t])&&(c(r[t])&&!p(r[t])||Array.isArray(r[t])&&!this.keepArray&&0!==r[t].length))return this.dot(r[t],e,i.concat(t));e[i.concat(t).join(this.separator)]=r[t]}.bind(this)),e},i.pick=n("pick"),i.move=n("move"),i.transfer=n("transfer"),i.transform=n("transform"),i.copy=n("copy"),i.object=n("object"),i.str=n("str"),i.set=n("set"),i.del=i.remove=n("remove"),i.dot=n("dot"),["override","overwrite"].forEach(function(t){Object.defineProperty(i,t,{get:function(){return e.override},set:function(t){e.override=!!t}})}),["useArray","keepArray"].forEach(function(r){Object.defineProperty(i,r,{get:function(){return e[r]},set:function(t){e[r]=t}})}),i._process=s,"function"==typeof define&&define.amd?define(function(){return i}):"undefined"!=typeof module&&module.exports?module.exports=i:t.DotObject=i}(this);
package/gulpfile.js CHANGED
@@ -33,8 +33,8 @@ gulp.task('watch', function () {
33
33
 
34
34
  gulp.task('build-node', function () {
35
35
  gulp.src('src/dot-object.js')
36
- .pipe(hf.footer('\nmodule.exports = DotObject;\n'))
37
- .pipe(rename({basename: 'index'}))
36
+ .pipe(hf.footer('\nmodule.exports = DotObject\n'))
37
+ .pipe(rename({ basename: 'index' }))
38
38
  .pipe(gulp.dest('./'))
39
39
  })
40
40
 
@@ -42,10 +42,10 @@ gulp.task('build-bower', function () {
42
42
  gulp.src('src/dot-object.js')
43
43
  .pipe(hf.header('src/header.tpl'))
44
44
  .pipe(hf.footer('src/footer.tpl'))
45
- .pipe(beautify({indentSize: 2}))
45
+ .pipe(beautify({ indentSize: 2 }))
46
46
  .pipe(gulp.dest(DEST))
47
47
  .pipe(uglify())
48
- .pipe(rename({extname: '.min.js'}))
48
+ .pipe(rename({ extname: '.min.js' }))
49
49
  .pipe(gulp.dest(DEST))
50
50
  })
51
51
 
package/index.js CHANGED
@@ -30,7 +30,19 @@ function parseKey (key, val) {
30
30
  }
31
31
 
32
32
  function isIndex (k) {
33
- return /^\d+/.test(k)
33
+ return /^\d+$/.test(k)
34
+ }
35
+
36
+ function isObject (val) {
37
+ return Object.prototype.toString.call(val) === '[object Object]'
38
+ }
39
+
40
+ function isArrayOrObject (val) {
41
+ return Object(val) === val
42
+ }
43
+
44
+ function isEmptyObject (val) {
45
+ return Object.keys(val).length === 0
34
46
  }
35
47
 
36
48
  function parsePath (path, sep) {
@@ -40,17 +52,17 @@ function parsePath (path, sep) {
40
52
  return path.split(sep)
41
53
  }
42
54
 
43
- function DotObject (seperator, override, useArray) {
55
+ function DotObject (separator, override, useArray) {
44
56
  if (!(this instanceof DotObject)) {
45
- return new DotObject(seperator, override, useArray)
57
+ return new DotObject(separator, override, useArray)
46
58
  }
47
59
 
48
- if (typeof seperator === 'undefined') seperator = '.'
49
60
  if (typeof override === 'undefined') override = false
50
61
  if (typeof useArray === 'undefined') useArray = true
51
- this.seperator = seperator
62
+ this.separator = separator || '.'
52
63
  this.override = override
53
64
  this.useArray = useArray
65
+ this.keepArray = false
54
66
 
55
67
  // contains touched arrays
56
68
  this.cleanup = []
@@ -70,21 +82,29 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
70
82
  obj[k] = obj[k] ||
71
83
  (this.useArray && isIndex(a[0]) ? [] : {})
72
84
 
73
- if (obj[k] !== Object(obj[k])) {
85
+ if (!isArrayOrObject(obj[k])) {
74
86
  if (this.override) {
75
87
  obj[k] = {}
76
88
  } else {
77
- throw new Error(
78
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
79
- )
89
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
90
+ throw new Error(
91
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
92
+ )
93
+ }
94
+
95
+ return
80
96
  }
81
97
  }
82
98
 
83
99
  this._fill(a, obj[k], v, mod)
84
100
  } else {
85
101
  if (!this.override &&
86
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
87
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
102
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
103
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
104
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
105
+ }
106
+
107
+ return
88
108
  }
89
109
 
90
110
  obj[k] = _process(v, mod)
@@ -119,10 +139,10 @@ DotObject.prototype.object = function (obj, mods) {
119
139
  Object.keys(obj).forEach(function (k) {
120
140
  var mod = mods === undefined ? null : mods[k]
121
141
  // normalize array notation.
122
- var ok = parsePath(k, self.seperator).join(self.seperator)
142
+ var ok = parsePath(k, self.separator).join(self.separator)
123
143
 
124
- if (ok.indexOf(self.seperator) !== -1) {
125
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
144
+ if (ok.indexOf(self.separator) !== -1) {
145
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
126
146
  delete obj[k]
127
147
  } else if (self.override) {
128
148
  obj[k] = _process(obj[k], mod)
@@ -139,8 +159,8 @@ DotObject.prototype.object = function (obj, mods) {
139
159
  * @param {Function|Array} mod optional modifier
140
160
  */
141
161
  DotObject.prototype.str = function (path, v, obj, mod) {
142
- if (path.indexOf(this.seperator) !== -1) {
143
- this._fill(path.split(this.seperator), obj, v, mod)
162
+ if (path.indexOf(this.separator) !== -1) {
163
+ this._fill(path.split(this.separator), obj, v, mod)
144
164
  } else if (!obj.hasOwnProperty(path) || this.override) {
145
165
  obj[path] = _process(v, mod)
146
166
  }
@@ -165,7 +185,7 @@ DotObject.prototype.pick = function (path, obj, remove) {
165
185
  var key
166
186
  var cp
167
187
 
168
- keys = parsePath(path, this.seperator)
188
+ keys = parsePath(path, this.separator)
169
189
  for (i = 0; i < keys.length; i++) {
170
190
  key = parseKey(keys[i], obj)
171
191
  if (obj && typeof obj === 'object' && key in obj) {
@@ -326,10 +346,6 @@ DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
326
346
  return obj2
327
347
  }
328
348
 
329
- function isObject (val) {
330
- return Object.prototype.toString.call(val) === '[object Object]'
331
- }
332
-
333
349
  /**
334
350
  *
335
351
  * Set a property on an object using dot notation.
@@ -349,7 +365,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
349
365
  if (typeof val === 'undefined') {
350
366
  return obj
351
367
  }
352
- keys = parsePath(path, this.seperator)
368
+ keys = parsePath(path, this.separator)
353
369
 
354
370
  for (i = 0; i < keys.length; i++) {
355
371
  key = keys[i]
@@ -438,10 +454,18 @@ DotObject.prototype.dot = function (obj, tgt, path) {
438
454
  tgt = tgt || {}
439
455
  path = path || []
440
456
  Object.keys(obj).forEach(function (key) {
441
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
457
+ if (
458
+ (
459
+ isArrayOrObject(obj[key]) &&
460
+ (
461
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
462
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
463
+ )
464
+ )
465
+ ) {
442
466
  return this.dot(obj[key], tgt, path.concat(key))
443
467
  } else {
444
- tgt[path.concat(key).join(this.seperator)] = obj[key]
468
+ tgt[path.concat(key).join(this.separator)] = obj[key]
445
469
  }
446
470
  }.bind(this))
447
471
  return tgt
@@ -469,15 +493,17 @@ DotObject.dot = wrap('dot')
469
493
  })
470
494
  })
471
495
 
472
- Object.defineProperty(DotObject, 'useArray', {
473
- get: function () {
474
- return dotDefault.useArray
475
- },
476
- set: function (val) {
477
- dotDefault.useArray = val
478
- }
496
+ ;['useArray', 'keepArray'].forEach(function (prop) {
497
+ Object.defineProperty(DotObject, prop, {
498
+ get: function () {
499
+ return dotDefault[prop]
500
+ },
501
+ set: function (val) {
502
+ dotDefault[prop] = val
503
+ }
504
+ })
479
505
  })
480
506
 
481
507
  DotObject._process = _process
482
508
 
483
- module.exports = DotObject;
509
+ module.exports = DotObject
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dot-object",
3
3
  "description": "dot-object makes it possible to transform and read (JSON) objects using dot notation.",
4
- "version": "1.5.3",
4
+ "version": "1.7.1",
5
5
  "author": {
6
6
  "name": "Rob Halff",
7
7
  "email": "rob.halff@gmail.com"
@@ -30,15 +30,15 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "gulp": "^3.9.1",
33
- "gulp-beautify": "^2.0.0",
33
+ "gulp-beautify": "^2.0.1",
34
34
  "gulp-headerfooter": "^1.0.3",
35
- "gulp-mocha": "^3.0.0",
36
- "gulp-rename": "^1.2.2",
37
- "gulp-standard": "^7.0.1",
38
- "gulp-uglify": "^2.0.0",
39
- "gulp-util": "^3.0.7",
40
- "mocha": "3.x.x",
41
- "should": "10.x.x",
35
+ "gulp-mocha": "^6.0.0",
36
+ "gulp-rename": "^1.4.0",
37
+ "gulp-standard": "^12.0.0",
38
+ "gulp-uglify": "^3.0.1",
39
+ "gulp-util": "^3.0.8",
40
+ "mocha": "5.x.x",
41
+ "should": "13.x.x",
42
42
  "underscore.string": "latest"
43
43
  },
44
44
  "keywords": [
@@ -49,7 +49,7 @@
49
49
  "dot"
50
50
  ],
51
51
  "dependencies": {
52
- "commander": "^2.9.0",
53
- "glob": "^7.0.5"
52
+ "commander": "^2.19.0",
53
+ "glob": "^7.1.3"
54
54
  }
55
55
  }
package/src/dot-object.js CHANGED
@@ -30,7 +30,19 @@ function parseKey (key, val) {
30
30
  }
31
31
 
32
32
  function isIndex (k) {
33
- return /^\d+/.test(k)
33
+ return /^\d+$/.test(k)
34
+ }
35
+
36
+ function isObject (val) {
37
+ return Object.prototype.toString.call(val) === '[object Object]'
38
+ }
39
+
40
+ function isArrayOrObject (val) {
41
+ return Object(val) === val
42
+ }
43
+
44
+ function isEmptyObject (val) {
45
+ return Object.keys(val).length === 0
34
46
  }
35
47
 
36
48
  function parsePath (path, sep) {
@@ -40,17 +52,17 @@ function parsePath (path, sep) {
40
52
  return path.split(sep)
41
53
  }
42
54
 
43
- function DotObject (seperator, override, useArray) {
55
+ function DotObject (separator, override, useArray) {
44
56
  if (!(this instanceof DotObject)) {
45
- return new DotObject(seperator, override, useArray)
57
+ return new DotObject(separator, override, useArray)
46
58
  }
47
59
 
48
- if (typeof seperator === 'undefined') seperator = '.'
49
60
  if (typeof override === 'undefined') override = false
50
61
  if (typeof useArray === 'undefined') useArray = true
51
- this.seperator = seperator
62
+ this.separator = separator || '.'
52
63
  this.override = override
53
64
  this.useArray = useArray
65
+ this.keepArray = false
54
66
 
55
67
  // contains touched arrays
56
68
  this.cleanup = []
@@ -70,21 +82,29 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
70
82
  obj[k] = obj[k] ||
71
83
  (this.useArray && isIndex(a[0]) ? [] : {})
72
84
 
73
- if (obj[k] !== Object(obj[k])) {
85
+ if (!isArrayOrObject(obj[k])) {
74
86
  if (this.override) {
75
87
  obj[k] = {}
76
88
  } else {
77
- throw new Error(
78
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
79
- )
89
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
90
+ throw new Error(
91
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
92
+ )
93
+ }
94
+
95
+ return
80
96
  }
81
97
  }
82
98
 
83
99
  this._fill(a, obj[k], v, mod)
84
100
  } else {
85
101
  if (!this.override &&
86
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
87
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
102
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
103
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
104
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
105
+ }
106
+
107
+ return
88
108
  }
89
109
 
90
110
  obj[k] = _process(v, mod)
@@ -119,10 +139,10 @@ DotObject.prototype.object = function (obj, mods) {
119
139
  Object.keys(obj).forEach(function (k) {
120
140
  var mod = mods === undefined ? null : mods[k]
121
141
  // normalize array notation.
122
- var ok = parsePath(k, self.seperator).join(self.seperator)
142
+ var ok = parsePath(k, self.separator).join(self.separator)
123
143
 
124
- if (ok.indexOf(self.seperator) !== -1) {
125
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
144
+ if (ok.indexOf(self.separator) !== -1) {
145
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
126
146
  delete obj[k]
127
147
  } else if (self.override) {
128
148
  obj[k] = _process(obj[k], mod)
@@ -139,8 +159,8 @@ DotObject.prototype.object = function (obj, mods) {
139
159
  * @param {Function|Array} mod optional modifier
140
160
  */
141
161
  DotObject.prototype.str = function (path, v, obj, mod) {
142
- if (path.indexOf(this.seperator) !== -1) {
143
- this._fill(path.split(this.seperator), obj, v, mod)
162
+ if (path.indexOf(this.separator) !== -1) {
163
+ this._fill(path.split(this.separator), obj, v, mod)
144
164
  } else if (!obj.hasOwnProperty(path) || this.override) {
145
165
  obj[path] = _process(v, mod)
146
166
  }
@@ -165,7 +185,7 @@ DotObject.prototype.pick = function (path, obj, remove) {
165
185
  var key
166
186
  var cp
167
187
 
168
- keys = parsePath(path, this.seperator)
188
+ keys = parsePath(path, this.separator)
169
189
  for (i = 0; i < keys.length; i++) {
170
190
  key = parseKey(keys[i], obj)
171
191
  if (obj && typeof obj === 'object' && key in obj) {
@@ -326,10 +346,6 @@ DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
326
346
  return obj2
327
347
  }
328
348
 
329
- function isObject (val) {
330
- return Object.prototype.toString.call(val) === '[object Object]'
331
- }
332
-
333
349
  /**
334
350
  *
335
351
  * Set a property on an object using dot notation.
@@ -349,7 +365,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
349
365
  if (typeof val === 'undefined') {
350
366
  return obj
351
367
  }
352
- keys = parsePath(path, this.seperator)
368
+ keys = parsePath(path, this.separator)
353
369
 
354
370
  for (i = 0; i < keys.length; i++) {
355
371
  key = keys[i]
@@ -438,10 +454,18 @@ DotObject.prototype.dot = function (obj, tgt, path) {
438
454
  tgt = tgt || {}
439
455
  path = path || []
440
456
  Object.keys(obj).forEach(function (key) {
441
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
457
+ if (
458
+ (
459
+ isArrayOrObject(obj[key]) &&
460
+ (
461
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
462
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
463
+ )
464
+ )
465
+ ) {
442
466
  return this.dot(obj[key], tgt, path.concat(key))
443
467
  } else {
444
- tgt[path.concat(key).join(this.seperator)] = obj[key]
468
+ tgt[path.concat(key).join(this.separator)] = obj[key]
445
469
  }
446
470
  }.bind(this))
447
471
  return tgt
@@ -469,13 +493,15 @@ DotObject.dot = wrap('dot')
469
493
  })
470
494
  })
471
495
 
472
- Object.defineProperty(DotObject, 'useArray', {
473
- get: function () {
474
- return dotDefault.useArray
475
- },
476
- set: function (val) {
477
- dotDefault.useArray = val
478
- }
496
+ ;['useArray', 'keepArray'].forEach(function (prop) {
497
+ Object.defineProperty(DotObject, prop, {
498
+ get: function () {
499
+ return dotDefault[prop]
500
+ },
501
+ set: function (val) {
502
+ dotDefault[prop] = val
503
+ }
504
+ })
479
505
  })
480
506
 
481
507
  DotObject._process = _process
package/src/footer.tpl CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  if (typeof define === 'function' && define.amd) {
4
4
  define(function() {
5
- return DotObject;
6
- });
5
+ return DotObject
6
+ })
7
7
  } else if (typeof module != 'undefined' && module.exports) {
8
- module.exports = DotObject;
8
+ module.exports = DotObject
9
9
  } else {
10
- global[exportName] = DotObject;
10
+ global[exportName] = DotObject
11
11
  }
12
12
 
13
- })(this, 'DotObject');
13
+ })(this, 'DotObject')
@@ -66,8 +66,8 @@ describe('Dotted Array notation', function () {
66
66
  it('multiple indexes', function () {
67
67
  var src = {
68
68
  I: [
69
- {am: [{nes: ['ted']}]},
70
- {me: 'too'}
69
+ { am: [{ nes: ['ted'] }] },
70
+ { me: 'too' }
71
71
  ]
72
72
  }
73
73
 
@@ -82,47 +82,47 @@ describe('Dotted Array notation', function () {
82
82
 
83
83
  describe('can set', function () {
84
84
  it('index at target', function () {
85
- var obj = {path: []}
85
+ var obj = { path: [] }
86
86
 
87
87
  Dot.set(v('path.0'), 'test', obj)
88
88
  Dot.set(v('path.1'), 'test2', obj)
89
89
 
90
- obj.path.should.be.an.Array
91
- obj.should.eql({path: ['test', 'test2']})
90
+ obj.path.should.be.instanceOf(Array)
91
+ obj.should.eql({ path: ['test', 'test2'] })
92
92
  })
93
93
 
94
94
  it('index and set undefined for empty indices', function () {
95
- var obj = {path: []}
95
+ var obj = { path: [] }
96
96
 
97
97
  Dot.set(v('path.0'), 'test', obj)
98
98
  Dot.set(v('path.2'), 'test2', obj)
99
99
 
100
- obj.path.should.be.an.Array
100
+ obj.path.should.be.instanceOf(Array)
101
101
 
102
102
  // array will have an undefined index.
103
103
  JSON.stringify(obj)
104
104
  .should.eql(
105
- JSON.stringify({path: ['test', undefined, 'test2']})
106
- )
105
+ JSON.stringify({ path: ['test', undefined, 'test2'] })
106
+ )
107
107
 
108
108
  // to json will converted it to null
109
109
  JSON.stringify(obj).should.eql('{"path":["test",null,"test2"]}')
110
110
  })
111
111
 
112
112
  it('index and overwrite existing values', function () {
113
- var obj = {path: ['still', 'shall', 'be', 'gone', 'here']}
113
+ var obj = { path: ['still', 'shall', 'be', 'gone', 'here'] }
114
114
 
115
115
  Dot.set(v('path.1'), 'x', obj)
116
116
  Dot.set(v('path.2'), 'xx', obj)
117
117
  Dot.set(v('path.3'), 'xxx', obj)
118
118
 
119
- obj.should.eql({path: ['still', 'x', 'xx', 'xxx', 'here']})
119
+ obj.should.eql({ path: ['still', 'x', 'xx', 'xxx', 'here'] })
120
120
  })
121
121
  })
122
122
 
123
123
  describe('can remove', function () {
124
124
  it('indexes one by one leaving traces', function () {
125
- var obj = {path: ['still', 'shall', 'really', 'be', 'gone', 'here']}
125
+ var obj = { path: ['still', 'shall', 'really', 'be', 'gone', 'here'] }
126
126
 
127
127
  Dot.remove(v('path.1'), obj)
128
128
  Dot.remove(v('path.2'), obj)
@@ -132,12 +132,12 @@ describe('Dotted Array notation', function () {
132
132
  // array will have an undefined index.
133
133
  JSON.stringify(obj)
134
134
  .should.eql(
135
- JSON.stringify({
136
- path: [
137
- 'still', undefined, undefined, undefined, undefined, 'here'
138
- ]
139
- })
140
- )
135
+ JSON.stringify({
136
+ path: [
137
+ 'still', undefined, undefined, undefined, undefined, 'here'
138
+ ]
139
+ })
140
+ )
141
141
 
142
142
  // to json will converted it to null
143
143
  JSON.stringify(obj).should.eql(
@@ -146,7 +146,7 @@ describe('Dotted Array notation', function () {
146
146
  })
147
147
 
148
148
  it('array of indexes leaving no traces', function () {
149
- var obj = {path: ['still', 'shall', 'really', 'be', 'gone', 'here']}
149
+ var obj = { path: ['still', 'shall', 'really', 'be', 'gone', 'here'] }
150
150
 
151
151
  Dot.remove([
152
152
  v('path.1'),
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "empty array",
3
+ "input": [
4
+ {
5
+ "a": []
6
+ },
7
+ {
8
+ "a.0": 1,
9
+ "a": []
10
+ },
11
+ {
12
+ "a": [],
13
+ "a.0": 2
14
+ },
15
+ {
16
+ "a.0.b": []
17
+ },
18
+ {
19
+ "b.a.0": "b",
20
+ "b.a": [],
21
+ "b.a.1": "c"
22
+ }
23
+ ],
24
+ "expected": [
25
+ {
26
+ "a": []
27
+ },
28
+ {
29
+ "a": [1]
30
+ },
31
+ {
32
+ "a": [2]
33
+ },
34
+ {
35
+ "a" : [ {"b" : [] } ]
36
+ },
37
+ {
38
+ "b" : {
39
+ "a": [ "b", "c" ]
40
+ }
41
+ }
42
+ ]
43
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "empty object",
3
+ "input": [
4
+ {
5
+ "a.b": {}
6
+ },
7
+ {
8
+ "a.b.c": 1,
9
+ "a.b": {} ,
10
+ "a.b.d": 2
11
+ }
12
+ ],
13
+ "expected": [
14
+ {
15
+ "a" : {"b" : {} }
16
+ },
17
+ {
18
+ "a" : {
19
+ "b": { "c": 1, "d": 2 }
20
+ }
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = [
2
+ require('./array_deep_bug'),
3
+ require('./array_deep_bug2'),
4
+ require('./empty_array'),
5
+ require('./empty_object'),
6
+ require('./object_deep_numeric_keys'),
7
+ require('./object_deep_numeric_keys2')
8
+ ]
package/test/dot-json.js CHANGED
@@ -55,6 +55,28 @@ describe('Object test:', function () {
55
55
  })
56
56
  })
57
57
 
58
+ it('Should allow keys with numbers', function () {
59
+ var row = {
60
+ 'id': 2,
61
+ '0A': 'a',
62
+ '0A9': 'b',
63
+ '0B.1AB.A34C9': 'c'
64
+ }
65
+
66
+ Dot.object(row)
67
+
68
+ row.should.eql({
69
+ 'id': 2,
70
+ '0A': 'a',
71
+ '0A9': 'b',
72
+ '0B': {
73
+ '1AB': {
74
+ 'A34C9': 'c'
75
+ }
76
+ }
77
+ })
78
+ })
79
+
58
80
  it('Should expand dotted string', function () {
59
81
  var tgt = {}
60
82
 
@@ -130,39 +152,39 @@ describe('Object test:', function () {
130
152
 
131
153
  Dot.object(row, mods)
132
154
 
133
- row.should.eql({'page': {'title': 'My Page', 'slug': 'my-page'}})
155
+ row.should.eql({ 'page': { 'title': 'My Page', 'slug': 'my-page' } })
134
156
  })
135
157
 
136
158
  it('should not process non dot value with modifier when override is false',
137
159
  function () {
138
- var row = {'title': 'my page', 'slug': 'My Page'}
160
+ var row = { 'title': 'my page', 'slug': 'My Page' }
139
161
 
140
- var mods = {'title': _s.titleize, 'slug': _s.slugify}
162
+ var mods = { 'title': _s.titleize, 'slug': _s.slugify }
141
163
 
142
164
  Dot.object(row, mods)
143
165
 
144
- row.should.eql({'title': 'my page', 'slug': 'My Page'})
166
+ row.should.eql({ 'title': 'my page', 'slug': 'My Page' })
145
167
  }
146
168
  )
147
169
 
148
170
  it('Dot.object should process multiple modifiers', function () {
149
- var row = {'page.name': ' My Page '}
171
+ var row = { 'page.name': ' My Page ' }
150
172
 
151
- var mods = {'page.name': [_s.trim, _s.underscored]}
173
+ var mods = { 'page.name': [_s.trim, _s.underscored] }
152
174
 
153
175
  Dot.object(row, mods)
154
176
 
155
- row.should.eql({'page': {'name': 'my_page'}})
177
+ row.should.eql({ 'page': { 'name': 'my_page' } })
156
178
  })
157
179
 
158
- it('Dot.object should work with a different seperator', function () {
159
- var row = {'page=>name': ' My Page '}
180
+ it('Dot.object should work with a different separator', function () {
181
+ var row = { 'page=>name': ' My Page ' }
160
182
 
161
- var mods = {'page=>name': [_s.trim, _s.underscored]}
183
+ var mods = { 'page=>name': [_s.trim, _s.underscored] }
162
184
 
163
185
  var dot = new Dot('=>', false)
164
186
  dot.object(row, mods)
165
187
 
166
- row.should.eql({'page': {'name': 'my_page'}})
188
+ row.should.eql({ 'page': { 'name': 'my_page' } })
167
189
  })
168
190
  })
package/test/dot.js CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  require('should')
4
4
  var Dot = require('../index')
5
+ var pkg = require('./fixtures/package.json')
5
6
 
6
- describe('dotted-key/value pairs:', function () {
7
+ describe('dot():', function () {
7
8
  var obj
8
- var expected
9
9
 
10
10
  beforeEach(function () {
11
11
  obj = {
@@ -28,8 +28,10 @@ describe('dotted-key/value pairs:', function () {
28
28
  first: new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
29
29
  }
30
30
  }
31
+ })
31
32
 
32
- expected = {
33
+ it('Should be able to convert to dotted-key/value pairs', function () {
34
+ var expected = {
33
35
  id: 'my-id',
34
36
  'nes.ted.value': true,
35
37
  'other.nested.stuff': 5,
@@ -38,14 +40,38 @@ describe('dotted-key/value pairs:', function () {
38
40
  ehrm: 123,
39
41
  'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
40
42
  }
41
- })
42
43
 
43
- it('Should be able to convert to dotted-key/value pairs', function () {
44
44
  Dot.dot(obj).should.eql(expected)
45
45
  })
46
46
 
47
47
  it('dot() should equal object()', function () {
48
- var pkg = require('./fixtures/package.json')
49
48
  Dot.object(Dot.dot(pkg)).should.eql(pkg)
50
49
  })
50
+
51
+ it('keepArray prevents arrays from being dotted', function () {
52
+ var expected = {
53
+ id: 'my-id',
54
+ 'nes.ted.value': true,
55
+ 'other.nested.stuff': 5,
56
+ 'some.array': ['A', 'B'],
57
+ ehrm: 123,
58
+ 'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
59
+ }
60
+
61
+ Dot.keepArray = true
62
+
63
+ Dot.dot(obj).should.eql(expected)
64
+
65
+ Dot.keepArray = false
66
+ })
67
+
68
+ it('Always keeps empty arrays', function () {
69
+ Dot.dot({ hello: [] }).should.eql({ 'hello': [] })
70
+ Dot.dot({ hello: { world: [] } }).should.eql({ 'hello.world': [] })
71
+ })
72
+
73
+ it('Always keeps empty objects', function () {
74
+ Dot.dot({ hello: {} }).should.eql({ 'hello': {} })
75
+ Dot.dot({ hello: { world: {} } }).should.eql({ 'hello.world': {} })
76
+ })
51
77
  })
package/test/move.js CHANGED
@@ -15,8 +15,8 @@ describe('Move test:', function () {
15
15
 
16
16
  var expected = {
17
17
  id: '527423a65e380f0000588e47',
18
- source: {id: '526dd5c6b4c4aa8770000001', port: 'github'},
19
- target: {id: '527402d6b15d1800008755cf', port: 'in'}
18
+ source: { id: '526dd5c6b4c4aa8770000001', port: 'github' },
19
+ target: { id: '527402d6b15d1800008755cf', port: 'in' }
20
20
  }
21
21
 
22
22
  Dot.move('source', 'source.id', link)
@@ -36,8 +36,8 @@ describe('Move test:', function () {
36
36
  }
37
37
 
38
38
  var expected = {
39
- source: {id: '526dd5c6b4c4aa8770000001'},
40
- target: {port: 'in'},
39
+ source: { id: '526dd5c6b4c4aa8770000001' },
40
+ target: { port: 'in' },
41
41
  out: 'github'
42
42
  }
43
43
 
@@ -56,8 +56,8 @@ describe('Move test:', function () {
56
56
  }
57
57
 
58
58
  var expected = {
59
- source: {id: 'ONE'},
60
- target: {port: 'TWO'}
59
+ source: { id: 'ONE' },
60
+ target: { port: 'TWO' }
61
61
  }
62
62
 
63
63
  function up (val) { return val.toUpperCase() }
package/test/override.js CHANGED
@@ -17,7 +17,7 @@ describe('Override test:', function () {
17
17
 
18
18
  obj.should.eql({
19
19
  'some': 'value',
20
- 'already': {'new': 'value'}
20
+ 'already': { 'new': 'value' }
21
21
  })
22
22
  })
23
23
 
@@ -34,7 +34,7 @@ describe('Override test:', function () {
34
34
 
35
35
  obj.should.eql({
36
36
  'some': 'new_value',
37
- 'already': {'new': 'value'}
37
+ 'already': { 'new': 'value' }
38
38
  })
39
39
  })
40
40
 
@@ -52,7 +52,7 @@ describe('Override test:', function () {
52
52
 
53
53
  Dot.override = true
54
54
 
55
- Dot.str('sample.dotted.bar', {baz: 'boom'}, obj)
55
+ Dot.str('sample.dotted.bar', { baz: 'boom' }, obj)
56
56
 
57
57
  Dot.override = false
58
58
 
package/test/pick.js CHANGED
@@ -36,7 +36,7 @@ describe('Pick:', function () {
36
36
 
37
37
  var val = Dot.pick('some', obj)
38
38
 
39
- ;(val === null).should.be.true
39
+ ;(val === null).should.equal(true)
40
40
  })
41
41
 
42
42
  it('Should return undefined when picking an non-existing value', function () {
@@ -46,7 +46,7 @@ describe('Pick:', function () {
46
46
 
47
47
  var val = Dot.pick('other', obj)
48
48
 
49
- ;(val === undefined).should.be.true
49
+ ;(val === undefined).should.equal(true)
50
50
  })
51
51
 
52
52
  it('Should return undefined when picking an non-existing dotted value',
@@ -57,7 +57,7 @@ describe('Pick:', function () {
57
57
 
58
58
  var val = Dot.pick('some.other', obj)
59
59
 
60
- ;(val === undefined).should.be.true
60
+ ;(val === undefined).should.equal(true)
61
61
  }
62
62
  )
63
63
 
@@ -73,6 +73,6 @@ describe('Pick:', function () {
73
73
  objIns.should.have.property('some')
74
74
 
75
75
  var val = Dot.pick('some.other', objIns)
76
- val.should.be.a.String
76
+ val.should.be.instanceOf(String)
77
77
  })
78
78
  })
package/test/test_data.js CHANGED
@@ -3,12 +3,12 @@
3
3
  require('should')
4
4
  var Dot = require('../index')
5
5
 
6
- var testData = [
7
- require('./data/array_deep_bug'),
8
- require('./data/array_deep_bug2'),
9
- require('./data/object_deep_numeric_keys'),
10
- require('./data/object_deep_numeric_keys2')
11
- ]
6
+ var testData = require('./data')
7
+
8
+ function singleTest (dot, input, expected) {
9
+ dot.object(input)
10
+ JSON.stringify(input).should.eql(JSON.stringify(expected))
11
+ }
12
12
 
13
13
  describe('Test Data:', function () {
14
14
  var dot = new Dot()
@@ -19,8 +19,20 @@ describe('Test Data:', function () {
19
19
  dot[name] = test.options[name]
20
20
  })
21
21
  }
22
- dot.object(test.input)
23
- JSON.stringify(test.input).should.eql(JSON.stringify(test.expected))
22
+
23
+ if (Array.isArray(test.input)) {
24
+ if (
25
+ !Array.isArray(test.expected) ||
26
+ test.input.length !== test.expected.length
27
+ ) {
28
+ throw Error('Input and Expected tests length must be the same')
29
+ }
30
+ test.expected.forEach((expected, i) => {
31
+ singleTest(dot, test.input[i], expected)
32
+ })
33
+ } else {
34
+ singleTest(dot, test.input, test.expected)
35
+ }
24
36
  })
25
37
  }
26
38
 
package/test/transfer.js CHANGED
@@ -19,7 +19,7 @@ describe('Transfer:', function () {
19
19
  name: 'Brandon'
20
20
  }
21
21
 
22
- var srcExpected = {name: 'John', stuff: {}}
22
+ var srcExpected = { name: 'John', stuff: {} }
23
23
 
24
24
  var tgtExpected = {
25
25
  name: 'Brandon',
@@ -59,7 +59,7 @@ describe('Transfer:', function () {
59
59
  name: 'Brandon'
60
60
  }
61
61
 
62
- var srcExpected = {name: 'John', stuff: {}}
62
+ var srcExpected = { name: 'John', stuff: {} }
63
63
 
64
64
  var tgtExpected = {
65
65
  name: 'Brandon',