2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
5
- package mcp_test
5
+ package mcp
6
6
7
7
import (
8
8
"context"
9
+ "encoding/json"
10
+ "reflect"
9
11
"testing"
10
12
11
13
"github.com/google/go-cmp/cmp"
12
14
"github.com/google/go-cmp/cmp/cmpopts"
13
- "golang.org/x/tools/internal/mcp"
14
15
"golang.org/x/tools/internal/mcp/jsonschema"
15
16
)
16
17
17
18
// testToolHandler is used for type inference in TestNewTool.
18
- func testToolHandler [T any ](context.Context , * mcp. ServerSession , * mcp. CallToolParamsFor [T ]) (* mcp. CallToolResultFor [any ], error ) {
19
+ func testToolHandler [T any ](context.Context , * ServerSession , * CallToolParamsFor [T ]) (* CallToolResultFor [any ], error ) {
19
20
panic ("not implemented" )
20
21
}
21
22
22
23
func TestNewTool (t * testing.T ) {
23
24
tests := []struct {
24
- tool * mcp. ServerTool
25
+ tool * ServerTool
25
26
want * jsonschema.Schema
26
27
}{
27
28
{
28
- mcp . NewTool ("basic" , "" , testToolHandler [struct {
29
+ NewTool ("basic" , "" , testToolHandler [struct {
29
30
Name string `json:"name"`
30
31
}]),
31
32
& jsonschema.Schema {
@@ -38,8 +39,8 @@ func TestNewTool(t *testing.T) {
38
39
},
39
40
},
40
41
{
41
- mcp . NewTool ("enum" , "" , testToolHandler [struct { Name string }], mcp . Input (
42
- mcp . Property ("Name" , mcp . Enum ("x" , "y" , "z" )),
42
+ NewTool ("enum" , "" , testToolHandler [struct { Name string }], Input (
43
+ Property ("Name" , Enum ("x" , "y" , "z" )),
43
44
)),
44
45
& jsonschema.Schema {
45
46
Type : "object" ,
@@ -51,13 +52,13 @@ func TestNewTool(t *testing.T) {
51
52
},
52
53
},
53
54
{
54
- mcp . NewTool ("required" , "" , testToolHandler [struct {
55
+ NewTool ("required" , "" , testToolHandler [struct {
55
56
Name string `json:"name"`
56
57
Language string `json:"language"`
57
58
X int `json:"x,omitempty"`
58
59
Y int `json:"y,omitempty"`
59
- }], mcp . Input (
60
- mcp . Property ("x" , mcp . Required (true )))),
60
+ }], Input (
61
+ Property ("x" , Required (true )))),
61
62
& jsonschema.Schema {
62
63
Type : "object" ,
63
64
Required : []string {"name" , "language" , "x" },
@@ -71,11 +72,11 @@ func TestNewTool(t *testing.T) {
71
72
},
72
73
},
73
74
{
74
- mcp . NewTool ("set_schema" , "" , testToolHandler [struct {
75
+ NewTool ("set_schema" , "" , testToolHandler [struct {
75
76
X int `json:"x,omitempty"`
76
77
Y int `json:"y,omitempty"`
77
- }], mcp . Input (
78
- mcp . Schema (& jsonschema.Schema {Type : "object" })),
78
+ }], Input (
79
+ Schema (& jsonschema.Schema {Type : "object" })),
79
80
),
80
81
& jsonschema.Schema {
81
82
Type : "object" ,
@@ -88,3 +89,42 @@ func TestNewTool(t *testing.T) {
88
89
}
89
90
}
90
91
}
92
+
93
+ func TestUnmarshalSchema (t * testing.T ) {
94
+ schema := & jsonschema.Schema {
95
+ Type : "object" ,
96
+ Properties : map [string ]* jsonschema.Schema {
97
+ "x" : {Type : "integer" , Default : json .RawMessage ("3" )},
98
+ },
99
+ }
100
+ resolved , err := schema .Resolve (& jsonschema.ResolveOptions {ValidateDefaults : true })
101
+ if err != nil {
102
+ t .Fatal (err )
103
+ }
104
+
105
+ type S struct {
106
+ X int `json:"x"`
107
+ }
108
+
109
+ for _ , tt := range []struct {
110
+ data string
111
+ v any
112
+ want any
113
+ }{
114
+ {`{"x": 1}` , new (S ), & S {X : 1 }},
115
+ {`{}` , new (S ), & S {X : 3 }}, // default applied
116
+ {`{"x": 0}` , new (S ), & S {X : 3 }}, // FAIL: should be 0. (requires double unmarshal)
117
+ {`{"x": 1}` , new (map [string ]any ), & map [string ]any {"x" : 1.0 }},
118
+ {`{}` , new (map [string ]any ), & map [string ]any {"x" : 3.0 }}, // default applied
119
+ {`{"x": 0}` , new (map [string ]any ), & map [string ]any {"x" : 0.0 }},
120
+ } {
121
+ raw := json .RawMessage (tt .data )
122
+ if err := unmarshalSchema (raw , resolved , tt .v ); err != nil {
123
+ t .Fatal (err )
124
+ }
125
+ if ! reflect .DeepEqual (tt .v , tt .want ) {
126
+ t .Errorf ("got %#v, want %#v" , tt .v , tt .want )
127
+ }
128
+
129
+ }
130
+ }
0 commit comments