|
1 | 1 | <?php |
2 | 2 |
|
| 3 | +use Laravel\Mcp\Server\Completions\ArrayCompletionResponse; |
| 4 | +use Laravel\Mcp\Server\Completions\CallbackCompletionResponse; |
3 | 5 | use Laravel\Mcp\Server\Completions\CompletionResponse; |
4 | | -use Laravel\Mcp\Server\Completions\DirectCompletionResponse; |
| 6 | +use Laravel\Mcp\Server\Completions\EnumCompletionResponse; |
5 | 7 |
|
6 | 8 | it('creates a completion result with values', function (): void { |
7 | 9 | $result = CompletionResponse::from(['php', 'python', 'javascript']); |
8 | 10 |
|
9 | 11 | expect($result->values())->toBe(['php', 'python', 'javascript']) |
10 | | - ->and($result->hasMore())->toBeFalse() |
11 | | - ->and($result->total())->toBeNull(); |
| 12 | + ->and($result->hasMore())->toBeFalse(); |
12 | 13 | }); |
13 | 14 |
|
14 | 15 | it('creates an empty completion result', function (): void { |
15 | 16 | $result = CompletionResponse::empty(); |
16 | 17 |
|
17 | 18 | expect($result->values())->toBe([]) |
18 | | - ->and($result->hasMore())->toBeFalse() |
19 | | - ->and($result->total())->toBeNull(); |
| 19 | + ->and($result->hasMore())->toBeFalse(); |
20 | 20 | }); |
21 | 21 |
|
22 | 22 | it('converts to array format', function (): void { |
23 | 23 | $result = CompletionResponse::from(['php', 'python']); |
24 | 24 |
|
25 | 25 | expect($result->toArray())->toBe([ |
26 | 26 | 'values' => ['php', 'python'], |
| 27 | + 'total' => 2, |
27 | 28 | 'hasMore' => false, |
28 | 29 | ]); |
29 | 30 | }); |
30 | 31 |
|
31 | | -it('includes total in an array when provided', function (): void { |
32 | | - $result = new DirectCompletionResponse(['php', 'python'], total: 5, hasMore: true); |
33 | | - |
34 | | - expect($result->toArray())->toBe([ |
35 | | - 'values' => ['php', 'python'], |
36 | | - 'total' => 5, |
37 | | - 'hasMore' => true, |
38 | | - ]); |
39 | | -}); |
40 | | - |
41 | | -it('auto-truncates values to 100 items', function (): void { |
| 32 | +it('auto-truncates values to 100 items and sets hasMore', function (): void { |
42 | 33 | $values = array_map(fn ($i): string => "item{$i}", range(1, 150)); |
43 | 34 | $result = CompletionResponse::from($values); |
44 | 35 |
|
45 | | - expect($result->values())->toHaveCount(100); |
46 | | -}); |
47 | | - |
48 | | -it('throws exception when constructor receives more than 100 items', function (): void { |
49 | | - $values = array_map(fn ($i): string => "item{$i}", range(1, 101)); |
50 | | - |
51 | | - new DirectCompletionResponse($values); |
52 | | -})->throws(InvalidArgumentException::class, 'Completion values cannot exceed 100 items'); |
53 | | - |
54 | | -it('allows exactly 100 items', function (): void { |
55 | | - $values = array_map(fn ($i): string => "item{$i}", range(1, 100)); |
56 | | - $result = new DirectCompletionResponse($values); |
57 | | - |
58 | | - expect($result->values())->toHaveCount(100); |
| 36 | + expect($result->values())->toHaveCount(100) |
| 37 | + ->and($result->hasMore())->toBeTrue(); |
59 | 38 | }); |
60 | 39 |
|
61 | 40 | it('supports single string in from', function (): void { |
|
64 | 43 | expect($result->values())->toBe(['single-value']); |
65 | 44 | }); |
66 | 45 |
|
67 | | -it('creates fromArray result', function (): void { |
| 46 | +it('fromArray creates ArrayCompletionResponse', function (): void { |
68 | 47 | $result = CompletionResponse::fromArray(['php', 'python', 'javascript']); |
69 | | - $resolved = $result->resolve('py'); |
70 | 48 |
|
71 | | - expect($resolved->values())->toBe(['python']); |
| 49 | + expect($result)->toBeInstanceOf(ArrayCompletionResponse::class); |
72 | 50 | }); |
73 | 51 |
|
74 | | -it('creates fromEnum result with backed enum', function (): void { |
75 | | - enum TestBackedEnum: string |
| 52 | +it('fromEnum creates EnumCompletionResponse', function (): void { |
| 53 | + enum FactoryTestEnum: string |
76 | 54 | { |
77 | 55 | case One = 'value-one'; |
78 | | - case Two = 'value-two'; |
79 | 56 | } |
80 | 57 |
|
81 | | - $result = CompletionResponse::fromEnum(TestBackedEnum::class); |
82 | | - $resolved = $result->resolve('value-o'); |
83 | | - |
84 | | - expect($resolved->values())->toBe(['value-one']); |
85 | | -}); |
86 | | - |
87 | | -it('creates fromEnum result with non-backed enum', function (): void { |
88 | | - enum TestEnum |
89 | | - { |
90 | | - case Active; |
91 | | - case Inactive; |
92 | | - } |
93 | | - |
94 | | - $result = CompletionResponse::fromEnum(TestEnum::class); |
95 | | - $resolved = $result->resolve('act'); |
96 | | - |
97 | | - expect($resolved->values())->toBe(['Active']); |
98 | | -}); |
99 | | - |
100 | | -it('throws an exception for an invalid enum class', function (): void { |
101 | | - CompletionResponse::fromEnum('NotAnEnum'); |
102 | | -})->throws(InvalidArgumentException::class, 'is not an enum'); |
103 | | - |
104 | | -it('creates fromCallback result', function (): void { |
105 | | - $result = CompletionResponse::fromCallback(fn (string $value): \Laravel\Mcp\Server\Completions\CompletionResponse => CompletionResponse::from(['test-value'])); |
106 | | - $resolved = $result->resolve('test'); |
| 58 | + $result = CompletionResponse::fromEnum(FactoryTestEnum::class); |
107 | 59 |
|
108 | | - expect($resolved->values())->toBe(['test-value']); |
| 60 | + expect($result)->toBeInstanceOf(EnumCompletionResponse::class); |
109 | 61 | }); |
110 | 62 |
|
111 | | -it('callback can return an array', function (): void { |
112 | | - $result = CompletionResponse::fromCallback(fn (string $value): array => ['value1', 'value2']); |
113 | | - $resolved = $result->resolve('val'); |
| 63 | +it('fromCallback creates CallbackCompletionResponse', function (): void { |
| 64 | + $result = CompletionResponse::fromCallback(fn (string $value): array => ['test']); |
114 | 65 |
|
115 | | - expect($resolved->values())->toBe(['value1', 'value2']); |
| 66 | + expect($result)->toBeInstanceOf(CallbackCompletionResponse::class); |
116 | 67 | }); |
117 | 68 |
|
118 | 69 | it('resolve returns self for direct type', function (): void { |
|
0 commit comments