Skip to content

Commit 225813d

Browse files
committed
final tests
1 parent 1ee4bf8 commit 225813d

1 file changed

Lines changed: 177 additions & 0 deletions

File tree

exercises/99.finished/01.solution.finished/src/index.test.ts

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,183 @@ test('Tool Definition', async () => {
8080
)
8181
})
8282

83+
test('Tool annotations and structured output', async () => {
84+
await using setup = await setupClient()
85+
const { client } = setup
86+
87+
// Check create_entry and create_tag annotations (always enabled)
88+
let list = await client.listTools()
89+
let toolMap = Object.fromEntries(list.tools.map((t) => [t.name, t]))
90+
91+
// Check create_entry annotations
92+
const createEntryTool = toolMap['create_entry']
93+
invariant(createEntryTool, '🚨 create_entry tool not found')
94+
expect(
95+
createEntryTool.annotations,
96+
'🚨 create_entry missing annotations',
97+
).toEqual(
98+
expect.objectContaining({
99+
destructiveHint: false,
100+
openWorldHint: false,
101+
}),
102+
)
103+
104+
// Check create_tag annotations
105+
const createTagTool = toolMap['create_tag']
106+
invariant(createTagTool, '🚨 create_tag tool not found')
107+
expect(
108+
createTagTool.annotations,
109+
'🚨 create_tag missing annotations',
110+
).toEqual(
111+
expect.objectContaining({
112+
destructiveHint: false,
113+
openWorldHint: false,
114+
}),
115+
)
116+
117+
// Create a tag and entry for further tool calls
118+
const tagResult = await client.callTool({
119+
name: 'create_tag',
120+
arguments: {
121+
name: 'TestTag',
122+
description: 'A tag for testing',
123+
},
124+
})
125+
expect(
126+
tagResult.structuredContent,
127+
'🚨 tagResult.structuredContent should be defined',
128+
).toBeDefined()
129+
const tag = (tagResult.structuredContent as any).tag
130+
invariant(tag, '🚨 No tag resource found')
131+
invariant(tag.id, '🚨 No tag ID found')
132+
133+
const entryResult = await client.callTool({
134+
name: 'create_entry',
135+
arguments: {
136+
title: 'Test Entry',
137+
content: 'This is a test entry',
138+
},
139+
})
140+
expect(
141+
entryResult.structuredContent,
142+
'🚨 entryResult.structuredContent should be defined',
143+
).toBeDefined()
144+
const entry = (entryResult.structuredContent as any).entry
145+
invariant(entry, '🚨 No entry resource found')
146+
invariant(entry.id, '🚨 No entry ID found')
147+
148+
// List tools again now that entry and tag exist
149+
list = await client.listTools()
150+
toolMap = Object.fromEntries(list.tools.map((t) => [t.name, t]))
151+
152+
// Check delete_entry annotations
153+
const deleteEntryTool = toolMap['delete_entry']
154+
invariant(deleteEntryTool, '🚨 delete_entry tool not found')
155+
expect(
156+
deleteEntryTool.annotations,
157+
'🚨 delete_entry missing annotations',
158+
).toEqual(
159+
expect.objectContaining({
160+
idempotentHint: true,
161+
openWorldHint: false,
162+
}),
163+
)
164+
165+
// Check delete_tag annotations
166+
const deleteTagTool = toolMap['delete_tag']
167+
invariant(deleteTagTool, '🚨 delete_tag tool not found')
168+
expect(
169+
deleteTagTool.annotations,
170+
'🚨 delete_tag missing annotations',
171+
).toEqual(
172+
expect.objectContaining({
173+
idempotentHint: true,
174+
openWorldHint: false,
175+
}),
176+
)
177+
178+
// get_entry structuredContent
179+
const getEntryResult = await client.callTool({
180+
name: 'get_entry',
181+
arguments: { id: entry.id },
182+
})
183+
const getEntryContent = (getEntryResult.structuredContent as any).entry
184+
invariant(getEntryContent, '🚨 get_entry missing entry in structuredContent')
185+
expect(getEntryContent.id, '🚨 get_entry structuredContent.id mismatch').toBe(
186+
entry.id,
187+
)
188+
189+
// get_tag structuredContent
190+
const getTagResult = await client.callTool({
191+
name: 'get_tag',
192+
arguments: { id: tag.id },
193+
})
194+
const getTagContent = (getTagResult.structuredContent as any).tag
195+
invariant(getTagContent, '🚨 get_tag missing tag in structuredContent')
196+
expect(getTagContent.id, '🚨 get_tag structuredContent.id mismatch').toBe(
197+
tag.id,
198+
)
199+
200+
// update_entry structuredContent
201+
const updateEntryResult = await client.callTool({
202+
name: 'update_entry',
203+
arguments: { id: entry.id, title: 'Updated Entry' },
204+
})
205+
const updateEntryContent = (updateEntryResult.structuredContent as any).entry
206+
invariant(
207+
updateEntryContent,
208+
'🚨 update_entry missing entry in structuredContent',
209+
)
210+
expect(
211+
updateEntryContent.title,
212+
'🚨 update_entry structuredContent.title mismatch',
213+
).toBe('Updated Entry')
214+
215+
// update_tag structuredContent
216+
const updateTagResult = await client.callTool({
217+
name: 'update_tag',
218+
arguments: { id: tag.id, name: 'UpdatedTag' },
219+
})
220+
const updateTagContent = (updateTagResult.structuredContent as any).tag
221+
invariant(updateTagContent, '🚨 update_tag missing tag in structuredContent')
222+
expect(
223+
updateTagContent.name,
224+
'🚨 update_tag structuredContent.name mismatch',
225+
).toBe('UpdatedTag')
226+
227+
// delete_entry structuredContent
228+
const deleteEntryResult = await client.callTool({
229+
name: 'delete_entry',
230+
arguments: { id: entry.id },
231+
})
232+
const deleteEntryContent = deleteEntryResult.structuredContent as any
233+
invariant(deleteEntryContent, '🚨 delete_entry missing structuredContent')
234+
expect(
235+
deleteEntryContent.success,
236+
'🚨 delete_entry structuredContent.success should be true',
237+
).toBe(true)
238+
expect(
239+
deleteEntryContent.entry.id,
240+
'🚨 delete_entry structuredContent.entry.id mismatch',
241+
).toBe(entry.id)
242+
243+
// delete_tag structuredContent
244+
const deleteTagResult = await client.callTool({
245+
name: 'delete_tag',
246+
arguments: { id: tag.id },
247+
})
248+
const deleteTagContent = deleteTagResult.structuredContent as any
249+
invariant(deleteTagContent, '🚨 delete_tag missing structuredContent')
250+
expect(
251+
deleteTagContent.success,
252+
'🚨 delete_tag structuredContent.success should be true',
253+
).toBe(true)
254+
expect(
255+
deleteTagContent.tag.id,
256+
'🚨 delete_tag structuredContent.tag.id mismatch',
257+
).toBe(tag.id)
258+
})
259+
83260
async function deferred<ResolvedValue>() {
84261
const ref = {} as {
85262
promise: Promise<ResolvedValue>

0 commit comments

Comments
 (0)