Skip to content

Commit 0b93551

Browse files
committed
test(windchill): assert block and tool params stay aligned for every operation
Validating the new operation surfaced that nothing enforced the block-to-tool alignment the review process had been checking by hand. Assert it for all 27 operations instead: every required tool param has a required, non-advanced input under that operation's condition, and no operation shows an input its tool cannot accept. Both fail on a deliberately broken condition or a dropped required flag.
1 parent d20ac2f commit 0b93551

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

apps/sim/tools/windchill/windchill.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,51 @@ describe('Windchill tools', () => {
125125
}
126126
})
127127

128+
it('gives every required tool param a required, non-advanced input for its operation', () => {
129+
const subBlocks = WindchillBlock.subBlocks
130+
const ALWAYS_SHOWN = new Set(['baseUrl', 'username', 'password'])
131+
const shownFor = (subBlock: (typeof subBlocks)[number], operation: string) => {
132+
const condition = subBlock.condition as { value?: unknown } | undefined
133+
if (!condition) return true
134+
const value = condition.value
135+
return Array.isArray(value) ? value.includes(operation) : value === operation
136+
}
137+
138+
for (const [operation, tool] of WINDCHILL_TOOLS_BY_ID) {
139+
for (const [name, param] of Object.entries(tool.params)) {
140+
if (!param.required || ALWAYS_SHOWN.has(name)) continue
141+
const members = subBlocks.filter(
142+
(subBlock) =>
143+
(subBlock.canonicalParamId ?? subBlock.id) === name && shownFor(subBlock, operation)
144+
)
145+
expect(
146+
members.length,
147+
`${operation} has no input for required param ${name}`
148+
).toBeGreaterThan(0)
149+
for (const member of members) {
150+
expect(member.required, `${operation}.${name} input is not required`).toBeTruthy()
151+
}
152+
}
153+
}
154+
})
155+
156+
it("shows no input an operation's tool cannot accept", () => {
157+
const subBlocks = WindchillBlock.subBlocks
158+
for (const [operation, tool] of WINDCHILL_TOOLS_BY_ID) {
159+
const dead = subBlocks
160+
.filter((subBlock) => {
161+
if (subBlock.id === 'operation') return false
162+
const condition = subBlock.condition as { value?: unknown } | undefined
163+
if (!condition) return false
164+
const value = condition.value
165+
return Array.isArray(value) ? value.includes(operation) : value === operation
166+
})
167+
.map((subBlock) => subBlock.canonicalParamId ?? subBlock.id)
168+
.filter((id) => !(id in tool.params))
169+
expect(dead, `${operation} shows inputs its tool ignores`).toEqual([])
170+
}
171+
})
172+
128173
it('wires every operation to the outputs family its producer actually emits', () => {
129174
const expected: Record<WindchillOperation, unknown> = {
130175
windchill_list_documents: WINDCHILL_LIST_DOCUMENTS_OUTPUTS,

0 commit comments

Comments
 (0)