< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Testing.ToolInvocationResult
Assembly: NexusLabs.Needlr.AgentFramework.Testing
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Testing/ToolInvocationResult.cs
Line coverage
100%
Covered lines: 19
Uncovered lines: 0
Coverable lines: 19
Total lines: 85
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_ReturnValue()100%11100%
get_Exception()100%11100%
get_FunctionSource()100%11100%
get_Workspace()100%11100%
get_Duration()100%11100%
get_Succeeded()100%11100%
GetValue()100%22100%
AssertSuccess()100%22100%
AssertResultContains(...)100%88100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Testing/ToolInvocationResult.cs

#LineLine coverage
 1using NexusLabs.Needlr.AgentFramework.Workspace;
 2
 3namespace NexusLabs.Needlr.AgentFramework.Testing;
 4
 5/// <summary>
 6/// Result of a single <see cref="ToolInvocationRunner.InvokeAsync{TTool}(string, Action{Microsoft.Extensions.AI.AIFunct
 7/// call.
 8/// </summary>
 9/// <param name="ReturnValue">
 10/// The raw return value from the underlying <see cref="Microsoft.Extensions.AI.AIFunction.InvokeAsync"/>
 11/// call, or <see langword="null"/> if the invocation threw.
 12/// </param>
 13/// <param name="Exception">
 14/// The exception thrown during invocation, or <see langword="null"/> if the invocation succeeded.
 15/// Exceptions from argument extraction (the source-generated wrapper) and from the user method
 16/// itself are not currently distinguished; both surface here.
 17/// </param>
 18/// <param name="FunctionSource">
 19/// Which discovery path produced the <see cref="Microsoft.Extensions.AI.AIFunction"/> that was
 20/// invoked. Use this in assertions to confirm the test exercised the source-generated wrapper
 21/// rather than the reflection fallback.
 22/// </param>
 23/// <param name="Workspace">
 24/// The <see cref="IWorkspace"/> attached to the execution context for the invocation, or
 25/// <see langword="null"/> if no workspace was configured. Useful for post-invocation
 26/// assertions on files the tool wrote.
 27/// </param>
 28/// <param name="Duration">Wall-clock duration of the invocation.</param>
 1229public sealed record ToolInvocationResult(
 530    object? ReturnValue,
 831    Exception? Exception,
 332    ToolFunctionSource FunctionSource,
 333    IWorkspace? Workspace,
 1334    TimeSpan Duration)
 35{
 36    /// <summary>
 37    /// Whether the invocation completed without throwing.
 38    /// </summary>
 139    public bool Succeeded => Exception is null;
 40
 41    /// <summary>
 42    /// Returns <see cref="ReturnValue"/> cast to <typeparamref name="T"/>, or
 43    /// <see langword="default"/> if the value is <see langword="null"/> or not assignable to
 44    /// <typeparamref name="T"/>.
 45    /// </summary>
 46    /// <typeparam name="T">Expected return type.</typeparam>
 247    public T? GetValue<T>() => ReturnValue is T typed ? typed : default;
 48
 49    /// <summary>
 50    /// Throws if the invocation failed, surfacing the original exception with context.
 51    /// </summary>
 52    /// <exception cref="InvalidOperationException">
 53    /// Thrown when <see cref="Exception"/> is not <see langword="null"/>, with the original
 54    /// exception attached as the inner exception.
 55    /// </exception>
 56    public void AssertSuccess()
 57    {
 358        if (Exception is not null)
 59        {
 160            throw new InvalidOperationException(
 161                $"Tool invocation failed via {FunctionSource} path: {Exception.Message}",
 162                Exception);
 63        }
 264    }
 65
 66    /// <summary>
 67    /// Throws if the string form of <see cref="ReturnValue"/> does not contain
 68    /// <paramref name="substring"/>.
 69    /// </summary>
 70    /// <param name="substring">The substring expected to appear in the return value.</param>
 71    /// <exception cref="InvalidOperationException">
 72    /// Thrown when the return value is <see langword="null"/> or does not contain the substring.
 73    /// </exception>
 74    public void AssertResultContains(string substring)
 75    {
 376        ArgumentNullException.ThrowIfNull(substring);
 77
 378        var text = ReturnValue?.ToString();
 379        if (text is null || !text.Contains(substring, StringComparison.Ordinal))
 80        {
 281            throw new InvalidOperationException(
 282                $"Expected tool return value to contain '{substring}'. Actual: '{text ?? "<null>"}'.");
 83        }
 184    }
 85}