Fix bug with selection order on multi-select constraints (#4138)

* Sort selections in order of appearance before applying `transformSecondarySketchLinesTagFirst`

* Add an integration test for this sorting behavior

* Remove console logs from test
This commit is contained in:
Frank Noirot
2024-10-11 09:49:58 -04:00
committed by GitHub
parent 1fd4aa9ede
commit 23c2aa948a
2 changed files with 84 additions and 2 deletions

View File

@ -9,7 +9,7 @@ import {
getConstraintLevelFromSourceRange, getConstraintLevelFromSourceRange,
} from './sketchcombos' } from './sketchcombos'
import { ToolTip } from 'lang/langHelpers' import { ToolTip } from 'lang/langHelpers'
import { Selections } from 'lib/selections' import { Selection, Selections } from 'lib/selections'
import { err } from 'lib/trap' import { err } from 'lib/trap'
import { enginelessExecutor } from '../../lib/testHelpers' import { enginelessExecutor } from '../../lib/testHelpers'
@ -96,6 +96,86 @@ function makeSelections(
} }
describe('testing transformAstForSketchLines for equal length constraint', () => { describe('testing transformAstForSketchLines for equal length constraint', () => {
describe(`should always reorder selections to have the base selection first`, () => {
const inputScript = `sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([5, 5], %)
|> line([-2, 5], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)`
const expectedModifiedScript = `sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([5, 5], %, $seg01)
|> angledLine([112, segLen(seg01)], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
`
const selectLine = (script: string, lineNumber: number): Selection => {
const lines = script.split('\n')
const codeBeforeLine = lines.slice(0, lineNumber).join('\n').length
const line = lines.find((_, i) => i === lineNumber)
if (!line) {
throw new Error(
`line index ${lineNumber} not found in test sample, friend`
)
}
const start = codeBeforeLine + line.indexOf('|> ' + 5)
const range: [number, number] = [start, start]
return {
type: 'default',
range,
}
}
async function applyTransformation(
inputCode: string,
selectionRanges: Selections['codeBasedSelections']
) {
const ast = parse(inputCode)
if (err(ast)) return Promise.reject(ast)
const execState = await enginelessExecutor(ast)
const transformInfos = getTransformInfos(
makeSelections(selectionRanges.slice(1)),
ast,
'equalLength'
)
const transformedSelection = makeSelections(selectionRanges)
const newAst = transformSecondarySketchLinesTagFirst({
ast,
selectionRanges: transformedSelection,
transformInfos,
programMemory: execState.memory,
})
if (err(newAst)) return Promise.reject(newAst)
const newCode = recast(newAst.modifiedAst)
return newCode
}
it(`Should reorder when user selects first-to-last`, async () => {
const selectionRanges: Selections['codeBasedSelections'] = [
selectLine(inputScript, 3),
selectLine(inputScript, 4),
]
const newCode = await applyTransformation(inputScript, selectionRanges)
expect(newCode).toBe(expectedModifiedScript)
})
it(`Should reorder when user selects last-to-first`, async () => {
const selectionRanges: Selections['codeBasedSelections'] = [
selectLine(inputScript, 4),
selectLine(inputScript, 3),
]
const newCode = await applyTransformation(inputScript, selectionRanges)
expect(newCode).toBe(expectedModifiedScript)
})
})
const inputScript = `myVar = 3 const inputScript = `myVar = 3
myVar2 = 5 myVar2 = 5
myVar3 = 6 myVar3 = 6

View File

@ -1559,7 +1559,9 @@ export function transformSecondarySketchLinesTagFirst({
} }
| Error { | Error {
// let node = structuredClone(ast) // let node = structuredClone(ast)
const primarySelection = selectionRanges.codeBasedSelections[0].range const primarySelection = selectionRanges.codeBasedSelections.sort(
(a, b) => a.range[0] - b.range[0]
)[0].range
const _tag = giveSketchFnCallTag(ast, primarySelection, forceSegName) const _tag = giveSketchFnCallTag(ast, primarySelection, forceSegName)
if (err(_tag)) return _tag if (err(_tag)) return _tag