diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index 2ca4c416e..183644ed5 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -1,217 +1,214 @@ -import type { Page } from '@playwright/test' -import type { LineInputsType } from '@src/lang/std/sketchcombos' -import { uuidv4 } from '@src/lib/utils' +import { Page } from '@playwright/test' +import { test, expect } from './zoo-test' -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' +import { deg, getUtils, wiggleMove } from './test-utils' +import { LineInputsType } from 'lang/std/sketchcombos' +import { uuidv4 } from 'lib/utils' +import { EditorFixture } from './fixtures/editorFixture' test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { - 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 expect(page.getByText('Added variable')).not.toBeVisible() + 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 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', + await editor.expectEditor.toContain(expectBeforeUnconstrained, { + shouldNormalise: true, }) - .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', + 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, }) - .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) + 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) + 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, + }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `part001 = startSketchOn('XZ') |> startProfileAt([5 + 0, 20 + 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine(angle = 3 + 0, length = 32 + 0 ) @@ -220,8 +217,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { |> yLine(endAbsolute = 20 + -10.77, tag = $a) |> xLine(length = 26.04) |> yLine(length = 21.14 + 0) - |> angledLine(angle = 181 + 0, xLength = 23.14) - |> angledLine(angle = -91, yLength = 19 + 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) |> angledLineThatIntersects({ @@ -231,165 +228,160 @@ 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 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 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 + // 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 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 ) @@ -400,69 +392,69 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { |> yLine(length = 21.14 + 0) |> angledLineOfXLength({ angle = 181 + 0, length = 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', - `@settings(defaultLengthUnit = in) - 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', + `part001 = startSketchOn('XZ') |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine(angle = 3 + 0, length = 32 + 0 ) @@ -482,119 +474,119 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> 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"]` ) - localStorage.setItem('disableAxis', 'true') + 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"]', + }) }) - 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', - `@settings(defaultLengthUnit = in) - part001 = startSketchOn(XZ) + 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 ) @@ -614,62 +606,6 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> tangentialArcTo([3.14 + 13, 1.14], %) ` -<<<<<<< HEAD -||||||| parent of bcbec9f87 (Update KCL in JS project) - ) - 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: - 'angledLineToX({ angle = 3 + 0, to = 26 }, %)', - expectAfterUnconstrained: 'angledLineToX({ angle = 3, to = 26 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 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: - 'angledLineToX({ angle = angle001, to = 26 }, %)', - expectAfterUnconstrained: - 'angledLineToX({ angle = angle001, to = xAbs001 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 26 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="9"]', - }) - - const angledLineToY = await u.getBoundingBox( - `[data-overlay-index="10"]` -======= ) localStorage.setItem('disableAxis', 'true') }) @@ -723,41 +659,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { const angledLineToY = await u.getBoundingBox( `[data-overlay-index="10"]` ->>>>>>> bcbec9f87 (Update KCL in JS project) ) -<<<<<<< HEAD - localStorage.setItem('disableAxis', 'true') - }) - const u = await getUtils(page) - await page.setBodyDimensions({ width: 1200, height: 500 }) -||||||| parent of bcbec9f87 (Update KCL in JS project) - ang = await u.getAngle(`[data-overlay-index="10"]`) - console.log('angledLineToY') - await clickUnconstrained({ - hoverPos: { x: angledLineToY.x, y: angledLineToY.y }, - constraintType: 'angle', - expectBeforeUnconstrained: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineToY({ angle = angle002, to = 9.14 + 0 }, %)', - expectFinal: 'angledLineToY({ 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: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineToY({ angle = 89, to = 9.14 }, %)', - expectFinal: 'angledLineToY({ angle = 89, to = yAbs001 }, %)', - ang: ang + 180, - locator: '[data-overlay-toolbar-index="10"]', - }) -======= ang = await u.getAngle(`[data-overlay-index="10"]`) console.log('angledLineToY') await clickUnconstrained({ @@ -784,145 +686,71 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { ang: ang + 180, locator: '[data-overlay-toolbar-index="10"]', }) ->>>>>>> bcbec9f87 (Update KCL in JS project) - 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: - 'angledLineToX({ angle = 3 + 0, to = 26 }, %)', - expectAfterUnconstrained: 'angledLineToX({ angle = 3, to = 26 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 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: - 'angledLineToX({ angle = angle001, to = 26 }, %)', - expectAfterUnconstrained: - 'angledLineToX({ angle = angle001, to = xAbs001 }, %)', - expectFinal: 'angledLineToX({ angle = angle001, to = 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: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: - 'angledLineToY({ angle = angle002, to = 9.14 + 0 }, %)', - expectFinal: 'angledLineToY({ 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: - 'angledLineToY({ angle = 89, to = 9.14 + 0 }, %)', - expectAfterUnconstrained: 'angledLineToY({ angle = 89, to = 9.14 }, %)', - expectFinal: 'angledLineToY({ angle = 89, to = 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({ + 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({ + expectAfterUnconstrained: `angledLineThatIntersects({ angle = angle003, intersectTag = a, offset = 9 }, %)`, - expectFinal: `angledLineThatIntersects({ + 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({ + 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({ + expectAfterUnconstrained: `angledLineThatIntersects({ angle = -176, offset = perpDist001, intersectTag = a }, %)`, - expectFinal: `angledLineThatIntersects({ + expectFinal: `angledLineThatIntersects({ angle = -176, offset = 9, intersectTag = a }, %)`, - ang: ang + 180, - locator: '[data-overlay-toolbar-index="11"]', + 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) + 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 ) @@ -942,260 +770,129 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { }, %) |> 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"]' ) - localStorage.setItem('disableAxis', 'true') + 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"]', + }) }) - 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) + 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') + ) + 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"]', + }) }) - 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) => @@ -1230,78 +927,17 @@ part001 = startSketchOn(XZ) shouldNormalise: true, }) - await page - .locator(`[data-stdlib-fn-name="${stdLibFnName}"]`) - .first() - .click() + 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, - scene, - cmdBar, - }) => { + test('all segment types', async ({ page, editor, homePage }) => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', -<<<<<<< HEAD - `@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) - |> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %) - |> angledLineOfYLength({ angle = -91, length = 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 - }, %) - -||||||| parent of bcbec9f87 (Update KCL in JS project) - `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 }, %) - |> 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], %) -======= `part001 = startSketchOn('XZ') |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) @@ -1321,8 +957,7 @@ part001 = startSketchOn(XZ) offset = 9 }, %) |> tangentialArcTo([3.14 + 13, 1.14], %) ->>>>>>> bcbec9f87 (Update KCL in JS project) - ` + ` ) localStorage.setItem('disableAxis', 'true') }) @@ -1330,55 +965,27 @@ part001 = startSketchOn(XZ) await page.setBodyDimensions({ width: 1200, height: 500 }) await homePage.goToModelingScene() - await scene.connectionEstablished() - await scene.settled(cmdBar) await u.waitForPageLoad() + // 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(16) + await expect(page.getByTestId('segment-overlay')).toHaveCount(13) 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"]', - }) + u.getBoundingBox(`[data-overlay-index="${index}"]`) segmentToDelete = await getOverlayByIndex(12) - ang = await u.getAngle('[data-overlay-index="12"]') + let ang = await u.getAngle(`[data-overlay-index="${12}"]`) await deleteSegmentSequence({ hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y }, codeToBeDeleted: 'tangentialArcTo([3.14 + 13, 1.14], %)', @@ -1389,14 +996,14 @@ part001 = startSketchOn(XZ) }) 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({ - angle = 4.14, - intersectTag = a, - offset = 9 - }, %)`, + angle = 4.14, + intersectTag = a, + offset = 9 + }, %)`, stdLibFnName: 'angledLineThatIntersects', ang: ang + 180, steps: 7, @@ -1404,7 +1011,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1414,7 +1021,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1424,7 +1031,7 @@ part001 = startSketchOn(XZ) }) 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: @@ -1435,7 +1042,7 @@ part001 = startSketchOn(XZ) }) 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: @@ -1446,7 +1053,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1456,7 +1063,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1466,7 +1073,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1476,7 +1083,7 @@ part001 = startSketchOn(XZ) }) 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)', @@ -1486,7 +1093,7 @@ part001 = startSketchOn(XZ) }) 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 } @@ -1519,7 +1126,7 @@ part001 = startSketchOn(XZ) }) 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 )', @@ -1529,7 +1136,7 @@ part001 = startSketchOn(XZ) }) 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])', @@ -1560,126 +1167,117 @@ part001 = startSketchOn(XZ) 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', - `@settings(defaultLengthUnit = in) - 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', + `part001 = startSketchOn('XZ') |> startProfileAt([5, 6], %) - |> ${ lineToBeDeleted } + |> ${lineToBeDeleted} |> line(end = [-10, -15]) -<<<<<<< HEAD - |> angledLine([-176, segLen(seg01)], %) -||||||| parent of bcbec9f87 (Update KCL in JS project) - |> angledLine([-176, segLen(seg01)], %) -======= |> angledLine(angle = -176, length = segLen(seg01)) ->>>>>>> bcbec9f87 (Update KCL in JS project) - ${ extraLine? 'myVar = segLen(seg01)': '' }` - ) - }, - { - 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 + ${extraLine ? 'myVar = segLen(seg01)' : ''}` + ) + }, + { + lineToBeDeleted: lineOfInterest, + extraLine: doesHaveTagOutsideSketch, } - }) - .toBe(true) - await page.getByRole('button', { name: 'Edit Sketch' }).click() + ) + const u = await getUtils(page) + await page.setBodyDimensions({ width: 1200, height: 500 }) - await expect(page.getByTestId('segment-overlay')).toHaveCount(3) - const segmentToDelete = await u.getBoundingBox( - `[data - overlay - index= "0"]` - ) + await homePage.goToModelingScene() + await u.waitForPageLoad() + await page.waitForTimeout(1000) - 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 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 page.mouse.move(hoverPos.x + x, hoverPos.y + y) - await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) + await expect(page.getByTestId('segment-overlay')).toHaveCount(3) + const segmentToDelete = await u.getBoundingBox( + `[data-overlay-index="0"]` + ) - await editor.expectEditor.toContain(lineOfInterest, { - shouldNormalise: true, - }) + 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.getByTestId('overlay-menu').click() - await page.waitForTimeout(100) - await page.getByText('Delete Segment').click() + await page.mouse.move(hoverPos.x + x, hoverPos.y + y) + await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) - 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, { + + 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, }) - // eslint-disable-next-line jest/no-conditional-expect - await editor.expectEditor.not.toContain('seg01', { - 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, + }) + } + }) } } }) @@ -1719,18 +1317,18 @@ part001 = startSketchOn(XZ) 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, tag = $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 ({ + test(`${before.split('=')[0]}${isObj ? '-[obj-input]' : ''}`, async ({ page, editor, homePage, @@ -1739,11 +1337,10 @@ part001 = startSketchOn(XZ) async ({ lineToBeDeleted }) => { localStorage.setItem( 'persistCode', - `@settings(defaultLengthUnit = in) - part001 = startSketchOn(XZ) - |> startProfileAt([5, 6], %) - |> ${ lineToBeDeleted } - |> line(end = [-10, -15]) + `part001 = startSketchOn('XZ') + |> startProfileAt([5, 6], %) + |> ${lineToBeDeleted} + |> line(end = [-10, -15]) |> angledLine(angle = -176, length = segLen(seg01))` ) }, @@ -1766,8 +1363,8 @@ part001 = startSketchOn(XZ) await expect(page.getByTestId('segment-overlay')).toHaveCount(3) 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"]') + const hoverPos = await u.getBoundingBox(`[data-overlay-index="0"]`) + let ang = await u.getAngle(`[data-overlay-index="${0}"]`) ang += 180 await page.mouse.move(0, 0) diff --git a/src/lang/constants.ts b/src/lang/constants.ts index 00032417d..df792d69e 100644 --- a/src/lang/constants.ts +++ b/src/lang/constants.ts @@ -5,3 +5,8 @@ export const ARG_END_ABSOLUTE = 'endAbsolute' export const ARG_CIRCLE_CENTER = 'center' export const ARG_CIRCLE_RADIUS = 'radius' export const DETERMINING_ARGS = [ARG_LENGTH, ARG_END, ARG_END_ABSOLUTE] +export const ARG_LENGTH_X = 'lengthX' +export const ARG_LENGTH_Y = 'lengthY' +export const ARG_ANGLE = 'angle' +export const ARG_END_ABSOLUTE_X = 'endAbsoluteX' +export const ARG_END_ABSOLUTE_Y = 'endAbsoluteY' diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 514062c17..deda76567 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -182,6 +182,7 @@ const commonConstraintInfoHelper = ( pathToNode: PathToNode, filterValue?: string ) => { + console.warn('ADAM: Must be updated to handle angled line kw args') if (callExp.type !== 'CallExpression' && callExp.type !== 'CallExpressionKw') return [] const firstArg = (() => { @@ -235,39 +236,39 @@ const commonConstraintInfoHelper = ( const pathToFirstArg: PathToNode = isArr ? [...pathToArrayExpression, [0, 'index']] : [ - ...pathToArrayExpression, - [ - firstArg.properties.findIndex( - (a) => a.key.name === abbreviatedInputs[0].objInput - ), - 'index', - ], - ['value', 'Property'], - ] + ...pathToArrayExpression, + [ + firstArg.properties.findIndex( + (a) => a.key.name === abbreviatedInputs[0].objInput + ), + 'index', + ], + ['value', 'Property'], + ] const pathToSecondArg: PathToNode = isArr ? [...pathToArrayExpression, [1, 'index']] : [ - ...pathToArrayExpression, - [ - firstArg.properties.findIndex( - (a) => a.key.name === abbreviatedInputs[1].objInput - ), - 'index', - ], - ['value', 'Property'], - ] + ...pathToArrayExpression, + [ + firstArg.properties.findIndex( + (a) => a.key.name === abbreviatedInputs[1].objInput + ), + 'index', + ], + ['value', 'Property'], + ] const input1 = isArr ? firstArg.elements[0] : firstArg.properties.find( - (a) => a.key.name === abbreviatedInputs[0].objInput - )?.value + (a) => a.key.name === abbreviatedInputs[0].objInput + )?.value const input2 = isArr ? firstArg.elements[1] : firstArg.properties.find( - (a) => a.key.name === abbreviatedInputs[1].objInput - )?.value + (a) => a.key.name === abbreviatedInputs[1].objInput + )?.value const constraints: ConstrainInfo[] = [] if (input1) @@ -2169,7 +2170,7 @@ export const circleThreePoint: SketchLineHelperKw = { return finalConstraints }, } -export const angledLine: SketchLineHelper = { +export const angledLine: SketchLineHelperKw = { add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => { if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { from, to } = segmentInput @@ -2181,12 +2182,13 @@ export const angledLine: SketchLineHelper = { const newAngleVal = createLiteral(roundOff(getAngle(from, to), 0)) const newLengthVal = createLiteral(roundOff(getLength(from, to), 2)) - const newLine = createCallExpression('angledLine', [ - createArrayExpression([newAngleVal, newLengthVal]), - createPipeSubstitution(), + const newLine = createCallExpressionStdLibKw('angledLine', null, [ + createLabeledArg('angle', newAngleVal), + createLabeledArg('length', newLengthVal), ]) if (replaceExistingCallback) { + console.warn('ADAM: Probably needs to be adjusted for kw args') const { index: callIndex } = splitPathAtPipeExpression(pathToNode) const result = replaceExistingCallback([ { @@ -2224,7 +2226,7 @@ export const angledLine: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const angle = roundOff(getAngle(from, to), 0) @@ -2234,18 +2236,17 @@ export const angledLine: SketchLineHelper = { const lengthLit = createLiteral(lineLength) const firstArg = callExpression.arguments?.[0] - if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) { - mutateObjExpProp(firstArg, angleLit, 'angle') - mutateObjExpProp(firstArg, lengthLit, 'length') - } + removeDeterminingArgs(callExpression) + mutateKwArg(ARG_ANGLE, callExpression, angleLit) + mutateKwArg(ARG_LENGTH, callExpression, lengthLit) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => commonConstraintInfoHelper( callExp, @@ -2259,7 +2260,7 @@ export const angledLine: SketchLineHelper = { ), } -export const angledLineOfXLength: SketchLineHelper = { +export const angledLineOfXLength: SketchLineHelperKw = { add: ({ node, variables, @@ -2313,9 +2314,9 @@ export const angledLineOfXLength: SketchLineHelper = { if (err(result)) return result newLine = result.callExp } else { - newLine = createCallExpression('angledLineOfXLength', [ - createArrayExpression([angle, xLength]), - createPipeSubstitution(), + newLine = createCallExpressionStdLibKw('angledLineOfXLength', null, [ + createLabeledArg(ARG_ANGLE, angle), + createLabeledArg(ARG_LENGTH_X, xLength), ]) } const { index: callIndex } = splitPathAtPipeExpression(pathToNode) @@ -2333,32 +2334,38 @@ export const angledLineOfXLength: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const angle = roundOff(getAngle(from, to), 0) const xLength = roundOff(Math.abs(to[0] - from[0]), 2) - const firstArg = callExpression.arguments?.[0] - const adjustedXLength = isAngleLiteral(firstArg) + const oldAngle = findKwArg(ARG_ANGLE, callExpression) + if (oldAngle === undefined) { + return new Error( + `expected an angle arg, but it was not found. Args were ${allLabels( + callExpression + )}` + ) + } + const adjustedXLength = isAngleLiteral(oldAngle) ? Math.abs(xLength) : xLength // todo make work for variable angle > 180 const angleLit = createLiteral(angle) const lengthLit = createLiteral(adjustedXLength) - if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) { - mutateObjExpProp(firstArg, angleLit, 'angle') - mutateObjExpProp(firstArg, lengthLit, 'length') - } + removeDeterminingArgs(callExpression) + mutateKwArg(ARG_ANGLE, callExpression, angleLit) + mutateKwArg(ARG_LENGTH_X, callExpression, lengthLit) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => commonConstraintInfoHelper( callExp, @@ -2372,7 +2379,7 @@ export const angledLineOfXLength: SketchLineHelper = { ), } -export const angledLineOfYLength: SketchLineHelper = { +export const angledLineOfYLength: SketchLineHelperKw = { add: ({ node, variables, @@ -2424,9 +2431,9 @@ export const angledLineOfYLength: SketchLineHelper = { if (err(result)) return result newLine = result.callExp } else { - newLine = createCallExpression('angledLineOfYLength', [ - createArrayExpression([angle, yLength]), - createPipeSubstitution(), + newLine = createCallExpressionStdLibKw('angledLine', null, [ + createLabeledArg(ARG_ANGLE, angle), + createLabeledArg(ARG_LENGTH_Y, yLength), ]) } const { index: callIndex } = splitPathAtPipeExpression(pathToNode) @@ -2444,32 +2451,38 @@ export const angledLineOfYLength: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const angle = roundOff(getAngle(from, to), 0) const yLength = roundOff(to[1] - from[1], 2) - const firstArg = callExpression.arguments?.[0] - const adjustedYLength = isAngleLiteral(firstArg) + const oldAngle = findKwArg(ARG_ANGLE, callExpression) + if (oldAngle === undefined) { + return new Error( + `expected an angle arg, but it was not found. Args were ${allLabels( + callExpression + )}` + ) + } + const adjustedYLength = isAngleLiteral(oldAngle) ? Math.abs(yLength) : yLength // todo make work for variable angle > 180 const angleLit = createLiteral(angle) const lengthLit = createLiteral(adjustedYLength) - if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) { - mutateObjExpProp(firstArg, angleLit, 'angle') - mutateObjExpProp(firstArg, lengthLit, 'length') - } + removeDeterminingArgs(callExpression) + mutateKwArg(ARG_ANGLE, callExpression, angleLit) + mutateKwArg(ARG_LENGTH_Y, callExpression, lengthLit) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => commonConstraintInfoHelper( callExp, @@ -2483,7 +2496,7 @@ export const angledLineOfYLength: SketchLineHelper = { ), } -export const angledLineToX: SketchLineHelper = { +export const angledLineToX: SketchLineHelperKw = { add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => { if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { from, to } = segmentInput @@ -2526,9 +2539,9 @@ export const angledLineToX: SketchLineHelper = { } } - const callExp = createCallExpression('angledLineToX', [ - createArrayExpression([angle, xArg]), - createPipeSubstitution(), + const callExp = createCallExpressionStdLibKw('angledLineToX', null, [ + createLabeledArg(ARG_ANGLE, angle), + createLabeledArg(ARG_END_ABSOLUTE_X, xArg), ]) pipe.body = [...pipe.body, callExp] return { @@ -2540,30 +2553,28 @@ export const angledLineToX: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const angle = roundOff(getAngle(from, to), 0) const xLength = roundOff(to[0], 2) - const firstArg = callExpression.arguments?.[0] const adjustedXLength = xLength const angleLit = createLiteral(angle) const lengthLit = createLiteral(adjustedXLength) - if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) { - mutateObjExpProp(firstArg, angleLit, 'angle') - mutateObjExpProp(firstArg, lengthLit, 'to') - } + removeDeterminingArgs(callExpression) + mutateKwArg(ARG_ANGLE, callExpression, angleLit) + mutateKwArg(ARG_END_ABSOLUTE_X, callExpression, lengthLit) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => commonConstraintInfoHelper( callExp, @@ -2577,7 +2588,7 @@ export const angledLineToX: SketchLineHelper = { ), } -export const angledLineToY: SketchLineHelper = { +export const angledLineToY: SketchLineHelperKw = { add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => { if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { from, to } = segmentInput @@ -2622,9 +2633,9 @@ export const angledLineToY: SketchLineHelper = { } } - const newLine = createCallExpression('angledLineToY', [ - createArrayExpression([angle, yArg]), - createPipeSubstitution(), + const newLine = createCallExpressionStdLibKw('angledLine', null, [ + createLabeledArg(ARG_ANGLE, angle), + createLabeledArg(ARG_END_ABSOLUTE_Y, yArg), ]) pipe.body = [...pipe.body, newLine] return { @@ -2636,30 +2647,28 @@ export const angledLineToY: SketchLineHelper = { if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR const { to, from } = input const _node = { ...node } - const nodeMeta = getNodeFromPath(_node, pathToNode) + const nodeMeta = getNodeFromPath(_node, pathToNode) if (err(nodeMeta)) return nodeMeta const { node: callExpression } = nodeMeta const angle = roundOff(getAngle(from, to), 0) const xLength = roundOff(to[1], 2) - const firstArg = callExpression.arguments?.[0] const adjustedXLength = xLength const angleLit = createLiteral(angle) const lengthLit = createLiteral(adjustedXLength) - if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) { - mutateObjExpProp(firstArg, angleLit, 'angle') - mutateObjExpProp(firstArg, lengthLit, 'to') - } + removeDeterminingArgs(callExpression) + mutateKwArg(ARG_ANGLE, callExpression, angleLit) + mutateKwArg(ARG_END_ABSOLUTE_Y, callExpression, lengthLit) return { modifiedAst: _node, pathToNode, } }, - getTag: getTag(), - addTag: addTag(), + getTag: getTagKwArg(), + addTag: addTagKw(), getConstraintInfo: (callExp, ...args) => commonConstraintInfoHelper( callExp, @@ -2750,7 +2759,7 @@ export const angledLineThatIntersects: SketchLineHelper = { const intersectTag = firstArg.type === 'ObjectExpression' ? firstArg.properties.find((p) => p.key.name === 'intersectTag') - ?.value || createLiteral('') + ?.value || createLiteral('') : createLiteral('') const intersectTagName = intersectTag.type === 'Name' ? intersectTag.name.name : '' @@ -2918,11 +2927,6 @@ export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({ } export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = { - angledLine, - angledLineOfXLength, - angledLineOfYLength, - angledLineToX, - angledLineToY, angledLineThatIntersects, tangentialArcTo, arc, @@ -2938,6 +2942,11 @@ export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = { yLine, xLineTo, yLineTo, + angledLine, + angledLineOfXLength, + angledLineOfYLength, + angledLineToX, + angledLineToY, } as const export function changeSketchArguments( @@ -2945,13 +2954,13 @@ export function changeSketchArguments( variables: VariableMap, sourceRangeOrPath: | { - type: 'sourceRange' - sourceRange: SourceRange - } + type: 'sourceRange' + sourceRange: SourceRange + } | { - type: 'path' - pathToNode: PathToNode - }, + type: 'path' + pathToNode: PathToNode + }, input: SegmentInputs ): { modifiedAst: Node; pathToNode: PathToNode } | Error { // TODO/less-than-ideal, this obvious relies on node getting mutated, as changing the following with `_node = structuredClone(node)` breaks the draft line animation. @@ -2983,10 +2992,10 @@ export function changeSketchArguments( }) } if (fnName in sketchLineHelperMapKw) { - const isAbsolute = - callExpression.type === 'CallExpressionKw' && - findKwArg(ARG_END_ABSOLUTE, callExpression) !== undefined - const correctFnName = fnNameToTooltip(isAbsolute, fnName) + const correctFnName = + callExpression.type === 'CallExpressionKw' + ? fnNameToTooltip(allLabels(callExpression), fnName) + : fnName if (err(correctFnName)) { return correctFnName } @@ -3015,9 +3024,11 @@ export function changeSketchArguments( * To put it another way, function names don't map cleanly to tooltips, but function names + arguments do. */ export function fnNameToTooltip( - isAbsolute: boolean, + argLabels: string[], fnName: string ): ToolTip | Error { + const isAbsolute = + argLabels.findIndex((label) => label === ARG_END_ABSOLUTE) >= 0 switch (fnName) { case 'line': return isAbsolute ? 'lineTo' : 'line' @@ -3028,6 +3039,23 @@ export function fnNameToTooltip( case 'circleThreePoint': case 'circle': return fnName + case 'angledLine': { + const argmap: Record = { + ARG_LENGTH_X: 'angledLineOfXLength', + ARG_LENGTH_Y: 'angledLineOfYLength', + ARG_END_ABSOLUTE_X: 'angledLineToX', + ARG_END_ABSOLUTE_Y: 'angledLineToY', + ARG_LENGTH: 'angledLine', + } + for (const [arg, tooltip] of Object.entries(argmap)) { + if (argLabels.findIndex((label) => label === arg) >= 0) { + return tooltip + } + } + const err = `Unknown angledline arguments, could not map to tooltip. Args were ${argLabels}` + console.error(err) + return new Error(err) + } default: const err = `Unknown sketch line function ${fnName}` console.error(err) @@ -3055,6 +3083,12 @@ export function tooltipToFnName(tooltip: ToolTip): string | Error { return 'xLine' case 'yLineTo': return 'yLine' + case 'angledLine': + case 'angledLineToX': + case 'angledLineToY': + case 'angledLineOfXLength': + case 'angledLineOfYLength': + return 'angledLine' default: return new Error(`Unknown tooltip function ${tooltip}`) } @@ -3092,7 +3126,7 @@ export function getConstraintInfoKw( return [] } if (!(fnName in sketchLineHelperMapKw)) return [] - const correctFnName = fnNameToTooltip(isAbsolute, fnName) + const correctFnName = fnNameToTooltip(allLabels(callExpression), fnName) if (err(correctFnName)) { console.error(correctFnName) return [] @@ -3147,9 +3181,9 @@ export function addNewSketchLn({ spliceBetween = false, }: CreateLineFnCallArgs): | { - modifiedAst: Node - pathToNode: PathToNode - } + modifiedAst: Node + pathToNode: PathToNode + } | Error { const node = structuredClone(_node) const { add, updateArgs } = @@ -3244,10 +3278,10 @@ export function replaceSketchLine({ referencedSegment?: Path }): | { - modifiedAst: Node - valueUsedInTransform?: number - pathToNode: PathToNode - } + modifiedAst: Node + valueUsedInTransform?: number + pathToNode: PathToNode + } | Error { if (![...toolTips, 'intersect', 'circle'].includes(fnName)) { return new Error(`The following function name is not tooltip: ${fnName}`) @@ -3299,9 +3333,9 @@ function addTagToChamfer( edgeCutMeta: EdgeCutInfo ): | { - modifiedAst: Node - tag: string - } + modifiedAst: Node + tag: string + } | Error { const _node = structuredClone(tagInfo.node) let pipeIndex = 0 @@ -3416,9 +3450,9 @@ export function addTagForSketchOnFace( edgeCutMeta: EdgeCutInfo | null ): | { - modifiedAst: Node - tag: string - } + modifiedAst: Node + tag: string + } | Error { if (expressionName === 'close') { return addTagKw()(tagInfo) @@ -3453,15 +3487,35 @@ export function getTagFromCallExpression( return new Error(`"${callExp.callee.name.name}" is not a sketch line helper`) } +<<<<<<< HEAD function isAngleLiteral(lineArugement: Expr): boolean { return lineArugement?.type === 'ArrayExpression' ? isLiteralArrayOrStatic(lineArugement.elements[0]) : lineArugement?.type === 'ObjectExpression' ? isLiteralArrayOrStatic( - lineArugement.properties.find(({ key }) => key.name === 'angle') - ?.value - ) + lineArugement.properties.find(({ key }) => key.name === 'angle') + ?.value + ) : false +||||||| parent of 27a8a2a50 (Start changing JS codemods) +function isAngleLiteral(lineArugement: Expr): boolean { + return lineArugement?.type === 'ArrayExpression' + ? isLiteralArrayOrStatic(lineArugement.elements[0]) + : lineArugement?.type === 'ObjectExpression' + ? isLiteralArrayOrStatic( + lineArugement.properties.find(({ key }) => key.name === 'angle')?.value + ) + : false +======= +function isAngleLiteral(lineArgument: Expr): boolean { + return lineArgument?.type === 'ArrayExpression' + ? isLiteralArrayOrStatic(lineArgument.elements[0]) + : lineArgument?.type === 'ObjectExpression' + ? isLiteralArrayOrStatic( + lineArgument.properties.find(({ key }) => key.name === 'angle')?.value + ) + : lineArgument?.type === 'Literal' +>>>>>>> 27a8a2a50 (Start changing JS codemods) } type addTagFn = ( @@ -3522,14 +3576,14 @@ function addTagKw(): addTagFn { callExpr.node.type === 'CallExpressionKw' ? callExpr.node : { - type: 'CallExpressionKw', - callee: callExpr.node.callee, - unlabeled: callExpr.node.arguments.length - ? callExpr.node.arguments[0] - : null, - nonCodeMeta: nonCodeMetaEmpty(), - arguments: [], - } + type: 'CallExpressionKw', + callee: callExpr.node.callee, + unlabeled: callExpr.node.arguments.length + ? callExpr.node.arguments[0] + : null, + nonCodeMeta: nonCodeMetaEmpty(), + arguments: [], + } const tagArg = findKwArg(ARG_TAG, primaryCallExp) const tagDeclarator = tagArg || createTagDeclarator(findUniqueName(_node, 'seg', 2)) @@ -3586,9 +3640,9 @@ export function getXComponent( function getFirstArgValuesForXYFns(callExpression: CallExpression): | { - val: [Expr, Expr] - tag?: Expr - } + val: [Expr, Expr] + tag?: Expr + } | Error { // used for lineTo, line const firstArg = callExpression.arguments[0] @@ -3597,9 +3651,9 @@ function getFirstArgValuesForXYFns(callExpression: CallExpression): function getValuesForXYFns(arg: Expr): | { - val: [Expr, Expr] - tag?: Expr - } + val: [Expr, Expr] + tag?: Expr + } | Error { if (arg.type === 'ArrayExpression') { return { val: [arg.elements[0], arg.elements[1]] } @@ -3617,9 +3671,9 @@ function getValuesForXYFns(arg: Expr): function getFirstArgValuesForAngleFns(callExpression: CallExpression): | { - val: [Expr, Expr] - tag?: Expr - } + val: [Expr, Expr] + tag?: Expr + } | Error { // used for angledLine, angledLineOfXLength, angledLineToX, angledLineOfYLength, angledLineToY const firstArg = callExpression.arguments[0] @@ -3676,9 +3730,9 @@ export const getCircle = ( callExp: CallExpressionKw ): | { - val: [Expr, Expr, Expr] - tag?: Expr - } + val: [Expr, Expr, Expr] + tag?: Expr + } | Error => { const firstArg = callExp.arguments[0] if (firstArg.type === 'LabeledArg') { @@ -3704,9 +3758,9 @@ const getAngledLineThatIntersects = ( callExp: CallExpression ): | { - val: [Expr, Expr, Expr] - tag?: Expr - } + val: [Expr, Expr, Expr] + tag?: Expr + } | Error => { const firstArg = callExp.arguments[0] if (firstArg.type === 'ObjectExpression') { @@ -3765,9 +3819,9 @@ Also known as the 'determining' arg. */ export function getArgForEnd(lineCall: CallExpressionKw): | { - val: Expr | [Expr, Expr] | [Expr, Expr, Expr] - tag?: Expr - } + val: Expr | [Expr, Expr] | [Expr, Expr, Expr] + tag?: Expr + } | Error { const name = lineCall?.callee?.name.name @@ -3782,7 +3836,7 @@ export function getArgForEnd(lineCall: CallExpressionKw): return getValuesForXYFns(arg) } case 'yLine': - case 'xLine': + case 'xLine': { const arg = findKwArgAny(DETERMINING_ARGS, lineCall) const tag = findKwArg(ARG_TAG, lineCall) if (arg === undefined) { @@ -3790,6 +3844,30 @@ export function getArgForEnd(lineCall: CallExpressionKw): } else { return { val: arg, tag } } + } + case 'angledLine': { + const angle = findKwArg(ARG_ANGLE, lineCall) + if (angle === undefined) { + return new Error(`call to ${name} needs an ${ARG_ANGLE} arg`) + } + const length = findKwArgAny( + [ + ARG_LENGTH, + ARG_LENGTH_X, + ARG_LENGTH_Y, + ARG_END_ABSOLUTE_X, + ARG_END_ABSOLUTE_Y, + ], + lineCall + ) + if (length === undefined) { + return new Error( + `call to ${name} needs an arg like ${ARG_LENGTH}, or ${ARG_END_ABSOLUTE_X} or something` + ) + } + const tag = findKwArg(ARG_TAG, lineCall) + return { val: [angle, length], tag } + } default: return new Error(`unknown function ${name}`) } @@ -3797,9 +3875,9 @@ export function getArgForEnd(lineCall: CallExpressionKw): export function getFirstArg(callExp: CallExpression): | { - val: Expr | [Expr, Expr] | [Expr, Expr, Expr] - tag?: Expr - } + val: Expr | [Expr, Expr] | [Expr, Expr, Expr] + tag?: Expr + } | Error { const name = callExp?.callee?.name.name if ( diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts index 17aa4cbba..fcbe6723b 100644 --- a/src/lang/std/sketchcombos.ts +++ b/src/lang/std/sketchcombos.ts @@ -5,7 +5,12 @@ import { ARG_END_ABSOLUTE, ARG_LENGTH, ARG_TAG, + ARG_ANGLE, DETERMINING_ARGS, + ARG_END_ABSOLUTE_X, + ARG_END_ABSOLUTE_Y, + ARG_LENGTH_X, + ARG_LENGTH_Y, } from '@src/lang/constants' import { createArrayExpression, @@ -162,6 +167,43 @@ function createCallWrapper( valueUsedInTransform, } } + if ( + tooltip === 'angledLine' || + tooltip === 'angledLineToX' || + tooltip === 'angledLineToY' || + tooltip === 'angledLineOfXLength' || + tooltip === 'angledLineOfYLength' + ) { + const args = [createLabeledArg(ARG_ANGLE, val[0])] + const v = val[1] + args.push( + (() => { + switch (tooltip) { + case 'angledLine': + return createLabeledArg(ARG_LENGTH, v) + case 'angledLineToX': + return createLabeledArg(ARG_END_ABSOLUTE_X, v) + case 'angledLineToY': + return createLabeledArg(ARG_END_ABSOLUTE_Y, v) + case 'angledLineOfXLength': + return createLabeledArg(ARG_LENGTH_X, v) + case 'angledLineOfYLength': + return createLabeledArg(ARG_LENGTH_Y, v) + } + })() + ) + if (tag) { + args.push(createLabeledArg(ARG_TAG, tag)) + } + return { + callExp: createCallExpressionStdLibKw( + 'angledLine', + null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution. + args + ), + valueUsedInTransform, + } + } } else { // In this branch, `val` is an expression. const arg = (() => { @@ -321,17 +363,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 = @@ -340,49 +382,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, @@ -453,57 +495,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 - - 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], + ({ + referenceSegName, tag, - valueUsedInTransform - ) - } + 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 setHorzVertDistanceForAngleLineCreateNode = (xOrY: 'x' | 'y', index = xOrY === 'x' ? 0 : 1): CreateStdLibSketchCallExpr => - ({ - 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], + ({ + referenceSegName, tag, - valueUsedInTransform - ) - } + 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 + ) + } const setAbsDistanceCreateNode = ( @@ -511,94 +553,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) { + ({ 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 + ) + } return createCallWrapper( - xOrY === 'x' ? 'xLineTo' : 'yLineTo', - val, + 'lineTo', + !index ? [val, args[1].expr] : [args[0].expr, 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, - 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, + ({ + referenceSegName, tag, - valueUsedInTransform - ) - } + 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 + ) + } 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, - ]) - - 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)), + ({ 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 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, @@ -651,48 +693,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([ - 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], + ({ + referenceSegName, tag, - valueUsedInTransform - ) - } + 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([ + 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: @@ -1506,7 +1548,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) => @@ -1612,10 +1654,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)) { @@ -1669,10 +1711,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') { @@ -1685,8 +1727,7 @@ function getTransformMapPathKw( } return false } - const isAbsolute = findKwArg(ARG_END_ABSOLUTE, sketchFnExp) !== undefined - const tooltip = fnNameToTooltip(isAbsolute, name) + const tooltip = fnNameToTooltip(allLabels(sketchFnExp), name) if (err(tooltip)) { return false } @@ -1717,6 +1758,7 @@ function getTransformMapPathKw( } // check what constraints the function has + const isAbsolute = findKwArg(ARG_END_ABSOLUTE, sketchFnExp) !== undefined const lineInputType = getConstraintType(argForEnd.val, name, isAbsolute) if (lineInputType) { const info = transformMap?.[tooltip]?.[lineInputType]?.[constraintType] @@ -1873,14 +1915,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) @@ -1952,10 +1994,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) @@ -2100,25 +2142,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({ diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 30ff5576a..2068096c5 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,7 +2,7 @@ import type { Binary as BSONBinary } from 'bson' import { v4 } from 'uuid' import type { AnyMachineSnapshot } from 'xstate' -import type { SourceRange } from '@src/lang/wasm' +import type { CallExpressionKw, SourceRange } from '@src/lang/wasm' import { isDesktop } from '@src/lib/isDesktop' import type { AsyncFn } from '@src/lib/types' @@ -469,3 +469,7 @@ export function binaryToUuid( hexValues.slice(10, 16).join(''), ].join('-') } + +export function allLabels(callExpression: CallExpressionKw): string[] { + return callExpression.arguments.map((a) => a.label.name) +}