Skip to content

Commit 379564f

Browse files
authored
Merge pull request #9 from leehack/add-more-tests
Add more tests
2 parents a184695 + 74de327 commit 379564f

File tree

1 file changed

+215
-3
lines changed

1 file changed

+215
-3
lines changed

test/types_test.dart

Lines changed: 215 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import 'dart:convert';
2-
3-
import 'package:test/test.dart';
41
import 'package:mcp_dart/mcp_dart.dart';
2+
import 'package:test/test.dart';
53

64
void main() {
75
group('JsonRpcMessage Tests', () {
@@ -29,6 +27,20 @@ void main() {
2927
equals(latestProtocolVersion));
3028
});
3129

30+
test('JsonRpcResponse serialization', () {
31+
final response = JsonRpcResponse(
32+
id: 1,
33+
result: {'key': 'value'},
34+
meta: {'metaKey': 'metaValue'},
35+
);
36+
37+
final json = response.toJson();
38+
expect(json['jsonrpc'], equals(jsonRpcVersion));
39+
expect(json['id'], equals(1));
40+
expect(json['result']['key'], equals('value'));
41+
expect(json['result']['_meta']['metaKey'], equals('metaValue'));
42+
});
43+
3244
test('JsonRpcError serialization and deserialization', () {
3345
final error = JsonRpcError(
3446
id: 1,
@@ -43,10 +55,15 @@ void main() {
4355
expect(json['jsonrpc'], equals(jsonRpcVersion));
4456
expect(json['error']['code'], equals(ErrorCode.invalidRequest.value));
4557
expect(json['error']['message'], equals('Invalid request'));
58+
expect(
59+
json['error']['data']['details'], equals('Missing required field'));
4660

4761
final deserialized = JsonRpcError.fromJson(json);
4862
expect(deserialized.id, equals(error.id));
4963
expect(deserialized.error.code, equals(ErrorCode.invalidRequest.value));
64+
expect(deserialized.error.message, equals('Invalid request'));
65+
expect(
66+
deserialized.error.data['details'], equals('Missing required field'));
5067
});
5168
});
5269

@@ -112,6 +129,19 @@ void main() {
112129
expect(deserialized.data, equals('base64data'));
113130
expect(deserialized.mimeType, equals('image/png'));
114131
});
132+
133+
test('UnknownContent serialization and deserialization', () {
134+
final content = UnknownContent(
135+
type: 'unknown', additionalProperties: {'key': 'value'});
136+
final json = content.toJson();
137+
expect(json['type'], equals('unknown'));
138+
expect(json['key'], equals('value'));
139+
140+
final deserialized =
141+
UnknownContent(type: 'unknown', additionalProperties: json);
142+
expect(deserialized.type, equals('unknown'));
143+
expect(deserialized.additionalProperties['key'], equals('value'));
144+
});
115145
});
116146

117147
group('Resource Tests', () {
@@ -151,6 +181,24 @@ void main() {
151181
expect(deserialized.uri, equals('file://example.txt'));
152182
expect(deserialized.text, equals('Sample text content'));
153183
});
184+
185+
test('BlobResourceContents serialization and deserialization', () {
186+
final contents = BlobResourceContents(
187+
uri: 'file://example.bin',
188+
blob: 'base64data',
189+
mimeType: 'application/octet-stream',
190+
);
191+
192+
final json = contents.toJson();
193+
expect(json['uri'], equals('file://example.bin'));
194+
expect(json['blob'], equals('base64data'));
195+
expect(json['mimeType'], equals('application/octet-stream'));
196+
197+
final deserialized =
198+
ResourceContents.fromJson(json) as BlobResourceContents;
199+
expect(deserialized.uri, equals('file://example.bin'));
200+
expect(deserialized.blob, equals('base64data'));
201+
});
154202
});
155203

156204
group('Prompt Tests', () {
@@ -173,5 +221,169 @@ void main() {
173221
expect(deserialized.name, equals('example-prompt'));
174222
expect(deserialized.arguments?.first.name, equals('arg1'));
175223
});
224+
225+
test('PromptArgument serialization and deserialization', () {
226+
final argument = PromptArgument(
227+
name: 'arg1',
228+
description: 'Argument 1',
229+
required: true,
230+
);
231+
232+
final json = argument.toJson();
233+
expect(json['name'], equals('arg1'));
234+
expect(json['description'], equals('Argument 1'));
235+
expect(json['required'], equals(true));
236+
237+
final deserialized = PromptArgument.fromJson(json);
238+
expect(deserialized.name, equals('arg1'));
239+
expect(deserialized.description, equals('Argument 1'));
240+
expect(deserialized.required, equals(true));
241+
});
242+
});
243+
group('CreateMessageResult Tests', () {
244+
test('CreateMessageResult serialization and deserialization', () {
245+
final result = CreateMessageResult(
246+
model: 'gpt-4',
247+
stopReason: StopReason.maxTokens,
248+
role: SamplingMessageRole.assistant,
249+
content: SamplingTextContent(text: 'Hello, world!'),
250+
meta: {'key': 'value'},
251+
);
252+
253+
final json = result.toJson();
254+
expect(json['model'], equals('gpt-4'));
255+
expect(json['stopReason'], equals(StopReason.maxTokens.toString()));
256+
expect(json['role'], equals('assistant'));
257+
expect(json['content']['type'], equals('text'));
258+
expect(json['content']['text'], equals('Hello, world!'));
259+
expect(json['_meta'], isNull); // `_meta` is not included in `toJson`
260+
261+
final deserialized = CreateMessageResult.fromJson({
262+
'model': 'gpt-4',
263+
'stopReason': 'maxTokens',
264+
'role': 'assistant',
265+
'content': {'type': 'text', 'text': 'Hello, world!'},
266+
'_meta': {'key': 'value'},
267+
});
268+
269+
expect(deserialized.model, equals('gpt-4'));
270+
expect(deserialized.stopReason, equals(StopReason.maxTokens));
271+
expect(deserialized.role, equals(SamplingMessageRole.assistant));
272+
expect(deserialized.content, isA<SamplingTextContent>());
273+
expect((deserialized.content as SamplingTextContent).text,
274+
equals('Hello, world!'));
275+
expect(deserialized.meta, equals({'key': 'value'}));
276+
});
277+
278+
test('CreateMessageResult handles custom stopReason', () {
279+
final result = CreateMessageResult(
280+
model: 'gpt-4',
281+
stopReason: 'customReason',
282+
role: SamplingMessageRole.assistant,
283+
content: SamplingTextContent(text: 'Custom reason test'),
284+
);
285+
286+
final json = result.toJson();
287+
expect(json['stopReason'], equals('customReason'));
288+
289+
final deserialized = CreateMessageResult.fromJson({
290+
'model': 'gpt-4',
291+
'stopReason': 'customReason',
292+
'role': 'assistant',
293+
'content': {'type': 'text', 'text': 'Custom reason test'},
294+
});
295+
296+
expect(deserialized.stopReason, equals('customReason'));
297+
});
298+
299+
test('CreateMessageResult handles invalid stopReason gracefully', () {
300+
final deserialized = CreateMessageResult.fromJson({
301+
'model': 'gpt-4',
302+
'stopReason': 'invalidReason',
303+
'role': 'assistant',
304+
'content': {'type': 'text', 'text': 'Invalid reason test'},
305+
});
306+
307+
expect(deserialized.stopReason, equals('invalidReason'));
308+
});
309+
});
310+
311+
group('JsonRpcMessage.fromJson Tests', () {
312+
test('Parses valid request with method and id', () {
313+
final json = {
314+
'jsonrpc': '2.0',
315+
'id': 1,
316+
'method': 'ping',
317+
};
318+
final message = JsonRpcMessage.fromJson(json);
319+
expect(message, isA<JsonRpcPingRequest>());
320+
expect((message as JsonRpcPingRequest).id, equals(1));
321+
});
322+
323+
test('Parses valid notification without id', () {
324+
final json = {
325+
'jsonrpc': '2.0',
326+
'method': 'notifications/initialized',
327+
};
328+
final message = JsonRpcMessage.fromJson(json);
329+
expect(message, isA<JsonRpcInitializedNotification>());
330+
});
331+
332+
test('Parses valid response with result and meta', () {
333+
final json = {
334+
'jsonrpc': '2.0',
335+
'id': 1,
336+
'result': {
337+
'key': 'value',
338+
'_meta': {'metaKey': 'metaValue'}
339+
},
340+
};
341+
final message = JsonRpcMessage.fromJson(json);
342+
expect(message, isA<JsonRpcResponse>());
343+
final response = message as JsonRpcResponse;
344+
expect(response.id, equals(1));
345+
expect(response.result, equals({'key': 'value'}));
346+
expect(response.meta, equals({'metaKey': 'metaValue'}));
347+
});
348+
349+
test('Parses valid error response', () {
350+
final json = {
351+
'jsonrpc': '2.0',
352+
'id': 1,
353+
'error': {'code': -32601, 'message': 'Method not found'},
354+
};
355+
final message = JsonRpcMessage.fromJson(json);
356+
expect(message, isA<JsonRpcError>());
357+
final error = message as JsonRpcError;
358+
expect(error.id, equals(1));
359+
expect(error.error.code, equals(-32601));
360+
expect(error.error.message, equals('Method not found'));
361+
});
362+
363+
test('Throws FormatException for invalid JSON-RPC version', () {
364+
final json = {
365+
'jsonrpc': '1.0',
366+
'id': 1,
367+
'method': 'ping',
368+
};
369+
expect(() => JsonRpcMessage.fromJson(json), throwsFormatException);
370+
});
371+
372+
test('Throws UnimplementedError for unknown method', () {
373+
final json = {
374+
'jsonrpc': '2.0',
375+
'id': 1,
376+
'method': 'unknownMethod',
377+
};
378+
expect(() => JsonRpcMessage.fromJson(json), throwsUnimplementedError);
379+
});
380+
381+
test('Throws FormatException for invalid message format', () {
382+
final json = {
383+
'jsonrpc': '2.0',
384+
'id': 1,
385+
};
386+
expect(() => JsonRpcMessage.fromJson(json), throwsFormatException);
387+
});
176388
});
177389
}

0 commit comments

Comments
 (0)