Skip to content

Commit

Permalink
range refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
Afsin Ustundag committed Jun 24, 2015
1 parent 3fecab5 commit ac7e325
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 24 deletions.
44 changes: 25 additions & 19 deletions lib/jsonpath/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,28 @@ var Tracer = {
this.traceProperties(properties, accumulator);
};
},
traceArrayRangeGen: function (expr) {
var indices = expr.split(':');
var start = (indices[0] && parseInt(indices[0], 10)) || 0;
var end = (indices[1] && parseInt(indices[1], 10)) || null;
var step = (indices[2] && parseInt(indices[2], 10)) || 1;

traceExpandedPropertiesGen: function (parameters) {
return function (accumulator) {
var obj = accumulator.currentObject();
var length = obj.length;
var localStart = (start < 0) ? Math.max(0, start + length) : Math.min(length, start);
var localEnd = (end === null) ? length : end;
localEnd = (localEnd < 0) ? Math.max(0, localEnd + length) : Math.min(length, localEnd);
var range = _.range(localStart, localEnd, step);
this.traceProperties(range, accumulator);

var properties = parameters.reduce(function (r, p) {
var type = typeof p;
if (type === 'object') {
var start = (p.start < 0) ? Math.max(0, p.start + length) : Math.min(length, p.start);
var end = (p.end === null) ? length : p.end;
end = (end < 0) ? Math.max(0, end + length) : Math.min(length, end);
var range = _.range(start, end, p.step);
Array.prototype.push.apply(r, range);
} else if ((type === 'number') && (p < 0)) {
var index = Math.max(0, p + length);
r.push(index);
} else {
r.push(p);
}
return r;
}, []);
this.traceProperties(properties, accumulator);
};
},
tracePropertyGen: function (property) {
Expand Down Expand Up @@ -364,6 +372,12 @@ var tracerAdapter = (function () {
pathNeeded: parameter.indexOf('@path') > -1,
branches: true
};
},
properties: function (parameter) {
return {
method: Tracer.traceExpandedPropertiesGen(parameter),
branches: (parameter.length > 1) || (typeof parameter[0] === 'object')
};
}
};

Expand All @@ -381,14 +395,6 @@ var tracerAdapter = (function () {
branches: true
};
}
}, {
re: /^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/,
obj: function (expr) {
return {
method: Tracer.traceArrayRangeGen(expr),
branches: true
};
}
}, {
re: /\(\)$/,
obj: function (expr, opts) {
Expand Down
18 changes: 15 additions & 3 deletions lib/jsonpath/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ var propertyUpdate = {
}
};

var subscriptToProperties = function subscriptToProperties(subscript, properties) {
var reKeys = Object.keys(re);
var expandSubscriptProperties = exports.expandSubscriptProperties = function expandSubscriptProperties(subscript, properties) {
var reKeys = ['range'];
var n = reKeys.length;
for (var i = 0; i < n; ++i) {
var key = reKeys[i];
Expand All @@ -69,7 +69,7 @@ var subscriptToProperties = function subscriptToProperties(subscript, properties
throw new Error('Invalid character');
}
subscript = subscript.substring(nResult + 1);
return subscriptToProperties(subscript, properties);
return expandSubscriptProperties(subscript, properties);
}
}
return false;
Expand Down Expand Up @@ -111,6 +111,18 @@ var subscriptToNode = function (subscript) {
};
}

var properties = [];
var result = expandSubscriptProperties(subscript, properties);
if (result) {
return {
type: 'properties',
parameter: properties
};
}
if (properties.length > 0) {
throw new Error('Invalid subscript: ' + subscript);
}

return subscript;
};

Expand Down
20 changes: 18 additions & 2 deletions test/jsonpath/test-normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,15 @@ describe('jsonpath normalization', function () {

it('$..book[-1:]', function () {
var actual = jsonpath.normalize('$..book[-1:]');
expect(actual).to.deep.equal([jsonpath.types.ROOT, jsonpath.types.RECURSIVE_DESCENT, 'book', '-1:']);
var propertiesObject = {
type: 'properties',
parameter: [{
start: -1,
end: null,
step: 1
}]
};
expect(actual).to.deep.equal([jsonpath.types.ROOT, jsonpath.types.RECURSIVE_DESCENT, 'book', propertiesObject]);
});

it('$..book[1,2]', function () {
Expand All @@ -53,7 +61,15 @@ describe('jsonpath normalization', function () {

it('$..book[:2]', function () {
var actual = jsonpath.normalize('$..book[:2]');
expect(actual).to.deep.equal([jsonpath.types.ROOT, jsonpath.types.RECURSIVE_DESCENT, 'book', ':2']);
var propertiesObject = {
type: 'properties',
parameter: [{
start: 0,
end: 2,
step: 1
}]
};
expect(actual).to.deep.equal([jsonpath.types.ROOT, jsonpath.types.RECURSIVE_DESCENT, 'book', propertiesObject]);
});

it('$..book[*][category,author]', function () {
Expand Down
21 changes: 21 additions & 0 deletions test/jsonpath/test-parser-re.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var parser = require('../../lib/jsonpath/parser.js');

var expect = chai.expect;
var re = parser.re;
var expandSubscriptProperties = parser.expandSubscriptProperties;

describe('reqular expression verification', function () {
var expectSingleMatch = function (expression, result, count) {
Expand Down Expand Up @@ -177,3 +178,23 @@ describe('reqular expression verification', function () {
});
});
});

describe('expandSubscriptProperties', function () {
var subscripts = [{
value: '1:8:2',
expected: [{
start: 1,
end: 8,
step: 2
}]
}];

subscripts.forEach(function (subscript) {
it(subscript.value, function () {
var actual = [];
var r = expandSubscriptProperties(subscript.value, actual);
expect(r).to.equal(true);
expect(actual).to.deep.equal(subscript.expected);
});
});
});

0 comments on commit ac7e325

Please sign in to comment.