diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index 183644ed5..3b05ca2fd 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -1,226 +1,229 @@ -import { Page } from '@playwright/test' -import { test, expect } from './zoo-test' +import type { Page } from '@playwright/test' +import type { LineInputsType } from '@src/lang/std/sketchcombos' +import { uuidv4 } from '@src/lib/utils' -import { deg, getUtils, wiggleMove } from './test-utils' -import { LineInputsType } from 'lang/std/sketchcombos' -import { uuidv4 } from 'lib/utils' -import { EditorFixture } from './fixtures/editorFixture' +import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture' +import { + deg, + getUtils, + orRunWhenFullSuiteEnabled, + wiggleMove, +} from '@e2e/playwright/test-utils' +import { expect, test } from '@e2e/playwright/zoo-test' test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { - test.fixme( - 'Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', - () => { - // TODO: fix this test on mac after the electron migration - test.skip(process.platform === 'darwin', 'Skip on mac') - /** - * Clicks on an constrained element - * @param {Page} page - The page to perform the action on - * @param {Object} options - The options for the action - * @param {Object} options.hoverPos - The position to hover over - * @param {Object} options.constraintType - The type of constraint - * @param {number} options.ang - The angle - * @param {number} options.steps - The number of steps to perform - */ - const _clickConstrained = - (page: Page, editor: EditorFixture) => - async ({ - hoverPos, - constraintType, - expectBeforeUnconstrained, - expectAfterUnconstrained, - expectFinal, - ang = 45, - steps = 10, - locator, - }: { - hoverPos: { x: number; y: number } - constraintType: - | 'horizontal' - | 'vertical' - | 'tangentialWithPrevious' - | LineInputsType - expectBeforeUnconstrained: string - expectAfterUnconstrained: string - expectFinal: string - ang?: number - steps?: number - locator?: string - }) => { - await expect(page.getByText('Added variable')).not.toBeVisible() - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - let x = 0, - y = 0 - x = hoverPos.x + Math.cos(ang * deg) * 32 - y = hoverPos.y - Math.sin(ang * deg) * 32 - await page.mouse.move(x, y) - await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) - await page.mouse.move(x, y) - - await editor.expectEditor.toContain(expectBeforeUnconstrained, { - shouldNormalise: true, - }) - const constrainedLocator = page.locator( - `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` - ) - await expect(constrainedLocator).toBeVisible() - await constrainedLocator.hover() - await expect( - await page.getByTestId('constraint-symbol-popover').count() - ).toBeGreaterThan(0) - await constrainedLocator.click() - await editor.expectEditor.toContain(expectAfterUnconstrained, { - shouldNormalise: true, - }) - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - x = hoverPos.x + Math.cos(ang * deg) * 32 - y = hoverPos.y - Math.sin(ang * deg) * 32 - await page.mouse.move(x, y) - await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) - await page.mouse.move(x, y) - - const unconstrainedLocator = page.locator( - `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` - ) - await expect(unconstrainedLocator).toBeVisible() - await unconstrainedLocator.hover() - await expect( - await page.getByTestId('constraint-symbol-popover').count() - ).toBeGreaterThan(0) - await unconstrainedLocator.click() - await expect( - page.getByTestId('cmd-bar-arg-value').getByRole('textbox') - ).toBeFocused() - await page - .getByRole('button', { - name: 'arrow right Continue', - }) - .click() - await expect(page.locator('.cm-content')).toContainText(expectFinal) - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - } - - /** - * Clicks on an unconstrained element - * @param {Page} page - The page to perform the action on - * @param {Object} options - The options for the action - * @param {Object} options.hoverPos - The position to hover over - * @param {Object} options.constraintType - The type of constraint - * @param {number} options.ang - The angle - * @param {number} options.steps - The number of steps to perform - */ - const _clickUnconstrained = - (page: Page, editor: EditorFixture) => - async ({ - hoverPos, - constraintType, - expectBeforeUnconstrained, - expectAfterUnconstrained, - expectFinal, - ang = 45, - steps = 5, - locator, - }: { - hoverPos: { x: number; y: number } - constraintType: - | 'horizontal' - | 'vertical' - | 'tangentialWithPrevious' - | LineInputsType - expectBeforeUnconstrained: string - expectAfterUnconstrained: string - expectFinal: string - ang?: number - steps?: number - locator?: string - }) => { - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - let x = 0, - y = 0 - x = hoverPos.x + Math.cos(ang * deg) * 32 - y = hoverPos.y - Math.sin(ang * deg) * 32 - await page.mouse.move(x, y) - await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) - await page.mouse.move(x, y) - - await expect(page.getByText('Added variable')).not.toBeVisible() - await editor.expectEditor.toContain(expectBeforeUnconstrained, { - shouldNormalise: true, - }) - const unconstrainedLocator = page.locator( - `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` - ) - await expect(unconstrainedLocator).toBeVisible() - await unconstrainedLocator.hover() - await expect( - await page.getByTestId('constraint-symbol-popover').count() - ).toBeGreaterThan(0) - await unconstrainedLocator.click() - await expect( - page.getByTestId('cmd-bar-arg-value').getByRole('textbox') - ).toBeFocused() - await page - .getByRole('button', { - name: 'arrow right Continue', - }) - .click() - await editor.expectEditor.toContain(expectAfterUnconstrained, { - shouldNormalise: true, - }) - await expect(page.getByText('Added variable')).not.toBeVisible() - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - x = hoverPos.x + Math.cos(ang * deg) * 32 - y = hoverPos.y - Math.sin(ang * deg) * 32 - await page.mouse.move(x, y) - await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) - await page.mouse.move(x, y) - - const constrainedLocator = page.locator( - `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` - ) - await expect(constrainedLocator).toBeVisible() - await constrainedLocator.hover() - await expect( - await page.getByTestId('constraint-symbol-popover').count() - ).toBeGreaterThan(0) - await constrainedLocator.click() - await editor.expectEditor.toContain(expectFinal, { - shouldNormalise: true, - }) - } - test.setTimeout(120000) - test('for segments [line, angledLine, xLineTo]', async ({ - page, - editor, - homePage, + test('Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', () => { + // TODO: fix this test on mac after the electron migration + test.fixme(orRunWhenFullSuiteEnabled()) + /** + * Clicks on an constrained element + * @param {Page} page - The page to perform the action on + * @param {Object} options - The options for the action + * @param {Object} options.hoverPos - The position to hover over + * @param {Object} options.constraintType - The type of constraint + * @param {number} options.ang - The angle + * @param {number} options.steps - The number of steps to perform + */ + const _clickConstrained = + (page: Page, editor: EditorFixture) => + async ({ + hoverPos, + constraintType, + expectBeforeUnconstrained, + expectAfterUnconstrained, + expectFinal, + ang = 45, + steps = 10, + locator, + }: { + hoverPos: { x: number; y: number } + constraintType: + | 'horizontal' + | 'vertical' + | 'tangentialWithPrevious' + | LineInputsType + expectBeforeUnconstrained: string + expectAfterUnconstrained: string + expectFinal: string + ang?: number + steps?: number + locator?: string }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + await expect(page.getByText('Added variable')).not.toBeVisible() + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + let x = 0, + y = 0 + x = hoverPos.x + Math.cos(ang * deg) * 32 + y = hoverPos.y - Math.sin(ang * deg) * 32 + await page.mouse.move(x, y) + await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) + await page.mouse.move(x, y) + + await editor.expectEditor.toContain(expectBeforeUnconstrained, { + shouldNormalise: true, + }) + const constrainedLocator = page.locator( + `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` + ) + await expect(constrainedLocator).toBeVisible() + await constrainedLocator.hover() + await expect( + await page.getByTestId('constraint-symbol-popover').count() + ).toBeGreaterThan(0) + await constrainedLocator.click() + await editor.expectEditor.toContain(expectAfterUnconstrained, { + shouldNormalise: true, + }) + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + x = hoverPos.x + Math.cos(ang * deg) * 32 + y = hoverPos.y - Math.sin(ang * deg) * 32 + await page.mouse.move(x, y) + await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) + await page.mouse.move(x, y) + + const unconstrainedLocator = page.locator( + `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` + ) + await expect(unconstrainedLocator).toBeVisible() + await unconstrainedLocator.hover() + await expect( + await page.getByTestId('constraint-symbol-popover').count() + ).toBeGreaterThan(0) + await unconstrainedLocator.click() + await expect( + page.getByTestId('cmd-bar-arg-value').getByRole('textbox') + ).toBeFocused() + await page + .getByRole('button', { + name: 'arrow right Continue', + }) + .click() + await expect(page.locator('.cm-content')).toContainText(expectFinal) + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + } + + /** + * Clicks on an unconstrained element + * @param {Page} page - The page to perform the action on + * @param {Object} options - The options for the action + * @param {Object} options.hoverPos - The position to hover over + * @param {Object} options.constraintType - The type of constraint + * @param {number} options.ang - The angle + * @param {number} options.steps - The number of steps to perform + */ + const _clickUnconstrained = + (page: Page, editor: EditorFixture) => + async ({ + hoverPos, + constraintType, + expectBeforeUnconstrained, + expectAfterUnconstrained, + expectFinal, + ang = 45, + steps = 5, + locator, + }: { + hoverPos: { x: number; y: number } + constraintType: + | 'horizontal' + | 'vertical' + | 'tangentialWithPrevious' + | LineInputsType + expectBeforeUnconstrained: string + expectAfterUnconstrained: string + expectFinal: string + ang?: number + steps?: number + locator?: string + }) => { + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + let x = 0, + y = 0 + x = hoverPos.x + Math.cos(ang * deg) * 32 + y = hoverPos.y - Math.sin(ang * deg) * 32 + await page.mouse.move(x, y) + await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) + await page.mouse.move(x, y) + + await expect(page.getByText('Added variable')).not.toBeVisible() + await editor.expectEditor.toContain(expectBeforeUnconstrained, { + shouldNormalise: true, + }) + const unconstrainedLocator = page.locator( + `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` + ) + await unconstrainedLocator.hover() + await expect( + await page.getByTestId('constraint-symbol-popover').count() + ).toBeGreaterThan(0) + await unconstrainedLocator.click() + await expect( + page.getByTestId('cmd-bar-arg-value').getByRole('textbox') + ).toBeFocused() + await page + .getByRole('button', { + name: 'arrow right Continue', + }) + .click() + await editor.expectEditor.toContain(expectAfterUnconstrained, { + shouldNormalise: true, + }) + await expect(page.getByText('Added variable')).not.toBeVisible() + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + x = hoverPos.x + Math.cos(ang * deg) * 32 + y = hoverPos.y - Math.sin(ang * deg) * 32 + await page.mouse.move(x, y) + await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) + await page.mouse.move(x, y) + + const constrainedLocator = page.locator( + `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` + ) + await expect(constrainedLocator).toBeVisible() + await constrainedLocator.hover() + await expect( + await page.getByTestId('constraint-symbol-popover').count() + ).toBeGreaterThan(0) + await constrainedLocator.click() + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) + } + test.setTimeout(120000) + test('for segments [line, angledLine, xLineTo]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5 + 0, 20 + 0], %) |> line(end = [0.5, -14 + 0]) - |> angledLine(angle = 3 + 0, length = 32 + 0 ) + |> angledLine(angle = 3 + 0, length = 32 + 0) |> line(endAbsolute = [5 + 33, 20 + 11.5 + 0]) |> xLine(endAbsolute = 5 + 9 - 5) |> yLine(endAbsolute = 20 + -10.77, tag = $a) |> xLine(length = 26.04) |> yLine(length = 21.14 + 0) |> angledLine(angle = 181 + 0, lengthX = 23.14) - |> angledLine(angle = -91, lengthX = 19 + 0) - |> angledLine(angle = 3 + 0, endAbsoluteX = 5 + 26) - |> angledLine(angle = 89, endAbsoluteY = 20 + 9.14 + 0) + |> angledLine(angle = -91, lengthY = 19 + 0) + |> angledLine(angle = 3 + 0, endAbsoluteX = 5 + 26) + |> angledLine(angle = 89, endAbsoluteY = 20 + 9.14 + 0) |> angledLineThatIntersects({ angle = 4.14, intersectTag = a, @@ -228,735 +231,253 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], %) ` - ) - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + ) + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() + await homePage.goToModelingScene() - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - await page.getByText('xLine(endAbsolute = 5 + 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) + await page.getByText('xLine(endAbsolute = 5 + 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) - await u.openAndClearDebugPanel() - await u.sendCustomCmd({ - type: 'modeling_cmd_req', - cmd_id: uuidv4(), - cmd: { - type: 'default_camera_look_at', - vantage: { x: 80, y: -1350, z: 510 }, - center: { x: 80, y: 0, z: 510 }, - up: { x: 0, y: 0, z: 1 }, - }, - }) - await page.waitForTimeout(100) - await u.sendCustomCmd({ - type: 'modeling_cmd_req', - cmd_id: uuidv4(), - cmd: { - type: 'default_camera_get_settings', - }, - }) - await page.waitForTimeout(100) - await u.closeDebugPanel() + await u.openAndClearDebugPanel() + await u.sendCustomCmd({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'default_camera_look_at', + vantage: { x: 80, y: -1350, z: 510 }, + center: { x: 80, y: 0, z: 510 }, + up: { x: 0, y: 0, z: 1 }, + }, + }) + await page.waitForTimeout(100) + await u.sendCustomCmd({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'default_camera_get_settings', + }, + }) + await page.waitForTimeout(100) + await u.closeDebugPanel() - let ang = 0 + let ang = 0 - const line = await u.getBoundingBox(`[data-overlay-index="${0}"]`) - ang = await u.getAngle(`[data-overlay-index="${0}"]`) - console.log('line1', line, ang) - await clickConstrained({ - hoverPos: { x: line.x, y: line.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: '|> line(end = [0.5, -14 + 0])', - expectAfterUnconstrained: '|> line(end = [0.5, -14])', - expectFinal: '|> line(end = [0.5, yRel001])', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="0"]', - }) - console.log('line2') - await clickUnconstrained({ - hoverPos: { x: line.x, y: line.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: '|> line(end = [0.5, yRel001])', - expectAfterUnconstrained: 'line(end = [xRel001, yRel001])', - expectFinal: '|> line(end = [0.5, yRel001])', - ang: ang + 180, - locator: '[data-overlay-index="0"]', - }) - - const angledLine = await u.getBoundingBox(`[data-overlay-index="1"]`) - ang = await u.getAngle(`[data-overlay-index="1"]`) - console.log('angledLine1') - await clickConstrained({ - hoverPos: { x: angledLine.x, y: angledLine.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLine(angle = 3 + 0, length = 32 + 0 )', - expectAfterUnconstrained: 'angledLine(angle = 3, length = 32 + 0 )', - expectFinal: 'angledLine(angle = angle001, length = 32 + 0 )', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="1"]', - }) - console.log('angledLine2') - await clickConstrained({ - hoverPos: { x: angledLine.x, y: angledLine.y }, - constraintType: 'length', - expectBeforeUnconstrained: - 'angledLine(angle = angle001, length = 32 + 0 )', - expectAfterUnconstrained: - 'angledLine(angle = angle001, length = 32 )', - expectFinal: 'angledLine(angle = angle001, length = len001 )', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="1"]', - }) - - await page.mouse.move(700, 250) - await page.waitForTimeout(100) - - let lineTo = await u.getBoundingBox(`[data-overlay-index="2"]`) - ang = await u.getAngle(`[data-overlay-index="2"]`) - console.log('lineTo1') - await clickConstrained({ - hoverPos: { x: lineTo.x, y: lineTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: - 'line(endAbsolute = [5 + 33, 20 + 11.5 + 0])', - expectAfterUnconstrained: 'line(endAbsolute = [5 + 33, 31.5])', - expectFinal: 'line(endAbsolute = [5 + 33, yAbs001])', - steps: 8, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="2"]', - }) - console.log('lineTo2') - await clickConstrained({ - hoverPos: { x: lineTo.x, y: lineTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'line(endAbsolute = [5 + 33, yAbs001])', - expectAfterUnconstrained: 'line(endAbsolute = [38, yAbs001])', - expectFinal: 'line(endAbsolute = [xAbs001, yAbs001])', - steps: 8, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="2"]', - }) - - const xLineTo = await u.getBoundingBox(`[data-overlay-index="3"]`) - ang = await u.getAngle(`[data-overlay-index="3"]`) - console.log('xlineTo1') - await clickConstrained({ - hoverPos: { x: xLineTo.x, y: xLineTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'xLine(endAbsolute = 5 + 9 - 5)', - expectAfterUnconstrained: 'xLine(endAbsolute = 9)', - expectFinal: 'xLine(endAbsolute = xAbs002)', - ang: ang + 180, - steps: 8, - locator: '[data-overlay-toolbar-index="3"]', - }) + const line = await u.getBoundingBox('[data-overlay-index="0"]') + ang = await u.getAngle('[data-overlay-index="0"]') + console.log('line1', line, ang) + await clickConstrained({ + hoverPos: { x: line.x, y: line.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: '|> line(end = [0.5, -14 + 0])', + expectAfterUnconstrained: '|> line(end = [0.5, -14])', + expectFinal: '|> line(end = [0.5, yRel001])', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('line2') + await clickUnconstrained({ + hoverPos: { x: line.x, y: line.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: '|> line(end = [0.5, yRel001])', + expectAfterUnconstrained: 'line(end = [xRel001, yRel001])', + expectFinal: '|> line(end = [0.5, yRel001])', + ang: ang + 180, + locator: '[data-overlay-index="0"]', }) - // Broken on main at time of writing! - test.fixme( - 'for segments [yLineTo, xLine]', - async ({ page, editor, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `yRel001 = -14 + const angledLine = await u.getBoundingBox('[data-overlay-index="1"]') + ang = await u.getAngle('[data-overlay-index="1"]') + console.log('angledLine1') + await clickConstrained({ + hoverPos: { x: angledLine.x, y: angledLine.y }, + constraintType: 'angle', + expectBeforeUnconstrained: 'angledLine(angle = 3 + 0, length = 32 + 0)', + expectAfterUnconstrained: 'angledLine(angle = 3, length = 32 + 0)', + expectFinal: 'angledLine(angle = angle001, length = 32 + 0)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="1"]', + }) + console.log('angledLine2') + await clickConstrained({ + hoverPos: { x: angledLine.x, y: angledLine.y }, + constraintType: 'length', + expectBeforeUnconstrained: + 'angledLine(angle = angle001, length = 32 + 0)', + expectAfterUnconstrained: 'angledLine(angle = angle001, length = 32)', + expectFinal: 'angledLine(angle = angle001, length = len001)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="1"]', + }) + + await page.mouse.move(700, 250) + await page.waitForTimeout(100) + + let lineTo = await u.getBoundingBox('[data-overlay-index="2"]') + ang = await u.getAngle('[data-overlay-index="2"]') + console.log('lineTo1') + await clickConstrained({ + hoverPos: { x: lineTo.x, y: lineTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: + 'line(endAbsolute = [5 + 33, 20 + 11.5 + 0])', + expectAfterUnconstrained: 'line(endAbsolute = [5 + 33, 31.5])', + expectFinal: 'line(endAbsolute = [5 + 33, yAbs001])', + steps: 8, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="2"]', + }) + console.log('lineTo2') + await clickConstrained({ + hoverPos: { x: lineTo.x, y: lineTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'line(endAbsolute = [5 + 33, yAbs001])', + expectAfterUnconstrained: 'line(endAbsolute = [38, yAbs001])', + expectFinal: 'line(endAbsolute = [xAbs001, yAbs001])', + steps: 8, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="2"]', + }) + + const xLineTo = await u.getBoundingBox('[data-overlay-index="3"]') + ang = await u.getAngle('[data-overlay-index="3"]') + console.log('xlineTo1') + await clickConstrained({ + hoverPos: { x: xLineTo.x, y: xLineTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'xLine(endAbsolute = 5 + 9 - 5)', + expectAfterUnconstrained: 'xLine(endAbsolute = 9)', + expectFinal: 'xLine(endAbsolute = xAbs002)', + ang: ang + 180, + steps: 8, + locator: '[data-overlay-toolbar-index="3"]', + }) + }) + + // Broken on main at time of writing! + test('for segments [yLineTo, xLine]', async ({ + page, + editor, + homePage, + }) => { + test.fixme(orRunWhenFullSuiteEnabled()) + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + yRel001 = -14 xRel001 = 0.5 angle001 = 3 len001 = 32 yAbs001 = 11.5 xAbs001 = 33 xAbs002 = 4 - part001 = startSketchOn('XZ') + part001 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> line(end = [0.5, yRel001]) - |> angledLine(angle = angle001, length = len001 ) + |> angledLine(angle = angle001, length = len001) |> line(endAbsolute = [33, yAbs001]) |> xLine(endAbsolute = xAbs002) |> yLine(endAbsolute = -10.77, tag = $a) |> xLine(length = 26.04) |> yLine(length = 21.14 + 0) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) + |> angledLine(angle = 181 + 0, lengthX = 23.14) ` - ) - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) + ) + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await homePage.goToModelingScene() + await homePage.goToModelingScene() - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() - await page.getByText('xLine(length = 26.04)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) + await page.getByText('xLine(length = 26.04)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) - await expect(page.getByTestId('segment-overlay')).toHaveCount(8) + await expect(page.getByTestId('segment-overlay')).toHaveCount(8) - const clickUnconstrained = _clickUnconstrained(page, editor) + const clickUnconstrained = _clickUnconstrained(page, editor) - await page.mouse.move(700, 250) - await page.waitForTimeout(100) + await page.mouse.move(700, 250) + await page.waitForTimeout(100) - let ang = 0 + let ang = 0 - const yLineTo = await u.getBoundingBox(`[data-overlay-index="4"]`) - ang = await u.getAngle(`[data-overlay-index="4"]`) - console.log('ylineTo1') - await clickUnconstrained({ - hoverPos: { x: yLineTo.x, y: yLineTo.y - 200 }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: 'yLine(endAbsolute = -10.77, tag = $a)', - expectAfterUnconstrained: 'yLine(endAbsolute = yAbs002, tag = $a)', - expectFinal: 'yLine(endAbsolute = -10.77, tag = $a)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="4"]', - }) + const yLineTo = await u.getBoundingBox('[data-overlay-index="4"]') + ang = await u.getAngle('[data-overlay-index="4"]') + console.log('ylineTo1') + await clickUnconstrained({ + hoverPos: { x: yLineTo.x, y: yLineTo.y - 200 }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: 'yLine(endAbsolute = -10.77, tag = $a)', + expectAfterUnconstrained: 'yLine(endAbsolute = yAbs002, tag = $a)', + expectFinal: 'yLine(endAbsolute = -10.77, tag = $a)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="4"]', + }) - const xLine = await u.getBoundingBox(`[data-overlay-index="5"]`) - ang = await u.getAngle(`[data-overlay-index="5"]`) - console.log('xline') - await clickUnconstrained({ - hoverPos: { x: xLine.x, y: xLine.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: 'xLine(length = 26.04)', - expectAfterUnconstrained: 'xLine(length = xRel002)', - expectFinal: 'xLine(length = 26.04)', - steps: 10, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="5"]', - }) - } - ) - test('for segments [yLine, angledLineOfXLength, angledLineOfYLength]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + const xLine = await u.getBoundingBox('[data-overlay-index="5"]') + ang = await u.getAngle('[data-overlay-index="5"]') + console.log('xline') + await clickUnconstrained({ + hoverPos: { x: xLine.x, y: xLine.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: 'xLine(length = 26.04)', + expectAfterUnconstrained: 'xLine(length = xRel002)', + expectFinal: 'xLine(length = 26.04)', + steps: 10, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="5"]', + }) + }) + test('for segments [yLine, angledLineOfXLength, angledLineOfYLength]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) - |> angledLine(angle = 3 + 0, length = 32 + 0 ) + |> angledLine(angle = 3 + 0, length = 32 + 0) |> line(endAbsolute = [33, 11.5 + 0]) |> xLine(endAbsolute = 9 - 5) |> yLine(endAbsolute = -10.77, tag = $a) |> xLine(length = 26.04) |> yLine(length = 21.14 + 0) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) - |> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %) - |> angledLine(angle = 3 + 0, endAbsoluteX = 26) - |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) + |> angledLine(angle = 181 + 0, lengthX = 23.14) + |> angledLine(angle = -91, lengthY = 19 + 0) + |> angledLine(angle = 3 + 0, endAbsoluteX = 26) + |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) |> angledLineThatIntersects({ angle = 4.14, intersectTag = a, offset = 9 }, %) |> tangentialArcTo([3.14 + 13, 3.14], %) - ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - await page.waitForTimeout(500) - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - let ang = 0 - - const yLine = await u.getBoundingBox(`[data-overlay-index="6"]`) - ang = await u.getAngle(`[data-overlay-index="6"]`) - console.log('yline1') - await clickConstrained({ - hoverPos: { x: yLine.x, y: yLine.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: 'yLine(length = 21.14 + 0)', - expectAfterUnconstrained: 'yLine(length = 21.14)', - expectFinal: 'yLine(length = yRel001)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="6"]', - }) - - const angledLineOfXLength = await u.getBoundingBox( - `[data-overlay-index="7"]` - ) - ang = await u.getAngle(`[data-overlay-index="7"]`) - console.log('angledLineOfXLength1') - await clickConstrained({ - hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)', - expectAfterUnconstrained: - 'angledLineOfXLength({ angle = -179, length = 23.14 }, %)', - expectFinal: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="7"]', - }) - console.log('angledLineOfXLength2') - await clickUnconstrained({ - hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, - constraintType: 'xRelative', - expectBeforeUnconstrained: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - expectAfterUnconstrained: - 'angledLineOfXLength({ angle = angle001, length = xRel001 }, %)', - expectFinal: - 'angledLineOfXLength({ angle = angle001, length = 23.14 }, %)', - steps: 7, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="7"]', - }) - - const angledLineOfYLength = await u.getBoundingBox( - `[data-overlay-index="8"]` - ) - ang = await u.getAngle(`[data-overlay-index="8"]`) - console.log('angledLineOfYLength1') - await clickUnconstrained({ - hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineOfYLength({ angle = angle002, length = 19 + 0 }, %)', - expectFinal: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - ang: ang + 180, - steps: 6, - locator: '[data-overlay-toolbar-index="8"]', - }) - console.log('angledLineOfYLength2') - await clickConstrained({ - hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, - constraintType: 'yRelative', - expectBeforeUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineOfYLength({ angle = -91, length = 19 }, %)', - expectFinal: - 'angledLineOfYLength({ angle = -91, length = yRel002 }, %)', - ang: ang + 180, - steps: 7, - locator: '[data-overlay-toolbar-index="8"]', - }) - }) - test('for segments [angledLineToX, angledLineToY, angledLineThatIntersects]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') - |> startProfileAt([0, 0], %) - |> line(end = [0.5, -14 + 0]) - |> angledLine(angle = 3 + 0, length = 32 + 0 ) - |> line(endAbsolute = [33, 11.5 + 0]) - |> xLine(endAbsolute = 9 - 5) - |> yLine(endAbsolute = -10.77, tag = $a) - |> xLine(length = 26.04) - |> yLine(length = 21.14 + 0) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) - |> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %) - |> angledLine(angle = 3 + 0, endAbsoluteX = 26) - |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) - |> angledLineThatIntersects({ - angle = 4.14, - intersectTag = a, - offset = 9 - }, %) - |> tangentialArcTo([3.14 + 13, 1.14], %) - ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - let ang = 0 - - const angledLineToX = await u.getBoundingBox(`[data-overlay-index="9"]`) - ang = await u.getAngle(`[data-overlay-index="9"]`) - console.log('angledLineToX') - await clickConstrained({ - hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLine(angle = 3 + 0, endAbsoluteX = 26)', - expectAfterUnconstrained: 'angledLine(angle = 3, endAbsoluteX = 26)', - expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="9"]', - }) - console.log('angledLineToX2') - await clickUnconstrained({ - hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: - 'angledLine(angle = angle001, endAbsoluteX = 26)', - expectAfterUnconstrained: - 'angledLine(angle = angle001, endAbsoluteX = xAbs001)', - expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="9"]', - }) - - const angledLineToY = await u.getBoundingBox( - `[data-overlay-index="10"]` - ) - ang = await u.getAngle(`[data-overlay-index="10"]`) - console.log('angledLineToY') - await clickUnconstrained({ - hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)', - expectAfterUnconstrained: - 'angledLine(angle = angle002, endAbsoluteY = 9.14 + 0)', - expectFinal: 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)', - steps: process.platform === 'darwin' ? 8 : 9, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="10"]', - }) - console.log('angledLineToY2') - await clickConstrained({ - hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: - 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)', - expectAfterUnconstrained: - 'angledLine(angle = 89, endAbsoluteY = 9.14)', - expectFinal: 'angledLine(angle = 89, endAbsoluteY = yAbs001)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="10"]', - }) - - const angledLineThatIntersects = await u.getBoundingBox( - `[data-overlay-index="11"]` - ) - ang = await u.getAngle(`[data-overlay-index="11"]`) - console.log('angledLineThatIntersects') - await clickUnconstrained({ - hoverPos: { - x: angledLineThatIntersects.x, - y: angledLineThatIntersects.y, - }, - constraintType: 'angle', - expectBeforeUnconstrained: `angledLineThatIntersects({ - angle = 4.14, - intersectTag = a, - offset = 9 - }, %)`, - expectAfterUnconstrained: `angledLineThatIntersects({ - angle = angle003, - intersectTag = a, - offset = 9 - }, %)`, - expectFinal: `angledLineThatIntersects({ - angle = -176, - offset = 9, - intersectTag = a - }, %)`, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="11"]', - }) - console.log('angledLineThatIntersects2') - await clickUnconstrained({ - hoverPos: { - x: angledLineThatIntersects.x, - y: angledLineThatIntersects.y, - }, - constraintType: 'intersectionOffset', - expectBeforeUnconstrained: `angledLineThatIntersects({ - angle = -176, - offset = 9, - intersectTag = a - }, %)`, - expectAfterUnconstrained: `angledLineThatIntersects({ - angle = -176, - offset = perpDist001, - intersectTag = a - }, %)`, - expectFinal: `angledLineThatIntersects({ - angle = -176, - offset = 9, - intersectTag = a - }, %)`, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="11"]', - }) - }) - test('for segment [tangentialArcTo]', async ({ - page, - editor, - homePage, - }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') - |> startProfileAt([0, 0], %) - |> line(end = [0.5, -14 + 0]) - |> angledLine(angle = 3 + 0, length = 32 + 0 ) - |> line(endAbsolute = [33, 11.5 + 0]) - |> xLine(endAbsolute = 9 - 5) - |> yLine(endAbsolute = -10.77, tag = $a) - |> xLine(length = 26.04) - |> yLine(length = 21.14 + 0) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) - |> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %) - |> angledLine(angle = 3 + 0, endAbsoluteX = 26) - |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) - |> angledLineThatIntersects({ - angle = 4.14, - intersectTag = a, - offset = 9 - }, %) - |> tangentialArcTo([3.14 + 13, -3.14], %) - ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - - await page.getByText('xLine(endAbsolute = 9 - 5)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(13) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - const tangentialArcTo = await u.getBoundingBox( - '[data-overlay-index="12"]' - ) - let ang = await u.getAngle('[data-overlay-index="12"]') - console.log('tangentialArcTo') - await clickConstrained({ - hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], %)', - expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], %)', - expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', - ang: ang + 180, - steps: 6, - locator: '[data-overlay-toolbar-index="12"]', - }) - console.log('tangentialArcTo2') - await clickUnconstrained({ - hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], %)', - expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], %)', - expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', - ang: ang + 180, - steps: 10, - locator: '[data-overlay-toolbar-index="12"]', - }) - }) - test('for segment [circle]', async ({ page, editor, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') - |> circle(center = [1 + 0, 0], radius = 8) - ` - ) - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - - // wait for execution done - await u.openDebugPanel() - await u.expectCmdLog('[data-message-type="execution-done"]') - await u.closeDebugPanel() - - await page.getByText('circle(center = [1 + 0, 0], radius = 8)').click() - await page.waitForTimeout(100) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.waitForTimeout(500) - - await expect(page.getByTestId('segment-overlay')).toHaveCount(1) - - const clickUnconstrained = _clickUnconstrained(page, editor) - const clickConstrained = _clickConstrained(page, editor) - - const hoverPos = { x: 789, y: 114 } as const - let ang = await u.getAngle('[data-overlay-index="0"]') - console.log('angl', ang) - console.log('circle center x') - await clickConstrained({ - hoverPos, - constraintType: 'xAbsolute', - expectBeforeUnconstrained: 'circle(center = [1 + 0, 0], radius = 8)', - expectAfterUnconstrained: 'circle(center = [1, 0], radius = 8)', - expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', - ang: ang + 105, - steps: 6, - locator: '[data-overlay-toolbar-index="0"]', - }) - console.log('circle center y') - await clickUnconstrained({ - hoverPos, - constraintType: 'yAbsolute', - expectBeforeUnconstrained: - 'circle(center = [xAbs001, 0], radius = 8)', - expectAfterUnconstrained: - 'circle(center = [xAbs001, yAbs001], radius = 8)', - expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', - ang: ang + 180, - steps: 30, - locator: '[data-overlay-toolbar-index="0"]', - }) - console.log('circle radius') - await clickUnconstrained({ - hoverPos, - constraintType: 'radius', - expectBeforeUnconstrained: - 'circle(center = [xAbs001, 0], radius = 8)', - expectAfterUnconstrained: - 'circle(center = [xAbs001, 0], radius = radius001)', - expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', - ang: ang + 105, - steps: 10, - locator: '[data-overlay-toolbar-index="0"]', - }) - }) - } - ) - test.describe('Testing deleting a segment', () => { - const _deleteSegmentSequence = - (page: Page, editor: EditorFixture) => - async ({ - hoverPos, - codeToBeDeleted, - stdLibFnName, - ang = 45, - steps = 6, - locator, - }: { - hoverPos: { x: number; y: number } - codeToBeDeleted: string - stdLibFnName: string - ang?: number - steps?: number - locator?: string - }) => { - await expect(page.getByText('Added variable')).not.toBeVisible() - - await page.mouse.move(0, 0) - await page.waitForTimeout(1000) - let x = 0, - y = 0 - x = hoverPos.x + Math.cos(ang * deg) * 32 - y = hoverPos.y - Math.sin(ang * deg) * 32 - await page.mouse.move(x, y) - await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) - await page.mouse.move(x, y) - - await editor.expectEditor.toContain(codeToBeDeleted, { - shouldNormalise: true, - }) - - await page.locator(`[data-stdlib-fn-name="${stdLibFnName}"]`).click() - await page.getByText('Delete Segment').click() - - await editor.expectEditor.not.toContain(codeToBeDeleted, { - shouldNormalise: true, - }) - } - test('all segment types', async ({ page, editor, homePage }) => { - await page.addInitScript(async () => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') - |> startProfileAt([0, 0], %) - |> line(end = [0.5, -14 + 0]) - |> angledLine(angle = 3 + 0, length = 32 + 0 ) - |> line(endAbsolute = [33, 11.5 + 0]) - |> xLine(endAbsolute = 9 - 5) - |> yLine(endAbsolute = -10.77, tag = $a) - |> xLine(length = 26.04) - |> yLine(length = 21.14 + 0) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) - |> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %) - |> angledLine(angle = 3 + 0, endAbsoluteX = 26) - |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) - |> angledLineThatIntersects({ - angle = 4.14, - intersectTag = a, - offset = 9 - }, %) - |> tangentialArcTo([3.14 + 13, 1.14], %) ` ) localStorage.setItem('disableAxis', 'true') @@ -965,7 +486,131 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.setBodyDimensions({ width: 1200, height: 500 }) await homePage.goToModelingScene() - await u.waitForPageLoad() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + await page.waitForTimeout(500) + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + let ang = 0 + + const yLine = await u.getBoundingBox('[data-overlay-index="6"]') + ang = await u.getAngle('[data-overlay-index="6"]') + console.log('yline1') + await clickConstrained({ + hoverPos: { x: yLine.x, y: yLine.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: 'yLine(length = 21.14 + 0)', + expectAfterUnconstrained: 'yLine(length = 21.14)', + expectFinal: 'yLine(length = yRel001)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="6"]', + }) + + const angledLineOfXLength = await u.getBoundingBox( + '[data-overlay-index="7"]' + ) + ang = await u.getAngle('[data-overlay-index="7"]') + console.log('angledLineOfXLength1') + await clickConstrained({ + hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLine(angle = 181 + 0, lengthX = 23.14)', + expectAfterUnconstrained: 'angledLine(angle = -179, lengthX = 23.14)', + expectFinal: 'angledLine(angle = angle001, lengthX = 23.14)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="7"]', + }) + console.log('angledLineOfXLength2') + await clickUnconstrained({ + hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y }, + constraintType: 'xRelative', + expectBeforeUnconstrained: + 'angledLine(angle = angle001, lengthX = 23.14)', + expectAfterUnconstrained: + 'angledLine(angle = angle001, lengthX = xRel001)', + expectFinal: 'angledLine(angle = angle001, lengthX = 23.14)', + steps: 7, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="7"]', + }) + + const angledLineOfYLength = await u.getBoundingBox( + '[data-overlay-index="8"]' + ) + ang = await u.getAngle('[data-overlay-index="8"]') + console.log('angledLineOfYLength1') + await clickUnconstrained({ + hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, + constraintType: 'angle', + expectBeforeUnconstrained: 'angledLine(angle = -91, lengthY = 19 + 0)', + expectAfterUnconstrained: + 'angledLine(angle = angle002, lengthY = 19 + 0)', + expectFinal: 'angledLine(angle = -91, lengthY = 19 + 0)', + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="8"]', + }) + console.log('angledLineOfYLength2') + await clickConstrained({ + hoverPos: { x: angledLineOfYLength.x, y: angledLineOfYLength.y }, + constraintType: 'yRelative', + expectBeforeUnconstrained: 'angledLine(angle = -91, lengthY = 19 + 0)', + expectAfterUnconstrained: 'angledLine(angle = -91, lengthY = 19)', + expectFinal: 'angledLine(angle = -91, lengthY = yRel002)', + ang: ang + 180, + steps: 7, + locator: '[data-overlay-toolbar-index="8"]', + }) + }) + test('for segments [angledLineToX, angledLineToY, angledLineThatIntersects]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) + |> startProfileAt([0, 0], %) + |> line(end = [0.5, -14 + 0]) + |> angledLine(angle = 3 + 0, length = 32 + 0) + |> line(endAbsolute = [33, 11.5 + 0]) + |> xLine(endAbsolute = 9 - 5) + |> yLine(endAbsolute = -10.77, tag = $a) + |> xLine(length = 26.04) + |> yLine(length = 21.14 + 0) + |> angledLine(angle = 181 + 0, lengthX = 23.14) + |> angledLine(angle = -91, lengthY = 19 + 0) + |> angledLine(angle = 3 + 0, endAbsoluteX = 26) + |> angledLine(angle = 89, endAbsoluteY = 9.14 + 0) + |> angledLineThatIntersects({ + angle = 4.14, + intersectTag = a, + offset = 9 + }, %) + |> tangentialArcTo([3.14 + 13, 1.14], %) + ` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() // wait for execution done await u.openDebugPanel() @@ -978,14 +623,542 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.waitForTimeout(500) await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + let ang = 0 + + const angledLineToX = await u.getBoundingBox('[data-overlay-index="9"]') + ang = await u.getAngle('[data-overlay-index="9"]') + console.log('angledLineToX') + await clickConstrained({ + hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, + constraintType: 'angle', + expectBeforeUnconstrained: + 'angledLine(angle = 3 + 0, endAbsoluteX = 26)', + expectAfterUnconstrained: 'angledLine(angle = 3, endAbsoluteX = 26)', + expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="9"]', + }) + console.log('angledLineToX2') + await clickUnconstrained({ + hoverPos: { x: angledLineToX.x, y: angledLineToX.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: + 'angledLine(angle = angle001, endAbsoluteX = 26)', + expectAfterUnconstrained: + 'angledLine(angle = angle001, endAbsoluteX = xAbs001)', + expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="9"]', + }) + + const angledLineToY = await u.getBoundingBox('[data-overlay-index="10"]') + ang = await u.getAngle('[data-overlay-index="10"]') + console.log('angledLineToY') + await clickUnconstrained({ + hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, + constraintType: 'angle', + expectBeforeUnconstrained: 'angledLine(angle = 89, to = 9.14 + 0)', + expectAfterUnconstrained: 'angledLine(angle = angle002, to = 9.14 + 0)', + expectFinal: 'angledLine(angle = 89, to = 9.14 + 0)', + steps: process.platform === 'darwin' ? 8 : 9, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="10"]', + }) + console.log('angledLineToY2') + await clickConstrained({ + hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: + 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)', + expectAfterUnconstrained: 'angledLine(angle = 89, endAbsoluteY = 9.14)', + expectFinal: 'angledLine(angle = 89, endAbsoluteY = yAbs001)', + ang: ang + 180, + locator: '[data-overlay-toolbar-index="10"]', + }) + + const angledLineThatIntersects = await u.getBoundingBox( + '[data-overlay-index="11"]' + ) + ang = await u.getAngle('[data-overlay-index="11"]') + console.log('angledLineThatIntersects') + await clickUnconstrained({ + hoverPos: { + x: angledLineThatIntersects.x, + y: angledLineThatIntersects.y, + }, + constraintType: 'angle', + expectBeforeUnconstrained: `angledLineThatIntersects({ + angle = 4.14, + intersectTag = a, + offset = 9 + }, %)`, + expectAfterUnconstrained: `angledLineThatIntersects({ + angle = angle003, + intersectTag = a, + offset = 9 + }, %)`, + expectFinal: `angledLineThatIntersects({ + angle = -176, + offset = 9, + intersectTag = a + }, %)`, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="11"]', + }) + console.log('angledLineThatIntersects2') + await clickUnconstrained({ + hoverPos: { + x: angledLineThatIntersects.x, + y: angledLineThatIntersects.y, + }, + constraintType: 'intersectionOffset', + expectBeforeUnconstrained: `angledLineThatIntersects({ + angle = -176, + offset = 9, + intersectTag = a + }, %)`, + expectAfterUnconstrained: `angledLineThatIntersects({ + angle = -176, + offset = perpDist001, + intersectTag = a + }, %)`, + expectFinal: `angledLineThatIntersects({ + angle = -176, + offset = 9, + intersectTag = a + }, %)`, + ang: ang + 180, + locator: '[data-overlay-toolbar-index="11"]', + }) + }) + test('for segment [tangentialArcTo]', async ({ + page, + editor, + homePage, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) + |> startProfileAt([0, 0], %) + |> line(end = [0.5, -14 + 0]) + |> angledLine(angle = 3 + 0, length = 32 + 0) + |> line(endAbsolute = [33, 11.5 + 0]) + |> xLine(endAbsolute = 9 - 5) + |> yLine(endAbsolute = -10.77, tag = $a) + |> xLine(length = 26.04) + |> yLine(length = 21.14 + 0) + |> angledLine(angle = 181 + 0, lengthX = 23.14) + |> angledLine(angle = -91, lengthY = 19 + 0) + |> angledLineToX({ angle = 3 + 0, to = 26 }, %) + |> angledLineToY({ angle = 89, to = 9.14 + 0 }, %) + |> angledLineThatIntersects({ + angle = 4.14, + intersectTag = a, + offset = 9 + }, %) + |> tangentialArcTo([3.14 + 13, -3.14], %) + ` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + const tangentialArcTo = await u.getBoundingBox( + '[data-overlay-index="12"]' + ) + let ang = await u.getAngle('[data-overlay-index="12"]') + console.log('tangentialArcTo') + await clickConstrained({ + hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], %)', + expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], %)', + expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="12"]', + }) + console.log('tangentialArcTo2') + await clickUnconstrained({ + hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], %)', + expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], %)', + expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)', + ang: ang + 180, + steps: 10, + locator: '[data-overlay-toolbar-index="12"]', + }) + }) + test('for segment [arcTo]', async ({ + page, + editor, + homePage, + scene, + cmdBar, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) +profile001 = startProfileAt([56.37, 120.33], sketch001) + |> line(end = [162.86, 106.48]) + |> arcTo({ + interior = [360.16, 231.76], + end = [391.48, 131.54] + }, %) + |> yLine(-131.54, %) + |> arc({ + radius = 126.46, + angleStart = 33.53, + angleEnd = -141.07 + }, %) +` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + await scene.connectionEstablished() + await scene.settled(cmdBar) + + // wait for execution done + + await page.getByText('line(end = [162.86, 106.48])').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(5) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + const arcTo = await u.getBoundingBox('[data-overlay-index="1"]') + let ang = await u.getAngle('[data-overlay-index="1"]') + console.log('arcTo interior x') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: `arcTo({ + interior = [360.16, 231.76], + end = [391.48, 131.54] + }, %)`, + expectAfterUnconstrained: `arcTo({ + interior = [360.16, 231.76], + end = [391.48, 131.54] + }, %)`, + expectFinal: `arcTo({ + interior = [xAbs001, 231.76], + end = [391.48, 131.54] + }, %)`, + ang: ang, + steps: 6, + locator: '[data-overlay-toolbar-index="1"]', + }) + + console.log('arcTo interior y') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: `arcTo({ + interior = [xAbs001, 231.76], + end = [391.48, 131.54] + }, %)`, + expectAfterUnconstrained: `arcTo({ + interior = [xAbs001, yAbs001], + end = [391.48, 131.54] + }, %)`, + expectFinal: `arcTo({ + interior = [xAbs001, 231.76], + end = [391.48, 131.54] + }, %)`, + ang: ang, + steps: 10, + locator: '[data-overlay-toolbar-index="1"]', + }) + + console.log('arcTo end x') + await clickConstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: `arcTo({ + interior = [xAbs001, 231.76], + end = [391.48, 131.54] + }, %)`, + expectAfterUnconstrained: `arcTo({ + interior = [xAbs001, 231.76], + end = [391.48, 131.54] + }, %)`, + expectFinal: `arcTo({ + interior = [xAbs001, 231.76], + end = [xAbs002, 131.54] + }, %)`, + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="1"]', + }) + + console.log('arcTo end y') + await clickUnconstrained({ + hoverPos: { x: arcTo.x, y: arcTo.y }, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: `arcTo({ + interior = [xAbs001, 231.76], + end = [xAbs002, 131.54] + }, %)`, + expectAfterUnconstrained: `arcTo({ + interior = [xAbs001, 231.76], + end = [xAbs002, yAbs002] + }, %)`, + expectFinal: `arcTo({ + interior = [xAbs001, 231.76], + end = [xAbs002, 131.54] + }, %)`, + ang: ang + 180, + steps: 10, + locator: '[data-overlay-toolbar-index="1"]', + }) + }) + test('for segment [circle]', async ({ page, editor, homePage }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) +part001 = startSketchOn(XZ) + |> circle(center = [1 + 0, 0], radius = 8) + ` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + + await page.getByText('circle(center = [1 + 0, 0], radius = 8)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(1) + + const clickUnconstrained = _clickUnconstrained(page, editor) + const clickConstrained = _clickConstrained(page, editor) + + const hoverPos = { x: 789, y: 114 } as const + let ang = await u.getAngle('[data-overlay-index="0"]') + console.log('angl', ang) + console.log('circle center x') + await clickConstrained({ + hoverPos, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: 'circle(center = [1 + 0, 0], radius = 8)', + expectAfterUnconstrained: 'circle(center = [1, 0], radius = 8)', + expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', + ang: ang + 105, + steps: 6, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('circle center y') + await clickUnconstrained({ + hoverPos, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: 'circle(center = [xAbs001, 0], radius = 8)', + expectAfterUnconstrained: + 'circle(center = [xAbs001, yAbs001], radius = 8)', + expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', + ang: ang + 180, + steps: 30, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('circle radius') + await clickUnconstrained({ + hoverPos, + constraintType: 'radius', + expectBeforeUnconstrained: 'circle(center = [xAbs001, 0], radius = 8)', + expectAfterUnconstrained: + 'circle(center = [xAbs001, 0], radius = radius001)', + expectFinal: 'circle(center = [xAbs001, 0], radius = 8)', + ang: ang + 105, + steps: 10, + locator: '[data-overlay-toolbar-index="0"]', + }) + }) + }) + test.describe('Testing deleting a segment', () => { + const _deleteSegmentSequence = + (page: Page, editor: EditorFixture) => + async ({ + hoverPos, + codeToBeDeleted, + stdLibFnName, + ang = 45, + steps = 6, + locator, + }: { + hoverPos: { x: number; y: number } + codeToBeDeleted: string + stdLibFnName: string + ang?: number + steps?: number + locator?: string + }) => { + await expect(page.getByText('Added variable')).not.toBeVisible() + + await page.mouse.move(0, 0) + await page.waitForTimeout(1000) + let x = 0, + y = 0 + x = hoverPos.x + Math.cos(ang * deg) * 32 + y = hoverPos.y - Math.sin(ang * deg) * 32 + await page.mouse.move(x, y) + await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) + await page.mouse.move(x, y) + + await editor.expectEditor.toContain(codeToBeDeleted, { + shouldNormalise: true, + }) + + await page + .locator(`[data-stdlib-fn-name="${stdLibFnName}"]`) + .first() + .click() + await page.getByText('Delete Segment').click() + + await editor.expectEditor.not.toContain(codeToBeDeleted, { + shouldNormalise: true, + }) + } + test('all segment types', async ({ + page, + editor, + homePage, + scene, + cmdBar, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) +part001 = startSketchOn(XZ) + |>startProfileAt([0, 0], %) + |> line(end = [0.5, -14 + 0]) + |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) + |> line(endAbsolute = [33, 11.5 + 0]) + |> xLine(endAbsolute = 9 - 5) + |> yLine(endAbsolute = -10.77, tag = $a) + |> xLine(length = 26.04) + |> yLine(length = 21.14 + 0) + |> angledLine(angle = 181 + 0, lengthX = 23.14) + |> angledLine(angle = -91, lengthY = 19 + 0) + |> angledLineToX({ angle = 3 + 0, to = 26 }, %) + |> angledLineToY({ angle = 89, to = 9.14 + 0 }, %) + |> angledLineThatIntersects({ + angle = 4.14, + intersectTag = a, + offset = 9 + }, %) + |> tangentialArcTo([3.14 + 13, 1.14], %) + |> arcTo({ + interior = [16.25, 5.12], + end = [21.61, 4.15] + }, %) + |> arc({ + radius = 9.03, + angleStart = 40.27, + angleEnd = -38.05 + }, %) + + ` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + await scene.connectionEstablished() + await scene.settled(cmdBar) + await u.waitForPageLoad() + + await page.getByText('xLine(endAbsolute = 9 - 5)').click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(16) const deleteSegmentSequence = _deleteSegmentSequence(page, editor) let segmentToDelete const getOverlayByIndex = (index: number) => u.getBoundingBox(`[data-overlay-index="${index}"]`) + + segmentToDelete = await getOverlayByIndex(14) + let ang = await u.getAngle('[data-overlay-index="14"]') + + await editor.scrollToText('angleEnd') + + await deleteSegmentSequence({ + hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, + codeToBeDeleted: `arc({ + radius = 9.03, + angleStart = 40.27, + angleEnd = -38.05 + }, %)`, + stdLibFnName: 'arc', + ang: ang + 180, + steps: 6, + locator: '[data-overlay-toolbar-index="14"]', + }) + segmentToDelete = await getOverlayByIndex(13) + ang = await u.getAngle('[data-overlay-index="13"]') + await deleteSegmentSequence({ + hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, + codeToBeDeleted: `arcTo({ + interior = [16.25, 5.12], + end = [21.61, 4.15] + }, %)`, + stdLibFnName: 'arcTo', + ang: ang, + steps: 6, + locator: '[data-overlay-toolbar-index="13"]', + }) segmentToDelete = await getOverlayByIndex(12) - let ang = await u.getAngle(`[data-overlay-index="${12}"]`) + ang = await u.getAngle('[data-overlay-index="12"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'tangentialArcTo([3.14 + 13, 1.14], %)', @@ -996,7 +1169,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(11) - ang = await u.getAngle(`[data-overlay-index="${11}"]`) + ang = await u.getAngle('[data-overlay-index="11"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: `angledLineThatIntersects({ @@ -1011,27 +1184,27 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(10) - ang = await u.getAngle(`[data-overlay-index="${10}"]`) + ang = await u.getAngle('[data-overlay-index="10"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, - codeToBeDeleted: 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)', + codeToBeDeleted: 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', stdLibFnName: 'angledLineToY', ang: ang + 180, locator: '[data-overlay-toolbar-index="10"]', }) segmentToDelete = await getOverlayByIndex(9) - ang = await u.getAngle(`[data-overlay-index="${9}"]`) + ang = await u.getAngle('[data-overlay-index="9"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, - codeToBeDeleted: 'angledLine(angle = 3 + 0, endAbsoluteX = 26)', + codeToBeDeleted: 'angledLineToX({ angle = 3 + 0, to = 26 }, %)', stdLibFnName: 'angledLineToX', ang: ang + 180, locator: '[data-overlay-toolbar-index="9"]', }) segmentToDelete = await getOverlayByIndex(8) - ang = await u.getAngle(`[data-overlay-index="${8}"]`) + ang = await u.getAngle('[data-overlay-index="8"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: @@ -1042,18 +1215,17 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(7) - ang = await u.getAngle(`[data-overlay-index="${7}"]`) + ang = await u.getAngle('[data-overlay-index="7"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, - codeToBeDeleted: - 'angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)', + codeToBeDeleted: 'angledLine(angle = 181 + 0, lengthX = 23.14)', stdLibFnName: 'angledLineOfXLength', ang: ang + 180, locator: '[data-overlay-toolbar-index="7"]', }) segmentToDelete = await getOverlayByIndex(6) - ang = await u.getAngle(`[data-overlay-index="${6}"]`) + ang = await u.getAngle('[data-overlay-index="6"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'yLine(length = 21.14 + 0)', @@ -1063,7 +1235,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(5) - ang = await u.getAngle(`[data-overlay-index="${5}"]`) + ang = await u.getAngle('[data-overlay-index="5"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'xLine(length = 26.04)', @@ -1073,7 +1245,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(4) - ang = await u.getAngle(`[data-overlay-index="${4}"]`) + ang = await u.getAngle('[data-overlay-index="4"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'yLine(endAbsolute = -10.77, tag = $a)', @@ -1083,7 +1255,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(3) - ang = await u.getAngle(`[data-overlay-index="${3}"]`) + ang = await u.getAngle('[data-overlay-index="3"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'xLine(endAbsolute = 9 - 5)', @@ -1093,7 +1265,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(2) - ang = await u.getAngle(`[data-overlay-index="${2}"]`) + ang = await u.getAngle('[data-overlay-index="2"]') await expect(page.getByText('Added variable')).not.toBeVisible() const hoverPos = { x: segmentToDelete.x, y: segmentToDelete.y } @@ -1126,17 +1298,17 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }) segmentToDelete = await getOverlayByIndex(1) - ang = await u.getAngle(`[data-overlay-index="${1}"]`) + ang = await u.getAngle('[data-overlay-index="1"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, - codeToBeDeleted: 'angledLine(angle = 3 + 0, length = 32 + 0 )', + codeToBeDeleted: 'angledLine({ angle = 3 + 0, length = 32 + 0 }, %)', stdLibFnName: 'angledLine', ang: ang + 180, locator: '[data-overlay-toolbar-index="1"]', }) segmentToDelete = await getOverlayByIndex(0) - ang = await u.getAngle(`[data-overlay-index="${0}"]`) + ang = await u.getAngle('[data-overlay-index="0"]') await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'line(end = [0.5, -14 + 0])', @@ -1150,134 +1322,135 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { test.describe('Testing delete with dependent segments', () => { const cases = [ 'line(end = [22, 2], tag = $seg01)', - 'angledLine(angle = 5, length = 23.03, tag = $seg01)', + 'angledLine([5, 23.03], %, $seg01)', 'xLine(length = 23, tag = $seg01)', 'yLine(length = -8, tag = $seg01)', 'xLine(endAbsolute = 30, tag = $seg01)', 'yLine(endAbsolute = -4, tag = $seg01)', 'angledLine(angle = 3, lengthX = 30, tag = $seg01)', - 'angledLineOfXLength({ angle = 3, length = 30 }, %, $seg01)', 'angledLine(angle = 3, lengthY = 1.5, tag = $seg01)', - 'angledLineOfYLength({ angle = 3, length = 1.5 }, %, $seg01)', - 'angledLine(angle = 3, endAbsoluteX = 30, tag = $seg01)', - 'angledLine(angle = 3, endAbsoluteX = 30, tag = $seg01)', - 'angledLine(angle = 3, endAbsoluteY = 7, tag = $seg01)', - 'angledLine(angle = 3, endAbsoluteY = 7, tag = $seg01)', + 'angledLineToX([3, 30], %, $seg01)', + 'angledLineToX({ angle = 3, to = 30 }, %, $seg01)', + 'angledLineToY([3, 7], %, $seg01)', + 'angledLineToY({ angle = 3, to = 7 }, %, $seg01)', ] for (const doesHaveTagOutsideSketch of [true, false]) { for (const lineOfInterest of cases) { const isObj = lineOfInterest.includes('{ angle = 3,') - test(`${lineOfInterest.split('=')[0]}${isObj ? '-[obj-input]' : ''}${doesHaveTagOutsideSketch ? '-[tagOutsideSketch]' : '' - }`, async ({ page, editor, homePage }) => { - await page.addInitScript( - async ({ lineToBeDeleted, extraLine }) => { - localStorage.setItem( - 'persistCode', - `part001 = startSketchOn('XZ') + test(`${lineOfInterest.split('=')[0]}${isObj ? '-[obj-input]' : ''}${ + doesHaveTagOutsideSketch ? '-[tagOutsideSketch]' : '' + }`, async ({ page, editor, homePage }) => { + await page.addInitScript( + async ({ lineToBeDeleted, extraLine }) => { + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5, 6], %) |> ${lineToBeDeleted} |> line(end = [-10, -15]) - |> angledLine(angle = -176, length = segLen(seg01)) + |> angledLine([-176, segLen(seg01)], %) ${extraLine ? 'myVar = segLen(seg01)' : ''}` - ) - }, - { - lineToBeDeleted: lineOfInterest, - extraLine: doesHaveTagOutsideSketch, + ) + }, + { + lineToBeDeleted: lineOfInterest, + extraLine: doesHaveTagOutsideSketch, + } + ) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) + + await homePage.goToModelingScene() + await u.waitForPageLoad() + await page.waitForTimeout(1000) + + await expect + .poll(async () => { + await editor.scrollToText(lineOfInterest) + await page.waitForTimeout(1000) + await page.keyboard.press('ArrowRight') + await page.waitForTimeout(500) + await page.keyboard.press('ArrowLeft') + await page.waitForTimeout(500) + try { + await expect( + page.getByRole('button', { name: 'Edit Sketch' }) + ).toBeVisible() + return true + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_e) { + return false } - ) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) - - await homePage.goToModelingScene() - await u.waitForPageLoad() - await page.waitForTimeout(1000) - - await expect - .poll(async () => { - await editor.scrollToText(lineOfInterest) - await page.waitForTimeout(1000) - await page.keyboard.press('ArrowRight') - await page.waitForTimeout(500) - await page.keyboard.press('ArrowLeft') - await page.waitForTimeout(500) - try { - await expect( - page.getByRole('button', { name: 'Edit Sketch' }) - ).toBeVisible() - return true - } catch (_) { - return false - } - }) - .toBe(true) - await page.getByRole('button', { name: 'Edit Sketch' }).click() - - await expect(page.getByTestId('segment-overlay')).toHaveCount(3) - const segmentToDelete = await u.getBoundingBox( - `[data-overlay-index="0"]` - ) - - const isYLine = lineOfInterest.toLowerCase().includes('yline') - const hoverPos = { - x: segmentToDelete.x + (isYLine ? 0 : -20), - y: segmentToDelete.y + (isYLine ? -20 : 0), - } - await expect(page.getByText('Added variable')).not.toBeVisible() - const ang = isYLine ? 45 : -45 - const [x, y] = [ - Math.cos((ang * Math.PI) / 180) * 45, - Math.sin((ang * Math.PI) / 180) * 45, - ] - - await page.mouse.move(hoverPos.x + x, hoverPos.y + y) - await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) - - await editor.expectEditor.toContain(lineOfInterest, { - shouldNormalise: true, }) + .toBe(true) + await page.getByRole('button', { name: 'Edit Sketch' }).click() - await page.getByTestId('overlay-menu').click() - await page.waitForTimeout(100) - await page.getByText('Delete Segment').click() + await expect(page.getByTestId('segment-overlay')).toHaveCount(3) + const segmentToDelete = await u.getBoundingBox( + `[data-overlay-index="0"]` + ) - await page.getByText('Cancel').click() + const isYLine = lineOfInterest.toLowerCase().includes('yline') + const hoverPos = { + x: segmentToDelete.x + (isYLine ? 0 : -20), + y: segmentToDelete.y + (isYLine ? -20 : 0), + } + await expect(page.getByText('Added variable')).not.toBeVisible() + const ang = isYLine ? 45 : -45 + const [x, y] = [ + Math.cos((ang * Math.PI) / 180) * 45, + Math.sin((ang * Math.PI) / 180) * 45, + ] - await page.mouse.move(hoverPos.x + x, hoverPos.y + y) - await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) + await page.mouse.move(hoverPos.x + x, hoverPos.y + y) + await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) - await editor.expectEditor.toContain(lineOfInterest, { - shouldNormalise: true, - }) - - await page.getByTestId('overlay-menu').click() - await page.waitForTimeout(100) - await page.getByText('Delete Segment').click() - - await page.getByText('Continue and unconstrain').last().click() - - if (doesHaveTagOutsideSketch) { - // eslint-disable-next-line jest/no-conditional-expect - await expect( - page.getByText( - 'Segment tag used outside of current Sketch. Could not delete.' - ) - ).toBeTruthy() - // eslint-disable-next-line jest/no-conditional-expect - await editor.expectEditor.toContain(lineOfInterest, { - shouldNormalise: true, - }) - } else { - // eslint-disable-next-line jest/no-conditional-expect - await editor.expectEditor.not.toContain(lineOfInterest, { - shouldNormalise: true, - }) - // eslint-disable-next-line jest/no-conditional-expect - await editor.expectEditor.not.toContain('seg01', { - shouldNormalise: true, - }) - } + await editor.expectEditor.toContain(lineOfInterest, { + shouldNormalise: true, }) + + await page.getByTestId('overlay-menu').click() + await page.waitForTimeout(100) + await page.getByText('Delete Segment').click() + + await page.getByText('Cancel').click() + + await page.mouse.move(hoverPos.x + x, hoverPos.y + y) + await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) + + await editor.expectEditor.toContain(lineOfInterest, { + shouldNormalise: true, + }) + + await page.getByTestId('overlay-menu').click() + await page.waitForTimeout(100) + await page.getByText('Delete Segment').click() + + await page.getByText('Continue and unconstrain').last().click() + + if (doesHaveTagOutsideSketch) { + // eslint-disable-next-line jest/no-conditional-expect + await expect( + page.getByText( + 'Segment tag used outside of current Sketch. Could not delete.' + ) + ).toBeTruthy() + // eslint-disable-next-line jest/no-conditional-expect + await editor.expectEditor.toContain(lineOfInterest, { + shouldNormalise: true, + }) + } else { + // eslint-disable-next-line jest/no-conditional-expect + await editor.expectEditor.not.toContain(lineOfInterest, { + shouldNormalise: true, + }) + // eslint-disable-next-line jest/no-conditional-expect + await editor.expectEditor.not.toContain('seg01', { + shouldNormalise: true, + }) + } + }) } } }) @@ -1289,7 +1462,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, { - before: `angledLine(angle = 5 + 0, length = 23.03 + 0, tag = $seg01)`, + before: `angledLine([5 + 0, 23.03 + 0], %, $seg01)`, after: `line(end = [22.94, 2.01], tag = $seg01)`, }, { @@ -1309,35 +1482,31 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { after: `line(end = [0, -10], tag = $seg01)`, }, { - before: `angledLineOfXLength({ angle = 3 + 0, length = 30 + 0 }, %, $seg01)`, + before: `angledLine(angle = 3 + 0, lengthX = 30 + 0, tag = $seg01)`, after: `line(end = [30, 1.57], tag = $seg01)`, }, { - before: `angledLineOfYLength({ angle = 3 + 0, length = 1.5 + 0 }, %, $seg01)`, + before: `angledLine(angle = 3 + 0, lengthY = 1.5 + 0, tag = $seg01)`, after: `line(end = [28.62, 1.5], tag = $seg01)`, }, { - before: `angledLine(angle = 3 + 0, endAbsoluteX = 30 + 0, tag = $seg01)`, + before: `angledLine(angle = 3 + 0, endAbsoluteX = 30 + 0, tag = $seg01)`, after: `line(end = [25, 1.31], tag = $seg01)`, }, { - before: `angledLine(angle = 3 + 0, endAbsoluteY = 7 + 0, tag = $seg01)`, + before: `angledLine(angle = 3 + 0, endAbsoluteY = 7 + 0, $seg01)`, after: `line(end = [19.08, 1], tag = $seg01)`, }, ] for (const { before, after } of cases) { - const isObj = before.includes('{ angle = 3') - test(`${before.split('=')[0]}${isObj ? '-[obj-input]' : ''}`, async ({ - page, - editor, - homePage, - }) => { + test(`${before.split('=')[0]}`, async ({ page, editor, homePage }) => { await page.addInitScript( async ({ lineToBeDeleted }) => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn('XZ') + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5, 6], %) |> ${lineToBeDeleted} |> line(end = [-10, -15]) @@ -1364,7 +1533,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await expect(page.getByText('Added variable')).not.toBeVisible() const hoverPos = await u.getBoundingBox(`[data-overlay-index="0"]`) - let ang = await u.getAngle(`[data-overlay-index="${0}"]`) + let ang = await u.getAngle('[data-overlay-index="0"]') ang += 180 await page.mouse.move(0, 0) diff --git a/rust/kcl-lib/e2e/executor/main.rs b/rust/kcl-lib/e2e/executor/main.rs index 473f0e366..bede47686 100644 --- a/rust/kcl-lib/e2e/executor/main.rs +++ b/rust/kcl-lib/e2e/executor/main.rs @@ -2,7 +2,7 @@ mod cache; use kcl_lib::{ test_server::{execute_and_export_step, execute_and_snapshot, execute_and_snapshot_no_auth}, - ExecError, UnitLength, + ExecError, }; /// The minimum permissible difference between asserted twenty-twenty images. @@ -26,7 +26,7 @@ pub(crate) fn assert_out(test_name: &str, result: &image::DynamicImage) -> Strin async fn kcl_test_fillet_duplicate_tags() { let code = kcl_input!("fillet_duplicate_tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.expect_err("Code should have failed due to the duplicate edges being filletted"); let err = err.as_kcl_error().unwrap(); @@ -48,7 +48,7 @@ async fn kcl_test_execute_engine_error_return() { |> extrude(length = 4) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -61,7 +61,7 @@ async fn kcl_test_execute_i_shape() { // This is some code from lee that starts a pipe expression with a variable. let code = kcl_input!("i_shape"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("i_shape", &result); } @@ -70,7 +70,7 @@ async fn kcl_test_execute_i_shape() { async fn kcl_test_execute_pipes_on_pipes() { let code = kcl_input!("pipes_on_pipes"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pipes_on_pipes", &result); } @@ -78,7 +78,7 @@ async fn kcl_test_execute_pipes_on_pipes() { async fn kcl_test_execute_cylinder() { let code = kcl_input!("cylinder"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cylinder", &result); } @@ -86,7 +86,7 @@ async fn kcl_test_execute_cylinder() { async fn kcl_test_execute_kittycad_svg() { let code = kcl_input!("kittycad_svg"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("kittycad_svg", &result); } @@ -94,7 +94,7 @@ async fn kcl_test_execute_kittycad_svg() { async fn kcl_test_execute_lsystem() { let code = kcl_input!("lsystem"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("lsystem", &result); } @@ -102,7 +102,7 @@ async fn kcl_test_execute_lsystem() { async fn kcl_test_member_expression_sketch() { let code = kcl_input!("member_expression_sketch"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("member_expression_sketch", &result); } @@ -110,7 +110,7 @@ async fn kcl_test_member_expression_sketch() { async fn kcl_test_helix_defaults() { let code = kcl_input!("helix_defaults"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_defaults", &result); } @@ -118,7 +118,7 @@ async fn kcl_test_helix_defaults() { async fn kcl_test_helix_defaults_negative_extrude() { let code = kcl_input!("helix_defaults_negative_extrude"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_defaults_negative_extrude", &result); } @@ -126,7 +126,7 @@ async fn kcl_test_helix_defaults_negative_extrude() { async fn kcl_test_helix_with_length() { let code = kcl_input!("helix_with_length"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_with_length", &result); } @@ -134,7 +134,7 @@ async fn kcl_test_helix_with_length() { async fn kcl_test_dimensions_match() { let code = kcl_input!("dimensions_match"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("dimensions_match", &result); } @@ -142,7 +142,7 @@ async fn kcl_test_dimensions_match() { async fn kcl_test_close_arc() { let code = kcl_input!("close_arc"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("close_arc", &result); } @@ -150,7 +150,7 @@ async fn kcl_test_close_arc() { async fn kcl_test_negative_args() { let code = kcl_input!("negative_args"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("negative_args", &result); } @@ -164,7 +164,7 @@ async fn kcl_test_basic_tangential_arc_with_point() { |> extrude(length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("tangential_arc_with_point", &result); } @@ -178,7 +178,7 @@ async fn kcl_test_basic_tangential_arc_to() { |> extrude(length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("tangential_arc_to", &result); } @@ -205,7 +205,7 @@ box(30, 43, 18, '-xy') let thing = box(-12, -15, 10, 'yz') box(-20, -5, 10, 'xy')"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("different_planes_same_drawing", &result); } @@ -263,7 +263,7 @@ part004 = startSketchOn('YZ') |> close() "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("lots_of_planes", &result); } @@ -280,7 +280,7 @@ async fn kcl_test_holes() { |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("holes", &result); } @@ -299,7 +299,7 @@ async fn optional_params() { thing = other_circle([2, 2], 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("optional_params", &result); } @@ -335,7 +335,7 @@ part = roundedRectangle([0, 0], 20, 20, 4) |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("rounded_with_holes", &result); } @@ -343,7 +343,7 @@ part = roundedRectangle([0, 0], 20, 20, 4) async fn kcl_test_top_level_expression() { let code = r#"startSketchOn('XY') |> circle(center = [0,0], radius= 22) |> extrude(length = 14)"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("top_level_expression", &result); } @@ -357,7 +357,7 @@ part = startSketchOn('XY') |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_with_math", &result); } @@ -369,7 +369,7 @@ async fn kcl_test_patterns_linear_basic() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic", &result); } @@ -385,7 +385,7 @@ async fn kcl_test_patterns_linear_basic_3d() { |> patternLinear3d(axis = [1, 0, 1], instances = 4, distance = 6) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_3d", &result); } @@ -397,7 +397,7 @@ async fn kcl_test_patterns_linear_basic_negative_distance() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_negative_distance", &result); } @@ -409,7 +409,7 @@ async fn kcl_test_patterns_linear_basic_negative_axis() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_negative_axis", &result); } @@ -430,7 +430,7 @@ rectangle = startSketchOn('XY') "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_holes", &result); } @@ -442,7 +442,7 @@ async fn kcl_test_patterns_circular_basic_2d() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_basic_2d", &result); } @@ -458,7 +458,7 @@ async fn kcl_test_patterns_circular_basic_3d() { |> patternCircular3d(axis = [0,0, 1], center = [-20, -20, -20], instances = 41, arcDegrees = 360, rotateDuplicates = false) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_basic_3d", &result); } @@ -474,7 +474,7 @@ async fn kcl_test_patterns_circular_3d_tilted_axis() { |> patternCircular3d(axis = [1,1,0], center = [10, 0, 10], instances = 11, arcDegrees = 360, rotateDuplicates = true) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_3d_tilted_axis", &result); } @@ -483,7 +483,7 @@ async fn kcl_test_import_file_doesnt_exist() { let code = r#"import 'thing.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -496,7 +496,7 @@ async fn kcl_test_import_obj_with_mtl() { let code = r#"import 'e2e/executor/inputs/cube.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_obj_with_mtl", &result); } @@ -506,7 +506,7 @@ async fn kcl_test_import_obj_with_mtl_units() { import 'e2e/executor/inputs/cube.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_obj_with_mtl_units", &result); } @@ -515,7 +515,7 @@ async fn kcl_test_import_stl() { let code = r#"import 'e2e/executor/inputs/2-5-long-m8-chc-screw.stl' as screw model = screw"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_stl", &result); } @@ -524,7 +524,7 @@ async fn kcl_test_import_gltf_with_bin() { let code = r#"import 'e2e/executor/inputs/cube.gltf' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_gltf_with_bin", &result); } @@ -533,7 +533,7 @@ async fn kcl_test_import_gltf_embedded() { let code = r#"import 'e2e/executor/inputs/cube-embedded.gltf' as cube model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_gltf_embedded", &result); } @@ -542,7 +542,7 @@ async fn kcl_test_import_glb() { let code = r#"import 'e2e/executor/inputs/cube.glb' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_glb", &result); } @@ -551,7 +551,7 @@ async fn kcl_test_import_glb_no_assign() { let code = r#"import 'e2e/executor/inputs/cube.glb' cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_glb_no_assign", &result); } @@ -561,7 +561,7 @@ async fn kcl_test_import_ext_doesnt_match() { import 'e2e/executor/inputs/cube.gltf' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -572,7 +572,7 @@ model = cube"#; #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_mm() { let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn('XY') + sg = startSketchOn(XY) |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -586,13 +586,14 @@ async fn kcl_test_cube_mm() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_mm", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_cm() { - let code = r#"fn cube = (pos, scale) => { + let code = r#"@settings(defaultLengthUnit = cm) +fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) @@ -607,13 +608,14 @@ async fn kcl_test_cube_cm() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Cm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_cm", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_m() { - let code = r#"fn cube = (pos, scale) => { + let code = r#"@settings(defaultLengthUnit = m) +fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) @@ -628,13 +630,14 @@ async fn kcl_test_cube_m() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::M, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_m", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_in() { - let code = r#"fn cube = (pos, scale) => { + let code = r#"@settings(defaultLengthUnit = in) +fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) @@ -649,13 +652,14 @@ async fn kcl_test_cube_in() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::In, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_in", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_ft() { - let code = r#"fn cube = (pos, scale) => { + let code = r#"@settings(defaultLengthUnit = ft) +fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) @@ -670,13 +674,14 @@ async fn kcl_test_cube_ft() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Ft, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_ft", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_yd() { - let code = r#"fn cube = (pos, scale) => { + let code = r#"@settings(defaultLengthUnit = yd) +fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) @@ -691,7 +696,7 @@ async fn kcl_test_cube_yd() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Yd, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_yd", &result); } @@ -719,7 +724,7 @@ part002 = startSketchOn(part001, part001.sketch.tags.here) |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { @@ -763,7 +768,7 @@ part003 = startSketchOn(part002, "end") |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("sketch_on_face_of_face", &result); } @@ -780,7 +785,7 @@ async fn kcl_test_stdlib_kcl_error_right_code_path() { |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -811,7 +816,7 @@ part002 = startSketchOn(part001, "end") |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("sketch_on_face_circle", &result); } @@ -853,7 +858,7 @@ part = rectShape([0, 0], 20, 20) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -880,7 +885,7 @@ async fn kcl_test_simple_revolve() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve", &result); } @@ -900,7 +905,7 @@ async fn kcl_test_simple_revolve_uppercase() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_uppercase", &result); } @@ -920,7 +925,7 @@ async fn kcl_test_simple_revolve_negative() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_negative", &result); } @@ -940,7 +945,7 @@ async fn kcl_test_revolve_bad_angle_low() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert!(result @@ -966,7 +971,7 @@ async fn kcl_test_revolve_bad_angle_high() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert!(result @@ -992,7 +997,7 @@ async fn kcl_test_simple_revolve_custom_angle() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_custom_angle", &result); } @@ -1012,7 +1017,7 @@ async fn kcl_test_simple_revolve_custom_axis() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_custom_axis", &result); } @@ -1036,7 +1041,7 @@ sketch001 = startSketchOn(box, "end") "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_edge", &result); } @@ -1060,7 +1065,7 @@ sketch001 = startSketchOn(box, revolveAxis) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap_err(); //this fails right now, but slightly differently, lets just say its enough for it to fail - mike @@ -1088,7 +1093,7 @@ sketch001 = startSketchOn(box, "END") }, %) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face_circle_edge", &result); } @@ -1110,7 +1115,7 @@ sketch001 = startSketchOn(box, "END") }, %) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face_circle", &result); } @@ -1136,7 +1141,7 @@ sketch001 = startSketchOn(box, "end") }, %) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face", &result); } @@ -1150,7 +1155,7 @@ async fn kcl_test_basic_revolve_circle() { }, %) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("basic_revolve_circle", &result); } @@ -1177,7 +1182,7 @@ part002 = startSketchOn(part001, 'end') |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_sketch_on_edge", &result); } @@ -1243,7 +1248,7 @@ plumbus1 = circle1 ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("plumbus_fillets", &result); } @@ -1251,7 +1256,7 @@ plumbus1 = circle1 async fn kcl_test_empty_file_is_ok() { let code = r#""#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap(); } @@ -1281,7 +1286,7 @@ async fn kcl_test_member_expression_in_params() { capScrew([0, 0.5, 0], 50, 37.5, 50, 25) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("member_expression_in_params", &result); } @@ -1326,7 +1331,7 @@ bracket = startSketchOn('XY') ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap(); } @@ -1346,7 +1351,7 @@ secondSketch = startSketchOn(part001, '') |> extrude(length = 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1377,7 +1382,7 @@ extrusion = startSketchOn('XY') |> extrude(length = height) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1410,7 +1415,7 @@ sketch001 = [profile001, profile002] extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("array_of_sketches", &result); } @@ -1447,7 +1452,7 @@ pattn1 = patternLinear3d( ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pattern3d_array_of_extrudes", &result); } @@ -1495,7 +1500,7 @@ baseExtrusion = extrude(sketch001, length = width) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("fillets_referencing_other_fillets", &result); } @@ -1543,7 +1548,7 @@ baseExtrusion = extrude(sketch001, length = width) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("chamfers_referencing_other_chamfers", &result); } @@ -1563,7 +1568,7 @@ async fn kcl_test_shell_with_tag() { ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("shell_with_tag", &result); } @@ -1594,7 +1599,7 @@ pattn1 = patternLinear3d( ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("linear_pattern3d_filleted_sketch", &result); } @@ -1621,7 +1626,7 @@ pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], i "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("circular_pattern3d_filleted_sketch", &result); } @@ -1647,7 +1652,7 @@ part001 = cube([0,0], 20) pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], instances = 5, arcDegrees = 360, rotateDuplicates = false) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("circular_pattern3d_chamfered_sketch", &result); } @@ -1674,7 +1679,7 @@ part001 = cube([0,0], 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -1706,7 +1711,7 @@ async fn kcl_test_duplicate_tags_should_error() { let p = triangle(200) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.unwrap_err(); let err = err.as_kcl_error().unwrap(); assert_eq!(err.message(), "Cannot redefine `a`"); @@ -1715,49 +1720,49 @@ let p = triangle(200) #[tokio::test(flavor = "multi_thread")] async fn kcl_test_global_tags() { let code = kcl_input!("global-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("global_tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_extrude_inside_fn_with_tags() { let code = kcl_input!("extrude-inside-fn-with-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("extrude-inside-fn-with-tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_pattern_vase() { let code = kcl_input!("pattern_vase"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pattern_vase", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_scoped_tags() { let code = kcl_input!("scoped-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("scoped_tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_order_sketch_extrude_in_order() { let code = kcl_input!("order-sketch-extrude-in-order"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("order-sketch-extrude-in-order", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_order_sketch_extrude_out_of_order() { let code = kcl_input!("order-sketch-extrude-out-of-order"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("order-sketch-extrude-out-of-order", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_extrude_custom_plane() { let code = kcl_input!("extrude-custom-plane"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("extrude-custom-plane", &result); } @@ -1779,7 +1784,7 @@ async fn kcl_test_arc_error_same_start_end() { ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1799,7 +1804,7 @@ async fn kcl_test_angled_line_to_x_90() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1819,7 +1824,7 @@ async fn kcl_test_angled_line_to_x_270() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1839,7 +1844,7 @@ async fn kcl_test_angled_line_to_y_0() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1859,7 +1864,7 @@ async fn kcl_test_angled_line_to_y_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1879,7 +1884,7 @@ async fn kcl_test_angled_line_of_x_length_90() { extrusion = extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1899,7 +1904,7 @@ async fn kcl_test_angled_line_of_x_length_270() { extrusion = extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1921,7 +1926,7 @@ async fn kcl_test_angled_line_of_y_length_0() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1943,7 +1948,7 @@ async fn kcl_test_angled_line_of_y_length_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1965,7 +1970,7 @@ async fn kcl_test_angled_line_of_y_length_negative_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1982,7 +1987,7 @@ async fn kcl_test_error_inside_fn_also_has_source_range_of_call_site() { someFunction('INVALID') "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -2003,7 +2008,7 @@ async fn kcl_test_error_inside_fn_also_has_source_range_of_call_site_recursive() someFunction('INVALID') "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -2027,7 +2032,7 @@ async fn kcl_test_error_no_auth_websocket() { ) "#; - let result = execute_and_snapshot_no_auth(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot_no_auth(code, None).await; assert!(result.is_err()); assert!(result .err() @@ -2053,9 +2058,7 @@ sketch000 = startSketchOn('XY') |> line(end = [0, innerDiameter / 2]) "#; - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()) - .await - .unwrap(); + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await.unwrap(); let mut exec_state = kcl_lib::ExecState::new(&ctx); let program = kcl_lib::Program::parse_no_errs(code).unwrap(); ctx.run(&program, &mut exec_state).await.unwrap(); @@ -2078,9 +2081,7 @@ async fn kcl_test_ensure_nothing_left_in_batch_multi_file() { // Change the current working directory to the test directory. std::env::set_current_dir(path.parent().unwrap()).unwrap(); - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()) - .await - .unwrap(); + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await.unwrap(); let mut exec_state = kcl_lib::ExecState::new(&ctx); let program = kcl_lib::Program::parse_no_errs(&code).unwrap(); ctx.run(&program, &mut exec_state).await.unwrap(); @@ -2098,7 +2099,7 @@ async fn kcl_test_better_type_names() { |> circle(center = [-95.51, -74.7], radius = 262.23) |> appearance(metalness = 0.9) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = match result.err() { Some(x) => match x { @@ -2117,7 +2118,7 @@ async fn kcl_test_exporting_step_file() { // This tests export like how we do it in cli and kcl.py. let code = kcl_input!("helix_defaults_negative_extrude"); - let (_, _, files) = execute_and_export_step(code, UnitLength::Mm, None).await.unwrap(); + let (_, _, files) = execute_and_export_step(code, None).await.unwrap(); for file in files { expectorate::assert_contents( format!("e2e/executor/outputs/helix_defaults_negative_extrude_{}", file.name), diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 3798631db..97a938f56 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -5,11 +5,16 @@ import type { Node } from '@rust/kcl-lib/bindings/Node' import type { TagDeclarator } from '@rust/kcl-lib/bindings/TagDeclarator' import { + ARG_ANGLE, ARG_CIRCLE_CENTER, ARG_CIRCLE_RADIUS, ARG_END, ARG_END_ABSOLUTE, + ARG_END_ABSOLUTE_X, + ARG_END_ABSOLUTE_Y, ARG_LENGTH, + ARG_LENGTH_X, + ARG_LENGTH_Y, ARG_TAG, DETERMINING_ARGS, } from '@src/lang/constants' @@ -79,7 +84,13 @@ import type { } from '@src/lang/wasm' import { sketchFromKclValue } from '@src/lang/wasm' import { err } from '@src/lib/trap' -import { getAngle, getLength, isArray, roundOff } from '@src/lib/utils' +import { + allLabels, + getAngle, + getLength, + isArray, + roundOff, +} from '@src/lib/utils' import type { EdgeCutInfo } from '@src/machines/modelingMachine' const STRAIGHT_SEGMENT_ERR = new Error( diff --git a/src/lang/std/sketchcombos.test.ts b/src/lang/std/sketchcombos.test.ts index a5c679274..3ba243248 100644 --- a/src/lang/std/sketchcombos.test.ts +++ b/src/lang/std/sketchcombos.test.ts @@ -1,7 +1,11 @@ import { ARG_END, ARG_END_ABSOLUTE } from '@src/lang/constants' import type { ToolTip } from '@src/lang/langHelpers' import { codeRefFromRange } from '@src/lang/std/artifactGraph' -import { fnNameToTooltip, getArgForEnd, isAbsoluteLine } from '@src/lang/std/sketch' +import { + fnNameToTooltip, + getArgForEnd, + isAbsoluteLine, +} from '@src/lang/std/sketch' import type { ConstraintLevel, ConstraintType, @@ -13,7 +17,7 @@ import { transformAstSketchLines, transformSecondarySketchLinesTagFirst, } from '@src/lang/std/sketchcombos' -import { findKwArg, topLevelRange } from '@src/lang/util' +import { findAngleLengthPair, findKwArg, topLevelRange } from '@src/lang/util' import type { Expr, Program } from '@src/lang/wasm' import { assertParse, initPromise, recast } from '@src/lang/wasm' import type { Selection, Selections } from '@src/lib/selections' @@ -93,7 +97,7 @@ function getConstraintTypeFromSourceHelper( ) } const args = arg.elements as [Expr, Expr] - const fnName = expr.callee.name as ToolTip + const fnName = expr.callee.name.name as ToolTip return getConstraintType(args, fnName, false) } case 'CallExpressionKw': { @@ -104,7 +108,7 @@ function getConstraintTypeFromSourceHelper( return new Error("couldn't find either end or endAbsolute in KW call") } const isAbsolute = endAbsolute ? true : false - const fnName = fnNameToTooltip(allLabels(expr), expr.callee.name) + const fnName = fnNameToTooltip(allLabels(expr), expr.callee.name.name) if (err(fnName)) { return fnName } diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts index 130a0ef07..d06998103 100644 --- a/src/lang/std/sketchcombos.ts +++ b/src/lang/std/sketchcombos.ts @@ -1,16 +1,16 @@ import type { Node } from '@rust/kcl-lib/bindings/Node' import { + ARG_ANGLE, ARG_END, ARG_END_ABSOLUTE, - ARG_LENGTH, - ARG_TAG, - ARG_ANGLE, - DETERMINING_ARGS, ARG_END_ABSOLUTE_X, ARG_END_ABSOLUTE_Y, + ARG_LENGTH, ARG_LENGTH_X, ARG_LENGTH_Y, + ARG_TAG, + DETERMINING_ARGS, } from '@src/lang/constants' import { createArrayExpression, @@ -34,6 +34,7 @@ import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils' import { createFirstArg, fnNameToTooltip, + getAngledLine, getArgForEnd, getCircle, getConstraintInfo, @@ -73,7 +74,13 @@ import type { import { sketchFromKclValue } from '@src/lang/wasm' import type { Selections } from '@src/lib/selections' import { cleanErrs, err } from '@src/lib/trap' -import { getAngle, isArray, normaliseAngle, roundOff } from '@src/lib/utils' +import { + allLabels, + getAngle, + isArray, + normaliseAngle, + roundOff, +} from '@src/lib/utils' export type LineInputsType = | 'xAbsolute' @@ -363,17 +370,17 @@ type TransformMap = { const xyLineSetLength = (xOrY: 'xLine' | 'yLine', referenceSeg = false): CreateStdLibSketchCallExpr => - ({ referenceSegName, tag, forceValueUsedInTransform, rawArgs: args }) => { - const segRef = createSegLen(referenceSegName) - const lineVal = forceValueUsedInTransform - ? forceValueUsedInTransform - : referenceSeg - ? segRef - : args[0].expr - const literalArg = asNum(args[0].expr.value) - if (err(literalArg)) return literalArg - return createCallWrapper(xOrY, lineVal, tag, literalArg) - } + ({ referenceSegName, tag, forceValueUsedInTransform, rawArgs: args }) => { + const segRef = createSegLen(referenceSegName) + const lineVal = forceValueUsedInTransform + ? forceValueUsedInTransform + : referenceSeg + ? segRef + : args[0].expr + const literalArg = asNum(args[0].expr.value) + if (err(literalArg)) return literalArg + return createCallWrapper(xOrY, lineVal, tag, literalArg) + } type AngLenNone = 'ang' | 'len' | 'none' const basicAngledLineCreateNode = @@ -382,49 +389,49 @@ const basicAngledLineCreateNode = valToForce: AngLenNone = 'none', varValToUse: AngLenNone = 'none' ): CreateStdLibSketchCallExpr => - ({ - referenceSegName, - tag, - forceValueUsedInTransform, - inputs, - rawArgs: args, - referencedSegment: path, - }) => { - const refAng = path ? getAngle(path?.from, path?.to) : 0 - const argValue = asNum(args[0].expr.value) - if (err(argValue)) return argValue - const nonForcedAng = - varValToUse === 'ang' - ? inputs[0].expr - : referenceSeg === 'ang' - ? getClosesAngleDirection( + ({ + referenceSegName, + tag, + forceValueUsedInTransform, + inputs, + rawArgs: args, + referencedSegment: path, + }) => { + const refAng = path ? getAngle(path?.from, path?.to) : 0 + const argValue = asNum(args[0].expr.value) + if (err(argValue)) return argValue + const nonForcedAng = + varValToUse === 'ang' + ? inputs[0].expr + : referenceSeg === 'ang' + ? getClosesAngleDirection( argValue, refAng, createSegAngle(referenceSegName) ) - : args[0].expr - const nonForcedLen = - varValToUse === 'len' - ? inputs[1].expr - : referenceSeg === 'len' - ? createSegLen(referenceSegName) - : args[1].expr - const shouldForceAng = valToForce === 'ang' && forceValueUsedInTransform - const shouldForceLen = valToForce === 'len' && forceValueUsedInTransform - const literalArg = asNum( - valToForce === 'ang' ? args[0].expr.value : args[1].expr.value - ) - if (err(literalArg)) return literalArg - return createCallWrapper( - 'angledLine', - [ - shouldForceAng ? forceValueUsedInTransform : nonForcedAng, - shouldForceLen ? forceValueUsedInTransform : nonForcedLen, - ], - tag, - literalArg - ) - } + : args[0].expr + const nonForcedLen = + varValToUse === 'len' + ? inputs[1].expr + : referenceSeg === 'len' + ? createSegLen(referenceSegName) + : args[1].expr + const shouldForceAng = valToForce === 'ang' && forceValueUsedInTransform + const shouldForceLen = valToForce === 'len' && forceValueUsedInTransform + const literalArg = asNum( + valToForce === 'ang' ? args[0].expr.value : args[1].expr.value + ) + if (err(literalArg)) return literalArg + return createCallWrapper( + 'angledLine', + [ + shouldForceAng ? forceValueUsedInTransform : nonForcedAng, + shouldForceLen ? forceValueUsedInTransform : nonForcedLen, + ], + tag, + literalArg + ) + } const angledLineAngleCreateNode: CreateStdLibSketchCallExpr = ({ referenceSegName, inputs, @@ -495,57 +502,57 @@ function getClosesAngleDirection( const setHorzVertDistanceCreateNode = (xOrY: 'x' | 'y', index = xOrY === 'x' ? 0 : 1): CreateStdLibSketchCallExpr => - ({ - referenceSegName, - tag, - forceValueUsedInTransform, - rawArgs: args, - referencedSegment, - }) => { - const refNum = referencedSegment?.to?.[index] - const literalArg = asNum(args?.[index].expr.value) - if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR + ({ + referenceSegName, + tag, + forceValueUsedInTransform, + rawArgs: args, + referencedSegment, + }) => { + const refNum = referencedSegment?.to?.[index] + const literalArg = asNum(args?.[index].expr.value) + if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR - const valueUsedInTransform = roundOff(literalArg - refNum, 2) - let finalValue: Node = createBinaryExpressionWithUnary([ - createSegEnd(referenceSegName, !index), - forceValueUsedInTransform || createLiteral(valueUsedInTransform), - ]) - if (isValueZero(forceValueUsedInTransform)) { - finalValue = createSegEnd(referenceSegName, !index) - } - return createCallWrapper( - 'lineTo', - !index ? [finalValue, args[1].expr] : [args[0].expr, finalValue], - tag, - valueUsedInTransform - ) + const valueUsedInTransform = roundOff(literalArg - refNum, 2) + let finalValue: Node = createBinaryExpressionWithUnary([ + createSegEnd(referenceSegName, !index), + forceValueUsedInTransform || createLiteral(valueUsedInTransform), + ]) + if (isValueZero(forceValueUsedInTransform)) { + finalValue = createSegEnd(referenceSegName, !index) } + return createCallWrapper( + 'lineTo', + !index ? [finalValue, args[1].expr] : [args[0].expr, finalValue], + tag, + valueUsedInTransform + ) + } const setHorzVertDistanceForAngleLineCreateNode = (xOrY: 'x' | 'y', index = xOrY === 'x' ? 0 : 1): CreateStdLibSketchCallExpr => - ({ - referenceSegName, + ({ + referenceSegName, + tag, + forceValueUsedInTransform, + inputs, + rawArgs: args, + referencedSegment, + }) => { + const refNum = referencedSegment?.to?.[index] + const literalArg = asNum(args?.[1].expr.value) + if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR + const valueUsedInTransform = roundOff(literalArg - refNum, 2) + const binExp = createBinaryExpressionWithUnary([ + createSegEnd(referenceSegName, !index), + forceValueUsedInTransform || createLiteral(valueUsedInTransform), + ]) + return createCallWrapper( + xOrY === 'x' ? 'angledLineToX' : 'angledLineToY', + [inputs[0].expr, binExp], tag, - forceValueUsedInTransform, - inputs, - rawArgs: args, - referencedSegment, - }) => { - const refNum = referencedSegment?.to?.[index] - const literalArg = asNum(args?.[1].expr.value) - if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR - const valueUsedInTransform = roundOff(literalArg - refNum, 2) - const binExp = createBinaryExpressionWithUnary([ - createSegEnd(referenceSegName, !index), - forceValueUsedInTransform || createLiteral(valueUsedInTransform), - ]) - return createCallWrapper( - xOrY === 'x' ? 'angledLineToX' : 'angledLineToY', - [inputs[0].expr, binExp], - tag, - valueUsedInTransform - ) - } + valueUsedInTransform + ) + } const setAbsDistanceCreateNode = ( @@ -553,94 +560,94 @@ const setAbsDistanceCreateNode = isXOrYLine = false, index = xOrY === 'x' ? 0 : 1 ): CreateStdLibSketchCallExpr => - ({ tag, forceValueUsedInTransform, rawArgs: args }) => { - const literalArg = asNum(args?.[index].expr.value) - if (err(literalArg)) return literalArg - const valueUsedInTransform = roundOff(literalArg, 2) - const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform) - if (isXOrYLine) { - return createCallWrapper( - xOrY === 'x' ? 'xLineTo' : 'yLineTo', - val, - tag, - valueUsedInTransform - ) - } + ({ tag, forceValueUsedInTransform, rawArgs: args }) => { + const literalArg = asNum(args?.[index].expr.value) + if (err(literalArg)) return literalArg + const valueUsedInTransform = roundOff(literalArg, 2) + const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform) + if (isXOrYLine) { return createCallWrapper( - 'lineTo', - !index ? [val, args[1].expr] : [args[0].expr, val], + xOrY === 'x' ? 'xLineTo' : 'yLineTo', + val, tag, valueUsedInTransform ) } + return createCallWrapper( + 'lineTo', + !index ? [val, args[1].expr] : [args[0].expr, val], + tag, + valueUsedInTransform + ) + } const setAbsDistanceForAngleLineCreateNode = (xOrY: 'x' | 'y'): CreateStdLibSketchCallExpr => - ({ tag, forceValueUsedInTransform, inputs, rawArgs: args }) => { - const literalArg = asNum(args?.[1].expr.value) - if (err(literalArg)) return literalArg - const valueUsedInTransform = roundOff(literalArg, 2) - const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform) - return createCallWrapper( - xOrY === 'x' ? 'angledLineToX' : 'angledLineToY', - [inputs[0].expr, val], - tag, - valueUsedInTransform - ) - } + ({ tag, forceValueUsedInTransform, inputs, rawArgs: args }) => { + const literalArg = asNum(args?.[1].expr.value) + if (err(literalArg)) return literalArg + const valueUsedInTransform = roundOff(literalArg, 2) + const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform) + return createCallWrapper( + xOrY === 'x' ? 'angledLineToX' : 'angledLineToY', + [inputs[0].expr, val], + tag, + valueUsedInTransform + ) + } const setHorVertDistanceForXYLines = (xOrY: 'x' | 'y'): CreateStdLibSketchCallExpr => - ({ - referenceSegName, + ({ + referenceSegName, + tag, + forceValueUsedInTransform, + rawArgs: args, + referencedSegment, + }) => { + const index = xOrY === 'x' ? 0 : 1 + const refNum = referencedSegment?.to?.[index] + const literalArg = asNum(args?.[index].expr.value) + if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR + const valueUsedInTransform = roundOff(literalArg - refNum, 2) + const makeBinExp = createBinaryExpressionWithUnary([ + createSegEnd(referenceSegName, xOrY === 'x'), + forceValueUsedInTransform || createLiteral(valueUsedInTransform), + ]) + return createCallWrapper( + xOrY === 'x' ? 'xLineTo' : 'yLineTo', + makeBinExp, tag, - forceValueUsedInTransform, - rawArgs: args, - referencedSegment, - }) => { - const index = xOrY === 'x' ? 0 : 1 - const refNum = referencedSegment?.to?.[index] - const literalArg = asNum(args?.[index].expr.value) - if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR - const valueUsedInTransform = roundOff(literalArg - refNum, 2) - const makeBinExp = createBinaryExpressionWithUnary([ - createSegEnd(referenceSegName, xOrY === 'x'), - forceValueUsedInTransform || createLiteral(valueUsedInTransform), - ]) - return createCallWrapper( - xOrY === 'x' ? 'xLineTo' : 'yLineTo', - makeBinExp, - tag, - valueUsedInTransform - ) - } + valueUsedInTransform + ) + } const setHorzVertDistanceConstraintLineCreateNode = (isX: boolean): CreateStdLibSketchCallExpr => - ({ referenceSegName, tag, inputs, rawArgs: args, referencedSegment }) => { - let varVal = isX ? inputs[1].expr : inputs[0].expr - varVal = isExprBinaryPart(varVal) ? varVal : createLiteral(0) - const varValBinExp = createBinaryExpressionWithUnary([ - createLastSeg(!isX), - varVal, - ]) + ({ referenceSegName, tag, inputs, rawArgs: args, referencedSegment }) => { + let varVal = isX ? inputs[1].expr : inputs[0].expr + varVal = isExprBinaryPart(varVal) ? varVal : createLiteral(0) + const varValBinExp = createBinaryExpressionWithUnary([ + createLastSeg(!isX), + varVal, + ]) - const makeBinExp = (index: 0 | 1) => { - const arg = asNum(args?.[index].expr.value) - const refNum = referencedSegment?.to?.[index] - if (err(arg) || isUndef(refNum)) return REF_NUM_ERR - return createBinaryExpressionWithUnary([ - createSegEnd(referenceSegName, isX), - createLiteral(roundOff(arg - refNum, 2)), - ]) - } - const binExpr = isX ? makeBinExp(0) : makeBinExp(1) - if (err(binExpr)) return new Error('Invalid value for distance') - return createCallWrapper( - 'lineTo', - isX ? [binExpr, varValBinExp] : [varValBinExp, binExpr], - tag - ) + const makeBinExp = (index: 0 | 1) => { + const arg = asNum(args?.[index].expr.value) + const refNum = referencedSegment?.to?.[index] + if (err(arg) || isUndef(refNum)) return REF_NUM_ERR + return createBinaryExpressionWithUnary([ + createSegEnd(referenceSegName, isX), + createLiteral(roundOff(arg - refNum, 2)), + ]) } + const binExpr = isX ? makeBinExp(0) : makeBinExp(1) + if (err(binExpr)) return new Error('Invalid value for distance') + return createCallWrapper( + 'lineTo', + isX ? [binExpr, varValBinExp] : [varValBinExp, binExpr], + tag + ) + } const setAngledIntersectLineForLines: CreateStdLibSketchCallExpr = ({ referenceSegName, @@ -693,48 +700,48 @@ const setAngledIntersectForAngledLines: CreateStdLibSketchCallExpr = ({ const setAngleBetweenCreateNode = (tranformToType: 'none' | 'xAbs' | 'yAbs'): CreateStdLibSketchCallExpr => - ({ - referenceSegName, - tag, - forceValueUsedInTransform, - inputs, - rawArgs: args, - referencedSegment, - }) => { - const refAngle = referencedSegment - ? getAngle(referencedSegment?.from, referencedSegment?.to) - : 0 - const val = asNum(args[0].expr.value) - if (err(val)) return val - let valueUsedInTransform = roundOff(normaliseAngle(val - refAngle)) - let firstHalfValue = createSegAngle(referenceSegName) - if (Math.abs(valueUsedInTransform) > 90) { - firstHalfValue = createBinaryExpression([ - firstHalfValue, - '+', - createName(['turns'], 'HALF_TURN'), - ]) - valueUsedInTransform = normaliseAngle(valueUsedInTransform - 180) - } - const binExp = createBinaryExpressionWithUnary([ + ({ + referenceSegName, + tag, + forceValueUsedInTransform, + inputs, + rawArgs: args, + referencedSegment, + }) => { + const refAngle = referencedSegment + ? getAngle(referencedSegment?.from, referencedSegment?.to) + : 0 + const val = asNum(args[0].expr.value) + if (err(val)) return val + let valueUsedInTransform = roundOff(normaliseAngle(val - refAngle)) + let firstHalfValue = createSegAngle(referenceSegName) + if (Math.abs(valueUsedInTransform) > 90) { + firstHalfValue = createBinaryExpression([ firstHalfValue, - forceValueUsedInTransform || createLiteral(valueUsedInTransform), + '+', + createName(['turns'], 'HALF_TURN'), ]) - return createCallWrapper( - tranformToType === 'none' - ? 'angledLine' - : tranformToType === 'xAbs' - ? 'angledLineToX' - : 'angledLineToY', - tranformToType === 'none' - ? [binExp, args[1].expr] - : tranformToType === 'xAbs' - ? [binExp, inputs[0].expr] - : [binExp, inputs[1].expr], - tag, - valueUsedInTransform - ) + valueUsedInTransform = normaliseAngle(valueUsedInTransform - 180) } + const binExp = createBinaryExpressionWithUnary([ + firstHalfValue, + forceValueUsedInTransform || createLiteral(valueUsedInTransform), + ]) + return createCallWrapper( + tranformToType === 'none' + ? 'angledLine' + : tranformToType === 'xAbs' + ? 'angledLineToX' + : 'angledLineToY', + tranformToType === 'none' + ? [binExp, args[1].expr] + : tranformToType === 'xAbs' + ? [binExp, inputs[0].expr] + : [binExp, inputs[1].expr], + tag, + valueUsedInTransform + ) + } /** IMO, the transformMap is a nested structure that maps like this: @@ -1548,7 +1555,7 @@ export function removeSingleConstraint({ rawValue.type === 'arrayInObject' && rawValue.key === currentArg.key && rawValue.index === - (currentArg.type === 'arrayInObject' ? currentArg.index : -1) + (currentArg.type === 'arrayInObject' ? currentArg.index : -1) ) const rawLiteralObjProp = rawArgs.find( (rawValue) => @@ -1654,10 +1661,10 @@ function getTransformMapPath( constraintType: ConstraintType ): | { - toolTip: ToolTip - lineInputType: LineInputsType | 'free' - constraintType: ConstraintType - } + toolTip: ToolTip + lineInputType: LineInputsType | 'free' + constraintType: ConstraintType + } | false { const name = sketchFnExp.callee.name.name as ToolTip if (!toolTips.includes(name)) { @@ -1711,10 +1718,10 @@ function getTransformMapPathKw( constraintType: ConstraintType ): | { - toolTip: ToolTip - lineInputType: LineInputsType | 'free' - constraintType: ConstraintType - } + toolTip: ToolTip + lineInputType: LineInputsType | 'free' + constraintType: ConstraintType + } | false { const name = sketchFnExp.callee.name.name as ToolTip if (name === 'circleThreePoint') { @@ -1916,14 +1923,14 @@ export function transformSecondarySketchLinesTagFirst({ forceValueUsedInTransform?: BinaryPart }): | { - modifiedAst: Node - valueUsedInTransform?: number - pathToNodeMap: PathToNodeMap - tagInfo: { - tag: string - isTagExisting: boolean + modifiedAst: Node + valueUsedInTransform?: number + pathToNodeMap: PathToNodeMap + tagInfo: { + tag: string + isTagExisting: boolean + } } - } | Error { // let node = structuredClone(ast) @@ -1995,10 +2002,10 @@ export function transformAstSketchLines({ forceValueUsedInTransform?: BinaryPart }): | { - modifiedAst: Node - valueUsedInTransform?: number - pathToNodeMap: PathToNodeMap - } + modifiedAst: Node + valueUsedInTransform?: number + pathToNodeMap: PathToNodeMap + } | Error { // deep clone since we are mutating in a loop, of which any could fail let node = structuredClone(ast) @@ -2143,25 +2150,25 @@ export function transformAstSketchLines({ segmentInput: seg.type === 'Circle' ? { - type: 'arc-segment', - center: seg.center, - radius: seg.radius, - from, - to: from, // For a full circle, to is the same as from - ccw: true, // Default to counter-clockwise for circles - } + type: 'arc-segment', + center: seg.center, + radius: seg.radius, + from, + to: from, // For a full circle, to is the same as from + ccw: true, // Default to counter-clockwise for circles + } : seg.type === 'CircleThreePoint' || seg.type === 'ArcThreePoint' ? { - type: 'circle-three-point-segment', - p1: seg.p1, - p2: seg.p2, - p3: seg.p3, - } + type: 'circle-three-point-segment', + p1: seg.p1, + p2: seg.p2, + p3: seg.p3, + } : { - type: 'straight-segment', - to, - from, - }, + type: 'straight-segment', + to, + from, + }, replaceExistingCallback: (rawArgs) => callBack({