@@ -20,6 +20,159 @@ struct ToolTests {
20
20
#expect( tool. inputSchema != nil )
21
21
}
22
22
23
+ @Test ( " Tool Annotations initialization and properties " )
24
+ func testToolAnnotationsInitialization( ) throws {
25
+ // Empty annotations
26
+ let emptyAnnotations = Tool . Annotations ( )
27
+ #expect( emptyAnnotations. isEmpty)
28
+ #expect( emptyAnnotations. title == nil )
29
+ #expect( emptyAnnotations. readOnlyHint == nil )
30
+ #expect( emptyAnnotations. destructiveHint == nil )
31
+ #expect( emptyAnnotations. idempotentHint == nil )
32
+ #expect( emptyAnnotations. openWorldHint == nil )
33
+
34
+ // Full annotations
35
+ let fullAnnotations = Tool . Annotations (
36
+ title: " Test Tool " ,
37
+ readOnlyHint: true ,
38
+ destructiveHint: false ,
39
+ idempotentHint: true ,
40
+ openWorldHint: false
41
+ )
42
+
43
+ #expect( !fullAnnotations. isEmpty)
44
+ #expect( fullAnnotations. title == " Test Tool " )
45
+ #expect( fullAnnotations. readOnlyHint == true )
46
+ #expect( fullAnnotations. destructiveHint == false )
47
+ #expect( fullAnnotations. idempotentHint == true )
48
+ #expect( fullAnnotations. openWorldHint == false )
49
+
50
+ // Partial annotations - should not be empty
51
+ let partialAnnotations = Tool . Annotations ( title: " Partial Test " )
52
+ #expect( !partialAnnotations. isEmpty)
53
+ #expect( partialAnnotations. title == " Partial Test " )
54
+
55
+ // Initialize with nil literal
56
+ let nilAnnotations : Tool . Annotations = nil
57
+ #expect( nilAnnotations. isEmpty)
58
+ }
59
+
60
+ @Test ( " Tool Annotations encoding and decoding " )
61
+ func testToolAnnotationsEncodingDecoding( ) throws {
62
+ let annotations = Tool . Annotations (
63
+ title: " Test Tool " ,
64
+ readOnlyHint: true ,
65
+ destructiveHint: false ,
66
+ idempotentHint: true ,
67
+ openWorldHint: false
68
+ )
69
+
70
+ #expect( !annotations. isEmpty)
71
+
72
+ let encoder = JSONEncoder ( )
73
+ let decoder = JSONDecoder ( )
74
+
75
+ let data = try encoder. encode ( annotations)
76
+ let decoded = try decoder. decode ( Tool . Annotations. self, from: data)
77
+
78
+ #expect( decoded. title == annotations. title)
79
+ #expect( decoded. readOnlyHint == annotations. readOnlyHint)
80
+ #expect( decoded. destructiveHint == annotations. destructiveHint)
81
+ #expect( decoded. idempotentHint == annotations. idempotentHint)
82
+ #expect( decoded. openWorldHint == annotations. openWorldHint)
83
+
84
+ // Test that empty annotations are encoded as expected
85
+ let emptyAnnotations = Tool . Annotations ( )
86
+ let emptyData = try encoder. encode ( emptyAnnotations)
87
+ let decodedEmpty = try decoder. decode ( Tool . Annotations. self, from: emptyData)
88
+
89
+ #expect( decodedEmpty. isEmpty)
90
+ }
91
+
92
+ @Test ( " Tool with annotations encoding and decoding " )
93
+ func testToolWithAnnotationsEncodingDecoding( ) throws {
94
+ let annotations = Tool . Annotations (
95
+ title: " Calculator " ,
96
+ destructiveHint: false
97
+ )
98
+
99
+ let tool = Tool (
100
+ name: " calculate " ,
101
+ description: " Performs calculations " ,
102
+ inputSchema: . object( [
103
+ " expression " : . string( " Mathematical expression to evaluate " )
104
+ ] ) ,
105
+ annotations: annotations
106
+ )
107
+
108
+ let encoder = JSONEncoder ( )
109
+ let decoder = JSONDecoder ( )
110
+
111
+ let data = try encoder. encode ( tool)
112
+ let decoded = try decoder. decode ( Tool . self, from: data)
113
+
114
+ #expect( decoded. name == tool. name)
115
+ #expect( decoded. description == tool. description)
116
+ #expect( decoded. annotations. title == annotations. title)
117
+ #expect( decoded. annotations. destructiveHint == annotations. destructiveHint)
118
+
119
+ // Verify that the annotations field is properly included in the JSON
120
+ let jsonString = String ( data: data, encoding: . utf8) !
121
+ #expect( jsonString. contains ( " \" annotations \" " ) )
122
+ #expect( jsonString. contains ( " \" title \" : \" Calculator \" " ) )
123
+ }
124
+
125
+ @Test ( " Tool with empty annotations " )
126
+ func testToolWithEmptyAnnotations( ) throws {
127
+ var tool = Tool (
128
+ name: " test_tool " ,
129
+ description: " Test tool description "
130
+ )
131
+
132
+ do {
133
+ #expect( tool. annotations. isEmpty)
134
+
135
+ let encoder = JSONEncoder ( )
136
+ let data = try encoder. encode ( tool)
137
+
138
+ // Verify that empty annotations are not included in the JSON
139
+ let jsonString = String ( data: data, encoding: . utf8) !
140
+ #expect( !jsonString. contains ( " \" annotations \" " ) )
141
+ }
142
+
143
+ do {
144
+ tool. annotations. title = " Test "
145
+
146
+ #expect( !tool. annotations. isEmpty)
147
+
148
+ let encoder = JSONEncoder ( )
149
+ let data = try encoder. encode ( tool)
150
+
151
+ // Verify that empty annotations are not included in the JSON
152
+ let jsonString = String ( data: data, encoding: . utf8) !
153
+ #expect( jsonString. contains ( " \" annotations \" " ) )
154
+ }
155
+ }
156
+
157
+ @Test ( " Tool with nil literal annotations " )
158
+ func testToolWithNilLiteralAnnotations( ) throws {
159
+ let tool = Tool (
160
+ name: " test_tool " ,
161
+ description: " Test tool description " ,
162
+ inputSchema: nil ,
163
+ annotations: nil
164
+ )
165
+
166
+ #expect( tool. annotations. isEmpty)
167
+
168
+ let encoder = JSONEncoder ( )
169
+ let data = try encoder. encode ( tool)
170
+
171
+ // Verify that nil literal annotations are not included in the JSON
172
+ let jsonString = String ( data: data, encoding: . utf8) !
173
+ #expect( !jsonString. contains ( " \" annotations \" " ) )
174
+ }
175
+
23
176
@Test ( " Tool encoding and decoding " )
24
177
func testToolEncodingDecoding( ) throws {
25
178
let tool = Tool (
0 commit comments