Skip to content

Commit

Permalink
feat(projection): allow properties as projections
Browse files Browse the repository at this point in the history
  • Loading branch information
kantord committed Oct 10, 2018
1 parent c1b096c commit 14a281f
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 85 deletions.
166 changes: 118 additions & 48 deletions src/__tests__/__snapshots__/interpreter.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ exports[`interpreter correct target code {"foo": ("bar" | "baz")} 1`] = `"(funct

exports[`interpreter correct target code {"foo": ("bar" | "baz")}["foo"] 1`] = `"(function(_) { return (function(input) { return _.projection((_.objectify([[\\"foo\\",((function (input) {return \\"baz\\"})(\\"bar\\"))]])), [\\"foo\\"])})})"`;

exports[`interpreter correct target code {"foo": [{"bar": "baz"}]} | $.foo[0].bar 1`] = `"(function(_) { return (function(input) { return (function (input) {return _.projection(input.foo, [0]).bar})((_.objectify([[\\"foo\\",[(_.objectify([[\\"bar\\",\\"baz\\"]]))]]])))})})"`;

exports[`interpreter correct target code {"original": $.foo} | {"new": $} 1`] = `"(function(_) { return (function(input) { return (function (input) {return (_.objectify([[\\"new\\",input]]))})((_.objectify([[\\"original\\",input.foo]])))})})"`;

exports[`interpreter correct target code false | true 1`] = `"(function(_) { return (function(input) { return (function (input) {return true})(false)})})"`;
Expand Down Expand Up @@ -93,17 +95,7 @@ exports[`interpreter correct target tree .apple.pear 1`] = `
Object {
"status": true,
"value": Object {
"end": Object {
"column": 12,
"line": 1,
"offset": 11,
},
"name": "valueProp",
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
"value": Object {
"left": Object {
"name": "inputProp",
Expand All @@ -119,17 +111,7 @@ exports[`interpreter correct target tree .apple.pear.bar 1`] = `
Object {
"status": true,
"value": Object {
"end": Object {
"column": 16,
"line": 1,
"offset": 15,
},
"name": "valueProp",
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
"value": Object {
"left": Object {
"name": "inputProp",
Expand Down Expand Up @@ -994,17 +976,17 @@ Object {
}
`;

exports[`interpreter correct target tree {"original": $.foo} | {"new": $} 1`] = `
exports[`interpreter correct target tree {"foo": [{"bar": "baz"}]} | $.foo[0].bar 1`] = `
Object {
"status": true,
"value": Object {
"name": "pipe",
"value": Object {
"left": Object {
"end": Object {
"column": 20,
"column": 26,
"line": 1,
"offset": 19,
"offset": 25,
},
"name": "object",
"start": Object {
Expand All @@ -1018,20 +1000,128 @@ Object {
"value": Array [
Object {
"name": "primitive",
"value": "\\"original\\"",
"value": "\\"foo\\"",
},
Object {
"end": Object {
"column": 19,
"column": 25,
"line": 1,
"offset": 18,
"offset": 24,
},
"name": "list",
"start": Object {
"column": 9,
"line": 1,
"offset": 8,
},
"value": Array [
Object {
"end": Object {
"column": 24,
"line": 1,
"offset": 23,
},
"name": "object",
"start": Object {
"column": 10,
"line": 1,
"offset": 9,
},
"value": Array [
Object {
"name": "tuple",
"value": Array [
Object {
"name": "primitive",
"value": "\\"bar\\"",
},
Object {
"name": "primitive",
"value": "\\"baz\\"",
},
],
},
],
},
],
},
],
},
],
},
"right": Object {
"name": "valueProp",
"value": Object {
"left": Object {
"name": "projection",
"value": Object {
"left": Object {
"name": "valueProp",
"value": Object {
"left": Object {
"name": "input",
"value": "$",
},
"right": ".foo",
},
},
"right": Object {
"end": Object {
"column": 37,
"line": 1,
"offset": 36,
},
"name": "list",
"start": Object {
"column": 14,
"column": 34,
"line": 1,
"offset": 13,
"offset": 33,
},
"value": Array [
Object {
"name": "primitive",
"value": "0",
},
],
},
},
},
"right": ".bar",
},
},
},
},
}
`;

exports[`interpreter correct target tree {"original": $.foo} | {"new": $} 1`] = `
Object {
"status": true,
"value": Object {
"name": "pipe",
"value": Object {
"left": Object {
"end": Object {
"column": 20,
"line": 1,
"offset": 19,
},
"name": "object",
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
"value": Array [
Object {
"name": "tuple",
"value": Array [
Object {
"name": "primitive",
"value": "\\"original\\"",
},
Object {
"name": "valueProp",
"value": Object {
"left": Object {
"name": "input",
Expand Down Expand Up @@ -1149,17 +1239,7 @@ Object {
"value": "\\"original\\"",
},
Object {
"end": Object {
"column": 28,
"line": 1,
"offset": 27,
},
"name": "valueProp",
"start": Object {
"column": 23,
"line": 1,
"offset": 22,
},
"value": Object {
"left": Object {
"name": "input",
Expand Down Expand Up @@ -1217,17 +1297,7 @@ Object {
"value": "\\"original\\"",
},
Object {
"end": Object {
"column": 28,
"line": 1,
"offset": 27,
},
"name": "valueProp",
"start": Object {
"column": 23,
"line": 1,
"offset": 22,
},
"value": Object {
"left": Object {
"name": "input",
Expand Down
4 changes: 4 additions & 0 deletions src/__tests__/interpreter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ const tests = [
{
sourceCode: `[0,1,"foo"][1,2][1,1][0]`,
output: 'foo'
},
{
sourceCode: `{"foo": [{"bar": "baz"}]} | $.foo[0].bar`,
output: 'baz'
}
]

Expand Down
2 changes: 1 addition & 1 deletion src/parsers/__tests__/valueProp.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import parser from '../valueProp'
import parser from '../projection'

describe('valueProp parser', () => {
it('parses .bar.foo', () => {
Expand Down
6 changes: 1 addition & 5 deletions src/parsers/projectable.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import P from 'parsimmon'
import ValuePropParser from './valueProp'
import ValueParser from './value'
import ObjectParser from './object'

export default P.alt(
ValuePropParser,
P.alt(ObjectParser, ValueParser)
)
export default P.alt(ObjectParser, ValueParser)
52 changes: 40 additions & 12 deletions src/parsers/projection.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,60 @@ import P from 'parsimmon'
import type {
ListNodeType,
ProjectionNodeType,
ValuePropNodeType,
ProjectableNodeType
} from '../types'

type WrappedProjectionNodeType =
| {name: 'projection', value: ListNodeType}
| {name: 'valueProp', value: string};

const unpackOne = (
projectable: ProjectableNodeType | ProjectionNodeType,
projection: ListNodeType
): ProjectionNodeType => ({
name: 'projection',
value: {
left: projectable,
right: projection
}
})
projectable: ProjectableNodeType | ProjectionNodeType | ValuePropNodeType,
projection: WrappedProjectionNodeType
): ProjectionNodeType | ValuePropNodeType | ProjectableNodeType =>
projection.name === 'projection'
? {
name: 'projection',
value: {
left: projectable,
right: projection.value
}
}
: projection.name === 'valueProp'
? {
name: 'valueProp',
value: {
left: projectable,
right: projection.value
}
}
: projectable

const unpack = ([projectable, projections]: [
ProjectableNodeType,
Array<ListNodeType>
]): ProjectionNodeType | ProjectableNodeType =>
Array<WrappedProjectionNodeType>
]): ProjectionNodeType | ValuePropNodeType | ProjectableNodeType =>
projections.reduce(unpackOne, projectable)

const ProjectionParser = P.lazy((): mixed => {
const ProjectableParser = require('./projectable').default
const ListParser = require('./list').default
const PropertyParser = P.regexp(/(\.[$A-Z_][0-9A-Z_$]*)+/i)
return P.seq(
ProjectableParser.skip(P.optWhitespace),
ListParser.skip(P.optWhitespace).atLeast(1)
P.alt(
ListParser.map((x: ListNodeType): WrappedProjectionNodeType => ({
value: x,
name: 'projection'
})),
PropertyParser.map((x: string): WrappedProjectionNodeType => ({
value: x,
name: 'valueProp'
}))
)
.skip(P.optWhitespace)
.atLeast(1)
).map(unpack)
})

Expand Down
19 changes: 0 additions & 19 deletions src/parsers/valueProp.js

This file was deleted.

0 comments on commit 14a281f

Please sign in to comment.