File: IntentResolutionRatingTests.cs
Web Access
Project: src\test\Libraries\Microsoft.Extensions.AI.Evaluation.Tests\Microsoft.Extensions.AI.Evaluation.Tests.csproj (Microsoft.Extensions.AI.Evaluation.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Text.Json;
using Microsoft.Extensions.AI.Evaluation.Quality;
using Microsoft.Extensions.AI.Evaluation.Quality.JsonSerialization;
using Xunit;
 
namespace Microsoft.Extensions.AI.Evaluation.Tests;
 
public class IntentResolutionRatingTests
{
    [Fact]
    public void JsonIsValid()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 5
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(5, rating.ResolutionScore);
        Assert.Equal("The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.", rating.Explanation);
        Assert.Equal("provide a comprehensive chocolate cake recipe", rating.AgentPerceivedIntent);
        Assert.Equal("bake a chocolate cake", rating.ActualUserIntent);
        Assert.True(rating.ConversationHasIntent);
        Assert.True(rating.CorrectIntentDetected);
        Assert.True(rating.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonIsSurroundedWithMarkdownSyntax()
    {
        string json =
            """
 
            ```
            {
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 5,
            }
            ```
 
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(5, rating.ResolutionScore);
        Assert.Equal("The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.", rating.Explanation);
        Assert.Equal("provide a comprehensive chocolate cake recipe", rating.AgentPerceivedIntent);
        Assert.Equal("bake a chocolate cake", rating.ActualUserIntent);
        Assert.True(rating.ConversationHasIntent);
        Assert.True(rating.CorrectIntentDetected);
        Assert.True(rating.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonIsSurroundedWithMarkdownSyntaxWithJsonPrefix()
    {
        string json =
            """
 
            ```json
            {
                "resolution_score": 5,
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true
            }
            ```
 
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(5, rating.ResolutionScore);
        Assert.Equal("The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.", rating.Explanation);
        Assert.Equal("provide a comprehensive chocolate cake recipe", rating.AgentPerceivedIntent);
        Assert.Equal("bake a chocolate cake", rating.ActualUserIntent);
        Assert.True(rating.ConversationHasIntent);
        Assert.True(rating.CorrectIntentDetected);
        Assert.True(rating.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonCanBeRoundTripped()
    {
        IntentResolutionRating rating =
            new IntentResolutionRating(
                resolutionScore: 1,
                explanation: "explanation",
                agentPerceivedIntent: "perceived intent",
                actualUserIntent: "actual intent",
                conversationHasIntent: false,
                correctIntentDetected: true,
                intentResolved: true);
 
        string json = JsonSerializer.Serialize(rating, SerializerContext.Default.IntentResolutionRating);
        IntentResolutionRating deserialized = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(rating.ResolutionScore, deserialized.ResolutionScore);
        Assert.Equal(rating.Explanation, deserialized.Explanation);
        Assert.Equal(rating.AgentPerceivedIntent, deserialized.AgentPerceivedIntent);
        Assert.Equal(rating.ActualUserIntent, deserialized.ActualUserIntent);
        Assert.Equal(rating.ConversationHasIntent, deserialized.ConversationHasIntent);
        Assert.Equal(rating.CorrectIntentDetected, deserialized.CorrectIntentDetected);
        Assert.Equal(rating.IntentResolved, deserialized.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void InconclusiveJsonCanBeRoundTripped()
    {
        IntentResolutionRating rating = IntentResolutionRating.Inconclusive;
 
        string json = JsonSerializer.Serialize(rating, SerializerContext.Default.IntentResolutionRating);
        IntentResolutionRating deserialized = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(rating.ResolutionScore, deserialized.ResolutionScore);
        Assert.Equal(rating.Explanation, deserialized.Explanation);
        Assert.Equal(rating.AgentPerceivedIntent, deserialized.AgentPerceivedIntent);
        Assert.Equal(rating.ActualUserIntent, deserialized.ActualUserIntent);
        Assert.Equal(rating.ConversationHasIntent, deserialized.ConversationHasIntent);
        Assert.Equal(rating.CorrectIntentDetected, deserialized.CorrectIntentDetected);
        Assert.Equal(rating.IntentResolved, deserialized.IntentResolved);
        Assert.True(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithNegativeScoreIsInconclusive()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": -1
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.True(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithZeroScoreIsInconclusive()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 0
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.True(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithExcessivelyHighScoreIsInconclusive()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 200
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.True(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithAdditionalHallucinatedPropertyIsProcessedCorrectly()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "hallucinated_property": "Some hallucinated text.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 5,
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(5, rating.ResolutionScore);
        Assert.Equal("The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.", rating.Explanation);
        Assert.Equal("provide a comprehensive chocolate cake recipe", rating.AgentPerceivedIntent);
        Assert.Equal("bake a chocolate cake", rating.ActualUserIntent);
        Assert.True(rating.ConversationHasIntent);
        Assert.True(rating.CorrectIntentDetected);
        Assert.True(rating.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithDuplicatePropertyUsesLastValue()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "explanation": "Duplicate explanation.",
                "conversation_has_intent": true,
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 5,
            }
            """;
 
        IntentResolutionRating rating = IntentResolutionRating.FromJson(json);
 
        Assert.Equal(5, rating.ResolutionScore);
        Assert.Equal("Duplicate explanation.", rating.Explanation);
        Assert.Equal("provide a comprehensive chocolate cake recipe", rating.AgentPerceivedIntent);
        Assert.Equal("bake a chocolate cake", rating.ActualUserIntent);
        Assert.True(rating.ConversationHasIntent);
        Assert.True(rating.CorrectIntentDetected);
        Assert.True(rating.IntentResolved);
        Assert.False(rating.IsInconclusive);
    }
 
    [Fact]
    public void JsonWithSemicolonsInsteadOfCommasThrowsException()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.";
                "conversation_has_intent": true;
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe";
                "actual_user_intent": "bake a chocolate cake";
                "correct_intent_detected": true;
                "intent_resolved": true;
                "resolution_score": 5
            }
            """;
 
        Assert.Throws<JsonException>(() => IntentResolutionRating.FromJson(json));
    }
 
    [Fact]
    public void JsonWithMissingPropertiesThrowsException()
    {
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "intent_resolved": true,
                "resolution_score": 5
            }
            """;
 
        Assert.Throws<JsonException>(() => IntentResolutionRating.FromJson(json));
    }
 
    [Fact]
    public void JsonWithIncorrectPropertyValueTypeThrowsException()
    {
        // Incorrect property value (string instead of boolean for conversation_has_intent).
        string json =
            """
            {
                "explanation": "The response delivers a complete and precise recipe, fully addressing the user's query about baking a chocolate cake.",
                "conversation_has_intent": "A string value",
                "agent_perceived_intent": "provide a comprehensive chocolate cake recipe",
                "actual_user_intent": "bake a chocolate cake",
                "correct_intent_detected": true,
                "intent_resolved": true,
                "resolution_score": 5,
            }
            """;
 
        Assert.Throws<JsonException>(() => IntentResolutionRating.FromJson(json));
    }
}