Files
holocron/plugins/hello-world/tests/test_mcp_server.sh
Defame1297 b5bcf08acb test: add TDD tests for hello-world MCP server
23 tests covering the full JSON-RPC 2.0 protocol surface:
initialize handshake, silent notifications/initialized, tools/list
schema, tools/call with and without args, unknown tool error,
unknown method error, and invalid JSON resilience.

Fixed assert helpers to use grep -qF -- to prevent leading-dash
patterns (like -32601) from being parsed as grep flags.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 16:43:30 +00:00

107 lines
4.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Tests for plugins/hello-world/bin/mcp-server.js
# Protocol: JSON-RPC 2.0 over stdio. Tests send input lines and assert on stdout.
set -euo pipefail
SERVER="$(cd "$(dirname "$0")/../bin" && pwd)/mcp-server.js"
PASS=0; FAIL=0
# ── helpers ──────────────────────────────────────────────────────────────────
assert_contains() {
local label="$1" expected="$2" actual="$3"
if echo "$actual" | grep -qF -- "$expected"; then
echo " PASS: $label"
PASS=$((PASS+1))
else
echo " FAIL: $label"
echo " expected to contain: $expected"
echo " got: $actual"
FAIL=$((FAIL+1))
fi
}
assert_not_contains() {
local label="$1" unexpected="$2" actual="$3"
if echo "$actual" | grep -qF -- "$unexpected"; then
echo " FAIL: $label"
echo " expected NOT to contain: $unexpected"
echo " got: $actual"
FAIL=$((FAIL+1))
else
echo " PASS: $label"
PASS=$((PASS+1))
fi
}
# Send newline-separated JSON lines to the server, capture stdout
run_server() {
printf '%s\n' "$@" | node "$SERVER" 2>/dev/null
}
# ── tests ────────────────────────────────────────────────────────────────────
echo "initialize"
OUT=$(run_server '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}},"id":1}')
assert_contains "returns protocolVersion" '"protocolVersion":"2024-11-05"' "$OUT"
assert_contains "returns capabilities" '"capabilities"' "$OUT"
assert_contains "returns serverInfo name" '"name":"hello-world"' "$OUT"
assert_contains "returns serverInfo version" '"version":"1.0.0"' "$OUT"
assert_contains "echoes id" '"id":1' "$OUT"
echo "notifications/initialized"
OUT=$(run_server '{"jsonrpc":"2.0","method":"notifications/initialized"}')
assert_not_contains "no response for notification" '"jsonrpc"' "$OUT"
echo "tools/list"
OUT=$(run_server \
'{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' \
'{"jsonrpc":"2.0","method":"tools/list","id":2}')
assert_contains "lists say_hello tool" '"name":"say_hello"' "$OUT"
assert_contains "tool has description" '"description"' "$OUT"
assert_contains "tool has inputSchema" '"inputSchema"' "$OUT"
assert_contains "schema has name property" '"name"' "$OUT"
assert_contains "echoes id 2" '"id":2' "$OUT"
echo "tools/call say_hello — no args"
OUT=$(run_server \
'{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' \
'{"jsonrpc":"2.0","method":"tools/call","params":{"name":"say_hello","arguments":{}},"id":3}')
assert_contains "generic greeting content" 'Hello from the holocron' "$OUT"
assert_contains "response has content array" '"content"' "$OUT"
assert_contains "content type is text" '"type":"text"' "$OUT"
echo "tools/call say_hello — with name"
OUT=$(run_server \
'{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' \
'{"jsonrpc":"2.0","method":"tools/call","params":{"name":"say_hello","arguments":{"name":"Obi-Wan"}},"id":4}')
assert_contains "personalised greeting" 'Hello, Obi-Wan!' "$OUT"
assert_not_contains "not generic greeting" 'Hello from the holocron' "$OUT"
echo "tools/call — unknown tool"
OUT=$(run_server \
'{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' \
'{"jsonrpc":"2.0","method":"tools/call","params":{"name":"does_not_exist","arguments":{}},"id":5}')
assert_contains "error code -32601" '"code":-32601' "$OUT"
assert_contains "error field present" '"error"' "$OUT"
echo "unknown method with id"
OUT=$(run_server \
'{"jsonrpc":"2.0","method":"no_such_method","id":6}')
assert_contains "error returned" '"error"' "$OUT"
assert_contains "method not found code" '"code":-32601' "$OUT"
assert_contains "echoes id 6" '"id":6' "$OUT"
echo "invalid JSON — no crash, process continues"
OUT=$(run_server \
'this is not json' \
'{"jsonrpc":"2.0","method":"tools/list","id":7}')
assert_contains "valid request after bad input succeeds" '"id":7' "$OUT"
assert_not_contains "no error for bad json line" '"error"' "$OUT"
# ── summary ──────────────────────────────────────────────────────────────────
echo ""
echo "Results: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]] && exit 0 || exit 1