Check for local name clash with existing variables in Insert flow (#6375)

Check for local name alias clashes with extisting var in Insert flow
Fixes #6230
This commit is contained in:
Pierre Jacquier
2025-04-21 06:35:43 -04:00
committed by GitHub
parent 790613e708
commit 0dee219e46
5 changed files with 62 additions and 13 deletions

View File

@ -143,28 +143,45 @@ test.describe('Point-and-click assemblies tests', () => {
await scene.settled(cmdBar)
})
await test.step('Insert a second time and expect error', async () => {
// TODO: revisit once we have clone with #6209
await insertPartIntoAssembly(
'bracket.kcl',
'bracket',
toolbar,
cmdBar,
page
)
await test.step('Insert a second time with the same name and expect error', async () => {
await toolbar.insertButton.click()
await cmdBar.selectOption({ name: 'bracket.kcl' }).click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'localName',
currentArgValue: '',
headerArguments: { Path: 'bracket.kcl', LocalName: '' },
highlightedHeaderArg: 'localName',
commandName: 'Insert',
})
await page.keyboard.insertText('bracket')
await cmdBar.progressCmdBar()
await expect(
page.getByText('This variable name is already in use')
).toBeVisible()
})
await test.step('Insert a second time with a different name and expect error', async () => {
await page.keyboard.insertText('2')
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
headerArguments: { Path: 'bracket.kcl', LocalName: 'bracket2' },
commandName: 'Insert',
})
await cmdBar.progressCmdBar()
await editor.expectEditor.toContain(
`
import "cylinder.kcl" as cylinder
import "bracket.kcl" as bracket
import "bracket.kcl" as bracket
import "bracket.kcl" as bracket2
cylinder
bracket
bracket
bracket2
`,
{ shouldNormalise: true }
)
await scene.settled(cmdBar)
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// TODO: update once we have clone() with #6209
})
}
)

View File

@ -220,6 +220,13 @@ export type CommandArgumentConfig<
machineContext?: C
) => OutputType)
defaultValueFromContext?: (context: C) => OutputType
validation?: ({
data,
context,
}: {
data: any
context: CommandBarContext
}) => Promise<boolean | string>
}
| {
inputType: 'text'
@ -343,6 +350,13 @@ export type CommandArgument<
commandBarContext: ContextFrom<typeof commandBarMachine>,
machineContext?: ContextFrom<T>
) => OutputType)
validation?: ({
data,
context,
}: {
data: any
context: CommandBarContext
}) => Promise<boolean | string>
}
| {
inputType: 'path'

View File

@ -211,6 +211,15 @@ export function buildCommandArgument<
defaultValue: arg.defaultValue,
...baseCommandArgument,
} satisfies CommandArgument<O, T> & { inputType: 'kcl' }
} else if (arg.inputType === 'string') {
return {
inputType: arg.inputType,
defaultValue: arg.defaultValueFromContext
? arg.defaultValueFromContext(context)
: arg.defaultValue,
validation: arg.validation,
...baseCommandArgument,
} satisfies CommandArgument<O, T> & { inputType: 'string' }
} else {
return {
inputType: arg.inputType,

View File

@ -133,6 +133,14 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] {
const path = context.argumentsToSubmit['path'] as string
return getPathFilenameInVariableCase(path)
},
validation: async ({ data, context }) => {
const variableExists = kclManager.variables[data.localName]
if (variableExists) {
return 'This variable name is already in use.'
}
return true
},
},
},
onSubmit: (data) => {

View File

@ -307,6 +307,7 @@ export const commandBarMachine = setup({
context.currentArgument &&
context.selectedCommand &&
(argConfig?.inputType === 'selection' ||
argConfig?.inputType === 'string' ||
argConfig?.inputType === 'selectionMixed') &&
argConfig?.validation
) {