diff --git a/src/lang/modifyAst.test.ts b/src/lang/modifyAst.test.ts index 33a94bd0a..33479f3c3 100644 --- a/src/lang/modifyAst.test.ts +++ b/src/lang/modifyAst.test.ts @@ -114,7 +114,8 @@ describe('Testing addSketchTo', () => { expect(str).toBe(`const part001 = startSketchAt('default') |> ry(90, %) |> line('default', %) -show(part001)`) +show(part001) +`) }) }) diff --git a/src/lang/recast.test.ts b/src/lang/recast.test.ts index 8b8277cb3..c90dee500 100644 --- a/src/lang/recast.test.ts +++ b/src/lang/recast.test.ts @@ -11,26 +11,27 @@ describe('recast', () => { const code = '1 + 2' const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('variable declaration', () => { const code = 'const myVar = 5' const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it("variable declaration that's binary with string", () => { const code = "const myVar = 5 + 'yo'" const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) const codeWithOtherQuotes = 'const myVar = 5 + "yo"' const { ast: ast2 } = code2ast(codeWithOtherQuotes) - expect(recast(ast2)).toBe(codeWithOtherQuotes) + expect(recast(ast2).trim()).toBe(codeWithOtherQuotes) }) it('test assigning two variables, the second summing with the first', () => { const code = `const myVar = 5 -const newVar = myVar + 1` +const newVar = myVar + 1 +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -42,11 +43,12 @@ const newVar = myVar + 1` ) const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('test with function call', () => { const code = `const myVar = "hello" -log(5, myVar)` +log(5, myVar) +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -61,7 +63,7 @@ log(5, myVar)` ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('recast sketch declaration', () => { let code = `const mySketch = startSketchAt([0, 0]) @@ -70,10 +72,11 @@ log(5, myVar)` |> lineTo({ to: [1, 0], tag: "rightPath" }, %) |> close(%) -show(mySketch)` +show(mySketch) +` const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted).toBe(code) }) it('sketch piped into callExpression', () => { const code = [ @@ -85,7 +88,7 @@ show(mySketch)` ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('recast BinaryExpression piped into CallExpression', () => { const code = [ @@ -97,37 +100,37 @@ show(mySketch)` ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('recast nested binary expression', () => { const code = ['const myVar = 1 + 2 * 5'].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('recast nested binary expression with parans', () => { const code = ['const myVar = 1 + (1 + 2) * 5'].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('unnecessary paran wrap will be remove', () => { const code = ['const myVar = 1 + (2 * 5)'].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.replace('(', '').replace(')', '')) + expect(recasted.trim()).toBe(code.replace('(', '').replace(')', '')) }) it('complex nested binary expression', () => { const code = ['1 * ((2 + 3) / 4 + 5)'].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('multiplied paren expressions', () => { const code = ['3 + (1 + 2) * (3 + 4)'].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('recast array declaration', () => { const code = ['const three = 3', "const yo = [1, '2', three, 4 + 5]"].join( @@ -135,7 +138,7 @@ show(mySketch)` ) const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('recast long array declaration', () => { const code = [ @@ -150,7 +153,7 @@ show(mySketch)` ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted.trim()).toBe(code.trim()) }) it('recast long object exectution', () => { const code = `const three = 3 @@ -159,26 +162,29 @@ const yo = { anum: 2, identifier: three, binExp: 4 + 5 -}` +} +` const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted).toBe(code) }) it('recast short object exectution', () => { - const code = `const yo = { key: 'val' }` + const code = `const yo = { key: 'val' } +` const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted).toBe(code) }) it('recast object execution with member expression', () => { const code = `const yo = { a: { b: { c: '123' } } } const key = 'c' const myVar = yo.a['b'][key] const key2 = 'b' -const myVar2 = yo['a'][key2].c` +const myVar2 = yo['a'][key2].c +` const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code.trim()) + expect(recasted).toBe(code) }) }) @@ -186,7 +192,8 @@ describe('testing recasting with comments and whitespace', () => { it('code with comments', () => { const code = `const yo = { a: { b: { c: '123' } } } // this is a comment -const key = 'c'` +const key = 'c' +` const { ast } = code2ast(code) const recasted = recast(ast) @@ -199,7 +206,8 @@ const key = 'c'` /* this is a comment */ -const yo = 'bing'` +const yo = 'bing' +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -209,7 +217,8 @@ const yo = 'bing'` const yo = { a: { b: { c: '123' } } } const key = 'c' -// this is also a comment` +// this is also a comment +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -223,7 +232,8 @@ const key = 'c' comment */ const key = 'c' // this is also a comment -}` +} +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -239,7 +249,7 @@ const key = 'c' ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('comments sprinkled in all over the place', () => { const code = ` @@ -261,7 +271,8 @@ const mySk1 = startSketchAt([0, 0]) |> rx(45, %) /* one more for good measure - */` + */ +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(`// comment at start @@ -278,7 +289,8 @@ a comment between pipe expression statements */ // and another with just white space between others below |> ry(45, %) |> rx(45, %) -// one more for good measure`) +// one more for good measure +`) }) }) @@ -287,19 +299,19 @@ describe('testing call Expressions in BinaryExpressions and UnaryExpressions', ( const code = 'const myVar = 2 + min(100, legLen(5, 3))' const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('nested callExpression in unaryExpression', () => { const code = 'const myVar = -min(100, legLen(5, 3))' const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('with unaryExpression in callExpression', () => { const code = 'const myVar = min(5, -legLen(5, 4))' const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) it('with unaryExpression in sketch situation', () => { const code = [ @@ -308,7 +320,7 @@ describe('testing call Expressions in BinaryExpressions and UnaryExpressions', ( ].join('\n') const { ast } = code2ast(code) const recasted = recast(ast) - expect(recasted).toBe(code) + expect(recasted.trim()).toBe(code) }) }) @@ -323,7 +335,8 @@ describe('it recasts wrapped object expressions in pipe bodies with correct inde intersectTag: 'seg01' }, %) |> line([-0.42, -1.72], %) -show(part001)` +show(part001) +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -333,7 +346,8 @@ show(part001)` angle: 201, offset: -1.35, intersectTag: 'seg01' -}, %)` +}, %) +` const { ast } = code2ast(code) const recasted = recast(ast) expect(recasted).toBe(code) @@ -342,7 +356,8 @@ show(part001)` describe('it recasts binary expression using brackets where needed', () => { it('when there are two minus in a row', () => { - const code = `const part001 = 1 - (def - abc)` + const code = `const part001 = 1 - (def - abc) +` const recasted = recast(code2ast(code).ast) expect(recasted).toBe(code) }) diff --git a/src/lang/std/sketch.test.ts b/src/lang/std/sketch.test.ts index 852263556..6612070e1 100644 --- a/src/lang/std/sketch.test.ts +++ b/src/lang/std/sketch.test.ts @@ -101,7 +101,8 @@ describe('testing changeSketchArguments', () => { |> ${line} |> lineTo([0.46, -5.82], %) // |> rx(45, %) -show(mySketch001)` +show(mySketch001) +` const code = genCode(lineToChange) const expectedCode = genCode(lineAfterChange) const ast = parser_wasm(code) @@ -164,7 +165,8 @@ show(mySketch001)` |> lineTo([-1.59, -1.54], %) |> lineTo([0.46, -5.82], %) |> lineTo([2, 3], %) -show(mySketch001)` +show(mySketch001) +` expect(recast(modifiedAst)).toBe(expectedCode) }) }) @@ -177,7 +179,8 @@ describe('testing addTagForSketchOnFace', () => { // |> rx(45, %) |> ${line} |> lineTo([0.46, -5.82], %) -show(mySketch001)` +show(mySketch001) +` const code = genCode(originalLine) const ast = parser_wasm(code) const programMemory = await enginelessExecutor(ast) diff --git a/src/lang/std/sketchcombos.test.ts b/src/lang/std/sketchcombos.test.ts index 1556c25f2..0a83592d2 100644 --- a/src/lang/std/sketchcombos.test.ts +++ b/src/lang/std/sketchcombos.test.ts @@ -124,7 +124,8 @@ const part001 = startSketchAt([0, 0]) |> yLine(1.04, %) // ln-yLine-free should sub in segLen |> xLineTo(30, %) // ln-xLineTo-free should convert to xLine |> yLineTo(20, %) // ln-yLineTo-free should convert to yLine -show(part001)` +show(part001) +` const expectModifiedScript = `const myVar = 3 const myVar2 = 5 const myVar3 = 6 @@ -195,7 +196,8 @@ const part001 = startSketchAt([0, 0]) |> yLine(segLen('seg01', %), %) // ln-yLine-free should sub in segLen |> xLine(segLen('seg01', %), %) // ln-xLineTo-free should convert to xLine |> yLine(segLen('seg01', %), %) // ln-yLineTo-free should convert to yLine -show(part001)` +show(part001) +` it('should transform the ast', async () => { const ast = parser_wasm(inputScript) const selectionRanges: Selections['codeBasedSelections'] = inputScript @@ -254,7 +256,8 @@ const part001 = startSketchAt([0, 0]) |> angledLineToY([223, 7.68], %) // select for vertical constraint 9 |> angledLineToX([333, myVar3], %) // select for horizontal constraint 10 |> angledLineToY([301, myVar], %) // select for vertical constraint 10 -show(part001)` +show(part001) +` it('should transform horizontal lines the ast', async () => { const expectModifiedScript = `const myVar = 2 const myVar2 = 12 @@ -281,7 +284,8 @@ const part001 = startSketchAt([0, 0]) |> angledLineToY([223, 7.68], %) // select for vertical constraint 9 |> xLineTo(myVar3, %) // select for horizontal constraint 10 |> angledLineToY([301, myVar], %) // select for vertical constraint 10 -show(part001)` +show(part001) +` const ast = parser_wasm(inputScript) const selectionRanges: Selections['codeBasedSelections'] = inputScript .split('\n') @@ -338,7 +342,8 @@ const part001 = startSketchAt([0, 0]) |> yLineTo(7.68, %) // select for vertical constraint 9 |> angledLineToX([333, myVar3], %) // select for horizontal constraint 10 |> yLineTo(myVar, %) // select for vertical constraint 10 -show(part001)` +show(part001) +` const ast = parser_wasm(inputScript) const selectionRanges: Selections['codeBasedSelections'] = inputScript .split('\n') @@ -380,7 +385,8 @@ const part001 = startSketchAt([0, 0]) |> line([0.45, 1.46], %) // free |> line([myVar, 0.01], %) // xRelative |> line([0.7, myVar], %) // yRelative -show(part001)` +show(part001) +` it('testing for free to horizontal and vertical distance', async () => { const expectedHorizontalCode = await helperThing( inputScript, diff --git a/src/wasm-lib/kcl/src/abstract_syntax_tree_types.rs b/src/wasm-lib/kcl/src/abstract_syntax_tree_types.rs index 47c5deaea..55d1a0e1e 100644 --- a/src/wasm-lib/kcl/src/abstract_syntax_tree_types.rs +++ b/src/wasm-lib/kcl/src/abstract_syntax_tree_types.rs @@ -2016,6 +2016,9 @@ impl_value_meta!(FunctionExpression); impl FunctionExpression { pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String { + // We don't want to end with a new line inside nested functions. + let mut new_options = options.clone(); + new_options.insert_final_newline = false; format!( "({}) => {{\n{}{}\n}}", self.params @@ -2024,7 +2027,7 @@ impl FunctionExpression { .collect::>() .join(", "), options.get_indentation(indentation_level + 1), - self.body.recast(options, indentation_level + 1) + self.body.recast(&new_options, indentation_level + 1) ) } @@ -2092,7 +2095,7 @@ impl FormatOptions { Self { tab_size: 2, use_tabs: false, - insert_final_newline: false, + insert_final_newline: true, } } @@ -2163,7 +2166,8 @@ show(part001)"#; r#"const part001 = startSketchAt('default') |> ry(90, %) |> line('default', %) -show(part001)"# +show(part001) +"# ); } @@ -2181,7 +2185,8 @@ show(part001)"# recasted, r#"const part001 = startSketchAt([0.0, 5.0]) |> line([0.4900857016, -0.0240763666], %) - |> line([0.6804562304, 0.9087880491], %)"# + |> line([0.6804562304, 0.9087880491], %) +"# ); } @@ -2199,7 +2204,8 @@ show(part001)"# recasted, r#"const part001 = startSketchAt([0.0, 5.0]) |> line([0.4900857016, -0.0240763666], %) // hello world - |> line([0.6804562304, 0.9087880491], %)"# + |> line([0.6804562304, 0.9087880491], %) +"# ); } #[test] @@ -2218,7 +2224,8 @@ show(part001)"# r#"const part001 = startSketchAt([0.0, 5.0]) |> line([0.4900857016, -0.0240763666], %) // hello world - |> line([0.6804562304, 0.9087880491], %)"# + |> line([0.6804562304, 0.9087880491], %) +"# ); } @@ -2248,7 +2255,8 @@ show(part001)"# const key = 'c' // this is also a comment return things -}"# +} +"# ); } @@ -2290,7 +2298,8 @@ a comment between pipe expression statements */ // and another with just white space between others below |> ry(45, %) |> rx(45, %) -// one more for good measure"# +// one more for good measure +"# ); } @@ -2312,7 +2321,7 @@ show(part001)"#; let program = parser.ast().unwrap(); let recasted = program.recast(&Default::default(), 0); - assert_eq!(recasted, some_program_string); + assert_eq!(recasted.trim(), some_program_string); } #[test] @@ -2331,7 +2340,8 @@ const yo = [ "three", 4 + 5, " hey oooooo really long long long" -]"#; +] +"#; let tokens = crate::tokeniser::lexer(some_program_string); let parser = crate::parser::Parser::new(tokens); let program = parser.ast().unwrap(); @@ -2355,7 +2365,7 @@ const things = "things" let program = parser.ast().unwrap(); let recasted = program.recast(&Default::default(), 0); - assert_eq!(recasted, some_program_string.trim()); + assert_eq!(recasted.trim(), some_program_string.trim()); } #[test] @@ -2373,7 +2383,7 @@ const things = "things" let program = parser.ast().unwrap(); let recasted = program.recast(&Default::default(), 0); - assert_eq!(recasted, some_program_string.trim()); + assert_eq!(recasted.trim(), some_program_string.trim()); } #[test] @@ -2398,7 +2408,7 @@ const part001 = startSketchAt([0, 0]) let program = parser.ast().unwrap(); let recasted = program.recast(&Default::default(), 0); - assert_eq!(recasted, some_program_string); + assert_eq!(recasted.trim(), some_program_string); } #[test] @@ -2471,7 +2481,8 @@ fn ghi = (part001) => { return part001 } -show(mySuperCoolPart)"# +show(mySuperCoolPart) +"# ); } @@ -2490,7 +2501,8 @@ show(mySuperCoolPart)"# recasted, r#"fn ghi = (newName, y, z) => { return newName -}"# +} +"# ); } @@ -2526,7 +2538,8 @@ const firstExtrude = startSketchAt([0, 0]) |> close(%) |> extrude(h, %) -show(firstExtrude)"# +show(firstExtrude) +"# ); } } diff --git a/src/wasm-lib/kcl/src/std/sketch.rs b/src/wasm-lib/kcl/src/std/sketch.rs index b2f0b7460..81c7b0a98 100644 --- a/src/wasm-lib/kcl/src/std/sketch.rs +++ b/src/wasm-lib/kcl/src/std/sketch.rs @@ -382,6 +382,20 @@ fn inner_angled_line( }, }; + args.send_modeling_cmd( + id, + ModelingCmd::ExtendPath { + path: sketch_group.id, + segment: kittycad::types::PathSegment::Line { + end: Point3D { + x: to[0], + y: to[1], + z: 0.0, + }, + }, + }, + )?; + let mut new_sketch_group = sketch_group.clone(); new_sketch_group.value.push(current_path); Ok(new_sketch_group)