1515use Mcp \Capability \Completion \ListCompletionProvider ;
1616use Mcp \Capability \Discovery \Discoverer ;
1717use Mcp \Capability \Registry ;
18- use Mcp \Capability \Registry \PromptReference ;
19- use Mcp \Capability \Registry \ResourceReference ;
20- use Mcp \Capability \Registry \ResourceTemplateReference ;
2118use Mcp \Capability \Registry \ToolReference ;
2219use Mcp \Tests \Unit \Capability \Attribute \CompletionProviderFixture ;
2320use Mcp \Tests \Unit \Capability \Discovery \Fixtures \DiscoverableToolHandler ;
@@ -40,96 +37,84 @@ protected function setUp(): void
4037
4138 public function testDiscoversAllElementTypesCorrectlyFromFixtureFiles ()
4239 {
43- $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
40+ $ discovery = $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
4441
45- $ tools = $ this -> registry ->getTools ();
42+ $ tools = $ discovery ->getTools ();
4643 $ this ->assertCount (4 , $ tools );
4744
48- $ greetUserTool = $ this ->registry ->getTool ('greet_user ' );
49- $ this ->assertInstanceOf (ToolReference::class, $ greetUserTool );
50- $ this ->assertFalse ($ greetUserTool ->isManual );
51- $ this ->assertEquals ('greet_user ' , $ greetUserTool ->tool ->name );
52- $ this ->assertEquals ('Greets a user by name. ' , $ greetUserTool ->tool ->description );
53- $ this ->assertEquals ([DiscoverableToolHandler::class, 'greet ' ], $ greetUserTool ->handler );
54- $ this ->assertArrayHasKey ('name ' , $ greetUserTool ->tool ->inputSchema ['properties ' ] ?? []);
55-
56- $ repeatActionTool = $ this ->registry ->getTool ('repeatAction ' );
57- $ this ->assertInstanceOf (ToolReference::class, $ repeatActionTool );
58- $ this ->assertEquals ('A tool with more complex parameters and inferred name/description. ' , $ repeatActionTool ->tool ->description );
59- $ this ->assertTrue ($ repeatActionTool ->tool ->annotations ->readOnlyHint );
60- $ this ->assertEquals (['count ' , 'loudly ' , 'mode ' ], array_keys ($ repeatActionTool ->tool ->inputSchema ['properties ' ] ?? []));
61-
62- $ invokableCalcTool = $ this ->registry ->getTool ('InvokableCalculator ' );
63- $ this ->assertInstanceOf (ToolReference::class, $ invokableCalcTool );
64- $ this ->assertFalse ($ invokableCalcTool ->isManual );
65- $ this ->assertEquals ([InvocableToolFixture::class, '__invoke ' ], $ invokableCalcTool ->handler );
66-
67- $ this ->assertNull ($ this ->registry ->getTool ('private_tool_should_be_ignored ' ));
68- $ this ->assertNull ($ this ->registry ->getTool ('protected_tool_should_be_ignored ' ));
69- $ this ->assertNull ($ this ->registry ->getTool ('static_tool_should_be_ignored ' ));
70-
71- $ resources = $ this ->registry ->getResources ();
45+ $ this ->assertArrayHasKey ('greet_user ' , $ tools );
46+ $ this ->assertFalse ($ tools ['greet_user ' ]->isManual );
47+ $ this ->assertEquals ('greet_user ' , $ tools ['greet_user ' ]->tool ->name );
48+ $ this ->assertEquals ('Greets a user by name. ' , $ tools ['greet_user ' ]->tool ->description );
49+ $ this ->assertEquals ([DiscoverableToolHandler::class, 'greet ' ], $ tools ['greet_user ' ]->handler );
50+ $ this ->assertArrayHasKey ('name ' , $ tools ['greet_user ' ]->tool ->inputSchema ['properties ' ] ?? []);
51+
52+ $ this ->assertArrayHasKey ('repeatAction ' , $ tools );
53+ $ this ->assertEquals ('A tool with more complex parameters and inferred name/description. ' , $ tools ['repeatAction ' ]->tool ->description );
54+ $ this ->assertTrue ($ tools ['repeatAction ' ]->tool ->annotations ->readOnlyHint );
55+ $ this ->assertEquals (['count ' , 'loudly ' , 'mode ' ], array_keys ($ tools ['repeatAction ' ]->tool ->inputSchema ['properties ' ] ?? []));
56+
57+ $ this ->assertArrayHasKey ('InvokableCalculator ' , $ tools );
58+ $ this ->assertInstanceOf (ToolReference::class, $ tools ['InvokableCalculator ' ]);
59+ $ this ->assertFalse ($ tools ['InvokableCalculator ' ]->isManual );
60+ $ this ->assertEquals ([InvocableToolFixture::class, '__invoke ' ], $ tools ['InvokableCalculator ' ]->handler );
61+
62+ $ this ->assertArrayNotHasKey ('private_tool_should_be_ignored ' , $ tools );
63+ $ this ->assertArrayNotHasKey ('protected_tool_should_be_ignored ' , $ tools );
64+ $ this ->assertArrayNotHasKey ('static_tool_should_be_ignored ' , $ tools );
65+
66+ $ resources = $ discovery ->getResources ();
7267 $ this ->assertCount (3 , $ resources );
7368
74- $ appVersionRes = $ this ->registry ->getResource ('app://info/version ' );
75- $ this ->assertInstanceOf (ResourceReference::class, $ appVersionRes );
76- $ this ->assertFalse ($ appVersionRes ->isManual );
77- $ this ->assertEquals ('app_version ' , $ appVersionRes ->schema ->name );
78- $ this ->assertEquals ('text/plain ' , $ appVersionRes ->schema ->mimeType );
69+ $ this ->assertArrayHasKey ('app://info/version ' , $ resources );
70+ $ this ->assertFalse ($ resources ['app://info/version ' ]->isManual );
71+ $ this ->assertEquals ('app_version ' , $ resources ['app://info/version ' ]->schema ->name );
72+ $ this ->assertEquals ('text/plain ' , $ resources ['app://info/version ' ]->schema ->mimeType );
7973
80- $ invokableStatusRes = $ this ->registry ->getResource ('invokable://config/status ' );
81- $ this ->assertInstanceOf (ResourceReference::class, $ invokableStatusRes );
82- $ this ->assertFalse ($ invokableStatusRes ->isManual );
83- $ this ->assertEquals ([InvocableResourceFixture::class, '__invoke ' ], $ invokableStatusRes ->handler );
74+ $ this ->assertArrayHasKey ('invokable://config/status ' , $ resources );
75+ $ this ->assertFalse ($ resources ['invokable://config/status ' ]->isManual );
76+ $ this ->assertEquals ([InvocableResourceFixture::class, '__invoke ' ], $ resources ['invokable://config/status ' ]->handler );
8477
85- $ prompts = $ this -> registry ->getPrompts ();
78+ $ prompts = $ discovery ->getPrompts ();
8679 $ this ->assertCount (4 , $ prompts );
8780
88- $ storyPrompt = $ this ->registry ->getPrompt ('creative_story_prompt ' );
89- $ this ->assertInstanceOf (PromptReference::class, $ storyPrompt );
90- $ this ->assertFalse ($ storyPrompt ->isManual );
91- $ this ->assertCount (2 , $ storyPrompt ->prompt ->arguments );
92- $ this ->assertEquals (CompletionProviderFixture::class, $ storyPrompt ->completionProviders ['genre ' ]);
81+ $ this ->assertArrayHasKey ('creative_story_prompt ' , $ prompts );
82+ $ this ->assertFalse ($ prompts ['creative_story_prompt ' ]->isManual );
83+ $ this ->assertCount (2 , $ prompts ['creative_story_prompt ' ]->prompt ->arguments );
84+ $ this ->assertEquals (CompletionProviderFixture::class, $ prompts ['creative_story_prompt ' ]->completionProviders ['genre ' ]);
9385
94- $ simplePrompt = $ this ->registry ->getPrompt ('simpleQuestionPrompt ' );
95- $ this ->assertInstanceOf (PromptReference::class, $ simplePrompt );
96- $ this ->assertFalse ($ simplePrompt ->isManual );
86+ $ this ->assertArrayHasKey ('simpleQuestionPrompt ' , $ prompts );
87+ $ this ->assertFalse ($ prompts ['simpleQuestionPrompt ' ]->isManual );
9788
98- $ invokableGreeter = $ this ->registry ->getPrompt ('InvokableGreeterPrompt ' );
99- $ this ->assertInstanceOf (PromptReference::class, $ invokableGreeter );
100- $ this ->assertFalse ($ invokableGreeter ->isManual );
101- $ this ->assertEquals ([InvocablePromptFixture::class, '__invoke ' ], $ invokableGreeter ->handler );
89+ $ this ->assertArrayHasKey ('InvokableGreeterPrompt ' , $ prompts );
90+ $ this ->assertFalse ($ prompts ['InvokableGreeterPrompt ' ]->isManual );
91+ $ this ->assertEquals ([InvocablePromptFixture::class, '__invoke ' ], $ prompts ['InvokableGreeterPrompt ' ]->handler );
10292
103- $ contentCreatorPrompt = $ this ->registry ->getPrompt ('content_creator ' );
104- $ this ->assertInstanceOf (PromptReference::class, $ contentCreatorPrompt );
105- $ this ->assertFalse ($ contentCreatorPrompt ->isManual );
106- $ this ->assertCount (3 , $ contentCreatorPrompt ->completionProviders );
93+ $ this ->assertArrayHasKey ('content_creator ' , $ prompts );
94+ $ this ->assertFalse ($ prompts ['content_creator ' ]->isManual );
95+ $ this ->assertCount (3 , $ prompts ['content_creator ' ]->completionProviders );
10796
108- $ templates = $ this -> registry ->getResourceTemplates ();
97+ $ templates = $ discovery ->getResourceTemplates ();
10998 $ this ->assertCount (4 , $ templates );
11099
111- $ productTemplate = $ this ->registry ->getResourceTemplate ('product://{region}/details/{productId} ' );
112- $ this ->assertInstanceOf (ResourceTemplateReference::class, $ productTemplate );
113- $ this ->assertFalse ($ productTemplate ->isManual );
114- $ this ->assertEquals ('product_details_template ' , $ productTemplate ->resourceTemplate ->name );
115- $ this ->assertEquals (CompletionProviderFixture::class, $ productTemplate ->completionProviders ['region ' ]);
116- $ this ->assertEqualsCanonicalizing (['region ' , 'productId ' ], $ productTemplate ->getVariableNames ());
117-
118- $ invokableUserTemplate = $ this ->registry ->getResourceTemplate ('invokable://user-profile/{userId} ' );
119- $ this ->assertInstanceOf (ResourceTemplateReference::class, $ invokableUserTemplate );
120- $ this ->assertFalse ($ invokableUserTemplate ->isManual );
121- $ this ->assertEquals ([InvocableResourceTemplateFixture::class, '__invoke ' ], $ invokableUserTemplate ->handler );
100+ $ this ->assertArrayHasKey ('product://{region}/details/{productId} ' , $ templates );
101+ $ this ->assertFalse ($ templates ['product://{region}/details/{productId} ' ]->isManual );
102+ $ this ->assertEquals ('product_details_template ' , $ templates ['product://{region}/details/{productId} ' ]->resourceTemplate ->name );
103+ $ this ->assertEquals (CompletionProviderFixture::class, $ templates ['product://{region}/details/{productId} ' ]->completionProviders ['region ' ]);
104+ $ this ->assertEqualsCanonicalizing (['region ' , 'productId ' ], $ templates ['product://{region}/details/{productId} ' ]->getVariableNames ());
105+
106+ $ this ->assertArrayHasKey ('invokable://user-profile/{userId} ' , $ templates );
107+ $ this ->assertFalse ($ templates ['invokable://user-profile/{userId} ' ]->isManual );
108+ $ this ->assertEquals ([InvocableResourceTemplateFixture::class, '__invoke ' ], $ templates ['invokable://user-profile/{userId} ' ]->handler );
122109 }
123110
124111 public function testDoesNotDiscoverElementsFromExcludedDirectories ()
125112 {
126- $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
127- $ this ->assertInstanceOf (ToolReference::class, $ this ->registry ->getTool ('hidden_subdir_tool ' ));
128-
129- $ this ->registry ->clear ();
113+ $ discovery = $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
114+ $ this ->assertArrayHasKey ('hidden_subdir_tool ' , $ discovery ->getTools ());
130115
131- $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ], ['SubDir ' ]);
132- $ this ->assertNull ( $ this -> registry -> getTool ( ' hidden_subdir_tool ' ));
116+ $ discovery = $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ], ['SubDir ' ]);
117+ $ this ->assertArrayNotHasKey ( ' hidden_subdir_tool ' , $ discovery -> getTools ( ));
133118 }
134119
135120 public function testHandlesEmptyDirectoriesOrDirectoriesWithNoPhpFiles ()
@@ -141,43 +126,41 @@ public function testHandlesEmptyDirectoriesOrDirectoriesWithNoPhpFiles()
141126
142127 public function testCorrectlyInfersNamesAndDescriptionsFromMethodsOrClassesIfNotSetInAttribute ()
143128 {
144- $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
129+ $ discovery = $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
145130
146- $ repeatActionTool = $ this ->registry -> getTool ('repeatAction ' );
147- $ this ->assertEquals ('repeatAction ' , $ repeatActionTool ->tool ->name );
148- $ this ->assertEquals ('A tool with more complex parameters and inferred name/description. ' , $ repeatActionTool ->tool ->description );
131+ $ this ->assertArrayHasKey ('repeatAction ' , $ tools = $ discovery -> getTools () );
132+ $ this ->assertEquals ('repeatAction ' , $ tools [ ' repeatAction ' ] ->tool ->name );
133+ $ this ->assertEquals ('A tool with more complex parameters and inferred name/description. ' , $ tools [ ' repeatAction ' ] ->tool ->description );
149134
150- $ simplePrompt = $ this ->registry -> getPrompt ('simpleQuestionPrompt ' );
151- $ this ->assertEquals ('simpleQuestionPrompt ' , $ simplePrompt ->prompt ->name );
152- $ this ->assertNull ($ simplePrompt ->prompt ->description );
135+ $ this ->assertArrayHasKey ('simpleQuestionPrompt ' , $ prompts = $ discovery -> getPrompts () );
136+ $ this ->assertEquals ('simpleQuestionPrompt ' , $ prompts [ ' simpleQuestionPrompt ' ] ->prompt ->name );
137+ $ this ->assertNull ($ prompts [ ' simpleQuestionPrompt ' ] ->prompt ->description );
153138
154- $ invokableCalc = $ this ->registry -> getTool ('InvokableCalculator ' );
155- $ this ->assertEquals ('InvokableCalculator ' , $ invokableCalc ->tool ->name );
156- $ this ->assertEquals ('An invokable calculator tool. ' , $ invokableCalc ->tool ->description );
139+ $ this ->assertArrayHasKey ('InvokableCalculator ' , $ tools );
140+ $ this ->assertEquals ('InvokableCalculator ' , $ tools [ ' InvokableCalculator ' ] ->tool ->name );
141+ $ this ->assertEquals ('An invokable calculator tool. ' , $ tools [ ' InvokableCalculator ' ] ->tool ->description );
157142 }
158143
159144 public function testDiscoversEnhancedCompletionProvidersWithValuesAndEnumAttributes ()
160145 {
161- $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
146+ $ discovery = $ this ->discoverer ->discover (__DIR__ , ['Fixtures ' ]);
162147
163- $ contentPrompt = $ this ->registry ->getPrompt ('content_creator ' );
164- $ this ->assertInstanceOf (PromptReference::class, $ contentPrompt );
165- $ this ->assertCount (3 , $ contentPrompt ->completionProviders );
148+ $ this ->assertArrayHasKey ('content_creator ' , $ prompts = $ discovery ->getPrompts ());
149+ $ this ->assertCount (3 , $ prompts ['content_creator ' ]->completionProviders );
166150
167- $ typeProvider = $ contentPrompt ->completionProviders ['type ' ];
151+ $ typeProvider = $ prompts [ ' content_creator ' ] ->completionProviders ['type ' ];
168152 $ this ->assertInstanceOf (ListCompletionProvider::class, $ typeProvider );
169153
170- $ statusProvider = $ contentPrompt ->completionProviders ['status ' ];
154+ $ statusProvider = $ prompts [ ' content_creator ' ] ->completionProviders ['status ' ];
171155 $ this ->assertInstanceOf (EnumCompletionProvider::class, $ statusProvider );
172156
173- $ priorityProvider = $ contentPrompt ->completionProviders ['priority ' ];
157+ $ priorityProvider = $ prompts [ ' content_creator ' ] ->completionProviders ['priority ' ];
174158 $ this ->assertInstanceOf (EnumCompletionProvider::class, $ priorityProvider );
175159
176- $ contentTemplate = $ this ->registry ->getResourceTemplate ('content://{category}/{slug} ' );
177- $ this ->assertInstanceOf (ResourceTemplateReference::class, $ contentTemplate );
178- $ this ->assertCount (1 , $ contentTemplate ->completionProviders );
160+ $ this ->assertArrayHasKey ('content://{category}/{slug} ' , $ templates = $ discovery ->getResourceTemplates ());
161+ $ this ->assertCount (1 , $ templates ['content://{category}/{slug} ' ]->completionProviders );
179162
180- $ categoryProvider = $ contentTemplate ->completionProviders ['category ' ];
163+ $ categoryProvider = $ templates [ ' content://{category}/{slug} ' ] ->completionProviders ['category ' ];
181164 $ this ->assertInstanceOf (ListCompletionProvider::class, $ categoryProvider );
182165 }
183166}
0 commit comments