Skip to content

Commit 0dee219

Browse files
authored
Check for local name clash with existing variables in Insert flow (KittyCAD#6375)
Check for local name alias clashes with extisting var in Insert flow Fixes KittyCAD#6230
1 parent 790613e commit 0dee219

File tree

5 files changed

+62
-13
lines changed

5 files changed

+62
-13
lines changed

e2e/playwright/point-click-assemblies.spec.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,28 +143,45 @@ test.describe('Point-and-click assemblies tests', () => {
143143
await scene.settled(cmdBar)
144144
})
145145

146-
await test.step('Insert a second time and expect error', async () => {
147-
// TODO: revisit once we have clone with #6209
148-
await insertPartIntoAssembly(
149-
'bracket.kcl',
150-
'bracket',
151-
toolbar,
152-
cmdBar,
153-
page
154-
)
146+
await test.step('Insert a second time with the same name and expect error', async () => {
147+
await toolbar.insertButton.click()
148+
await cmdBar.selectOption({ name: 'bracket.kcl' }).click()
149+
await cmdBar.expectState({
150+
stage: 'arguments',
151+
currentArgKey: 'localName',
152+
currentArgValue: '',
153+
headerArguments: { Path: 'bracket.kcl', LocalName: '' },
154+
highlightedHeaderArg: 'localName',
155+
commandName: 'Insert',
156+
})
157+
await page.keyboard.insertText('bracket')
158+
await cmdBar.progressCmdBar()
159+
await expect(
160+
page.getByText('This variable name is already in use')
161+
).toBeVisible()
162+
})
163+
164+
await test.step('Insert a second time with a different name and expect error', async () => {
165+
await page.keyboard.insertText('2')
166+
await cmdBar.progressCmdBar()
167+
await cmdBar.expectState({
168+
stage: 'review',
169+
headerArguments: { Path: 'bracket.kcl', LocalName: 'bracket2' },
170+
commandName: 'Insert',
171+
})
172+
await cmdBar.progressCmdBar()
155173
await editor.expectEditor.toContain(
156174
`
157175
import "cylinder.kcl" as cylinder
158176
import "bracket.kcl" as bracket
159-
import "bracket.kcl" as bracket
177+
import "bracket.kcl" as bracket2
160178
cylinder
161179
bracket
162-
bracket
180+
bracket2
163181
`,
164182
{ shouldNormalise: true }
165183
)
166-
await scene.settled(cmdBar)
167-
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
184+
// TODO: update once we have clone() with #6209
168185
})
169186
}
170187
)

src/lib/commandTypes.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ export type CommandArgumentConfig<
220220
machineContext?: C
221221
) => OutputType)
222222
defaultValueFromContext?: (context: C) => OutputType
223+
validation?: ({
224+
data,
225+
context,
226+
}: {
227+
data: any
228+
context: CommandBarContext
229+
}) => Promise<boolean | string>
223230
}
224231
| {
225232
inputType: 'text'
@@ -343,6 +350,13 @@ export type CommandArgument<
343350
commandBarContext: ContextFrom<typeof commandBarMachine>,
344351
machineContext?: ContextFrom<T>
345352
) => OutputType)
353+
validation?: ({
354+
data,
355+
context,
356+
}: {
357+
data: any
358+
context: CommandBarContext
359+
}) => Promise<boolean | string>
346360
}
347361
| {
348362
inputType: 'path'

src/lib/createMachineCommand.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,15 @@ export function buildCommandArgument<
211211
defaultValue: arg.defaultValue,
212212
...baseCommandArgument,
213213
} satisfies CommandArgument<O, T> & { inputType: 'kcl' }
214+
} else if (arg.inputType === 'string') {
215+
return {
216+
inputType: arg.inputType,
217+
defaultValue: arg.defaultValueFromContext
218+
? arg.defaultValueFromContext(context)
219+
: arg.defaultValue,
220+
validation: arg.validation,
221+
...baseCommandArgument,
222+
} satisfies CommandArgument<O, T> & { inputType: 'string' }
214223
} else {
215224
return {
216225
inputType: arg.inputType,

src/lib/kclCommands.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] {
133133
const path = context.argumentsToSubmit['path'] as string
134134
return getPathFilenameInVariableCase(path)
135135
},
136+
validation: async ({ data, context }) => {
137+
const variableExists = kclManager.variables[data.localName]
138+
if (variableExists) {
139+
return 'This variable name is already in use.'
140+
}
141+
142+
return true
143+
},
136144
},
137145
},
138146
onSubmit: (data) => {

src/machines/commandBarMachine.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ export const commandBarMachine = setup({
307307
context.currentArgument &&
308308
context.selectedCommand &&
309309
(argConfig?.inputType === 'selection' ||
310+
argConfig?.inputType === 'string' ||
310311
argConfig?.inputType === 'selectionMixed') &&
311312
argConfig?.validation
312313
) {

0 commit comments

Comments
 (0)