# `ExMCP.Testing.Builders`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/testing/builders.ex#L1)

Test data builders and generators for ExMCP.

This module provides factories and builders for creating test data that
conforms to MCP protocol specifications. It includes builders for all
major MCP entities and supports both fixed and randomized test data.

## Features

- **Content Builders**: Generate valid content for all supported types
- **Tool Builders**: Create tool definitions and results
- **Resource Builders**: Generate resource definitions and data
- **Prompt Builders**: Create prompt templates and arguments
- **Message Builders**: Generate MCP protocol messages
- **Schema Builders**: Create JSON schemas for validation
- **Randomized Data**: Support for property-based testing

## Usage

    alias ExMCP.Testing.Builders

    # Create test content
    text_content = Builders.text_content("Hello world")
    image_content = Builders.image_content()

    # Create test tools
    tool = Builders.tool("sample_tool")
    tool_with_schema = Builders.tool("complex_tool", schema: Builders.object_schema())

    # Create test messages
    request = Builders.request("list_tools", id: 1)
    response = Builders.success_response(1, %{"tools" => []})

# `builder_opts`

```elixir
@type builder_opts() :: [
  random: boolean(),
  seed: integer(),
  size: pos_integer(),
  format: atom(),
  metadata: map()
]
```

Builder options for customizing generated data

# `annotation_content`

```elixir
@spec annotation_content(String.t() | nil, builder_opts()) ::
  ExMCP.Content.Protocol.annotation()
```

Builds annotation content for testing.

## Examples

    # Simple annotation
    annotation_content("sentiment")

    # With confidence and text
    annotation_content("sentiment", confidence: 0.95, text: "positive")

    # Random annotation
    annotation_content(random: true)

# `array_schema`

```elixir
@spec array_schema(map() | nil, builder_opts()) :: map()
```

Builds an array JSON Schema for testing.

## Examples

    array_schema(string_schema())
    array_schema(object_schema(), min_items: 1, max_items: 10)

# `audio_content`

```elixir
@spec audio_content(builder_opts()) :: ExMCP.Content.Protocol.audio()
```

Builds audio content for testing.

## Examples

    # Default test audio
    audio_content()

    # With transcript
    audio_content(transcript: "Hello world")

    # With duration
    audio_content(duration: 10.5)

    # Random audio data
    audio_content(random: true, size: 2048)

# `error_response`

```elixir
@spec error_response(integer(), integer(), String.t(), any()) :: map()
```

Builds an MCP error response for testing.

## Examples

    # Method not found error
    error_response(1, -32601, "Method not found")

    # Custom error with data
    error_response(2, -1, "Tool error", %{"details" => "Something went wrong"})

# `image_content`

```elixir
@spec image_content(builder_opts()) :: ExMCP.Content.Protocol.image()
```

Builds image content for testing.

## Examples

    # Default test image
    image_content()

    # Custom MIME type
    image_content(mime_type: "image/jpeg")

    # With dimensions
    image_content(width: 800, height: 600)

    # Random image data
    image_content(random: true, size: 1024)

# `integer_schema`

```elixir
@spec integer_schema(builder_opts()) :: map()
```

Builds an integer JSON Schema for testing.

## Examples

    integer_schema()
    integer_schema(minimum: 0, maximum: 100)
    integer_schema(multiple_of: 5)

# `notification`

```elixir
@spec notification(String.t(), map()) :: map()
```

Builds an MCP notification for testing.

## Examples

    # Simple notification
    notification("notifications/message", %{"level" => "info", "text" => "Hello"})

    # Progress notification
    notification("notifications/progress", %{
      "progressToken" => "task_1",
      "progress" => 50,
      "total" => 100
    })

# `object_schema`

```elixir
@spec object_schema(map() | nil, builder_opts()) :: map()
```

Builds a JSON Schema object for testing.

## Examples

    # Simple object schema
    object_schema()

    # Object with properties
    object_schema(%{
      "name" => string_schema(),
      "age" => integer_schema(minimum: 0),
      "email" => string_schema(format: "email")
    })

    # Required properties
    object_schema(%{"name" => string_schema()}, required: ["name"])

# `prompt`

```elixir
@spec prompt(String.t() | nil, String.t() | nil, builder_opts()) :: map()
```

Builds a prompt definition for testing.

## Examples

    # Simple prompt
    prompt("sample_prompt", "A test prompt")

    # Prompt with arguments
    prompt("complex_prompt", "Complex prompt", arguments: [
      prompt_argument("topic", "The topic to discuss", required: true),
      prompt_argument("style", "Writing style", required: false)
    ])

    # Random prompt
    prompt(random: true)

# `prompt_argument`

```elixir
@spec prompt_argument(String.t(), String.t(), builder_opts()) :: map()
```

Builds a prompt argument for testing.

## Examples

    # Required argument
    prompt_argument("topic", "The topic to discuss", required: true)

    # Optional argument
    prompt_argument("style", "Writing style", required: false)

# `prompt_data`

```elixir
@spec prompt_data(String.t() | [map()], builder_opts()) :: map()
```

Builds prompt data for testing.

## Examples

    # Simple prompt result
    prompt_data("Write about: space exploration")

    # Prompt with multiple messages
    prompt_data([
      %{"role" => "system", "content" => "You are a helpful assistant"},
      %{"role" => "user", "content" => "Hello"}
    ])

# `random_bytes`

```elixir
@spec random_bytes(pos_integer()) :: binary()
```

Generates random bytes.

# `random_string`

```elixir
@spec random_string(pos_integer()) :: String.t()
```

Generates random string of specified length.

# `random_text`

```elixir
@spec random_text(pos_integer()) :: String.t()
```

Generates random text of specified length.

# `request`

```elixir
@spec request(String.t(), builder_opts()) :: map()
```

Builds an MCP request message for testing.

## Examples

    # Simple request
    request("list_tools", id: 1)

    # Request with parameters
    request("call_tool", id: 2, params: %{
      "name" => "sample_tool",
      "arguments" => %{"input" => "test"}
    })

# `resource`

```elixir
@spec resource(String.t() | nil, String.t() | nil, builder_opts()) :: map()
```

Builds a resource definition for testing.

## Examples

    # Simple resource
    resource("file://data.txt", "Test Data")

    # Resource with metadata
    resource("https://api.example.com", "API",
      description: "REST API endpoint",
      mime_type: "application/json"
    )

    # Random resource
    resource(random: true)

# `resource_content`

```elixir
@spec resource_content(String.t() | nil, builder_opts()) ::
  ExMCP.Content.Protocol.resource()
```

Builds resource content for testing.

## Examples

    # File resource
    resource_content("file://data.txt")

    # HTTP resource with metadata
    resource_content("https://example.com/api",
      text: "API endpoint",
      mime_type: "application/json"
    )

    # Random resource
    resource_content(random: true)

# `resource_data`

```elixir
@spec resource_data(String.t() | nil, String.t() | nil, builder_opts()) :: map()
```

Builds resource data for testing.

## Examples

    # Text resource data
    resource_data("Hello world", "text/plain")

    # Binary resource data
    resource_data(random: true, mime_type: "application/octet-stream", size: 1024)

# `string_schema`

```elixir
@spec string_schema(builder_opts()) :: map()
```

Builds a string JSON Schema for testing.

## Examples

    string_schema()
    string_schema(min_length: 1, max_length: 100)
    string_schema(pattern: "^[a-z]+$")
    string_schema(format: "email")

# `success_response`

```elixir
@spec success_response(integer(), any()) :: map()
```

Builds an MCP success response for testing.

## Examples

    # Simple success response
    success_response(1, %{"tools" => []})

    # Tool call response
    success_response(2, tool_result("Success"))

# `text_content`

```elixir
@spec text_content(String.t() | nil, builder_opts()) :: ExMCP.Content.Protocol.text()
```

Builds text content for testing.

## Examples

    # Fixed content
    text_content("Hello world")

    # Random content
    text_content(random: true)

    # Markdown content
    text_content("# Header", format: :markdown)

    # With metadata
    text_content("Test", metadata: %{author: "test"})

# `tool`

```elixir
@spec tool(String.t() | nil, builder_opts()) :: map()
```

Builds a tool definition for testing.

## Examples

    # Simple tool
    tool("sample_tool")

    # Tool with custom description
    tool("sample_tool", description: "Custom description")

    # Tool with complex schema
    tool("complex_tool", schema: object_schema(%{
      "name" => string_schema(),
      "age" => integer_schema()
    }))

    # Random tool
    tool(random: true)

# `tool_result`

```elixir
@spec tool_result(
  String.t() | [ExMCP.Content.Protocol.content()] | nil,
  builder_opts()
) :: map()
```

Builds a tool result for testing.

## Examples

    # Simple text result
    tool_result("Operation completed")

    # Multiple content items
    tool_result([
      text_content("Result 1"),
      text_content("Result 2")
    ])

    # Error result
    tool_result(error: "Something went wrong")

---

*Consult [api-reference.md](api-reference.md) for complete listing*
