AtlatestRepositorysigil-mcp

sigil-mcp / tree / testtest-protocol.sgl

1(import (sigil test)
2 (sigil mcp protocol)
3 (sigil json))
4
5;; ============================================================
6;; parse-message
7;; ============================================================
8
9(test-group "parse-message"
10 (test "request with id+method+params"
11 (let* ((json (json-decode "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"ping\",\"params\":{}}"))
12 (msg (parse-message json)))
13 (assert-true (jsonrpc-request? msg))
14 (assert-equal 1 (jsonrpc-request-id msg))
15 (assert-equal "ping" (jsonrpc-request-method msg))))
17 (test "notification (no id)"
18 (let* ((json (json-decode "{\"jsonrpc\":\"2.0\",\"method\":\"notify\",\"params\":{}}"))
19 (msg (parse-message json)))
20 (assert-true (jsonrpc-notification? msg))
21 (assert-equal "notify" (jsonrpc-notification-method msg))))
23 (test "missing jsonrpc field returns #f"
24 (let* ((json (json-decode "{\"id\":1,\"method\":\"test\"}"))
25 (msg (parse-message json)))
26 (assert-false msg)))
28 (test "wrong version returns #f"
29 (let* ((json (json-decode "{\"jsonrpc\":\"1.0\",\"id\":1,\"method\":\"test\"}"))
30 (msg (parse-message json)))
31 (assert-false msg)))
33 (test "missing method returns #f"
34 (let* ((json (json-decode "{\"jsonrpc\":\"2.0\",\"id\":1}"))
35 (msg (parse-message json)))
36 (assert-false msg)))
38 (test "non-dict returns #f"
39 (assert-false (parse-message "not a dict")))
41 (test "successful response"
42 (let ((msg (parse-message-string
43 "{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":{\"ok\":true}}")))
44 (assert-true (jsonrpc-response? msg))
45 (assert-equal 0 (jsonrpc-response-id msg))
46 (assert-true (dict-ref (jsonrpc-response-result msg) ok:))))
48 (test "successful response preserves a false result"
49 (let ((msg (parse-message-string
50 "{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":false}")))
51 (assert-true (jsonrpc-response? msg))
52 (assert-equal 0 (jsonrpc-response-id msg))
53 (assert-false (jsonrpc-response-result msg))))
55 (test "error response"
56 (let ((msg (parse-message-string
57 "{\"jsonrpc\":\"2.0\",\"id\":7,\"error\":{\"code\":-32001,\"message\":\"refused\",\"data\":{\"kind\":\"policy\"}}}")))
58 (assert-true (jsonrpc-error-response? msg))
59 (assert-equal 7 (jsonrpc-error-response-id msg))
60 (assert-equal -32001 (jsonrpc-error-response-code msg))
61 (assert-equal "refused" (jsonrpc-error-response-message msg)))))
63;; ============================================================
64;; parse-message-string
65;; ============================================================
67(test-group "parse-message-string"
68 (test "JSON string roundtrip"
69 (let ((msg (parse-message-string "{\"jsonrpc\":\"2.0\",\"id\":42,\"method\":\"tools/list\",\"params\":{}}")))
70 (assert-true (jsonrpc-request? msg))
71 (assert-equal 42 (jsonrpc-request-id msg))
72 (assert-equal "tools/list" (jsonrpc-request-method msg)))))
74;; ============================================================
75;; Serialization
76;; ============================================================
78(test-group "serialization"
79 (test "response->json produces valid JSON"
80 (let* ((resp (make-response 1 "ok"))
81 (json-str (response->json resp))
82 (parsed (json-decode json-str)))
83 (assert-true (dict? parsed))
84 (assert-equal "2.0" (dict-ref parsed jsonrpc:))
85 (assert-equal 1 (dict-ref parsed id:))
86 (assert-equal "ok" (dict-ref parsed result:))))
88 (test "error-response->json includes error"
89 (let* ((resp (make-error-response 1 -32600 "Invalid Request"))
90 (json-str (error-response->json resp))
91 (parsed (json-decode json-str)))
92 (assert-true (dict? parsed))
93 (assert-equal 1 (dict-ref parsed id:))
94 (let ((err (dict-ref parsed error:)))
95 (assert-true (dict? err))
96 (assert-equal -32600 (dict-ref err code:))
97 (assert-equal "Invalid Request" (dict-ref err message:)))))
99 (test "notification->json omits id"
100 (let* ((notif (make-notification "update"))
101 (json-str (notification->json notif))
102 (parsed (json-decode json-str)))
103 (assert-equal "2.0" (dict-ref parsed jsonrpc:))
104 (assert-equal "update" (dict-ref parsed method:))
105 (assert-false (dict-ref parsed id: #f))))
107 (test "request->json includes all fields"
108 (let* ((req (jsonrpc-request id: 5 method: "test" params: (dict)))
109 (json-str (request->json req))
110 (parsed (json-decode json-str)))
111 (assert-equal 5 (dict-ref parsed id:))
112 (assert-equal "test" (dict-ref parsed method:)))))
114;; ============================================================
115;; Helper constructors
116;; ============================================================
118(test-group "helper constructors"
119 (test "make-response"
120 (let ((r (make-response 1 "data")))
121 (assert-true (jsonrpc-response? r))
122 (assert-equal 1 (jsonrpc-response-id r))
123 (assert-equal "data" (jsonrpc-response-result r))))
125 (test "make-error-response without data"
126 (let ((r (make-error-response 2 -32700 "Parse error")))
127 (assert-true (jsonrpc-error-response? r))
128 (assert-equal 2 (jsonrpc-error-response-id r))
129 (assert-equal -32700 (jsonrpc-error-response-code r))
130 (assert-equal "Parse error" (jsonrpc-error-response-message r))))
132 (test "make-notification"
133 (let ((n (make-notification "event")))
134 (assert-true (jsonrpc-notification? n))
135 (assert-equal "event" (jsonrpc-notification-method n)))))
137;; ============================================================
138;; Error codes
139;; ============================================================
141(test-group "error codes"
142 (test "error-parse"
143 (assert-equal -32700 error-parse))
145 (test "error-invalid-request"
146 (assert-equal -32600 error-invalid-request))
148 (test "error-method-not-found"
149 (assert-equal -32601 error-method-not-found))
151 (test "error-invalid-params"
152 (assert-equal -32602 error-invalid-params))
154 (test "error-internal"
155 (assert-equal -32603 error-internal)))
157(run-tests)