svrnty-mcp-server/tests/Svrnty.MCP.Core.Tests/IMcpToolTests.cs
Svrnty 516e1479c6 docs: comprehensive AI coding assistant research and MCP-first implementation plan
Research conducted on modern AI coding assistants (Cursor, GitHub Copilot, Cline,
Aider, Windsurf, Replit Agent) to understand architecture patterns, context management,
code editing workflows, and tool use protocols.

Key Decision: Pivoted from building full CLI (40-50h) to validation-driven MCP-first
approach (10-15h). Build 5 core CODEX MCP tools that work with ANY coding assistant,
validate adoption over 2-4 weeks, then decide on full CLI if demand proven.

Files:
- research/ai-systems/modern-coding-assistants-architecture.md (comprehensive research)
- research/ai-systems/codex-coding-assistant-implementation-plan.md (original CLI plan, preserved)
- research/ai-systems/codex-mcp-tools-implementation-plan.md (approved MCP-first plan)
- ideas/registry.json (updated with approved MCP tools proposal)

Architech Validation: APPROVED with pivot to MCP-first approach
Human Decision: Approved (pragmatic validation-driven development)

Next: Begin Phase 1 implementation (10-15 hours, 5 core MCP tools)

🤖 Generated with CODEX Research System

Co-Authored-By: The Archivist <archivist@codex.svrnty.io>
Co-Authored-By: The Architech <architech@codex.svrnty.io>
Co-Authored-By: Mathias Beaulieu-Duncan <mat@svrnty.io>
2025-10-22 21:00:34 -04:00

121 lines
3.3 KiB
C#

using Xunit;
using Moq;
using System.Threading.Tasks;
using System.Text.Json;
namespace OpenHarbor.MCP.Core.Tests;
/// <summary>
/// Unit tests for IMcpTool interface following TDD approach.
/// Tests the core abstraction for MCP tools.
/// </summary>
public class IMcpToolTests
{
[Fact]
public void IMcpTool_ShouldHaveNameProperty()
{
// Arrange - Create a mock implementation
var mockTool = new Mock<IMcpTool>();
mockTool.Setup(t => t.Name).Returns("test_tool");
// Act
var name = mockTool.Object.Name;
// Assert
Assert.Equal("test_tool", name);
}
[Fact]
public void IMcpTool_ShouldHaveDescriptionProperty()
{
// Arrange
var mockTool = new Mock<IMcpTool>();
mockTool.Setup(t => t.Description).Returns("A test tool");
// Act
var description = mockTool.Object.Description;
// Assert
Assert.Equal("A test tool", description);
}
[Fact]
public void IMcpTool_ShouldHaveSchemaProperty()
{
// Arrange
var mockTool = new Mock<IMcpTool>();
var schema = JsonDocument.Parse("""
{
"type": "object",
"properties": {
"query": { "type": "string" }
}
}
""");
mockTool.Setup(t => t.Schema).Returns(schema);
// Act
var toolSchema = mockTool.Object.Schema;
// Assert
Assert.NotNull(toolSchema);
Assert.Equal("object", toolSchema.RootElement.GetProperty("type").GetString());
}
[Fact]
public async Task IMcpTool_ShouldExecuteAsync()
{
// Arrange
var mockTool = new Mock<IMcpTool>();
var expectedResult = JsonDocument.Parse("""{"status": "success"}""");
var arguments = JsonDocument.Parse("""{"query": "test"}""");
mockTool.Setup(t => t.ExecuteAsync(It.IsAny<JsonDocument>()))
.ReturnsAsync(expectedResult);
// Act
var result = await mockTool.Object.ExecuteAsync(arguments);
// Assert
Assert.NotNull(result);
Assert.Equal("success", result.RootElement.GetProperty("status").GetString());
}
[Fact]
public async Task IMcpTool_ExecuteAsync_ShouldHandleNullArguments()
{
// Arrange
var mockTool = new Mock<IMcpTool>();
var expectedResult = JsonDocument.Parse("""{"status": "executed"}""");
mockTool.Setup(t => t.ExecuteAsync(null!))
.ReturnsAsync(expectedResult);
// Act
var result = await mockTool.Object.ExecuteAsync(null!);
// Assert
Assert.NotNull(result);
}
[Fact]
public async Task IMcpTool_ExecuteAsync_ShouldReturnJsonResult()
{
// Arrange
var mockTool = new Mock<IMcpTool>();
var arguments = JsonDocument.Parse("""{"input": "value"}""");
var expectedResult = JsonDocument.Parse("""{"output": "result"}""");
mockTool.Setup(t => t.ExecuteAsync(arguments))
.ReturnsAsync(expectedResult);
// Act
var result = await mockTool.Object.ExecuteAsync(arguments);
// Assert
Assert.NotNull(result);
Assert.True(result.RootElement.TryGetProperty("output", out var output));
Assert.Equal("result", output.GetString());
}
}