Skip to content

Commit

Permalink
Don't mutate pointer array. Performance speedup.
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Mar 17, 2016
1 parent c413470 commit 89ac53f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 36 deletions.
22 changes: 11 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ function api (obj, pointer, value) {
* @returns {*}
*/
api.get = function get (obj, pointer) {
var tok,
refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer);
while (refTokens.length) {
tok = refTokens.shift();
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer);

for (var i = 0; i < refTokens.length; ++i) {
var tok = refTokens[i];
if (!(typeof obj == 'object' && tok in obj)) {
throw new Error('Invalid reference token: ' + tok);
}
Expand All @@ -67,14 +67,14 @@ api.get = function get (obj, pointer) {
*/
api.set = function set (obj, pointer, value) {
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer),
tok,
nextTok = refTokens[0];
while (refTokens.length > 1) {
tok = refTokens.shift();
nextTok = refTokens[0];

for (var i = 0; i < refTokens.length - 1; ++i) {
var tok = refTokens[i];
if (tok === '-' && Array.isArray(obj)) {
tok = obj.length;
}
nextTok = refTokens[0];
nextTok = refTokens[i + 1];

if (!(tok in obj)) {
if (nextTok.match(/^(\d+|-)$/)) {
Expand All @@ -100,11 +100,11 @@ api.set = function set (obj, pointer, value) {
*/
api.remove = function (obj, pointer) {
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer);
var finalToken = refTokens.pop();
var finalToken = refTokens[refTokens.length -1];
if (finalToken === undefined) {
throw new Error('Invalid JSON pointer for remove: "' + pointer + '"');
}
delete api.get(obj, api.compile(refTokens))[finalToken];
delete api.get(obj, refTokens.slice(0, -1))[finalToken];
};

/**
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
"url": "git://github.com/manuelstofer/json-pointer.git"
},
"devDependencies": {
"chai": "^1.9.1",
"mocha": "^1.9.0",
"chai": "^1.9.1"
"seamless-immutable": "^5.1.1"
},
"scripts": {
"test": "make test"
Expand Down
49 changes: 25 additions & 24 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*global describe, it, beforeEach*/
if (typeof pointer === 'undefined') {
var pointer = require('..'),
chai = require('chai'),
each = require('foreach');
var pointer = require('..'),
chai = require('chai'),
each = require('foreach'),
immutable = require('seamless-immutable');
}

var expect = chai.expect;
Expand Down Expand Up @@ -84,7 +85,7 @@ describe('json-api', function () {
});

each(Object.keys(rfcParsed), function (p) {
var tokens = rfcParsed[p].tokens;
var tokens = immutable(rfcParsed[p].tokens);
it('should work for ' + JSON.stringify(tokens), function () {
var expectedValue = rfcParsed[p].value;
pointer.get(rfcExample, tokens).should.equal(expectedValue);
Expand Down Expand Up @@ -115,7 +116,7 @@ describe('json-api', function () {
existing: 'bla'
};

pointer.set(obj, ['new-value', 'bla'], 'expected');
pointer.set(obj, immutable(['new-value', 'bla']), 'expected');
obj['new-value'].bla.should.equal('expected');
});

Expand All @@ -133,7 +134,7 @@ describe('json-api', function () {
existing: 'bla'
};

pointer.set(obj, ['first-level'], 'expected');
pointer.set(obj, immutable(['first-level']), 'expected');
obj['first-level'].should.equal('expected');
});

Expand All @@ -147,7 +148,7 @@ describe('json-api', function () {

it('should create arrays for numeric reference tokens and objects for other tokens when tokens are passed', function () {
var obj = [];
pointer.set(obj, ['0', 'test', '0'], 'expected');
pointer.set(obj, immutable(['0', 'test', '0']), 'expected');
Array.isArray(obj).should.be.true;
Array.isArray(obj[0]).should.be.false;
Array.isArray(obj[0].test).should.be.true;
Expand All @@ -165,7 +166,7 @@ describe('json-api', function () {

it('should create arrays for - and reference the (nonexistent) member after the last array element when tokens are passed.', function () {
var obj = ['foo'];
pointer.set(obj, ['-', 'test', '-'], 'expected');
pointer.set(obj, immutable(['-', 'test', '-']), 'expected');
Array.isArray(obj).should.be.true;
obj.should.have.length(2);
Array.isArray(obj[1].test).should.be.true;
Expand All @@ -187,9 +188,9 @@ describe('json-api', function () {
each(Object.keys(rfcParsed), function (p) {
if (p !== '') {
it('should work for ' + JSON.stringify(rfcParsed[p].tokens), function () {
pointer.remove(rfcExample, rfcParsed[p].tokens);
pointer.remove(rfcExample, immutable(rfcParsed[p].tokens));
expect(function() {
pointer.get(pointer, rfcExample, rfcParsed[p].tokens);
pointer.get(pointer, rfcExample, immutable(rfcParsed[p].tokens));
}).to.throw(Error);
});
}
Expand Down Expand Up @@ -263,10 +264,10 @@ describe('json-api', function () {
foo: [['hello']],
abc: 'bla'
};
pointer.has(obj, ['bla']).should.be.true;
pointer.has(obj, ['abc']).should.be.true;
pointer.has(obj, ['foo', '0', '0']).should.be.true;
pointer.has(obj, ['bla', 'test']).should.be.true;
pointer.has(obj, immutable(['bla'])).should.be.true;
pointer.has(obj, immutable(['abc'])).should.be.true;
pointer.has(obj, immutable(['foo', '0', '0'])).should.be.true;
pointer.has(obj, immutable(['bla', 'test'])).should.be.true;
});

it('should return false when the pointer does not exist', function () {
Expand All @@ -289,10 +290,10 @@ describe('json-api', function () {
},
abc: 'bla'
};
pointer.has(obj, ['not-existing']).should.be.false;
pointer.has(obj, ['not-existing', 'bla']).should.be.false;
pointer.has(obj, ['test', '1', 'bla']).should.be.false;
pointer.has(obj, ['bla', 'test1']).should.be.false;
pointer.has(obj, immutable(['not-existing'])).should.be.false;
pointer.has(obj, immutable(['not-existing', 'bla'])).should.be.false;
pointer.has(obj, immutable(['test', '1', 'bla'])).should.be.false;
pointer.has(obj, immutable(['bla', 'test1'])).should.be.false;
});
});

Expand Down Expand Up @@ -330,7 +331,7 @@ describe('json-api', function () {
each(Object.keys(rfcValues), function (p) {

it('should equal for "' + p + '"', function () {
pointer.compile(pointer.parse(p)).should.equal(p);
pointer.compile(immutable(pointer.parse(p))).should.equal(p);
});
});
});
Expand All @@ -352,7 +353,7 @@ describe('convenience api wrapper', function() {
existing: 'expected'
};

pointer(obj, ['existing']);
pointer(obj, immutable(['existing']));
obj.existing.should.equal('expected');
});

Expand All @@ -370,7 +371,7 @@ describe('convenience api wrapper', function() {
existing: 'bla'
};

pointer(obj, ['new-value', 'bla'], 'expected');
pointer(obj, immutable(['new-value', 'bla']), 'expected');
obj['new-value'].bla.should.equal('expected');
});

Expand Down Expand Up @@ -403,8 +404,8 @@ describe('convenience api wrapper', function() {
},
objPointer = pointer(obj);

objPointer.set(['oo-style'], 'bla').set(['example', '0'], 'bla2');
objPointer.get(['oo-style']).should.equal('bla');
objPointer.get(['example', '0']).should.equal('bla2');
objPointer.set(immutable(['oo-style']), 'bla').set(['example', '0'], 'bla2');
objPointer.get(immutable(['oo-style'])).should.equal('bla');
objPointer.get(immutable(['example', '0'])).should.equal('bla2');
});
});

0 comments on commit 89ac53f

Please sign in to comment.