Comparing version 0.1.0 to 0.1.1
var assert = require("assert"); | ||
var getChildCache = require("private").makeAccessor(); | ||
var hasOwn = Object.prototype.hasOwnProperty; | ||
var Op = Object.prototype; | ||
var hasOwn = Op.hasOwnProperty; | ||
var toString = Op.toString; | ||
var arrayToString = toString.call([]); | ||
var Ap = Array.prototype; | ||
var slice = Ap.slice; | ||
var map = Ap.map; | ||
@@ -25,3 +31,6 @@ function Path(value, parentPath, name) { | ||
// Path's value was reached. | ||
name: { value: name } | ||
name: { | ||
value: name, | ||
configurable: true | ||
} | ||
}); | ||
@@ -88,2 +97,48 @@ } | ||
Pp.replace = function(replacement) { | ||
var count = arguments.length; | ||
assert.ok( | ||
this.parentPath instanceof Path, | ||
"Instead of replacing the root of the tree, create a new tree." | ||
); | ||
var name = this.name; | ||
var parentValue = this.parentPath.value; | ||
var parentCache = getChildCache(this.parentPath); | ||
if (count === 1) { | ||
delete parentCache[name]; | ||
parentValue[name] = replacement; | ||
} else { | ||
assert.strictEqual(toString.call(parentValue), arrayToString); | ||
delete parentCache.length; | ||
delete parentCache[name]; | ||
var moved = {}; | ||
for (var i = name + 1; i < parentValue.length; ++i) { | ||
var child = parentCache[i]; | ||
if (child) { | ||
var newIndex = i - 1 + count; | ||
moved[newIndex] = child; | ||
Object.defineProperty(child, "name", { value: newIndex }); | ||
delete parentCache[i]; | ||
} | ||
} | ||
var args = slice.call(arguments); | ||
args.unshift(name, 1); | ||
parentValue.splice.apply(parentValue, args); | ||
for (newIndex in moved) { | ||
if (hasOwn.call(moved, newIndex)) { | ||
parentCache[newIndex] = moved[newIndex]; | ||
} | ||
} | ||
} | ||
}; | ||
exports.Path = Path; |
@@ -13,3 +13,3 @@ { | ||
], | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"homepage": "http://github.com/benjamn/ast-path", | ||
@@ -16,0 +16,0 @@ "repository": { |
@@ -31,1 +31,79 @@ var assert = require("assert"); | ||
}); | ||
describe("replace method", function() { | ||
it("should work with single replacements", function() { | ||
var path = new Path({ | ||
foo: 42 | ||
}); | ||
var foo = path.get("foo"); | ||
assert.strictEqual(foo.value, 42); | ||
foo.replace("asdf"); | ||
var newFoo = path.get("foo"); | ||
assert.notStrictEqual(path.get("foo"), foo); | ||
assert.strictEqual(newFoo.value, "asdf"); | ||
assert.strictEqual(newFoo.name, "foo"); | ||
}); | ||
it("should fail at the root", function() { | ||
assert.throws(function() { | ||
new Path(1).replace(); | ||
}, assert.AssertionError); | ||
}); | ||
it("should work with arrays", function() { | ||
var array = [1, 2, 3]; | ||
var path = new Path(array); | ||
var second = path.get(1); | ||
var third = path.get(2); | ||
second.replace("a", "b", "c"); | ||
assert.strictEqual(third.name, 4); | ||
assert.strictEqual(third.value, 3); | ||
assert.strictEqual(third, path.get(4)); | ||
assert.strictEqual(array.length, 5); | ||
assert.deepEqual(array, [1, "a", "b", "c", 3]); | ||
assert.strictEqual(path.get(1).value, "a"); | ||
assert.strictEqual(path.get(2).value, "b"); | ||
assert.strictEqual(path.get(3).value, "c"); | ||
path.get(2).replace(); | ||
assert.deepEqual(array, [1, "a", "c", 3]); | ||
path = new Path([1, 2, 3, 4, 5]); | ||
path.get(0).replace(); | ||
assert.deepEqual(path.value, [2, 3, 4, 5]); | ||
path.get(2).replace(); | ||
assert.deepEqual(path.value, [2, 3, 5]); | ||
path.get(1).replace(); | ||
assert.deepEqual(path.value, [2, 5]); | ||
path.get(1).replace(); | ||
assert.deepEqual(path.value, [2]); | ||
path.get(0).replace(); | ||
assert.deepEqual(path.value, []); | ||
path.get(0).replace(1, 2, 3); | ||
assert.deepEqual(path.value, [1, 2, 3]); | ||
path.get(10).replace(4, 5); | ||
assert.deepEqual(path.value, [1, 2, 3, 4, 5]); | ||
}); | ||
var desc = "should support multiple replacements only for array elements"; | ||
it(desc, function() { | ||
assert.throws(function() { | ||
new Path({ foo: 42 }).get("foo").replace(2, 3); | ||
}); | ||
assert.throws(function() { | ||
new Path({ foo: 42 }).get("foo").replace(); | ||
}); | ||
}); | ||
}); |
129148
5013