diff --git a/src/__tests__/__snapshots__/interpreter.test.js.snap b/src/__tests__/__snapshots__/interpreter.test.js.snap index 3a9a00a6..43a8e2c3 100644 --- a/src/__tests__/__snapshots__/interpreter.test.js.snap +++ b/src/__tests__/__snapshots__/interpreter.test.js.snap @@ -52,7 +52,7 @@ exports[`interpreter correct target code [0,1,2][1,2][1,1][0] 1`] = `"(function( exports[`interpreter correct target code [0.14, true, "true 2"] 1`] = `"(function(_) { return (function(input) { return [0.14, true, \\"true 2\\"]})})"`; -exports[`interpreter correct target code [1, ...$, 3, ...$] 1`] = `"(function(_) { return (function(input) { return [1].concat(input).concat([3]).concat(input)})})"`; +exports[`interpreter correct target code [1, ...$, 3, ...$] 1`] = `"(function(_) { return (function(input) { return [1].concat(_.__spread__(input)).concat(_.__spread__([3])).concat(_.__spread__(input))})})"`; exports[`interpreter correct target code [3, 2][0] : [3, 2][1] 1`] = `"(function(_) { return (function(input) { return [_.projection([3, 2], [0], false),_.projection([3, 2], [1], false)]})})"`; @@ -73,6 +73,8 @@ exports[`interpreter correct target code {"foo": ("bar" | "baz")}["foo"] 1`] = ` exports[`interpreter correct target code {"foo": [{"bar": "baz"}]} | $.foo[0].bar 1`] = `"(function(_) { return (function(input) { return (function (input) {return _.projection(input.foo, [0], false).bar})((_.objectify([[\\"foo\\",[(_.objectify([[\\"bar\\",\\"baz\\"]]))]]])))})})"`; +exports[`interpreter correct target code {"foo": 3} | {"bar": "baz", ...$} 1`] = `"(function(_) { return (function(input) { return (function (input) {return (_.objectify([[\\"bar\\",\\"baz\\"]].concat(_.__spread__(input))))})((_.objectify([[\\"foo\\",3]])))})})"`; + 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 -(3 * 2) -1 > -1.34 * 3 && true 1`] = `"(function(_) { return (function(input) { return (-((3*2)))-1>-1.34*3&&true})})"`; @@ -3183,6 +3185,120 @@ Object { } `; +exports[`interpreter correct target tree {"foo": 3} | {"bar": "baz", ...$} 1`] = ` +Object { + "status": true, + "value": Object { + "name": "pipe", + "value": Object { + "left": Object { + "end": Object { + "column": 11, + "line": 1, + "offset": 10, + }, + "name": "object", + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + "value": Array [ + Object { + "end": Object { + "column": 10, + "line": 1, + "offset": 9, + }, + "name": "simpleList", + "start": Object { + "column": 2, + "line": 1, + "offset": 1, + }, + "value": Array [ + Object { + "name": "tuple", + "value": Array [ + Object { + "name": "primitive", + "value": "\\"foo\\"", + }, + Object { + "name": "primitive", + "value": "3", + }, + ], + }, + ], + }, + ], + }, + "right": Object { + "end": Object { + "column": 34, + "line": 1, + "offset": 33, + }, + "name": "object", + "start": Object { + "column": 14, + "line": 1, + "offset": 13, + }, + "value": Array [ + Object { + "end": Object { + "column": 27, + "line": 1, + "offset": 26, + }, + "name": "simpleList", + "start": Object { + "column": 15, + "line": 1, + "offset": 14, + }, + "value": Array [ + Object { + "name": "tuple", + "value": Array [ + Object { + "name": "primitive", + "value": "\\"bar\\"", + }, + Object { + "name": "primitive", + "value": "\\"baz\\"", + }, + ], + }, + ], + }, + Object { + "end": Object { + "column": 33, + "line": 1, + "offset": 32, + }, + "name": "spread", + "start": Object { + "column": 29, + "line": 1, + "offset": 28, + }, + "value": Object { + "name": "variable", + "value": "$", + }, + }, + ], + }, + }, + }, +} +`; + exports[`interpreter correct target tree {"original": $.foo} | {"new": $} 1`] = ` Object { "status": true, diff --git a/src/__tests__/builtins.test.js b/src/__tests__/builtins.test.js index bc406bc3..a3f0a445 100644 --- a/src/__tests__/builtins.test.js +++ b/src/__tests__/builtins.test.js @@ -16,7 +16,8 @@ const { values, combinations, product, - __opt__ + __opt__, + __spread__ } = builtIns describe('built ins', () => { @@ -62,6 +63,12 @@ describe('built ins', () => { expect(__opt__([], f)).toEqual('Hello') }) + describe('__spread__', () => { + const f = x => 'Hello'; // eslint-disable-line + expect(__spread__([1, 2])).toEqual([1, 2]) + expect(__spread__({ a: 'b', c: 3 })).toEqual([['a', 'b'], ['c', 3]]) + }) + describe('join', () => { it('returns correct value', () => { expect(join(' ')(['Hello', 'World'])).toEqual('Hello World') diff --git a/src/__tests__/interpreter.test.js b/src/__tests__/interpreter.test.js index 6b2359f0..7a090878 100644 --- a/src/__tests__/interpreter.test.js +++ b/src/__tests__/interpreter.test.js @@ -307,6 +307,13 @@ const tests = [ input: [1, 2], output: [1, 1, 2, 3, 1, 2] }, + { + sourceCode: `{"foo": 3} | {"bar": "baz", ...$}`, + output: { + foo: 3, + bar: 'baz' + } + }, { sourceCode: `$.uno?.dos?.tres`, input: { diff --git a/src/builtins.js b/src/builtins.js index 4bfd02a1..2ec69d7c 100644 --- a/src/builtins.js +++ b/src/builtins.js @@ -42,6 +42,9 @@ export default { __opt__: handleOptional, + __spread__: (input: mixed): mixed => + Array.isArray(input) ? input : Object.entries(input), + projection: ( left: ProjectableType, right: ProjectionRulesType, diff --git a/src/generators/__tests__/list.test.js b/src/generators/__tests__/list.test.js index cc6cc461..d9aaba8f 100644 --- a/src/generators/__tests__/list.test.js +++ b/src/generators/__tests__/list.test.js @@ -55,6 +55,8 @@ describe('list generator', () => { } ] }) - ).toEqual('[input, input, [null]].concat(input).concat(input)') + ).toEqual( + '[input, input, [null]].concat(_.__spread__(input)).concat(_.__spread__(input))' + ) }) }) diff --git a/src/generators/__tests__/object.test.js b/src/generators/__tests__/object.test.js index 19a2d875..639fd7a6 100644 --- a/src/generators/__tests__/object.test.js +++ b/src/generators/__tests__/object.test.js @@ -34,6 +34,8 @@ describe('object generator', () => { } ] }) - ).toEqual('(_.objectify([["foo","bar"], ["baz",4]].concat(input)))') + ).toEqual( + '(_.objectify([["foo","bar"], ["baz",4]].concat(_.__spread__(input))))' + ) }) }) diff --git a/src/generators/list.js b/src/generators/list.js index 6db0bec6..5a46e2ae 100644 --- a/src/generators/list.js +++ b/src/generators/list.js @@ -14,7 +14,9 @@ const CompileListSegmentItem = (item: NodeType): GeneratedCodeType => { return Generator(item) } -const CompileSimpleListSegment = (segment: SimpleListSegmentType): GeneratedCodeType => +const CompileSimpleListSegment = ( + segment: SimpleListSegmentType +): GeneratedCodeType => `[${segment.value.map(CompileListSegmentItem).join(', ')}]` const CompileListSegment = (segment: ListCoreSegmentType): GeneratedCodeType => @@ -25,7 +27,7 @@ const CompileListSegment = (segment: ListCoreSegmentType): GeneratedCodeType => const CompileListSegments = (segments: ListCoreValueType): GeneratedCodeType => segments.reduce( (a: GeneratedCodeType, b: ListCoreSegmentType): GeneratedCodeType => - `${a}.concat(${CompileListSegment(b)})`, + `${a}.concat(_.__spread__(${CompileListSegment(b)}))`, '' )