Rename test directory from model_context_protocol to mcp
Follow-up to #24. The directory structure of the product code and test code is expected to match.
This commit is contained in:
parent
7ad1e904eb
commit
f33fe309b4
1 changed files with 0 additions and 0 deletions
|
|
@ -1,230 +0,0 @@
|
|||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "test_helper"
|
||||
|
||||
module MCP
|
||||
class ToolTest < ActiveSupport::TestCase
|
||||
class TestTool < Tool
|
||||
tool_name "test_tool"
|
||||
description "a test tool for testing"
|
||||
input_schema({ properties: { message: { type: "string" } }, required: ["message"] })
|
||||
annotations(
|
||||
title: "Test Tool",
|
||||
read_only_hint: true,
|
||||
destructive_hint: false,
|
||||
idempotent_hint: true,
|
||||
open_world_hint: false,
|
||||
)
|
||||
|
||||
class << self
|
||||
def call(message:, server_context: nil)
|
||||
Tool::Response.new([{ type: "text", content: "OK" }])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "#to_h returns a hash with name, description, and inputSchema" do
|
||||
tool = Tool.define(name: "mock_tool", description: "a mock tool for testing")
|
||||
assert_equal tool.to_h, { name: "mock_tool", description: "a mock tool for testing", inputSchema: {} }
|
||||
end
|
||||
|
||||
test "#to_h includes annotations when present" do
|
||||
tool = TestTool
|
||||
expected_annotations = {
|
||||
title: "Test Tool",
|
||||
readOnlyHint: true,
|
||||
destructiveHint: false,
|
||||
idempotentHint: true,
|
||||
openWorldHint: false,
|
||||
}
|
||||
assert_equal tool.to_h[:annotations], expected_annotations
|
||||
end
|
||||
|
||||
test "#call invokes the tool block and returns the response" do
|
||||
tool = TestTool
|
||||
response = tool.call(message: "test")
|
||||
assert_equal response.content, [{ type: "text", content: "OK" }]
|
||||
assert_equal response.is_error, false
|
||||
end
|
||||
|
||||
test "allows declarative definition of tools as classes" do
|
||||
class MockTool < Tool
|
||||
tool_name "my_mock_tool"
|
||||
description "a mock tool for testing"
|
||||
input_schema({ properties: { message: { type: "string" } }, required: [:message] })
|
||||
end
|
||||
|
||||
tool = MockTool
|
||||
assert_equal tool.name_value, "my_mock_tool"
|
||||
assert_equal tool.description, "a mock tool for testing"
|
||||
assert_equal tool.input_schema.to_h,
|
||||
{ type: "object", properties: { message: { type: "string" } }, required: [:message] }
|
||||
end
|
||||
|
||||
test "defaults to class name as tool name" do
|
||||
class DefaultNameTool < Tool
|
||||
end
|
||||
|
||||
tool = DefaultNameTool
|
||||
|
||||
assert_equal tool.tool_name, "default_name_tool"
|
||||
end
|
||||
|
||||
test "accepts input schema as an InputSchema object" do
|
||||
class InputSchemaTool < Tool
|
||||
input_schema InputSchema.new(properties: { message: { type: "string" } }, required: [:message])
|
||||
end
|
||||
|
||||
tool = InputSchemaTool
|
||||
|
||||
expected = { type: "object", properties: { message: { type: "string" } }, required: [:message] }
|
||||
assert_equal expected, tool.input_schema.to_h
|
||||
end
|
||||
|
||||
test ".define allows definition of simple tools with a block" do
|
||||
tool = Tool.define(name: "mock_tool", description: "a mock tool for testing") do |_|
|
||||
Tool::Response.new([{ type: "text", content: "OK" }])
|
||||
end
|
||||
|
||||
assert_equal tool.name_value, "mock_tool"
|
||||
assert_equal tool.description, "a mock tool for testing"
|
||||
assert_equal tool.input_schema, nil
|
||||
end
|
||||
|
||||
test ".define allows definition of tools with annotations" do
|
||||
tool = Tool.define(
|
||||
name: "mock_tool",
|
||||
description: "a mock tool for testing",
|
||||
annotations: {
|
||||
title: "Mock Tool",
|
||||
read_only_hint: true,
|
||||
},
|
||||
) do |_|
|
||||
Tool::Response.new([{ type: "text", content: "OK" }])
|
||||
end
|
||||
|
||||
assert_equal tool.name_value, "mock_tool"
|
||||
assert_equal tool.description, "a mock tool for testing"
|
||||
assert_equal tool.input_schema, nil
|
||||
assert_equal tool.annotations_value.to_h, { title: "Mock Tool", readOnlyHint: true }
|
||||
end
|
||||
|
||||
# Tests for Tool::Annotations class
|
||||
test "Tool::Annotations initializes with all properties" do
|
||||
annotations = Tool::Annotations.new(
|
||||
title: "Test Tool",
|
||||
read_only_hint: true,
|
||||
destructive_hint: false,
|
||||
idempotent_hint: true,
|
||||
open_world_hint: false,
|
||||
)
|
||||
|
||||
assert_equal annotations.title, "Test Tool"
|
||||
assert_equal annotations.read_only_hint, true
|
||||
assert_equal annotations.destructive_hint, false
|
||||
assert_equal annotations.idempotent_hint, true
|
||||
assert_equal annotations.open_world_hint, false
|
||||
end
|
||||
|
||||
test "Tool::Annotations initializes with partial properties" do
|
||||
annotations = Tool::Annotations.new(
|
||||
title: "Test Tool",
|
||||
read_only_hint: true,
|
||||
)
|
||||
|
||||
assert_equal annotations.title, "Test Tool"
|
||||
assert_equal annotations.read_only_hint, true
|
||||
assert_nil annotations.destructive_hint
|
||||
assert_nil annotations.idempotent_hint
|
||||
assert_nil annotations.open_world_hint
|
||||
end
|
||||
|
||||
test "Tool::Annotations#to_h omits nil values" do
|
||||
annotations = Tool::Annotations.new(
|
||||
title: "Test Tool",
|
||||
read_only_hint: true,
|
||||
)
|
||||
|
||||
expected = {
|
||||
title: "Test Tool",
|
||||
readOnlyHint: true,
|
||||
}
|
||||
assert_equal annotations.to_h, expected
|
||||
end
|
||||
|
||||
test "Tool::Annotations#to_h handles all properties" do
|
||||
annotations = Tool::Annotations.new(
|
||||
title: "Test Tool",
|
||||
read_only_hint: true,
|
||||
destructive_hint: false,
|
||||
idempotent_hint: true,
|
||||
open_world_hint: false,
|
||||
)
|
||||
|
||||
expected = {
|
||||
title: "Test Tool",
|
||||
readOnlyHint: true,
|
||||
destructiveHint: false,
|
||||
idempotentHint: true,
|
||||
openWorldHint: false,
|
||||
}
|
||||
assert_equal annotations.to_h, expected
|
||||
end
|
||||
|
||||
test "Tool::Annotations#to_h returns empty hash when all values are nil" do
|
||||
annotations = Tool::Annotations.new
|
||||
assert_empty annotations.to_h
|
||||
end
|
||||
|
||||
test "Tool class method annotations can be set and retrieved" do
|
||||
class AnnotationsTestTool < Tool
|
||||
tool_name "annotations_test"
|
||||
annotations(
|
||||
title: "Annotations Test",
|
||||
read_only_hint: true,
|
||||
)
|
||||
end
|
||||
|
||||
tool = AnnotationsTestTool
|
||||
assert_instance_of Tool::Annotations, tool.annotations_value
|
||||
assert_equal tool.annotations_value.title, "Annotations Test"
|
||||
assert_equal tool.annotations_value.read_only_hint, true
|
||||
end
|
||||
|
||||
test "Tool class method annotations can be updated" do
|
||||
class UpdatableAnnotationsTool < Tool
|
||||
tool_name "updatable_annotations"
|
||||
end
|
||||
|
||||
tool = UpdatableAnnotationsTool
|
||||
tool.annotations(title: "Initial")
|
||||
assert_equal tool.annotations_value.title, "Initial"
|
||||
|
||||
tool.annotations(title: "Updated")
|
||||
assert_equal tool.annotations_value.title, "Updated"
|
||||
end
|
||||
|
||||
test "#call with Sorbet typed tools invokes the tool block and returns the response" do
|
||||
class TypedTestTool < Tool
|
||||
tool_name "test_tool"
|
||||
description "a test tool for testing"
|
||||
input_schema({ properties: { message: { type: "string" } }, required: ["message"] })
|
||||
|
||||
class << self
|
||||
extend T::Sig
|
||||
|
||||
sig { params(message: String, server_context: T.nilable(T.untyped)).returns(Tool::Response) }
|
||||
def call(message:, server_context: nil)
|
||||
Tool::Response.new([{ type: "text", content: "OK" }])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tool = TypedTestTool
|
||||
response = tool.call(message: "test")
|
||||
assert_equal response.content, [{ type: "text", content: "OK" }]
|
||||
assert_equal response.is_error, false
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue