Skip to content

Commit d7b7f14

Browse files
committed
Streamline using Pest Inbuilt expectations
1 parent f830156 commit d7b7f14

File tree

5 files changed

+103
-98
lines changed

5 files changed

+103
-98
lines changed

tests/Feature/Mcp/Tools/ApplicationInfoTest.php

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,27 @@
2929

3030
expect($result)->isToolResult()
3131
->toolHasNoError()
32-
->toolJsonContent(function ($content) {
33-
expect($content['php_version'])->toBe(PHP_VERSION)
34-
->and($content['laravel_version'])->toBe(app()->version())
35-
->and($content['database_engine'])->toBe(config('database.default'))
36-
->and($content['packages'])->toHaveCount(2)
37-
->and($content['packages'][0]['roster_name'])->toBe('LARAVEL')
38-
->and($content['packages'][0]['package_name'])->toBe('laravel/framework')
39-
->and($content['packages'][0]['version'])->toBe('11.0.0')
40-
->and($content['packages'][1]['roster_name'])->toBe('PEST')
41-
->and($content['packages'][1]['package_name'])->toBe('pestphp/pest')
42-
->and($content['packages'][1]['version'])->toBe('2.0.0')
43-
->and($content['models'])->toBeArray()
44-
->and($content['models'])->toHaveCount(2)
45-
->and($content['models'])->toContain('App\\Models\\User')
46-
->and($content['models'])->toContain('App\\Models\\Post');
47-
});
32+
->toolJsonContentToMatchArray([
33+
'php_version' => PHP_VERSION,
34+
'laravel_version' => app()->version(),
35+
'database_engine' => config('database.default'),
36+
'packages' => [
37+
[
38+
'roster_name' => 'LARAVEL',
39+
'package_name' => 'laravel/framework',
40+
'version' => '11.0.0',
41+
],
42+
[
43+
'roster_name' => 'PEST',
44+
'package_name' => 'pestphp/pest',
45+
'version' => '2.0.0',
46+
],
47+
],
48+
'models' => [
49+
'App\\Models\\User',
50+
'App\\Models\\Post',
51+
],
52+
]);
4853
});
4954

5055
test('it returns application info with no packages', function () {
@@ -59,12 +64,11 @@
5964

6065
expect($result)->isToolResult()
6166
->toolHasNoError()
62-
->toolJsonContent(function ($content) {
63-
expect($content['php_version'])->toBe(PHP_VERSION)
64-
->and($content['laravel_version'])->toBe(app()->version())
65-
->and($content['database_engine'])->toBe(config('database.default'))
66-
->and($content['packages'])->toHaveCount(0)
67-
->and($content['models'])->toBeArray()
68-
->and($content['models'])->toHaveCount(0);
69-
});
67+
->toolJsonContentToMatchArray([
68+
'php_version' => PHP_VERSION,
69+
'laravel_version' => app()->version(),
70+
'database_engine' => config('database.default'),
71+
'packages' => [],
72+
'models' => [],
73+
]);
7074
});

tests/Feature/Mcp/Tools/DatabaseConnectionsTest.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,10 @@
1919

2020
expect($result)->isToolResult()
2121
->toolHasNoError()
22-
->toolJsonContent(function ($content) {
23-
expect($content['default_connection'])->toBe('mysql')
24-
->and($content['connections'])->toHaveCount(3)
25-
->and($content['connections'])->toContain('mysql')
26-
->and($content['connections'])->toContain('pgsql')
27-
->and($content['connections'])->toContain('sqlite');
28-
});
22+
->toolJsonContentToMatchArray([
23+
'default_connection' => 'mysql',
24+
'connections' => ['mysql', 'pgsql', 'sqlite'],
25+
]);
2926
});
3027

3128
test('it returns empty connections when none configured', function () {
@@ -36,8 +33,8 @@
3633

3734
expect($result)->isToolResult()
3835
->toolHasNoError()
39-
->toolJsonContent(function ($content) {
40-
expect($content['default_connection'])->toBe('mysql')
41-
->and($content['connections'])->toHaveCount(0);
42-
});
36+
->toolJsonContentToMatchArray([
37+
'default_connection' => 'mysql',
38+
'connections' => [],
39+
]);
4340
});

tests/Feature/Mcp/Tools/DatabaseSchemaTest.php

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,21 @@
4141

4242
expect($response)->isToolResult()
4343
->toolHasNoError()
44+
->toolJsonContentToMatchArray([
45+
'engine' => 'sqlite',
46+
])
4447
->toolJsonContent(function ($schemaArray) {
45-
expect($schemaArray)->toHaveKey('engine')
46-
->and($schemaArray['engine'])->toBe('sqlite')
47-
->and($schemaArray)->toHaveKey('tables')
48+
expect($schemaArray)->toHaveKey('tables')
4849
->and($schemaArray['tables'])->toHaveKey('examples');
4950

5051
$exampleTable = $schemaArray['tables']['examples'];
51-
expect($exampleTable)->toHaveKey('columns')
52-
->and($exampleTable['columns'])->toHaveKey('id')
53-
->and($exampleTable['columns'])->toHaveKey('name')
52+
expect($exampleTable)->toHaveKeys(['columns', 'indexes', 'foreign_keys', 'triggers', 'check_constraints'])
53+
->and($exampleTable['columns'])->toHaveKeys(['id', 'name'])
5454
->and($exampleTable['columns']['id']['type'])->toBe('integer')
5555
->and($exampleTable['columns']['name']['type'])->toBe('varchar')
56-
->and($exampleTable)->toHaveKey('indexes')
57-
->and($exampleTable)->toHaveKey('foreign_keys')
58-
->and($exampleTable)->toHaveKey('triggers')
59-
->and($exampleTable)->toHaveKey('check_constraints');
56+
->and($schemaArray)->toHaveKey('global')
57+
->and($schemaArray['global'])->toHaveKeys(['views', 'stored_procedures', 'functions', 'sequences']);
6058

61-
expect($schemaArray)->toHaveKey('global')
62-
->and($schemaArray['global'])->toHaveKey('views')
63-
->and($schemaArray['global'])->toHaveKey('stored_procedures')
64-
->and($schemaArray['global'])->toHaveKey('functions')
65-
->and($schemaArray['global'])->toHaveKey('sequences');
6659
});
6760
});
6861

tests/Feature/Mcp/Tools/TinkerTest.php

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,44 @@
99
$result = $tool->handle(['code' => 'return 2 + 2;']);
1010

1111
expect($result)->isToolResult()
12-
->toolJsonContent(function ($data) {
13-
expect($data['result'])->toBe(4)
14-
->and($data['type'])->toBe('integer');
15-
});
12+
->toolJsonContentToMatchArray([
13+
'result' => 4,
14+
'type' => 'integer',
15+
]);
1616
});
1717

1818
test('executes code with output', function () {
1919
$tool = new Tinker;
2020
$result = $tool->handle(['code' => 'echo "Hello World"; return "test";']);
2121

2222
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-
});
23+
->toolJsonContentToMatchArray([
24+
'result' => 'test',
25+
'output' => 'Hello World',
26+
'type' => 'string',
27+
]);
2828
});
2929

3030
test('accesses laravel facades', function () {
3131
$tool = new Tinker;
3232
$result = $tool->handle(['code' => 'return config("app.name");']);
3333

3434
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-
});
35+
->toolJsonContentToMatchArray([
36+
'result' => config('app.name'),
37+
'type' => 'string',
38+
]);
4039
});
4140

4241
test('creates objects', function () {
4342
$tool = new Tinker;
4443
$result = $tool->handle(['code' => 'return new stdClass();']);
4544

4645
expect($result)->isToolResult()
47-
->toolJsonContent(function ($data) {
48-
expect($data['type'])->toBe('object')
49-
->and($data['class'])->toBe('stdClass');
50-
});
46+
->toolJsonContentToMatchArray([
47+
'type' => 'object',
48+
'class' => 'stdClass',
49+
]);
5150
});
5251

5352
test('handles syntax errors', function () {
@@ -56,10 +55,11 @@
5655

5756
expect($result)->isToolResult()
5857
->toolHasNoError()
58+
->toolJsonContentToMatchArray([
59+
'type' => 'ParseError',
60+
])
5961
->toolJsonContent(function ($data) {
60-
expect($data)->toHaveKey('error')
61-
->and($data)->toHaveKey('type')
62-
->and($data['type'])->toBe('ParseError');
62+
expect($data)->toHaveKey('error');
6363
});
6464
});
6565

@@ -69,10 +69,12 @@
6969

7070
expect($result)->isToolResult()
7171
->toolHasNoError()
72+
->toolJsonContentToMatchArray([
73+
'type' => 'Exception',
74+
'error' => 'Test error',
75+
])
7276
->toolJsonContent(function ($data) {
73-
expect($data)->toHaveKey('error')
74-
->and($data['type'])->toBe('Exception')
75-
->and($data['error'])->toBe('Test error');
77+
expect($data)->toHaveKey('error');
7678
});
7779
});
7880

@@ -81,21 +83,21 @@
8183
$result = $tool->handle(['code' => 'echo "First"; echo "Second"; return "done";']);
8284

8385
expect($result)->isToolResult()
84-
->toolJsonContent(function ($data) {
85-
expect($data['result'])->toBe('done')
86-
->and($data['output'])->toBe('FirstSecond');
87-
});
86+
->toolJsonContentToMatchArray([
87+
'result' => 'done',
88+
'output' => 'FirstSecond',
89+
]);
8890
});
8991

9092
test('executes code with different return types', function (string $code, mixed $expectedResult, string $expectedType) {
9193
$tool = new Tinker;
9294
$result = $tool->handle(['code' => $code]);
9395

9496
expect($result)->isToolResult()
95-
->toolJsonContent(function ($data) use ($expectedResult, $expectedType) {
96-
expect($data['result'])->toBe($expectedResult)
97-
->and($data['type'])->toBe($expectedType);
98-
});
97+
->toolJsonContentToMatchArray([
98+
'result' => $expectedResult,
99+
'type' => $expectedType,
100+
]);
99101
})->with([
100102
'integer' => ['return 42;', 42, 'integer'],
101103
'string' => ['return "hello";', 'hello', 'string'],
@@ -111,21 +113,21 @@
111113
$result = $tool->handle(['code' => '']);
112114

113115
expect($result)->isToolResult()
114-
->toolJsonContent(function ($data) {
115-
expect($data['result'])->toBeFalse()
116-
->and($data['type'])->toBe('boolean');
117-
});
116+
->toolJsonContentToMatchArray([
117+
'result' => false,
118+
'type' => 'boolean',
119+
]);
118120
});
119121

120122
test('handles code with no return statement', function () {
121123
$tool = new Tinker;
122124
$result = $tool->handle(['code' => '$x = 5;']);
123125

124126
expect($result)->isToolResult()
125-
->toolJsonContent(function ($data) {
126-
expect($data['result'])->toBeNull()
127-
->and($data['type'])->toBe('NULL');
128-
});
127+
->toolJsonContentToMatchArray([
128+
'result' => null,
129+
'type' => 'NULL',
130+
]);
129131
});
130132

131133
test('should register only in local environment', function () {
@@ -144,21 +146,21 @@
144146
$result = $tool->handle(['code' => 'return 2 + 2;', 'timeout' => 10]);
145147

146148
expect($result)->isToolResult()
147-
->toolJsonContent(function ($data) {
148-
expect($data['result'])->toBe(4)
149-
->and($data['type'])->toBe('integer');
150-
});
149+
->toolJsonContentToMatchArray([
150+
'result' => 4,
151+
'type' => 'integer',
152+
]);
151153
});
152154

153155
test('uses default timeout when not specified', function () {
154156
$tool = new Tinker;
155157
$result = $tool->handle(['code' => 'return 2 + 2;']);
156158

157159
expect($result)->isToolResult()
158-
->toolJsonContent(function ($data) {
159-
expect($data['result'])->toBe(4)
160-
->and($data['type'])->toBe('integer');
161-
});
160+
->toolJsonContentToMatchArray([
161+
'result' => 4,
162+
'type' => 'integer',
163+
]);
162164
});
163165

164166
test('times out when code takes too long', function () {

tests/Pest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@
5858
return $this;
5959
});
6060

61+
expect()->extend('toolJsonContentToMatchArray', function (array $expectedArray) {
62+
/** @var ToolResult $this->value */
63+
$data = $this->value->toArray();
64+
$content = json_decode($data['content'][0]['text'], true);
65+
expect($content)->toMatchArray($expectedArray);
66+
67+
return $this;
68+
});
69+
6170
function fixture(string $name): string
6271
{
6372
return file_get_contents(\Pest\testDirectory('fixtures/'.$name));

0 commit comments

Comments
 (0)