@elastic/micro-jq
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -0,1 +1,6 @@ | ||
## [`1.2.0`](https://github.com/elastic/micro-jq/tree/v1.2.0) | ||
- Better support for slices, indexing, and improved composability #3 | ||
- Update dependencies | ||
## [`1.1.0`](https://github.com/elastic/micro-jq/tree/v1.1.0) | ||
@@ -2,0 +7,0 @@ |
{ | ||
"name": "@elastic/micro-jq", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Small implementation of jq", | ||
@@ -14,8 +14,8 @@ "main": "./src/index.js", | ||
"devDependencies": { | ||
"eslint": "^6.6.0", | ||
"eslint-plugin-jest": "^23.0.4", | ||
"jest": "^24.9.0", | ||
"eslint": "^7.3.1", | ||
"eslint-plugin-jest": "^23.17.1", | ||
"jest": "^26.1.0", | ||
"pegjs": "^0.10.0", | ||
"prettier": "^1.15.3" | ||
"prettier": "^2.0.5" | ||
} | ||
} |
@@ -35,13 +35,2 @@ const parser = require('./parser') | ||
let picked = each[opCode.key] | ||
if (opCode.explode) { | ||
if (!Array.isArray(picked)) { | ||
throw new Error('Cannot iterate over ' + typeof picked) | ||
} | ||
return result.concat(picked) | ||
} else if (opCode.index != null) { | ||
if (!Array.isArray(picked)) { | ||
throw new Error('Cannot index into ' + typeof picked) | ||
} | ||
picked = picked[opCode.index] | ||
} | ||
result.push(picked) | ||
@@ -53,10 +42,38 @@ return result | ||
case 'index': | ||
context = context.map(x => { | ||
if (!Array.isArray(x)) { | ||
throw new Error('Can only index into arrays') | ||
context = context.reduce((result, each) => { | ||
if (!Array.isArray(each)) { | ||
if (opCode.strict) { | ||
throw new Error('Can only index into arrays') | ||
} | ||
return result | ||
} | ||
return x[opCode.index] | ||
}) | ||
let indexed | ||
if (Math.abs(opCode.index) > each.length || opCode.index === each.length) { | ||
indexed = null | ||
} else if (opCode.index < 0) { | ||
indexed = each.slice(opCode.index)[0] | ||
} else { | ||
indexed = each[opCode.index] | ||
} | ||
result.push(indexed) | ||
return result | ||
}, []) | ||
break | ||
case 'slice': | ||
context = context.reduce((result, each) => { | ||
if ('undefined' === typeof each.slice) { | ||
if (opCode.strict) { | ||
throw new Error('Cannot slice ' + typeof each) | ||
} | ||
return result | ||
} | ||
if (undefined === opCode.start && undefined === opCode.end) { | ||
throw new Error('Cannot slice with no offsets') | ||
} | ||
result.push(each.slice(opCode.start, opCode.end)) | ||
return result | ||
}, []) | ||
break | ||
case 'explode': | ||
@@ -63,0 +80,0 @@ context = context.reduce((result, each) => { |
@@ -37,2 +37,64 @@ const executeScript = require('../src/execute') | ||
test('pick negative index', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[-4]' | ||
expect(executeScript(input, script)).toEqual(3) | ||
}) | ||
test('pick first index by negative length', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[-7]' | ||
expect(executeScript(input, script)).toEqual(1) | ||
}) | ||
test('pick out of bounds index', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[7]' | ||
expect(executeScript(input, script)).toEqual(null) | ||
}) | ||
test('pick out of bounds negative index', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[-8]' | ||
expect(executeScript(input, script)).toEqual(null) | ||
}) | ||
test('slice', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[2:5]' | ||
expect(executeScript(input, script)).toEqual([2, 3, 5]) | ||
}) | ||
test('slice with no start', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[:5]' | ||
expect(executeScript(input, script)).toEqual([1, 1, 2, 3, 5]) | ||
}) | ||
test('slice with no end', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[2:]' | ||
expect(executeScript(input, script)).toEqual([2, 3, 5, 8, 13]) | ||
}) | ||
test('slice with no offsets', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[:]' | ||
expect(() => | ||
executeScript(input, script) | ||
).toThrowErrorMatchingInlineSnapshot('"Cannot slice with no offsets"') | ||
}) | ||
test('slice with negative offsets', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[-5:-2]' | ||
expect(executeScript(input, script)).toEqual([2, 3, 5]) | ||
}) | ||
test('slice with end offset greater than start', () => { | ||
const input = [1, 1, 2, 3, 5, 8, 13] | ||
const script = '.[5:2]' | ||
expect(executeScript(input, script)).toEqual([]) | ||
}) | ||
test('pick by identifier and then index', () => { | ||
@@ -44,2 +106,8 @@ const input = { foo: [1, 1, 2, 3, 5, 8, 13] } | ||
test('pick by identifier and then index by negative number', () => { | ||
const input = { foo: [1, 1, 2, 3, 5, 8, 13] } | ||
const script = '.foo[-4]' | ||
expect(executeScript(input, script)).toEqual(3) | ||
}) | ||
test('pick by identifier, index, then identifier again', () => { | ||
@@ -46,0 +114,0 @@ const input = { foo: [ { bar: 1 }, { bar: 2 } ] } |
@@ -17,4 +17,2 @@ const { parse } = require('../src/parser') | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "foo", | ||
@@ -32,4 +30,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "$foo", | ||
@@ -47,4 +43,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "foo", | ||
@@ -58,2 +52,17 @@ "op": "pick", | ||
test('pick with object index', () => { | ||
expect(parse('.["foo"]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"key": "foo", | ||
"op": "pick", | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('nested keys', () => { | ||
@@ -63,4 +72,2 @@ expect(parse('.foo.bar')).toMatchInlineSnapshot(` | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "foo", | ||
@@ -71,4 +78,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "bar", | ||
@@ -86,4 +91,8 @@ "op": "pick", | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"index": 1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
@@ -94,2 +103,96 @@ ] | ||
test('index an array with negative index', () => { | ||
expect(parse('.[-1]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"index": -1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('index non-strictly', () => { | ||
expect(parse('.[1]?')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"index": 1, | ||
"op": "index", | ||
"strict": false, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('slice an array', () => { | ||
expect(parse('.[1:3]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"end": 3, | ||
"op": "slice", | ||
"start": 1, | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('slice an array with negative offsets', () => { | ||
expect(parse('.[-3:-1]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"end": -1, | ||
"op": "slice", | ||
"start": -3, | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('slice an array with no start', () => { | ||
expect(parse('.[:3]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"end": 3, | ||
"op": "slice", | ||
"start": undefined, | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('slice an array with no end', () => { | ||
expect(parse('.[1:]')).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"end": undefined, | ||
"op": "slice", | ||
"start": 1, | ||
"strict": true, | ||
}, | ||
] | ||
`) | ||
}) | ||
test('get all values from an array', () => { | ||
@@ -99,2 +202,5 @@ expect(parse('.[]')).toMatchInlineSnapshot(` | ||
Object { | ||
"op": "current_context", | ||
}, | ||
Object { | ||
"op": "explode", | ||
@@ -111,4 +217,2 @@ "strict": true, | ||
Object { | ||
"explode": false, | ||
"index": 1, | ||
"key": "foo", | ||
@@ -118,2 +222,7 @@ "op": "pick", | ||
}, | ||
Object { | ||
"index": 1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
] | ||
@@ -127,4 +236,2 @@ `) | ||
Object { | ||
"explode": true, | ||
"index": null, | ||
"key": "foo", | ||
@@ -135,4 +242,6 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"op": "explode", | ||
"strict": true, | ||
}, | ||
Object { | ||
"key": "bar", | ||
@@ -150,4 +259,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": 1, | ||
"key": "foo", | ||
@@ -158,4 +265,7 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"index": 1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
Object { | ||
"key": "bar", | ||
@@ -173,4 +283,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "foo", | ||
@@ -181,4 +289,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "bar", | ||
@@ -243,4 +349,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "foo", | ||
@@ -253,4 +357,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "bar", | ||
@@ -275,4 +377,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": 1, | ||
"key": "foo", | ||
@@ -283,4 +383,7 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"index": 1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
Object { | ||
"key": "bar", | ||
@@ -293,4 +396,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": 1, | ||
"key": "foo", | ||
@@ -301,4 +402,7 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"index": 1, | ||
"op": "index", | ||
"strict": true, | ||
}, | ||
Object { | ||
"key": "bar", | ||
@@ -387,4 +491,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "bar", | ||
@@ -400,4 +502,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "quux", | ||
@@ -408,4 +508,2 @@ "op": "pick", | ||
Object { | ||
"explode": false, | ||
"index": null, | ||
"key": "schmee", | ||
@@ -412,0 +510,0 @@ "op": "pick", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
2754
133998