33declare (strict_types=1 );
44
55use Laravel \Boost \Mcp \Tools \Tinker ;
6- use Laravel \Mcp \Server \Tools \ToolResult ;
7-
8- function getToolResultData (ToolResult $ result ): array
9- {
10- $ data = $ result ->toArray ();
11-
12- return json_decode ($ data ['content ' ][0 ]['text ' ], true );
13- }
146
157test ('executes simple php code ' , function () {
168 $ tool = new Tinker ;
179 $ result = $ tool ->handle (['code ' => 'return 2 + 2; ' ]);
1810
19- expect ($ result )->isToolResult ();
20-
21- $ data = getToolResultData ( $ result);
22- expect ($ data ['result ' ])->toBe (4 )
23- -> and ( $ data [ ' type ' ])-> toBe ( ' integer ' );
11+ expect ($ result )->isToolResult ()
12+ -> toolJsonContent ( function ( $ data ) {
13+ expect ( $ data [ ' result ' ])-> toBe ( 4 )
14+ -> and ($ data ['type ' ])->toBe (' integer ' );
15+ } );
2416});
2517
2618test ('executes code with output ' , function () {
2719 $ tool = new Tinker ;
2820 $ result = $ tool ->handle (['code ' => 'echo "Hello World"; return "test"; ' ]);
2921
30- expect ($ result )->isToolResult ();
31-
32- $ data = getToolResultData ( $ result);
33- expect ($ data ['result ' ])->toBe ('test ' )
34- ->and ($ data ['output ' ])->toBe ('Hello World ' )
35- -> and ( $ data [ ' type ' ])-> toBe ( ' string ' );
22+ expect ($ result )->isToolResult ()
23+ -> toolJsonContent ( function ( $ data ) {
24+ expect ( $ data [ ' result ' ])-> toBe ( ' test ' )
25+ -> and ($ data ['output ' ])->toBe ('Hello World ' )
26+ ->and ($ data ['type ' ])->toBe ('string ' );
27+ } );
3628});
3729
3830test ('accesses laravel facades ' , function () {
3931 $ tool = new Tinker ;
4032 $ result = $ tool ->handle (['code ' => 'return config("app.name"); ' ]);
4133
42- expect ($ result )->isToolResult ();
43-
44- $ data = getToolResultData ( $ result);
45- expect ($ data ['result ' ])->toBeString ( )
46- ->and ($ data ['result ' ])->toBe (config ( ' app.name ' ))
47- -> and ( $ data [ ' type ' ])-> toBe ( ' string ' );
34+ expect ($ result )->isToolResult ()
35+ -> toolJsonContent ( function ( $ data ) {
36+ expect ( $ data [ ' result ' ])-> toBeString ()
37+ -> and ($ data ['result ' ])->toBe ( config ( ' app.name ' ) )
38+ ->and ($ data ['type ' ])->toBe (' string ' );
39+ } );
4840});
4941
5042test ('creates objects ' , function () {
5143 $ tool = new Tinker ;
5244 $ result = $ tool ->handle (['code ' => 'return new stdClass(); ' ]);
5345
54- expect ($ result )->isToolResult ();
55-
56- $ data = getToolResultData ( $ result );
57- expect ($ data ['type ' ])->toBe ('object ' )
58- -> and ( $ data [ ' class ' ])-> toBe ( ' stdClass ' );
46+ expect ($ result )->isToolResult ()
47+ -> toolJsonContent ( function ( $ data ) {
48+ expect ( $ data [ ' type ' ])-> toBe ( ' object ' )
49+ -> and ($ data ['class ' ])->toBe ('stdClass ' );
50+ } );
5951});
6052
6153test ('handles syntax errors ' , function () {
6254 $ tool = new Tinker ;
6355 $ result = $ tool ->handle (['code ' => 'invalid syntax here ' ]);
6456
65- expect ($ result )->isToolResult ();
66-
67- $ resultArray = $ result ->toArray ();
68- expect ($ resultArray ['isError ' ])->toBeFalse ();
69-
70- $ data = getToolResultData ($ result );
71- expect ($ data )->toHaveKey ('error ' )
72- ->and ($ data )->toHaveKey ('type ' )
73- ->and ($ data ['type ' ])->toBe ('ParseError ' );
57+ expect ($ result )->isToolResult ()
58+ ->toolHasNoError ()
59+ ->toolJsonContent (function ($ data ) {
60+ expect ($ data )->toHaveKey ('error ' )
61+ ->and ($ data )->toHaveKey ('type ' )
62+ ->and ($ data ['type ' ])->toBe ('ParseError ' );
63+ });
7464});
7565
7666test ('handles runtime errors ' , function () {
7767 $ tool = new Tinker ;
7868 $ result = $ tool ->handle (['code ' => 'throw new Exception("Test error"); ' ]);
7969
80- expect ($ result )->isToolResult ();
81-
82- $ resultArray = $ result ->toArray ();
83- expect ($ resultArray ['isError ' ])->toBeFalse ();
84-
85- $ data = getToolResultData ($ result );
86- expect ($ data )->toHaveKey ('error ' )
87- ->and ($ data ['type ' ])->toBe ('Exception ' )
88- ->and ($ data ['error ' ])->toBe ('Test error ' );
70+ expect ($ result )->isToolResult ()
71+ ->toolHasNoError ()
72+ ->toolJsonContent (function ($ data ) {
73+ expect ($ data )->toHaveKey ('error ' )
74+ ->and ($ data ['type ' ])->toBe ('Exception ' )
75+ ->and ($ data ['error ' ])->toBe ('Test error ' );
76+ });
8977});
9078
9179test ('captures multiple outputs ' , function () {
9280 $ tool = new Tinker ;
9381 $ result = $ tool ->handle (['code ' => 'echo "First"; echo "Second"; return "done"; ' ]);
9482
95- expect ($ result )->isToolResult ();
96-
97- $ data = getToolResultData ( $ result);
98- expect ($ data ['result ' ])->toBe ('done ' )
99- -> and ( $ data [ ' output ' ])-> toBe ( ' FirstSecond ' );
83+ expect ($ result )->isToolResult ()
84+ -> toolJsonContent ( function ( $ data ) {
85+ expect ( $ data [ ' result ' ])-> toBe ( ' done ' )
86+ -> and ($ data ['output ' ])->toBe ('FirstSecond ' );
87+ } );
10088});
10189
10290test ('executes code with different return types ' , function (string $ code , mixed $ expectedResult , string $ expectedType ) {
10391 $ tool = new Tinker ;
10492 $ result = $ tool ->handle (['code ' => $ code ]);
10593
106- expect ($ result )->isToolResult ();
107-
108- $ data = getToolResultData ( $ result);
109- expect ($ data ['result ' ])->toBe ($ expectedResult )
110- -> and ( $ data [ ' type ' ])-> toBe ( $ expectedType );
94+ expect ($ result )->isToolResult ()
95+ -> toolJsonContent ( function ( $ data ) use ( $ expectedResult , $ expectedType ) {
96+ expect ( $ data [ ' result ' ])-> toBe ( $ expectedResult )
97+ -> and ($ data ['type ' ])->toBe ($ expectedType );
98+ } );
11199})->with ([
112100 'integer ' => ['return 42; ' , 42 , 'integer ' ],
113101 'string ' => ['return "hello"; ' , 'hello ' , 'string ' ],
@@ -122,22 +110,22 @@ function getToolResultData(ToolResult $result): array
122110 $ tool = new Tinker ;
123111 $ result = $ tool ->handle (['code ' => '' ]);
124112
125- expect ($ result )->isToolResult ();
126-
127- $ data = getToolResultData ( $ result);
128- expect ($ data ['result ' ])->toBeFalse ()
129- -> and ( $ data [ ' type ' ])-> toBe ( ' boolean ' );
113+ expect ($ result )->isToolResult ()
114+ -> toolJsonContent ( function ( $ data ) {
115+ expect ( $ data [ ' result ' ])-> toBeFalse ()
116+ -> and ($ data ['type ' ])->toBe ( ' boolean ' );
117+ } );
130118});
131119
132120test ('handles code with no return statement ' , function () {
133121 $ tool = new Tinker ;
134122 $ result = $ tool ->handle (['code ' => '$x = 5; ' ]);
135123
136- expect ($ result )->isToolResult ();
137-
138- $ data = getToolResultData ( $ result);
139- expect ($ data ['result ' ])->toBeNull ()
140- -> and ( $ data [ ' type ' ])-> toBe ( ' NULL ' );
124+ expect ($ result )->isToolResult ()
125+ -> toolJsonContent ( function ( $ data ) {
126+ expect ( $ data [ ' result ' ])-> toBeNull ()
127+ -> and ($ data ['type ' ])->toBe ( ' NULL ' );
128+ } );
141129});
142130
143131test ('should register only in local environment ' , function () {
@@ -155,22 +143,22 @@ function getToolResultData(ToolResult $result): array
155143 $ tool = new Tinker ;
156144 $ result = $ tool ->handle (['code ' => 'return 2 + 2; ' , 'timeout ' => 10 ]);
157145
158- expect ($ result )->isToolResult ();
159-
160- $ data = getToolResultData ( $ result);
161- expect ($ data ['result ' ])->toBe (4 )
162- -> and ( $ data [ ' type ' ])-> toBe ( ' integer ' );
146+ expect ($ result )->isToolResult ()
147+ -> toolJsonContent ( function ( $ data ) {
148+ expect ( $ data [ ' result ' ])-> toBe ( 4 )
149+ -> and ($ data ['type ' ])->toBe (' integer ' );
150+ } );
163151});
164152
165153test ('uses default timeout when not specified ' , function () {
166154 $ tool = new Tinker ;
167155 $ result = $ tool ->handle (['code ' => 'return 2 + 2; ' ]);
168156
169- expect ($ result )->isToolResult ();
170-
171- $ data = getToolResultData ( $ result);
172- expect ($ data ['result ' ])->toBe (4 )
173- -> and ( $ data [ ' type ' ])-> toBe ( ' integer ' );
157+ expect ($ result )->isToolResult ()
158+ -> toolJsonContent ( function ( $ data ) {
159+ expect ( $ data [ ' result ' ])-> toBe ( 4 )
160+ -> and ($ data ['type ' ])->toBe (' integer ' );
161+ } );
174162});
175163
176164test ('times out when code takes too long ' , function () {
@@ -187,9 +175,9 @@ function getToolResultData(ToolResult $result): array
187175
188176 $ result = $ tool ->handle (['code ' => $ slowCode , 'timeout ' => 1 ]);
189177
190- expect ($ result )->isToolResult ();
191-
192- $ data = getToolResultData ( $ result );
193- expect ($ data )->toHaveKey ( ' error ' )
194- -> and ( $ data [ ' error ' ])-> toMatch ( ' /(Maximum execution time|Code execution timed out)/ ' );
178+ expect ($ result )->isToolResult ()
179+ -> toolJsonContent ( function ( $ data ) {
180+ expect ( $ data )-> toHaveKey ( ' error ' )
181+ -> and ($ data[ ' error ' ] )->toMatch ( ' /(Maximum execution time|Code execution timed out)/ ' );
182+ } );
195183});
0 commit comments