Socket
Socket
Sign inDemoInstall

traverse

Package Overview
Dependencies
Maintainers
3
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

traverse - npm Package Compare versions

Comparing version 0.6.6 to 0.6.7

.eslintrc

14

examples/json.js

@@ -0,1 +1,3 @@

'use strict';
var traverse = require('traverse');

@@ -5,10 +7,10 @@

var callbacks = {};
var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
var obj = { moo: function () {}, foo: [2, 3, 4, function () {}] };
var scrubbed = traverse(obj).map(function (x) {
if (typeof x === 'function') {
callbacks[id] = { id : id, f : x, path : this.path };
this.update('[Function]');
id++;
}
if (typeof x === 'function') {
callbacks[id] = { id: id, f: x, path: this.path };
this.update('[Function]');
id++;
}
});

@@ -15,0 +17,0 @@

@@ -0,15 +1,17 @@

'use strict';
var traverse = require('traverse');
var obj = {
a : [1,2,3],
b : 4,
c : [5,6],
d : { e : [7,8], f : 9 },
a: [1, 2, 3],
b: 4,
c: [5, 6],
d: { e: [7, 8], f: 9 },
};
var leaves = traverse(obj).reduce(function (acc, x) {
if (this.isLeaf) acc.push(x);
return acc;
if (this.isLeaf) { acc.push(x); }
return acc;
}, []);
console.dir(leaves);

@@ -0,8 +1,10 @@

'use strict';
var traverse = require('traverse');
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
if (x < 0) { this.update(x + 128); }
});
console.dir(obj);

@@ -0,10 +1,12 @@

'use strict';
// scrub out circular references
var traverse = require('traverse');
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var obj = { a: 1, b: 2, c: [3, 4] };
obj.c.push(obj);
var scrubbed = traverse(obj).map(function (x) {
if (this.circular) this.remove()
var scrubbed = traverse(obj).map(function () {
if (this.circular) { this.remove(); }
});
console.dir(scrubbed);
#!/usr/bin/env node
'use strict';
var traverse = require('traverse');
var obj = [ 'five', 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
var obj = ['five', 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
var s = '';
traverse(obj).forEach(function to_s (node) {
if (Array.isArray(node)) {
this.before(function () { s += '[' });
this.post(function (child) {
if (!child.isLast) s += ',';
});
this.after(function () { s += ']' });
}
else if (typeof node == 'object') {
this.before(function () { s += '{' });
this.pre(function (x, key) {
to_s(key);
s += ':';
});
this.post(function (child) {
if (!child.isLast) s += ',';
});
this.after(function () { s += '}' });
}
else if (typeof node == 'string') {
s += '"' + node.toString().replace(/"/g, '\\"') + '"';
}
else if (typeof node == 'function') {
s += 'null';
}
else {
s += node.toString();
}
traverse(obj).forEach(function toS(node) {
if (Array.isArray(node)) {
this.before(function () { s += '['; });
this.post(function (child) {
if (!child.isLast) { s += ','; }
});
this.after(function () { s += ']'; });
} else if (typeof node === 'object') {
this.before(function () { s += '{'; });
this.pre(function (x, key) {
toS(key);
s += ':';
});
this.post(function (child) {
if (!child.isLast) { s += ','; }
});
this.after(function () { s += '}'; });
} else if (typeof node === 'string') {
s += '"' + node.toString().replace(/"/g, '\\"') + '"';
} else if (typeof node === 'function') {
s += 'null';
} else {
s += node.toString();
}
});

@@ -36,0 +35,0 @@

@@ -1,314 +0,311 @@

var traverse = module.exports = function (obj) {
return new Traverse(obj);
'use strict';
// TODO: use call-bind, is-date, is-regex, is-string, is-boolean-object, is-number-object
function toS(obj) { return Object.prototype.toString.call(obj); }
function isDate(obj) { return toS(obj) === '[object Date]'; }
function isRegExp(obj) { return toS(obj) === '[object RegExp]'; }
function isError(obj) { return toS(obj) === '[object Error]'; }
function isBoolean(obj) { return toS(obj) === '[object Boolean]'; }
function isNumber(obj) { return toS(obj) === '[object Number]'; }
function isString(obj) { return toS(obj) === '[object String]'; }
// TODO: use isarray
var isArray = Array.isArray || function isArray(xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
function Traverse (obj) {
this.value = obj;
// TODO: use for-each?
function forEach(xs, fn) {
if (xs.forEach) { return xs.forEach(fn); }
for (var i = 0; i < xs.length; i++) {
fn(xs[i], i, xs);
}
return void undefined;
}
// TODO: use object-keys
var objectKeys = Object.keys || function keys(obj) {
var res = [];
for (var key in obj) { res.push(key); } // eslint-disable-line no-restricted-syntax
return res;
};
// TODO: use object.hasown
var hasOwnProperty = Object.prototype.hasOwnProperty || function (obj, key) {
return key in obj;
};
function copy(src) {
if (typeof src === 'object' && src !== null) {
var dst;
if (isArray(src)) {
dst = [];
} else if (isDate(src)) {
dst = new Date(src.getTime ? src.getTime() : src);
} else if (isRegExp(src)) {
dst = new RegExp(src);
} else if (isError(src)) {
dst = { message: src.message };
} else if (isBoolean(src) || isNumber(src) || isString(src)) {
dst = Object(src);
} else if (Object.create && Object.getPrototypeOf) {
dst = Object.create(Object.getPrototypeOf(src));
} else if (src.constructor === Object) {
dst = {};
} else {
var proto = (src.constructor && src.constructor.prototype)
|| src.__proto__
|| {};
var T = function T() {}; // eslint-disable-line func-style, func-name-matching
T.prototype = proto;
dst = new T();
}
forEach(objectKeys(src), function (key) {
dst[key] = src[key];
});
return dst;
}
return src;
}
function walk(root, cb, immutable) {
var path = [];
var parents = [];
var alive = true;
return (function walker(node_) {
var node = immutable ? copy(node_) : node_;
var modifiers = {};
var keepGoing = true;
var state = {
node: node,
node_: node_,
path: [].concat(path),
parent: parents[parents.length - 1],
parents: parents,
key: path[path.length - 1],
isRoot: path.length === 0,
level: path.length,
circular: null,
update: function (x, stopHere) {
if (!state.isRoot) {
state.parent.node[state.key] = x;
}
state.node = x;
if (stopHere) { keepGoing = false; }
},
delete: function (stopHere) {
delete state.parent.node[state.key];
if (stopHere) { keepGoing = false; }
},
remove: function (stopHere) {
if (isArray(state.parent.node)) {
state.parent.node.splice(state.key, 1);
} else {
delete state.parent.node[state.key];
}
if (stopHere) { keepGoing = false; }
},
keys: null,
before: function (f) { modifiers.before = f; },
after: function (f) { modifiers.after = f; },
pre: function (f) { modifiers.pre = f; },
post: function (f) { modifiers.post = f; },
stop: function () { alive = false; },
block: function () { keepGoing = false; },
};
if (!alive) { return state; }
function updateState() {
if (typeof state.node === 'object' && state.node !== null) {
if (!state.keys || state.node_ !== state.node) {
state.keys = objectKeys(state.node);
}
state.isLeaf = state.keys.length === 0;
for (var i = 0; i < parents.length; i++) {
if (parents[i].node_ === node_) {
state.circular = parents[i];
break; // eslint-disable-line no-restricted-syntax
}
}
} else {
state.isLeaf = true;
state.keys = null;
}
state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;
}
updateState();
// use return values to update if defined
var ret = cb.call(state, state.node);
if (ret !== undefined && state.update) { state.update(ret); }
if (modifiers.before) { modifiers.before.call(state, state.node); }
if (!keepGoing) { return state; }
if (
typeof state.node === 'object'
&& state.node !== null
&& !state.circular
) {
parents.push(state);
updateState();
forEach(state.keys, function (key, i) {
path.push(key);
if (modifiers.pre) { modifiers.pre.call(state, state.node[key], key); }
var child = walker(state.node[key]);
if (immutable && hasOwnProperty.call(state.node, key)) {
state.node[key] = child.node;
}
child.isLast = i === state.keys.length - 1;
child.isFirst = i === 0;
if (modifiers.post) { modifiers.post.call(state, child); }
path.pop();
});
parents.pop();
}
if (modifiers.after) { modifiers.after.call(state, state.node); }
return state;
}(root)).node;
}
function Traverse(obj) {
this.value = obj;
}
Traverse.prototype.get = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i ++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
node = undefined;
break;
}
node = node[key];
}
return node;
var node = this.value;
for (var i = 0; i < ps.length; i++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return void undefined;
}
node = node[key];
}
return node;
};
Traverse.prototype.has = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i ++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return false;
}
node = node[key];
}
return true;
var node = this.value;
for (var i = 0; i < ps.length; i++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return false;
}
node = node[key];
}
return true;
};
Traverse.prototype.set = function (ps, value) {
var node = this.value;
for (var i = 0; i < ps.length - 1; i ++) {
var key = ps[i];
if (!hasOwnProperty.call(node, key)) node[key] = {};
node = node[key];
}
node[ps[i]] = value;
return value;
var node = this.value;
for (var i = 0; i < ps.length - 1; i++) {
var key = ps[i];
if (!hasOwnProperty.call(node, key)) { node[key] = {}; }
node = node[key];
}
node[ps[i]] = value;
return value;
};
Traverse.prototype.map = function (cb) {
return walk(this.value, cb, true);
return walk(this.value, cb, true);
};
Traverse.prototype.forEach = function (cb) {
this.value = walk(this.value, cb, false);
return this.value;
this.value = walk(this.value, cb, false);
return this.value;
};
Traverse.prototype.reduce = function (cb, init) {
var skip = arguments.length === 1;
var acc = skip ? this.value : init;
this.forEach(function (x) {
if (!this.isRoot || !skip) {
acc = cb.call(this, acc, x);
}
});
return acc;
var skip = arguments.length === 1;
var acc = skip ? this.value : init;
this.forEach(function (x) {
if (!this.isRoot || !skip) {
acc = cb.call(this, acc, x);
}
});
return acc;
};
Traverse.prototype.paths = function () {
var acc = [];
this.forEach(function (x) {
acc.push(this.path);
});
return acc;
var acc = [];
this.forEach(function () {
acc.push(this.path);
});
return acc;
};
Traverse.prototype.nodes = function () {
var acc = [];
this.forEach(function (x) {
acc.push(this.node);
});
return acc;
var acc = [];
this.forEach(function () {
acc.push(this.node);
});
return acc;
};
Traverse.prototype.clone = function () {
var parents = [], nodes = [];
return (function clone (src) {
for (var i = 0; i < parents.length; i++) {
if (parents[i] === src) {
return nodes[i];
}
}
if (typeof src === 'object' && src !== null) {
var dst = copy(src);
parents.push(src);
nodes.push(dst);
forEach(objectKeys(src), function (key) {
dst[key] = clone(src[key]);
});
parents.pop();
nodes.pop();
return dst;
}
else {
return src;
}
})(this.value);
};
var parents = [];
var nodes = [];
function walk (root, cb, immutable) {
var path = [];
var parents = [];
var alive = true;
return (function walker (node_) {
var node = immutable ? copy(node_) : node_;
var modifiers = {};
var keepGoing = true;
var state = {
node : node,
node_ : node_,
path : [].concat(path),
parent : parents[parents.length - 1],
parents : parents,
key : path.slice(-1)[0],
isRoot : path.length === 0,
level : path.length,
circular : null,
update : function (x, stopHere) {
if (!state.isRoot) {
state.parent.node[state.key] = x;
}
state.node = x;
if (stopHere) keepGoing = false;
},
'delete' : function (stopHere) {
delete state.parent.node[state.key];
if (stopHere) keepGoing = false;
},
remove : function (stopHere) {
if (isArray(state.parent.node)) {
state.parent.node.splice(state.key, 1);
}
else {
delete state.parent.node[state.key];
}
if (stopHere) keepGoing = false;
},
keys : null,
before : function (f) { modifiers.before = f },
after : function (f) { modifiers.after = f },
pre : function (f) { modifiers.pre = f },
post : function (f) { modifiers.post = f },
stop : function () { alive = false },
block : function () { keepGoing = false }
};
if (!alive) return state;
function updateState() {
if (typeof state.node === 'object' && state.node !== null) {
if (!state.keys || state.node_ !== state.node) {
state.keys = objectKeys(state.node)
}
state.isLeaf = state.keys.length == 0;
for (var i = 0; i < parents.length; i++) {
if (parents[i].node_ === node_) {
state.circular = parents[i];
break;
}
}
}
else {
state.isLeaf = true;
state.keys = null;
}
state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;
}
updateState();
// use return values to update if defined
var ret = cb.call(state, state.node);
if (ret !== undefined && state.update) state.update(ret);
if (modifiers.before) modifiers.before.call(state, state.node);
if (!keepGoing) return state;
if (typeof state.node == 'object'
&& state.node !== null && !state.circular) {
parents.push(state);
updateState();
forEach(state.keys, function (key, i) {
path.push(key);
if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
var child = walker(state.node[key]);
if (immutable && hasOwnProperty.call(state.node, key)) {
state.node[key] = child.node;
}
child.isLast = i == state.keys.length - 1;
child.isFirst = i == 0;
if (modifiers.post) modifiers.post.call(state, child);
path.pop();
});
parents.pop();
}
if (modifiers.after) modifiers.after.call(state, state.node);
return state;
})(root).node;
}
return (function clone(src) {
for (var i = 0; i < parents.length; i++) {
if (parents[i] === src) {
return nodes[i];
}
}
function copy (src) {
if (typeof src === 'object' && src !== null) {
var dst;
if (isArray(src)) {
dst = [];
}
else if (isDate(src)) {
dst = new Date(src.getTime ? src.getTime() : src);
}
else if (isRegExp(src)) {
dst = new RegExp(src);
}
else if (isError(src)) {
dst = { message: src.message };
}
else if (isBoolean(src)) {
dst = new Boolean(src);
}
else if (isNumber(src)) {
dst = new Number(src);
}
else if (isString(src)) {
dst = new String(src);
}
else if (Object.create && Object.getPrototypeOf) {
dst = Object.create(Object.getPrototypeOf(src));
}
else if (src.constructor === Object) {
dst = {};
}
else {
var proto =
(src.constructor && src.constructor.prototype)
|| src.__proto__
|| {}
;
var T = function () {};
T.prototype = proto;
dst = new T;
}
forEach(objectKeys(src), function (key) {
dst[key] = src[key];
});
return dst;
}
else return src;
}
if (typeof src === 'object' && src !== null) {
var dst = copy(src);
var objectKeys = Object.keys || function keys (obj) {
var res = [];
for (var key in obj) res.push(key)
return res;
};
parents.push(src);
nodes.push(dst);
function toS (obj) { return Object.prototype.toString.call(obj) }
function isDate (obj) { return toS(obj) === '[object Date]' }
function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
function isError (obj) { return toS(obj) === '[object Error]' }
function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
function isNumber (obj) { return toS(obj) === '[object Number]' }
function isString (obj) { return toS(obj) === '[object String]' }
forEach(objectKeys(src), function (key) {
dst[key] = clone(src[key]);
});
var isArray = Array.isArray || function isArray (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
parents.pop();
nodes.pop();
return dst;
}
var forEach = function (xs, fn) {
if (xs.forEach) return xs.forEach(fn)
else for (var i = 0; i < xs.length; i++) {
fn(xs[i], i, xs);
}
return src;
}(this.value));
};
function traverse(obj) {
return new Traverse(obj);
}
// TODO: replace with object.assign?
forEach(objectKeys(Traverse.prototype), function (key) {
traverse[key] = function (obj) {
var args = [].slice.call(arguments, 1);
var t = new Traverse(obj);
return t[key].apply(t, args);
};
traverse[key] = function (obj) {
var args = [].slice.call(arguments, 1);
var t = new Traverse(obj);
return t[key].apply(t, args);
};
});
var hasOwnProperty = Object.hasOwnProperty || function (obj, key) {
return key in obj;
};
module.exports = traverse;
{
"name" : "traverse",
"version" : "0.6.6",
"description" : "traverse and transform objects by visiting every node on a recursive walk",
"main" : "index.js",
"directories" : {
"example" : "example",
"test" : "test"
},
"devDependencies" : {
"tape" : "~1.0.4"
},
"scripts" : {
"test" : "tape test/*.js"
},
"testling" : {
"files" : "test/*.js",
"browsers" : {
"iexplore" : [ "6.0", "7.0", "8.0", "9.0" ],
"chrome" : [ "10.0", "20.0" ],
"firefox" : [ "10.0", "15.0" ],
"safari" : [ "5.1" ],
"opera" : [ "12.0" ]
}
},
"repository" : {
"type" : "git",
"url" : "git://github.com/substack/js-traverse.git"
},
"homepage" : "https://github.com/substack/js-traverse",
"keywords" : [
"traverse",
"walk",
"recursive",
"map",
"forEach",
"deep",
"clone"
],
"author" : {
"name" : "James Halliday",
"email" : "mail@substack.net",
"url" : "http://substack.net"
},
"license" : "MIT"
"name": "traverse",
"version": "0.6.7",
"description": "traverse and transform objects by visiting every node on a recursive walk",
"main": "index.js",
"directories": {
"example": "example",
"test": "test"
},
"devDependencies": {
"@ljharb/eslint-config": "^21.0.0",
"aud": "^2.0.1",
"auto-changelog": "^2.4.0",
"eslint": "=8.8.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.0",
"safe-publish-latest": "^2.0.0",
"tape": "^5.6.1"
},
"scripts": {
"prepack": "npmignore --auto --commentLines=autogenerated",
"prepublishOnly": "safe-publish-latest",
"prepublish": "not-in-publish || npm run prepublishOnly",
"lint": "eslint --ext=js,mjs .",
"pretest": "npm run lint",
"tests-only": "tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "aud --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"testling": {
"files": "test/*.js",
"browsers": {
"iexplore": [
"6.0",
"7.0",
"8.0",
"9.0"
],
"chrome": [
"10.0",
"20.0"
],
"firefox": [
"10.0",
"15.0"
],
"safari": [
"5.1"
],
"opera": [
"12.0"
]
}
},
"repository": {
"type": "git",
"url": "git://github.com/ljharb/js-traverse.git"
},
"homepage": "https://github.com/ljharb/js-traverse",
"keywords": [
"traverse",
"walk",
"recursive",
"map",
"forEach",
"deep",
"clone"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
},
"license": "MIT",
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
}
}

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -7,112 +9,111 @@ var traverse = require('../');

test('circular', function (t) {
t.plan(1);
var obj = { x : 3 };
obj.y = obj;
traverse(obj).forEach(function (x) {
if (this.path.join('') == 'y') {
t.equal(
util.inspect(this.circular.node),
util.inspect(obj)
);
}
});
t.plan(1);
var obj = { x: 3 };
obj.y = obj;
traverse(obj).forEach(function () {
if (this.path.join('') === 'y') {
t.equal(
util.inspect(this.circular.node),
util.inspect(obj)
);
}
});
});
test('deepCirc', function (t) {
t.plan(2);
var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
obj.y[2] = obj;
var times = 0;
traverse(obj).forEach(function (x) {
if (this.circular) {
t.same(this.circular.path, []);
t.same(this.path, [ 'y', 2 ]);
}
});
t.plan(2);
var obj = { x: [1, 2, 3], y: [4, 5] };
obj.y[2] = obj;
traverse(obj).forEach(function () {
if (this.circular) {
t.deepEqual(this.circular.path, []);
t.deepEqual(this.path, ['y', '2']);
}
});
});
test('doubleCirc', function (t) {
var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
obj.y[2] = obj;
obj.x.push(obj.y);
var circs = [];
traverse(obj).forEach(function (x) {
if (this.circular) {
circs.push({ circ : this.circular, self : this, node : x });
}
});
t.same(circs[0].self.path, [ 'x', 3, 2 ]);
t.same(circs[0].circ.path, []);
t.same(circs[1].self.path, [ 'y', 2 ]);
t.same(circs[1].circ.path, []);
t.same(circs.length, 2);
t.end();
var obj = { x: [1, 2, 3], y: [4, 5] };
obj.y[2] = obj;
obj.x.push(obj.y);
var circs = [];
traverse(obj).forEach(function (x) {
if (this.circular) {
circs.push({ circ: this.circular, self: this, node: x });
}
});
t.deepEqual(circs[0].self.path, ['x', '3', '2']);
t.deepEqual(circs[0].circ.path, []);
t.deepEqual(circs[1].self.path, ['y', '2']);
t.deepEqual(circs[1].circ.path, []);
t.deepEqual(circs.length, 2);
t.end();
});
test('circDubForEach', function (t) {
var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
obj.y[2] = obj;
obj.x.push(obj.y);
traverse(obj).forEach(function (x) {
if (this.circular) this.update('...');
});
t.same(obj, { x : [ 1, 2, 3, [ 4, 5, '...' ] ], y : [ 4, 5, '...' ] });
t.end();
var obj = { x: [1, 2, 3], y: [4, 5] };
obj.y[2] = obj;
obj.x.push(obj.y);
traverse(obj).forEach(function () {
if (this.circular) { this.update('...'); }
});
t.same(obj, { x: [1, 2, 3, [4, 5, '...']], y: [4, 5, '...'] });
t.end();
});
test('circDubMap', function (t) {
var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
obj.y[2] = obj;
obj.x.push(obj.y);
var c = traverse(obj).map(function (x) {
if (this.circular) {
this.update('...');
}
});
t.same(c, { x : [ 1, 2, 3, [ 4, 5, '...' ] ], y : [ 4, 5, '...' ] });
t.end();
var obj = { x: [1, 2, 3], y: [4, 5] };
obj.y[2] = obj;
obj.x.push(obj.y);
var c = traverse(obj).map(function () {
if (this.circular) {
this.update('...');
}
});
t.same(c, { x: [1, 2, 3, [4, 5, '...']], y: [4, 5, '...'] });
t.end();
});
test('circClone', function (t) {
var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
obj.y[2] = obj;
obj.x.push(obj.y);
var clone = traverse.clone(obj);
t.ok(obj !== clone);
t.ok(clone.y[2] === clone);
t.ok(clone.y[2] !== obj);
t.ok(clone.x[3][2] === clone);
t.ok(clone.x[3][2] !== obj);
t.same(clone.x.slice(0,3), [1,2,3]);
t.same(clone.y.slice(0,2), [4,5]);
t.end();
var obj = { x: [1, 2, 3], y: [4, 5] };
obj.y[2] = obj;
obj.x.push(obj.y);
var clone = traverse.clone(obj);
t.ok(obj !== clone);
t.ok(clone.y[2] === clone);
t.ok(clone.y[2] !== obj);
t.ok(clone.x[3][2] === clone);
t.ok(clone.x[3][2] !== obj);
t.same(clone.x.slice(0, 3), [1, 2, 3]);
t.same(clone.y.slice(0, 2), [4, 5]);
t.end();
});
test('circMapScrub', function (t) {
var obj = { a : 1, b : 2 };
obj.c = obj;
var scrubbed = traverse(obj).map(function (node) {
if (this.circular) this.remove();
});
t.same(
Object.keys(scrubbed).sort(),
[ 'a', 'b' ]
);
t.ok(deepEqual(scrubbed, { a : 1, b : 2 }));
t.equal(obj.c, obj);
t.end();
var obj = { a: 1, b: 2 };
obj.c = obj;
var scrubbed = traverse(obj).map(function () {
if (this.circular) { this.remove(); }
});
t.same(
Object.keys(scrubbed).sort(),
['a', 'b']
);
t.ok(deepEqual(scrubbed, { a: 1, b: 2 }));
t.equal(obj.c, obj);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,34 +7,34 @@ var traverse = require('../');

test('dateEach', function (t) {
var obj = { x : new Date, y : 10, z : 5 };
var counts = {};
traverse(obj).forEach(function (node) {
var t = (node instanceof Date && 'Date') || typeof node;
counts[t] = (counts[t] || 0) + 1;
});
t.same(counts, {
object : 1,
Date : 1,
number : 2,
});
t.end();
var obj = { x: new Date(), y: 10, z: 5 };
var counts = {};
traverse(obj).forEach(function (node) {
var type = (node instanceof Date && 'Date') || typeof node;
counts[type] = (counts[type] || 0) + 1;
});
t.same(counts, {
object: 1,
Date: 1,
number: 2,
});
t.end();
});
test('dateMap', function (t) {
var obj = { x : new Date, y : 10, z : 5 };
var res = traverse(obj).map(function (node) {
if (typeof node === 'number') this.update(node + 100);
});
t.ok(obj.x !== res.x);
t.same(res, {
x : obj.x,
y : 110,
z : 105,
});
t.end();
var obj = { x: new Date(), y: 10, z: 5 };
var res = traverse(obj).map(function (node) {
if (typeof node === 'number') { this.update(node + 100); }
});
t.ok(obj.x !== res.x);
t.same(res, {
x: obj.x,
y: 110,
z: 105,
});
t.end();
});

@@ -0,240 +1,238 @@

'use strict';
var test = require('tape');
var traverse = require('../');
var deepEqual = require('./lib/deep_equal');
test('deepDates', function (t) {
t.plan(2);
t.ok(
deepEqual(
{ d : new Date, x : [ 1, 2, 3 ] },
{ d : new Date, x : [ 1, 2, 3 ] }
),
'dates should be equal'
);
var d0 = new Date;
setTimeout(function () {
t.ok(
!deepEqual(
{ d : d0, x : [ 1, 2, 3 ], },
{ d : new Date, x : [ 1, 2, 3 ] }
),
'microseconds should count in date equality'
);
}, 5);
t.plan(2);
t.ok(
deepEqual(
{ d: new Date(), x: [1, 2, 3] },
{ d: new Date(), x: [1, 2, 3] }
),
'dates should be equal'
);
var d0 = new Date();
setTimeout(function () {
t.ok(
!deepEqual(
{ d: d0, x: [1, 2, 3] },
{ d: new Date(), x: [1, 2, 3] }
),
'microseconds should count in date equality'
);
}, 5);
});
test('deepCircular', function (t) {
var a = [1];
a.push(a); // a = [ 1, *a ]
var b = [1];
b.push(a); // b = [ 1, [ 1, *a ] ]
t.ok(
!deepEqual(a, b),
'circular ref mount points count towards equality'
);
var c = [1];
c.push(c); // c = [ 1, *c ]
t.ok(
deepEqual(a, c),
'circular refs are structurally the same here'
);
var d = [1];
d.push(a); // c = [ 1, [ 1, *d ] ]
t.ok(
deepEqual(b, d),
'non-root circular ref structural comparison'
);
t.end();
var a = [1];
a.push(a); // a = [ 1, *a ]
var b = [1];
b.push(a); // b = [ 1, [ 1, *a ] ]
t.ok(
!deepEqual(a, b),
'circular ref mount points count towards equality'
);
var c = [1];
c.push(c); // c = [ 1, *c ]
t.ok(
deepEqual(a, c),
'circular refs are structurally the same here'
);
var d = [1];
d.push(a); // c = [ 1, [ 1, *d ] ]
t.ok(
deepEqual(b, d),
'non-root circular ref structural comparison'
);
t.end();
});
test('deepInstances', function (t) {
t.ok(
!deepEqual([ new Boolean(false) ], [ false ]),
'boolean instances are not real booleans'
);
t.ok(
!deepEqual([ new String('x') ], [ 'x' ]),
'string instances are not real strings'
);
t.ok(
!deepEqual([ new Number(4) ], [ 4 ]),
'number instances are not real numbers'
);
t.ok(
deepEqual([ new RegExp('x') ], [ /x/ ]),
'regexp instances are real regexps'
);
t.ok(
!deepEqual([ new RegExp(/./) ], [ /../ ]),
'these regexps aren\'t the same'
);
t.ok(
!deepEqual(
[ function (x) { return x * 2 } ],
[ function (x) { return x * 2 } ]
),
'functions with the same .toString() aren\'t necessarily the same'
);
var f = function (x) { return x * 2 };
t.ok(
deepEqual([ f ], [ f ]),
'these functions are actually equal'
);
t.end();
t.ok(
!deepEqual([Object(false)], [false]),
'boolean instances are not real booleans'
);
t.ok(
!deepEqual([Object('x')], ['x']),
'string instances are not real strings'
);
t.ok(
!deepEqual([Object(4)], [4]),
'number instances are not real numbers'
);
t.ok(
deepEqual([new RegExp('x')], [/x/]),
'regexp instances are real regexps'
);
t.ok(
!deepEqual([new RegExp(/./)], [/../]),
'these regexps aren\'t the same'
);
t.ok(
!deepEqual(
[function (x) { return x * 2; }],
[function (x) { return x * 2; }]
),
'functions with the same .toString() aren\'t necessarily the same'
);
function f(x) { return x * 2; }
t.ok(
deepEqual([f], [f]),
'these functions are actually equal'
);
t.end();
});
test('deepEqual', function (t) {
t.ok(
!deepEqual([ 1, 2, 3 ], { 0 : 1, 1 : 2, 2 : 3 }),
'arrays are not objects'
);
t.end();
t.ok(
!deepEqual([1, 2, 3], { 0: 1, 1: 2, 2: 3 }),
'arrays are not objects'
);
t.end();
});
test('falsy', function (t) {
t.ok(
!deepEqual([ undefined ], [ null ]),
'null is not undefined!'
);
t.ok(
!deepEqual([ null ], [ undefined ]),
'undefined is not null!'
);
t.ok(
!deepEqual(
{ a : 1, b : 2, c : [ 3, undefined, 5 ] },
{ a : 1, b : 2, c : [ 3, null, 5 ] }
),
'undefined is not null, however deeply!'
);
t.ok(
!deepEqual(
{ a : 1, b : 2, c : [ 3, undefined, 5 ] },
{ a : 1, b : 2, c : [ 3, null, 5 ] }
),
'null is not undefined, however deeply!'
);
t.ok(
!deepEqual(
{ a : 1, b : 2, c : [ 3, undefined, 5 ] },
{ a : 1, b : 2, c : [ 3, null, 5 ] }
),
'null is not undefined, however deeply!'
);
t.end();
t.ok(
!deepEqual([undefined], [null]),
'null is not undefined!'
);
t.ok(
!deepEqual([null], [undefined]),
'undefined is not null!'
);
t.ok(
!deepEqual(
{ a: 1, b: 2, c: [3, undefined, 5] },
{ a: 1, b: 2, c: [3, null, 5] }
),
'undefined is not null, however deeply!'
);
t.ok(
!deepEqual(
{ a: 1, b: 2, c: [3, undefined, 5] },
{ a: 1, b: 2, c: [3, null, 5] }
),
'null is not undefined, however deeply!'
);
t.ok(
!deepEqual(
{ a: 1, b: 2, c: [3, undefined, 5] },
{ a: 1, b: 2, c: [3, null, 5] }
),
'null is not undefined, however deeply!'
);
t.end();
});
test('deletedArrayEqual', function (t) {
var xs = [ 1, 2, 3, 4 ];
delete xs[2];
var ys = Object.create(Array.prototype);
ys[0] = 1;
ys[1] = 2;
ys[3] = 4;
t.ok(
deepEqual(xs, ys),
'arrays with deleted elements are only equal to'
+ ' arrays with similarly deleted elements'
);
t.ok(
!deepEqual(xs, [ 1, 2, undefined, 4 ]),
'deleted array elements cannot be undefined'
);
t.ok(
!deepEqual(xs, [ 1, 2, null, 4 ]),
'deleted array elements cannot be null'
);
t.end();
var xs = [1, 2, 3, 4];
delete xs[2];
var ys = Object.create(Array.prototype);
ys[0] = 1;
ys[1] = 2;
ys[3] = 4;
t.ok(
deepEqual(xs, ys),
'arrays with deleted elements are only equal to arrays with similarly deleted elements'
);
t.ok(
!deepEqual(xs, [1, 2, undefined, 4]),
'deleted array elements cannot be undefined'
);
t.ok(
!deepEqual(xs, [1, 2, null, 4]),
'deleted array elements cannot be null'
);
t.end();
});
test('deletedObjectEqual', function (t) {
var obj = { a : 1, b : 2, c : 3 };
delete obj.c;
t.ok(
deepEqual(obj, { a : 1, b : 2 }),
'deleted object elements should not show up'
);
t.ok(
!deepEqual(obj, { a : 1, b : 2, c : undefined }),
'deleted object elements are not undefined'
);
t.ok(
!deepEqual(obj, { a : 1, b : 2, c : null }),
'deleted object elements are not null'
);
t.end();
var obj = { a: 1, b: 2, c: 3 };
delete obj.c;
t.ok(
deepEqual(obj, { a: 1, b: 2 }),
'deleted object elements should not show up'
);
t.ok(
!deepEqual(obj, { a: 1, b: 2, c: undefined }),
'deleted object elements are not undefined'
);
t.ok(
!deepEqual(obj, { a: 1, b: 2, c: null }),
'deleted object elements are not null'
);
t.end();
});
test('emptyKeyEqual', function (t) {
t.ok(!deepEqual(
{ a : 1 }, { a : 1, '' : 55 }
));
t.end();
t.ok(!deepEqual({ a: 1 }, { a: 1, '': 55 }));
t.end();
});
test('deepArguments', function (t) {
t.ok(
!deepEqual(
[ 4, 5, 6 ],
(function () { return arguments })(4, 5, 6)
),
'arguments are not arrays'
);
t.ok(
deepEqual(
(function () { return arguments })(4, 5, 6),
(function () { return arguments })(4, 5, 6)
),
'arguments should equal'
);
t.end();
t.ok(
!deepEqual(
[4, 5, 6],
(function () { return arguments; }(4, 5, 6))
),
'arguments are not arrays'
);
t.ok(
deepEqual(
(function () { return arguments; }(4, 5, 6)),
(function () { return arguments; }(4, 5, 6))
),
'arguments should equal'
);
t.end();
});
test('deepUn', function (t) {
t.ok(!deepEqual({ a : 1, b : 2 }, undefined));
t.ok(!deepEqual({ a : 1, b : 2 }, {}));
t.ok(!deepEqual(undefined, { a : 1, b : 2 }));
t.ok(!deepEqual({}, { a : 1, b : 2 }));
t.ok(deepEqual(undefined, undefined));
t.ok(deepEqual(null, null));
t.ok(!deepEqual(undefined, null));
t.end();
t.ok(!deepEqual({ a: 1, b: 2 }, undefined));
t.ok(!deepEqual({ a: 1, b: 2 }, {}));
t.ok(!deepEqual(undefined, { a: 1, b: 2 }));
t.ok(!deepEqual({}, { a: 1, b: 2 }));
t.ok(deepEqual(undefined, undefined));
t.ok(deepEqual(null, null));
t.ok(!deepEqual(undefined, null));
t.end();
});
test('deepLevels', function (t) {
var xs = [ 1, 2, [ 3, 4, [ 5, 6 ] ] ];
t.ok(!deepEqual(xs, []));
t.end();
var xs = [1, 2, [3, 4, [5, 6]]];
t.ok(!deepEqual(xs, []));
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,8 +7,8 @@ var traverse = require('../');

test('traverse an Error', function (t) {
var obj = new Error("test");
var results = traverse(obj).map(function (node) {});
t.same(results, { message: 'test' });
t.end();
var obj = new Error('test');
var results = traverse(obj).map(function () {});
t.same(results, { message: 'test' });
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,12 +7,12 @@ var traverse = require('../');

test('has', function (t) {
var obj = { a : 2, b : [ 4, 5, { c : 6 } ] };
t.equal(traverse(obj).has([ 'b', 2, 'c' ]), true)
t.equal(traverse(obj).has([ 'b', 2, 'c', 0 ]), false)
t.equal(traverse(obj).has([ 'b', 2, 'd' ]), false)
t.equal(traverse(obj).has([]), true)
t.equal(traverse(obj).has([ 'a' ]), true)
t.equal(traverse(obj).has([ 'a', 2 ]), false)
t.end();
var obj = { a: 2, b: [4, 5, { c: 6 }] };
t.equal(traverse(obj).has(['b', 2, 'c']), true);
t.equal(traverse(obj).has(['b', 2, 'c', 0]), false);
t.equal(traverse(obj).has(['b', 2, 'd']), false);
t.equal(traverse(obj).has([]), true);
t.equal(traverse(obj).has(['a']), true);
t.equal(traverse(obj).has(['a', 2]), false);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -6,13 +8,11 @@ var traverse = require('../');

test('check instanceof on node elems', function (t) {
var counts = { emitter : 0 };
traverse([ new EventEmitter, 3, 4, { ev : new EventEmitter }])
.forEach(function (node) {
if (node instanceof EventEmitter) counts.emitter ++;
})
;
t.equal(counts.emitter, 2);
t.end();
var counts = { emitter: 0 };
traverse([new EventEmitter(), 3, 4, { ev: new EventEmitter() }])
.forEach(function (node) {
if (node instanceof EventEmitter) { counts.emitter += 1; }
});
t.equal(counts.emitter, 2);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,40 +7,41 @@ var traverse = require('../');

test('interface map', function (t) {
var obj = { a : [ 5,6,7 ], b : { c : [8] } };
t.same(
traverse.paths(obj)
.sort()
.map(function (path) { return path.join('/') })
.slice(1)
.join(' ')
,
'a a/0 a/1 a/2 b b/c b/c/0'
);
t.same(
traverse.nodes(obj),
[
{ a: [ 5, 6, 7 ], b: { c: [ 8 ] } },
[ 5, 6, 7 ], 5, 6, 7,
{ c: [ 8 ] }, [ 8 ], 8
]
);
t.same(
traverse.map(obj, function (node) {
if (typeof node == 'number') {
return node + 1000;
}
else if (Array.isArray(node)) {
return node.join(' ');
}
}),
{ a: '5 6 7', b: { c: '8' } }
);
var nodes = 0;
traverse.forEach(obj, function (node) { nodes ++ });
t.same(nodes, 8);
t.end();
var obj = { a: [5, 6, 7], b: { c: [8] } };
t.same(
traverse.paths(obj)
.sort()
.map(function (path) { return path.join('/'); })
.slice(1)
.join(' ')
,
'a a/0 a/1 a/2 b b/c b/c/0'
);
t.same(
traverse.nodes(obj),
[
{ a: [5, 6, 7], b: { c: [8] } },
[5, 6, 7], 5, 6, 7,
{ c: [8] }, [8], 8,
]
);
t.same(
traverse.map(obj, function (node) {
if (typeof node === 'number') {
return node + 1000;
}
if (Array.isArray(node)) {
return node.join(' ');
}
return void undefined;
}),
{ a: '5 6 7', b: { c: '8' } }
);
var nodes = 0;
traverse.forEach(obj, function () { nodes += 1; });
t.equal(nodes, 8);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,46 +7,50 @@ var traverse = require('../');

test('json test', function (t) {
var id = 54;
var callbacks = {};
var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
var scrubbed = traverse(obj).map(function (x) {
if (typeof x === 'function') {
callbacks[id] = { id : id, f : x, path : this.path };
this.update('[Function]');
id++;
}
});
t.equal(
scrubbed.moo, '[Function]',
'obj.moo replaced with "[Function]"'
);
t.equal(
scrubbed.foo[3], '[Function]',
'obj.foo[3] replaced with "[Function]"'
);
t.same(scrubbed, {
moo : '[Function]',
foo : [ 2, 3, 4, "[Function]" ]
}, 'Full JSON string matches');
t.same(
typeof obj.moo, 'function',
'Original obj.moo still a function'
);
t.same(
typeof obj.foo[3], 'function',
'Original obj.foo[3] still a function'
);
t.same(callbacks, {
54: { id: 54, f : obj.moo, path: [ 'moo' ] },
55: { id: 55, f : obj.foo[3], path: [ 'foo', '3' ] },
}, 'Check the generated callbacks list');
t.end();
var id = 54;
var callbacks = {};
var obj = { moo: function () {}, foo: [2, 3, 4, function () {}] };
var scrubbed = traverse(obj).map(function (x) {
if (typeof x === 'function') {
callbacks[id] = { id: id, f: x, path: this.path };
this.update('[Function]');
id += 1;
}
});
t.equal(
scrubbed.moo,
'[Function]',
'obj.moo replaced with "[Function]"'
);
t.equal(
scrubbed.foo[3],
'[Function]',
'obj.foo[3] replaced with "[Function]"'
);
t.same(scrubbed, {
moo: '[Function]',
foo: [2, 3, 4, '[Function]'],
}, 'Full JSON string matches');
t.same(
typeof obj.moo,
'function',
'Original obj.moo still a function'
);
t.same(
typeof obj.foo[3],
'function',
'Original obj.foo[3] still a function'
);
t.same(callbacks, {
54: { id: 54, f: obj.moo, path: ['moo'] },
55: { id: 55, f: obj.foo[3], path: ['foo', '3'] },
}, 'Check the generated callbacks list');
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,28 +7,28 @@ var traverse = require('../');

test('sort test', function (t) {
var acc = [];
traverse({
a: 30,
b: 22,
id: 9
}).forEach(function (node) {
if ((! Array.isArray(node)) && typeof node === 'object') {
this.before(function(node) {
this.keys = Object.keys(node);
this.keys.sort(function(a, b) {
a = [a === "id" ? 0 : 1, a];
b = [b === "id" ? 0 : 1, b];
return a < b ? -1 : a > b ? 1 : 0;
});
});
}
if (this.isLeaf) acc.push(node);
});
t.equal(
acc.join(' '),
'9 30 22',
'Traversal in a custom order'
);
t.end();
var acc = [];
traverse({
a: 30,
b: 22,
id: 9,
}).forEach(function (node) {
if (!Array.isArray(node) && typeof node === 'object') {
this.before(function (beforeNode) {
this.keys = Object.keys(beforeNode);
this.keys.sort(function (a, b) {
var aA = [a === 'id' ? 0 : 1, a];
var bA = [b === 'id' ? 0 : 1, b];
return aA < bA ? -1 : aA > bA ? 1 : 0;
});
});
}
if (this.isLeaf) { acc.push(node); }
});
t.equal(
acc.join(' '),
'9 30 22',
'Traversal in a custom order'
);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,19 +7,19 @@ var traverse = require('../');

test('leaves test', function (t) {
var acc = [];
traverse({
a : [1,2,3],
b : 4,
c : [5,6],
d : { e : [7,8], f : 9 }
}).forEach(function (x) {
if (this.isLeaf) acc.push(x);
});
t.equal(
acc.join(' '),
'1 2 3 4 5 6 7 8 9',
'Traversal in the right(?) order'
);
t.end();
var acc = [];
traverse({
a: [1, 2, 3],
b: 4,
c: [5, 6],
d: { e: [7, 8], f: 9 },
}).forEach(function (x) {
if (this.isLeaf) { acc.push(x); }
});
t.equal(
acc.join(' '),
'1 2 3 4 5 6 7 8 9',
'Traversal in the right(?) order'
);
t.end();
});

@@ -0,24 +1,29 @@

'use strict';
var traverse = require('../../');
function toS(o) {
return Object.prototype.toString.call(o);
}
module.exports = function (a, b) {
if (arguments.length !== 2) {
throw new Error(
'deepEqual requires exactly two objects to compare against'
);
}
var equal = true;
var node = b;
traverse(a).forEach(function (y) {
var notEqual = (function () {
equal = false;
//this.stop();
return undefined;
}).bind(this);
//if (node === undefined || node === null) return notEqual();
if (!this.isRoot) {
/*
if (arguments.length !== 2) {
throw new Error('deepEqual requires exactly two objects to compare against');
}
var equal = true;
function notEqual() {
equal = false;
// this.stop();
return undefined;
}
var node = b;
traverse(a).forEach(function (y) { // eslint-disable-line consistent-return
// if (node === undefined || node === null) return notEqual();
if (!this.isRoot) {
/*
if (!Object.hasOwnProperty.call(node, this.key)) {

@@ -28,70 +33,56 @@ return notEqual();

*/
if (typeof node !== 'object') return notEqual();
node = node[this.key];
}
var x = node;
this.post(function () {
node = x;
});
var toS = function (o) {
return Object.prototype.toString.call(o);
};
if (this.circular) {
if (traverse(b).get(this.circular.path) !== x) notEqual();
}
else if (typeof x !== typeof y) {
notEqual();
}
else if (x === null || y === null || x === undefined || y === undefined) {
if (x !== y) notEqual();
}
else if (x.__proto__ !== y.__proto__) {
notEqual();
}
else if (x === y) {
// nop
}
else if (typeof x === 'function') {
if (x instanceof RegExp) {
// both regexps on account of the __proto__ check
if (x.toString() != y.toString()) notEqual();
}
else if (x !== y) notEqual();
}
else if (typeof x === 'object') {
if (toS(y) === '[object Arguments]'
if (typeof node !== 'object') { return notEqual(); }
node = node[this.key];
}
var x = node;
this.post(function () {
node = x;
});
if (this.circular) {
if (traverse(b).get(this.circular.path) !== x) { notEqual(); }
} else if (typeof x !== typeof y) {
notEqual();
} else if (x === null || y === null || x === undefined || y === undefined) {
if (x !== y) { notEqual(); }
} else if (x.__proto__ !== y.__proto__) {
notEqual();
} else if (x === y) {
// nop
} else if (typeof x === 'function') {
if (x instanceof RegExp) {
// both regexps on account of the __proto__ check
if (String(x) !== String(y)) { notEqual(); }
} else if (x !== y) { notEqual(); }
} else if (typeof x === 'object') {
if (toS(y) === '[object Arguments]'
|| toS(x) === '[object Arguments]') {
if (toS(x) !== toS(y)) {
notEqual();
}
}
else if (toS(y) === '[object RegExp]'
if (toS(x) !== toS(y)) {
notEqual();
}
} else if (toS(y) === '[object RegExp]'
|| toS(x) === '[object RegExp]') {
if (!x || !y || x.toString() !== y.toString()) notEqual();
}
else if (x instanceof Date || y instanceof Date) {
if (!(x instanceof Date) || !(y instanceof Date)
if (!x || !y || x.toString() !== y.toString()) { notEqual(); }
} else if (x instanceof Date || y instanceof Date) {
if (!(x instanceof Date) || !(y instanceof Date)
|| x.getTime() !== y.getTime()) {
notEqual();
}
}
else {
var kx = Object.keys(x);
var ky = Object.keys(y);
if (kx.length !== ky.length) return notEqual();
for (var i = 0; i < kx.length; i++) {
var k = kx[i];
if (!Object.hasOwnProperty.call(y, k)) {
notEqual();
}
}
}
}
});
return equal;
notEqual();
}
} else {
var kx = Object.keys(x);
var ky = Object.keys(y);
if (kx.length !== ky.length) { return notEqual(); }
for (var i = 0; i < kx.length; i++) {
var k = kx[i];
if (!Object.hasOwnProperty.call(y, k)) {
notEqual();
}
}
}
}
});
return equal;
};

@@ -0,2 +1,5 @@

'use strict';
var test = require('tape');
var assert = require('assert');
var traverse = require('../');

@@ -6,296 +9,269 @@ var deepEqual = require('./lib/deep_equal');

test('mutate', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, res);
t.same(obj, { a : 1, b : 20, c : [ 3, 40 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, res);
t.same(obj, { a: 1, b: 20, c: [3, 40] });
t.end();
});
test('mutateT', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse.forEach(obj, function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, res);
t.same(obj, { a : 1, b : 20, c : [ 3, 40 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse.forEach(obj, function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, res);
t.same(obj, { a: 1, b: 20, c: [3, 40] });
t.end();
});
test('map', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).map(function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, { a : 1, b : 2, c : [ 3, 4 ] });
t.same(res, { a : 1, b : 20, c : [ 3, 40 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).map(function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, { a: 1, b: 2, c: [3, 4] });
t.same(res, { a: 1, b: 20, c: [3, 40] });
t.end();
});
test('mapT', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse.map(obj, function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, { a : 1, b : 2, c : [ 3, 4 ] });
t.same(res, { a : 1, b : 20, c : [ 3, 40 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse.map(obj, function (x) {
if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.same(obj, { a: 1, b: 2, c: [3, 4] });
t.same(res, { a: 1, b: 20, c: [3, 40] });
t.end();
});
test('clone', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).clone();
t.same(obj, res);
t.ok(obj !== res);
obj.a ++;
t.same(res.a, 1);
obj.c.push(5);
t.same(res.c, [ 3, 4 ]);
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).clone();
t.same(obj, res);
t.ok(obj !== res);
obj.a += 1;
t.same(res.a, 1);
obj.c.push(5);
t.same(res.c, [3, 4]);
t.end();
});
test('cloneT', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse.clone(obj);
t.same(obj, res);
t.ok(obj !== res);
obj.a ++;
t.same(res.a, 1);
obj.c.push(5);
t.same(res.c, [ 3, 4 ]);
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse.clone(obj);
t.same(obj, res);
t.ok(obj !== res);
obj.a += 1;
t.same(res.a, 1);
obj.c.push(5);
t.same(res.c, [3, 4]);
t.end();
});
test('reduce', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).reduce(function (acc, x) {
if (this.isLeaf) acc.push(x);
return acc;
}, []);
t.same(obj, { a : 1, b : 2, c : [ 3, 4 ] });
t.same(res, [ 1, 2, 3, 4 ]);
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).reduce(function (acc, x) {
if (this.isLeaf) { acc.push(x); }
return acc;
}, []);
t.same(obj, { a: 1, b: 2, c: [3, 4] });
t.same(res, [1, 2, 3, 4]);
t.end();
});
test('reduceInit', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).reduce(function (acc, x) {
if (this.isRoot) assert.fail('got root');
return acc;
});
t.same(obj, { a : 1, b : 2, c : [ 3, 4 ] });
t.same(res, obj);
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).reduce(function (acc) {
if (this.isRoot) { assert.fail('got root'); }
return acc;
});
t.same(obj, { a: 1, b: 2, c: [3, 4] });
t.same(res, obj);
t.end();
});
test('remove', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 == 0) this.remove();
});
t.same(obj, { a : 1, c : [ 3 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 === 0) { this.remove(); }
});
t.same(obj, { a: 1, c: [3] });
t.end();
});
exports.removeNoStop = function() {
var obj = { a : 1, b : 2, c : { d: 3, e: 4 }, f: 5 };
var keys = [];
traverse(obj).forEach(function (x) {
keys.push(this.key)
if (this.key == 'c') this.remove();
});
test('removeNoStop', function (t) {
var obj = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 5 };
t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e', 'f'])
t.end();
}
var keys = [];
traverse(obj).forEach(function () {
keys.push(this.key);
if (this.key === 'c') { this.remove(); }
});
exports.removeStop = function() {
var obj = { a : 1, b : 2, c : { d: 3, e: 4 }, f: 5 };
var keys = [];
traverse(obj).forEach(function (x) {
keys.push(this.key)
if (this.key == 'c') this.remove(true);
});
t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e', 'f']);
t.end();
});
t.same(keys, [undefined, 'a', 'b', 'c', 'f'])
t.end();
}
test('removeStop', function (t) {
var obj = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 5 };
var keys = [];
traverse(obj).forEach(function () {
keys.push(this.key);
if (this.key === 'c') { this.remove(true); }
});
t.same(keys, [undefined, 'a', 'b', 'c', 'f']);
t.end();
});
test('removeMap', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 == 0) this.remove();
});
t.same(obj, { a : 1, b : 2, c : [ 3, 4 ] });
t.same(res, { a : 1, c : [ 3 ] });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 === 0) { this.remove(); }
});
t.same(obj, { a: 1, b: 2, c: [3, 4] });
t.same(res, { a: 1, c: [3] });
t.end();
});
test('delete', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 == 0) this.delete();
});
t.ok(!deepEqual(
obj, { a : 1, c : [ 3, undefined ] }
));
t.ok(deepEqual(
obj, { a : 1, c : [ 3 ] }
));
t.ok(!deepEqual(
obj, { a : 1, c : [ 3, null ] }
));
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 === 0) { this.delete(); }
});
t.ok(!deepEqual(obj, { a: 1, c: [3, undefined] }));
t.ok(deepEqual(obj, { a: 1, c: [3] }));
t.ok(!deepEqual(obj, { a: 1, c: [3, null] }));
t.end();
});
test('deleteNoStop', function (t) {
var obj = { a : 1, b : 2, c : { d: 3, e: 4 } };
var keys = [];
traverse(obj).forEach(function (x) {
keys.push(this.key)
if (this.key == 'c') this.delete();
});
var obj = { a: 1, b: 2, c: { d: 3, e: 4 } };
t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e'])
t.end();
var keys = [];
traverse(obj).forEach(function () {
keys.push(this.key);
if (this.key === 'c') { this.delete(); }
});
t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e']);
t.end();
});
test('deleteStop', function (t) {
var obj = { a : 1, b : 2, c : { d: 3, e: 4 } };
var keys = [];
traverse(obj).forEach(function (x) {
keys.push(this.key)
if (this.key == 'c') this.delete(true);
});
var obj = { a: 1, b: 2, c: { d: 3, e: 4 } };
t.same(keys, [undefined, 'a', 'b', 'c'])
t.end();
var keys = [];
traverse(obj).forEach(function () {
keys.push(this.key);
if (this.key === 'c') { this.delete(true); }
});
t.same(keys, [undefined, 'a', 'b', 'c']);
t.end();
});
test('deleteRedux', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4, 5 ] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 == 0) this.delete();
});
t.ok(!deepEqual(
obj, { a : 1, c : [ 3, undefined, 5 ] }
));
t.ok(deepEqual(
obj, { a : 1, c : [ 3 ,, 5 ] }
));
t.ok(!deepEqual(
obj, { a : 1, c : [ 3, null, 5 ] }
));
t.ok(!deepEqual(
obj, { a : 1, c : [ 3, 5 ] }
));
t.end();
var obj = { a: 1, b: 2, c: [3, 4, 5] };
traverse(obj).forEach(function (x) {
if (this.isLeaf && x % 2 === 0) { this.delete(); }
});
t.ok(!deepEqual(obj, { a: 1, c: [3, undefined, 5] }));
t.ok(deepEqual(obj, { a: 1, c: [3,, 5] }));
t.ok(!deepEqual(obj, { a: 1, c: [3, null, 5] }));
t.ok(!deepEqual(obj, { a: 1, c: [3, 5] }));
t.end();
});
test('deleteMap', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 == 0) this.delete();
});
t.ok(deepEqual(
obj,
{ a : 1, b : 2, c : [ 3, 4 ] }
));
var xs = [ 3, 4 ];
delete xs[1];
t.ok(deepEqual(
res, { a : 1, c : xs }
));
t.ok(deepEqual(
res, { a : 1, c : [ 3, ] }
));
t.ok(deepEqual(
res, { a : 1, c : [ 3 ] }
));
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 === 0) { this.delete(); }
});
t.ok(deepEqual(
obj,
{ a: 1, b: 2, c: [3, 4] }
));
var xs = [3, 4];
delete xs[1];
t.ok(deepEqual(res, { a: 1, c: xs }));
t.ok(deepEqual(res, { a: 1, c: [3,,] })); // eslint-disable-line comma-spacing
t.ok(deepEqual(res, { a: 1, c: [3] }));
t.end();
});
test('deleteMapRedux', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4, 5 ] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 == 0) this.delete();
});
t.ok(deepEqual(
obj,
{ a : 1, b : 2, c : [ 3, 4, 5 ] }
));
var xs = [ 3, 4, 5 ];
delete xs[1];
t.ok(deepEqual(
res, { a : 1, c : xs }
));
t.ok(!deepEqual(
res, { a : 1, c : [ 3, 5 ] }
));
t.ok(deepEqual(
res, { a : 1, c : [ 3 ,, 5 ] }
));
t.end();
var obj = { a: 1, b: 2, c: [3, 4, 5] };
var res = traverse(obj).map(function (x) {
if (this.isLeaf && x % 2 === 0) { this.delete(); }
});
t.ok(deepEqual(
obj,
{ a: 1, b: 2, c: [3, 4, 5] }
));
var xs = [3, 4, 5];
delete xs[1];
t.ok(deepEqual(res, { a: 1, c: xs }));
t.ok(!deepEqual(res, { a: 1, c: [3, 5] }));
t.ok(deepEqual(res, { a: 1, c: [3,, 5] }));
t.end();
});
test('objectToString', function (t) {
var obj = { a : 1, b : 2, c : [ 3, 4 ] };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'object' && !this.isRoot) {
this.update(JSON.stringify(x));
}
});
t.same(obj, res);
t.same(obj, { a : 1, b : 2, c : "[3,4]" });
t.end();
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'object' && !this.isRoot) {
this.update(JSON.stringify(x));
}
});
t.same(obj, res);
t.same(obj, { a: 1, b: 2, c: '[3,4]' });
t.end();
});
test('stringToObject', function (t) {
var obj = { a : 1, b : 2, c : "[3,4]" };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'string') {
this.update(JSON.parse(x));
}
else if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.deepEqual(obj, res);
t.deepEqual(obj, { a : 1, b : 20, c : [ 3, 40 ] });
t.end();
var obj = { a: 1, b: 2, c: '[3,4]' };
var res = traverse(obj).forEach(function (x) {
if (typeof x === 'string') {
this.update(JSON.parse(x));
} else if (typeof x === 'number' && x % 2 === 0) {
this.update(x * 10);
}
});
t.deepEqual(obj, res);
t.deepEqual(obj, { a: 1, b: 20, c: [3, 40] });
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var traverse = require('../');

@@ -5,18 +7,20 @@ var test = require('tape');

test('negative update test', function (t) {
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
var fixed = traverse.map(obj, function (x) {
if (x < 0) this.update(x + 128);
});
t.same(fixed,
[ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ],
'Negative values += 128'
);
t.same(obj,
[ 5, 6, -3, [ 7, 8, -2, 1 ], { f: 10, g: -13 } ],
'Original references not modified'
);
t.end();
var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
var fixed = traverse.map(obj, function (x) {
if (x < 0) { this.update(x + 128); }
});
t.same(
fixed,
[5, 6, 125, [7, 8, 126, 1], { f: 10, g: 115 }],
'Negative values += 128'
);
t.same(
obj,
[5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }],
'Original references not modified'
);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,8 +7,8 @@ var traverse = require('../');

test('traverse an object with nested functions', function (t) {
t.plan(1);
function Cons (x) {
t.equal(x, 10)
};
traverse(new Cons(10));
t.plan(1);
function Cons(x) {
t.equal(x, 10);
}
traverse(new Cons(10));
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,34 +7,34 @@ var traverse = require('../');

test('siblings', function (t) {
var obj = { a : 1, b : 2, c : [ 4, 5, 6 ] };
var res = traverse(obj).reduce(function (acc, x) {
var p = '/' + this.path.join('/');
if (this.parent) {
acc[p] = {
siblings : this.parent.keys,
key : this.key,
index : this.parent.keys.indexOf(this.key)
};
}
else {
acc[p] = {
siblings : [],
key : this.key,
index : -1
}
}
return acc;
}, {});
t.same(res, {
'/' : { siblings : [], key : undefined, index : -1 },
'/a' : { siblings : [ 'a', 'b', 'c' ], key : 'a', index : 0 },
'/b' : { siblings : [ 'a', 'b', 'c' ], key : 'b', index : 1 },
'/c' : { siblings : [ 'a', 'b', 'c' ], key : 'c', index : 2 },
'/c/0' : { siblings : [ '0', '1', '2' ], key : '0', index : 0 },
'/c/1' : { siblings : [ '0', '1', '2' ], key : '1', index : 1 },
'/c/2' : { siblings : [ '0', '1', '2' ], key : '2', index : 2 }
});
t.end();
var obj = { a: 1, b: 2, c: [4, 5, 6] };
var res = traverse(obj).reduce(function (acc) {
/* eslint no-param-reassign: 0 */
var p = '/' + this.path.join('/');
if (this.parent) {
acc[p] = {
siblings: this.parent.keys,
key: this.key,
index: this.parent.keys.indexOf(this.key),
};
} else {
acc[p] = {
siblings: [],
key: this.key,
index: -1,
};
}
return acc;
}, {});
t.same(res, {
'/': { siblings: [], key: undefined, index: -1 },
'/a': { siblings: ['a', 'b', 'c'], key: 'a', index: 0 },
'/b': { siblings: ['a', 'b', 'c'], key: 'b', index: 1 },
'/c': { siblings: ['a', 'b', 'c'], key: 'c', index: 2 },
'/c/0': { siblings: ['0', '1', '2'], key: '0', index: 0 },
'/c/1': { siblings: ['0', '1', '2'], key: '1', index: 1 },
'/c/2': { siblings: ['0', '1', '2'], key: '2', index: 2 },
});
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,41 +7,41 @@ var traverse = require('../');

test('stop', function (t) {
var visits = 0;
traverse('abcdefghij'.split('')).forEach(function (node) {
if (typeof node === 'string') {
visits ++;
if (node === 'e') this.stop()
}
});
t.equal(visits, 5);
t.end();
var visits = 0;
traverse('abcdefghij'.split('')).forEach(function (node) {
if (typeof node === 'string') {
visits += 1;
if (node === 'e') { this.stop(); }
}
});
t.equal(visits, 5);
t.end();
});
test('stopMap', function (t) {
var s = traverse('abcdefghij'.split('')).map(function (node) {
if (typeof node === 'string') {
if (node === 'e') this.stop()
return node.toUpperCase();
}
}).join('');
t.equal(s, 'ABCDEfghij');
t.end();
var s = traverse('abcdefghij'.split('')).map(function (node) {
if (typeof node === 'string') {
if (node === 'e') { this.stop(); }
return node.toUpperCase();
}
return void undefined;
}).join('');
t.equal(s, 'ABCDEfghij');
t.end();
});
test('stopReduce', function (t) {
var obj = {
a : [ 4, 5 ],
b : [ 6, [ 7, 8, 9 ] ]
};
var xs = traverse(obj).reduce(function (acc, node) {
if (this.isLeaf) {
if (node === 7) this.stop();
else acc.push(node)
}
return acc;
}, []);
t.same(xs, [ 4, 5, 6 ]);
t.end();
var obj = {
a: [4, 5],
b: [6, [7, 8, 9]],
};
var xs = traverse(obj).reduce(function (acc, node) {
if (this.isLeaf) {
if (node === 7) { this.stop(); } else { acc.push(node); }
}
return acc;
}, []);
t.same(xs, [4, 5, 6]);
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var test = require('tape');

@@ -5,33 +7,30 @@ var traverse = require('../');

test('stringify', function (t) {
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
var s = '';
traverse(obj).forEach(function (node) {
if (Array.isArray(node)) {
this.before(function () { s += '[' });
this.post(function (child) {
if (!child.isLast) s += ',';
});
this.after(function () { s += ']' });
}
else if (typeof node == 'object') {
this.before(function () { s += '{' });
this.pre(function (x, key) {
s += '"' + key + '"' + ':';
});
this.post(function (child) {
if (!child.isLast) s += ',';
});
this.after(function () { s += '}' });
}
else if (typeof node == 'function') {
s += 'null';
}
else {
s += node.toString();
}
});
t.equal(s, JSON.stringify(obj));
t.end();
var obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
var s = '';
traverse(obj).forEach(function (node) {
if (Array.isArray(node)) {
this.before(function () { s += '['; });
this.post(function (child) {
if (!child.isLast) { s += ','; }
});
this.after(function () { s += ']'; });
} else if (typeof node === 'object') {
this.before(function () { s += '{'; });
this.pre(function (x, key) {
s += '"' + key + '":';
});
this.post(function (child) {
if (!child.isLast) { s += ','; }
});
this.after(function () { s += '}'; });
} else if (typeof node === 'function') {
s += 'null';
} else {
s += node.toString();
}
});
t.equal(s, JSON.stringify(obj));
t.end();
});

@@ -0,1 +1,3 @@

'use strict';
var traverse = require('../');

@@ -5,33 +7,36 @@ var test = require('tape');

test('subexpr', function (t) {
var obj = [ 'a', 4, 'b', 5, 'c', 6 ];
var r = traverse(obj).map(function (x) {
if (typeof x === 'number') {
this.update([ x - 0.1, x, x + 0.1 ], true);
}
});
t.same(obj, [ 'a', 4, 'b', 5, 'c', 6 ]);
t.same(r, [
'a', [ 3.9, 4, 4.1 ],
'b', [ 4.9, 5, 5.1 ],
'c', [ 5.9, 6, 6.1 ],
]);
t.end();
var obj = ['a', 4, 'b', 5, 'c', 6];
var r = traverse(obj).map(function (x) {
if (typeof x === 'number') {
this.update([x - 0.1, x, x + 0.1], true);
}
});
t.same(obj, ['a', 4, 'b', 5, 'c', 6]);
t.same(r, [
'a', [3.9, 4, 4.1],
'b', [4.9, 5, 5.1],
'c', [5.9, 6, 6.1],
]);
t.end();
});
test('block', function (t) {
var obj = [ [ 1 ], [ 2 ], [ 3 ] ];
var r = traverse(obj).map(function (x) {
if (Array.isArray(x) && !this.isRoot) {
if (x[0] === 5) this.block()
else this.update([ [ x[0] + 1 ] ])
}
});
t.same(r, [
[ [ [ [ [ 5 ] ] ] ] ],
[ [ [ [ 5 ] ] ] ],
[ [ [ 5 ] ] ],
]);
t.end();
var obj = [[1], [2], [3]];
var r = traverse(obj).map(function (x) {
if (Array.isArray(x) && !this.isRoot) {
if (x[0] === 5) {
this.block();
} else {
this.update([[x[0] + 1]]);
}
}
});
t.same(r, [
[[[[[5]]]]],
[[[[5]]]],
[[[5]]],
]);
t.end();
});

@@ -0,56 +1,56 @@

'use strict';
var test = require('tape');
var traverse = require('../');
var deepEqual = require('./lib/deep_equal');
function make() {
var a = { self: 'a' };
var b = { self: 'b' };
var c = { self: 'c' };
var d = { self: 'd' };
var e = { self: 'e' };
a.a = a;
a.b = b;
a.c = c;
b.a = a;
b.b = b;
b.c = c;
c.a = a;
c.b = b;
c.c = c;
c.d = d;
d.a = a;
d.b = b;
d.c = c;
d.d = d;
d.e = e;
e.a = a;
e.b = b;
e.c = c;
e.d = d;
e.e = e;
return a;
}
test('super_deep', function (t) {
var util = require('util');
var a0 = make();
var a1 = make();
t.ok(deepEqual(a0, a1));
a0.c.d.moo = true;
t.ok(!deepEqual(a0, a1));
a1.c.d.moo = true;
t.ok(deepEqual(a0, a1));
// TODO: this one
//a0.c.a = a1;
//t.ok(!deepEqual(a0, a1));
t.end();
var a0 = make();
var a1 = make();
t.ok(deepEqual(a0, a1));
a0.c.d.moo = true;
t.ok(!deepEqual(a0, a1));
a1.c.d.moo = true;
t.ok(deepEqual(a0, a1));
// TODO: this one
// a0.c.a = a1;
// t.ok(!deepEqual(a0, a1));
t.end();
});
function make () {
var a = { self : 'a' };
var b = { self : 'b' };
var c = { self : 'c' };
var d = { self : 'd' };
var e = { self : 'e' };
a.a = a;
a.b = b;
a.c = c;
b.a = a;
b.b = b;
b.c = c;
c.a = a;
c.b = b;
c.c = c;
c.d = d;
d.a = a;
d.b = b;
d.c = c;
d.d = d;
d.e = e;
e.a = a;
e.b = b;
e.c = c;
e.d = d;
e.e = e;
return a;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc