Skip to content

Commit 77d9203

Browse files
Update tests for exercise validation (#8)
Co-authored-by: me <[email protected]> Co-authored-by: Cursor Agent <[email protected]>
1 parent a932bd1 commit 77d9203

File tree

31 files changed

+1993
-171
lines changed

31 files changed

+1993
-171
lines changed

exercises/01.ping/01.problem.connect/src/index.test.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,35 @@ beforeAll(async () => {
1313
command: 'tsx',
1414
args: ['src/index.ts'],
1515
})
16-
await client.connect(transport)
16+
17+
try {
18+
await client.connect(transport)
19+
} catch (error: any) {
20+
console.error('🚨 Connection failed! This exercise requires implementing the main function in src/index.ts')
21+
console.error('🚨 Replace the "throw new Error(\'Not implemented\')" with the actual MCP server setup')
22+
console.error('🚨 You need to: 1) Create an EpicMeMCP instance, 2) Initialize it, 3) Connect to stdio transport')
23+
console.error('Original error:', error.message || error)
24+
throw error
25+
}
1726
})
1827

1928
afterAll(async () => {
2029
await client.transport?.close()
2130
})
2231

2332
test('Ping', async () => {
24-
const result = await client.ping()
25-
26-
expect(result).toEqual({})
33+
try {
34+
const result = await client.ping()
35+
expect(result).toEqual({})
36+
} catch (error: any) {
37+
if (error.message?.includes('Connection closed') || error.code === -32000) {
38+
console.error('🚨 Ping failed because the MCP server crashed!')
39+
console.error('🚨 This means the main() function in src/index.ts is not properly implemented')
40+
console.error('🚨 Check that you\'ve replaced the "Not implemented" error with actual server setup code')
41+
const enhancedError = new Error('🚨 MCP server implementation required in main() function. ' + (error.message || error))
42+
enhancedError.stack = error.stack
43+
throw enhancedError
44+
}
45+
throw error
46+
}
2747
})

exercises/01.ping/01.solution.connect/src/index.test.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,35 @@ beforeAll(async () => {
1313
command: 'tsx',
1414
args: ['src/index.ts'],
1515
})
16-
await client.connect(transport)
16+
17+
try {
18+
await client.connect(transport)
19+
} catch (error: any) {
20+
console.error('🚨 Connection failed! This exercise requires implementing the main function in src/index.ts')
21+
console.error('🚨 Replace the "throw new Error(\'Not implemented\')" with the actual MCP server setup')
22+
console.error('🚨 You need to: 1) Create an EpicMeMCP instance, 2) Initialize it, 3) Connect to stdio transport')
23+
console.error('Original error:', error.message || error)
24+
throw error
25+
}
1726
})
1827

1928
afterAll(async () => {
2029
await client.transport?.close()
2130
})
2231

2332
test('Ping', async () => {
24-
const result = await client.ping()
25-
26-
expect(result).toEqual({})
33+
try {
34+
const result = await client.ping()
35+
expect(result).toEqual({})
36+
} catch (error: any) {
37+
if (error.message?.includes('Connection closed') || error.code === -32000) {
38+
console.error('🚨 Ping failed because the MCP server crashed!')
39+
console.error('🚨 This means the main() function in src/index.ts is not properly implemented')
40+
console.error('🚨 Check that you\'ve replaced the "Not implemented" error with actual server setup code')
41+
const enhancedError = new Error('🚨 MCP server implementation required in main() function. ' + (error.message || error))
42+
enhancedError.stack = error.stack
43+
throw enhancedError
44+
}
45+
throw error
46+
}
2747
})

exercises/02.tools/01.problem.simple/src/index.test.ts

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,61 @@ afterAll(async () => {
2222
})
2323

2424
test('Tool Definition', async () => {
25-
const list = await client.listTools()
26-
const [firstTool] = list.tools
27-
invariant(firstTool, '🚨 No tools found')
25+
try {
26+
const list = await client.listTools()
27+
const [firstTool] = list.tools
28+
invariant(firstTool, '🚨 No tools found')
2829

29-
expect(firstTool).toEqual(
30-
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
33-
inputSchema: expect.objectContaining({
34-
type: 'object',
35-
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
39-
}),
30+
expect(firstTool).toEqual(
31+
expect.objectContaining({
32+
name: expect.stringMatching(/^add$/i),
33+
description: expect.stringMatching(/add/i),
34+
inputSchema: expect.objectContaining({
35+
type: 'object',
4036
}),
4137
}),
42-
}),
43-
)
38+
)
39+
} catch (error: any) {
40+
if (error.code === -32601) {
41+
console.error('🚨 Tools capability not implemented!')
42+
console.error('🚨 This exercise requires registering tools with the MCP server')
43+
console.error('🚨 You need to: 1) Add tools: {} to server capabilities, 2) Register an "add" tool in initializeTools()')
44+
console.error('🚨 Check src/tools.ts and make sure you implement the "add" tool')
45+
const enhancedError = new Error('🚨 Tools capability required. Register an "add" tool that hardcodes 1 + 2 = 3. ' + (error.message || error))
46+
enhancedError.stack = error.stack
47+
throw enhancedError
48+
}
49+
throw error
50+
}
4451
})
4552

4653
test('Tool Call', async () => {
47-
const result = await client.callTool({
48-
name: 'add',
49-
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
52-
},
53-
})
54+
try {
55+
const result = await client.callTool({
56+
name: 'add',
57+
arguments: {},
58+
})
5459

55-
expect(result).toEqual(
56-
expect.objectContaining({
57-
content: expect.arrayContaining([
58-
expect.objectContaining({
59-
type: 'text',
60-
text: expect.stringMatching(/3/),
61-
}),
62-
]),
63-
}),
64-
)
60+
expect(result).toEqual(
61+
expect.objectContaining({
62+
content: expect.arrayContaining([
63+
expect.objectContaining({
64+
type: 'text',
65+
text: expect.stringMatching(/3/),
66+
}),
67+
]),
68+
}),
69+
)
70+
} catch (error: any) {
71+
if (error.code === -32601) {
72+
console.error('🚨 Tool call failed - tools capability not implemented!')
73+
console.error('🚨 This means you haven\'t registered the "add" tool properly')
74+
console.error('🚨 In src/tools.ts, use agent.server.registerTool() to create a simple "add" tool')
75+
console.error('🚨 The tool should return "1 + 2 = 3" (hardcoded for this simple exercise)')
76+
const enhancedError = new Error('🚨 "add" tool registration required. ' + (error.message || error))
77+
enhancedError.stack = error.stack
78+
throw enhancedError
79+
}
80+
throw error
81+
}
6582
})

exercises/02.tools/01.solution.simple/src/index.test.ts

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,35 +22,61 @@ afterAll(async () => {
2222
})
2323

2424
test('Tool Definition', async () => {
25-
const list = await client.listTools()
26-
const [firstTool] = list.tools
27-
invariant(firstTool, '🚨 No tools found')
25+
try {
26+
const list = await client.listTools()
27+
const [firstTool] = list.tools
28+
invariant(firstTool, '🚨 No tools found')
2829

29-
expect(firstTool).toEqual(
30-
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/add/i),
33-
inputSchema: expect.objectContaining({
34-
type: 'object',
30+
expect(firstTool).toEqual(
31+
expect.objectContaining({
32+
name: expect.stringMatching(/^add$/i),
33+
description: expect.stringMatching(/add/i),
34+
inputSchema: expect.objectContaining({
35+
type: 'object',
36+
}),
3537
}),
36-
}),
37-
)
38+
)
39+
} catch (error: any) {
40+
if (error.code === -32601) {
41+
console.error('🚨 Tools capability not implemented!')
42+
console.error('🚨 This exercise requires registering tools with the MCP server')
43+
console.error('🚨 You need to: 1) Add tools: {} to server capabilities, 2) Register an "add" tool in initializeTools()')
44+
console.error('🚨 Check src/tools.ts and make sure you implement the "add" tool')
45+
const enhancedError = new Error('🚨 Tools capability required. Register an "add" tool that hardcodes 1 + 2 = 3. ' + (error.message || error))
46+
enhancedError.stack = error.stack
47+
throw enhancedError
48+
}
49+
throw error
50+
}
3851
})
3952

4053
test('Tool Call', async () => {
41-
const result = await client.callTool({
42-
name: 'add',
43-
arguments: {},
44-
})
54+
try {
55+
const result = await client.callTool({
56+
name: 'add',
57+
arguments: {},
58+
})
4559

46-
expect(result).toEqual(
47-
expect.objectContaining({
48-
content: expect.arrayContaining([
49-
expect.objectContaining({
50-
type: 'text',
51-
text: expect.stringMatching(/3/),
52-
}),
53-
]),
54-
}),
55-
)
60+
expect(result).toEqual(
61+
expect.objectContaining({
62+
content: expect.arrayContaining([
63+
expect.objectContaining({
64+
type: 'text',
65+
text: expect.stringMatching(/3/),
66+
}),
67+
]),
68+
}),
69+
)
70+
} catch (error: any) {
71+
if (error.code === -32601) {
72+
console.error('🚨 Tool call failed - tools capability not implemented!')
73+
console.error('🚨 This means you haven\'t registered the "add" tool properly')
74+
console.error('🚨 In src/tools.ts, use agent.server.registerTool() to create a simple "add" tool')
75+
console.error('🚨 The tool should return "1 + 2 = 3" (hardcoded for this simple exercise)')
76+
const enhancedError = new Error('🚨 "add" tool registration required. ' + (error.message || error))
77+
enhancedError.stack = error.stack
78+
throw enhancedError
79+
}
80+
throw error
81+
}
5682
})

exercises/02.tools/02.problem.args/src/index.test.ts

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,47 @@ test('Tool Definition', async () => {
2626
const [firstTool] = list.tools
2727
invariant(firstTool, '🚨 No tools found')
2828

29-
expect(firstTool).toEqual(
30-
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
33-
inputSchema: expect.objectContaining({
34-
type: 'object',
35-
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
29+
try {
30+
expect(firstTool).toEqual(
31+
expect.objectContaining({
32+
name: expect.stringMatching(/^add$/i),
33+
description: expect.stringMatching(/^add two numbers$/i),
34+
inputSchema: expect.objectContaining({
35+
type: 'object',
36+
properties: expect.objectContaining({
37+
firstNumber: expect.objectContaining({
38+
type: 'number',
39+
description: expect.stringMatching(/first/i),
40+
}),
41+
secondNumber: expect.objectContaining({
42+
type: 'number',
43+
description: expect.stringMatching(/second/i),
44+
}),
3945
}),
46+
required: expect.arrayContaining(['firstNumber', 'secondNumber']),
4047
}),
4148
}),
42-
}),
49+
)
50+
} catch (error: any) {
51+
console.error('🚨 Tool schema mismatch!')
52+
console.error('🚨 This exercise requires updating the "add" tool to accept dynamic arguments')
53+
console.error('🚨 Current tool schema:', JSON.stringify(firstTool, null, 2))
54+
console.error('🚨 You need to: 1) Add proper inputSchema with firstNumber and secondNumber parameters')
55+
console.error('🚨 2) Update the tool description to "add two numbers"')
56+
console.error('🚨 3) Make the tool calculate firstNumber + secondNumber instead of hardcoding 1 + 2')
57+
const enhancedError = new Error('🚨 Tool schema update required. Add firstNumber and secondNumber parameters to the "add" tool. ' + (error.message || error))
58+
enhancedError.stack = error.stack
59+
throw enhancedError
60+
}
61+
62+
// 🚨 Proactive check: Ensure the tool schema includes both required arguments
63+
invariant(
64+
firstTool.inputSchema?.properties?.firstNumber,
65+
'🚨 Tool must have firstNumber parameter defined'
66+
)
67+
invariant(
68+
firstTool.inputSchema?.properties?.secondNumber,
69+
'🚨 Tool must have secondNumber parameter defined'
4370
)
4471
})
4572

@@ -63,3 +90,35 @@ test('Tool Call', async () => {
6390
}),
6491
)
6592
})
93+
94+
test('Tool Call with Different Numbers', async () => {
95+
try {
96+
const result = await client.callTool({
97+
name: 'add',
98+
arguments: {
99+
firstNumber: 5,
100+
secondNumber: 7,
101+
},
102+
})
103+
104+
expect(result).toEqual(
105+
expect.objectContaining({
106+
content: expect.arrayContaining([
107+
expect.objectContaining({
108+
type: 'text',
109+
text: expect.stringMatching(/12/),
110+
}),
111+
]),
112+
}),
113+
)
114+
} catch (error: any) {
115+
console.error('🚨 Tool call with different numbers failed!')
116+
console.error('🚨 This suggests the tool implementation is still hardcoded')
117+
console.error('🚨 The tool should calculate firstNumber + secondNumber = 5 + 7 = 12')
118+
console.error('🚨 But it\'s probably still returning hardcoded "1 + 2 = 3"')
119+
console.error('🚨 Update the tool implementation to use the dynamic arguments from the input schema')
120+
const enhancedError = new Error('🚨 Dynamic tool calculation required. Tool should calculate arguments, not return hardcoded values. ' + (error.message || error))
121+
enhancedError.stack = error.stack
122+
throw enhancedError
123+
}
124+
})

0 commit comments

Comments
 (0)