// Copyright (c) Microsoft. All rights reserved. using System; using Microsoft.Extensions.AI; namespace Microsoft.Agents.AI.Abstractions.UnitTests; /// /// Contains tests for the class. /// public sealed class AdditionalPropertiesExtensionsTests { #region Add Method Tests [Fact] public void Add_WithValidValue_StoresValueUsingTypeName() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; // Act additionalProperties.Add(value); // Assert Assert.True(additionalProperties.ContainsKey(typeof(TestClass).FullName!)); Assert.Same(value, additionalProperties[typeof(TestClass).FullName!]); } [Fact] public void Add_WithNullDictionary_ThrowsArgumentNullException() { // Arrange AdditionalPropertiesDictionary? additionalProperties = null; TestClass value = new() { Name = "Test" }; // Act & Assert Assert.Throws(() => additionalProperties!.Add(value)); } [Fact] public void Add_WithStringValue_StoresValueCorrectly() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const string Value = "test string"; // Act additionalProperties.Add(Value); // Assert Assert.True(additionalProperties.ContainsKey(typeof(string).FullName!)); Assert.Equal(Value, additionalProperties[typeof(string).FullName!]); } [Fact] public void Add_WithIntValue_StoresValueCorrectly() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const int Value = 42; // Act additionalProperties.Add(Value); // Assert Assert.True(additionalProperties.ContainsKey(typeof(int).FullName!)); Assert.Equal(Value, additionalProperties[typeof(int).FullName!]); } [Fact] public void Add_ThrowsArgumentException_WhenSameTypeAddedTwice() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass firstValue = new() { Name = "First" }; TestClass secondValue = new() { Name = "Second" }; additionalProperties.Add(firstValue); // Act & Assert Assert.Throws(() => additionalProperties.Add(secondValue)); } [Fact] public void Add_WithMultipleDifferentTypes_StoresAllValues() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass testClassValue = new() { Name = "Test" }; AnotherTestClass anotherValue = new() { Id = 123 }; const string StringValue = "test"; // Act additionalProperties.Add(testClassValue); additionalProperties.Add(anotherValue); additionalProperties.Add(StringValue); // Assert Assert.Equal(3, additionalProperties.Count); Assert.Same(testClassValue, additionalProperties[typeof(TestClass).FullName!]); Assert.Same(anotherValue, additionalProperties[typeof(AnotherTestClass).FullName!]); Assert.Equal(StringValue, additionalProperties[typeof(string).FullName!]); } #endregion #region TryAdd Method Tests [Fact] public void TryAdd_WithValidValue_ReturnsTrueAndStoresValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; // Act bool result = additionalProperties.TryAdd(value); // Assert Assert.True(result); Assert.True(additionalProperties.ContainsKey(typeof(TestClass).FullName!)); Assert.Same(value, additionalProperties[typeof(TestClass).FullName!]); } [Fact] public void TryAdd_WithNullDictionary_ThrowsArgumentNullException() { // Arrange AdditionalPropertiesDictionary? additionalProperties = null; TestClass value = new() { Name = "Test" }; // Act & Assert Assert.Throws(() => additionalProperties!.TryAdd(value)); } [Fact] public void TryAdd_WithExistingType_ReturnsFalseAndKeepsOriginalValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass firstValue = new() { Name = "First" }; TestClass secondValue = new() { Name = "Second" }; additionalProperties.Add(firstValue); // Act bool result = additionalProperties.TryAdd(secondValue); // Assert Assert.False(result); Assert.Single(additionalProperties); Assert.Same(firstValue, additionalProperties[typeof(TestClass).FullName!]); } [Fact] public void TryAdd_WithStringValue_ReturnsTrueAndStoresValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const string Value = "test string"; // Act bool result = additionalProperties.TryAdd(Value); // Assert Assert.True(result); Assert.True(additionalProperties.ContainsKey(typeof(string).FullName!)); Assert.Equal(Value, additionalProperties[typeof(string).FullName!]); } [Fact] public void TryAdd_WithIntValue_ReturnsTrueAndStoresValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const int Value = 42; // Act bool result = additionalProperties.TryAdd(Value); // Assert Assert.True(result); Assert.True(additionalProperties.ContainsKey(typeof(int).FullName!)); Assert.Equal(Value, additionalProperties[typeof(int).FullName!]); } [Fact] public void TryAdd_WithMultipleDifferentTypes_StoresAllValues() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass testClassValue = new() { Name = "Test" }; AnotherTestClass anotherValue = new() { Id = 123 }; const string StringValue = "test"; // Act bool result1 = additionalProperties.TryAdd(testClassValue); bool result2 = additionalProperties.TryAdd(anotherValue); bool result3 = additionalProperties.TryAdd(StringValue); // Assert Assert.True(result1); Assert.True(result2); Assert.True(result3); Assert.Equal(3, additionalProperties.Count); Assert.Same(testClassValue, additionalProperties[typeof(TestClass).FullName!]); Assert.Same(anotherValue, additionalProperties[typeof(AnotherTestClass).FullName!]); Assert.Equal(StringValue, additionalProperties[typeof(string).FullName!]); } #endregion #region TryGetValue Method Tests [Fact] public void TryGetValue_WithExistingValue_ReturnsTrueAndValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass expectedValue = new() { Name = "Test" }; additionalProperties.Add(expectedValue); // Act bool result = additionalProperties.TryGetValue(out TestClass? actualValue); // Assert Assert.True(result); Assert.NotNull(actualValue); Assert.Same(expectedValue, actualValue); } [Fact] public void TryGetValue_WithNonExistingValue_ReturnsFalseAndNull() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); // Act bool result = additionalProperties.TryGetValue(out TestClass? actualValue); // Assert Assert.False(result); Assert.Null(actualValue); } [Fact] public void TryGetValue_WithNullDictionary_ThrowsArgumentNullException() { // Arrange AdditionalPropertiesDictionary? additionalProperties = null; // Act & Assert Assert.Throws(() => additionalProperties!.TryGetValue(out _)); } [Fact] public void TryGetValue_WithStringValue_ReturnsCorrectValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const string ExpectedValue = "test string"; additionalProperties.Add(ExpectedValue); // Act bool result = additionalProperties.TryGetValue(out string? actualValue); // Assert Assert.True(result); Assert.Equal(ExpectedValue, actualValue); } [Fact] public void TryGetValue_WithIntValue_ReturnsCorrectValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); const int ExpectedValue = 42; additionalProperties.Add(ExpectedValue); // Act bool result = additionalProperties.TryGetValue(out int actualValue); // Assert Assert.True(result); Assert.Equal(ExpectedValue, actualValue); } [Fact] public void TryGetValue_WithWrongType_ReturnsFalse() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass testValue = new() { Name = "Test" }; additionalProperties.Add(testValue); // Act bool result = additionalProperties.TryGetValue(out AnotherTestClass? actualValue); // Assert Assert.False(result); Assert.Null(actualValue); } [Fact] public void TryGetValue_AfterTryAddFails_ReturnsOriginalValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass firstValue = new() { Name = "First" }; TestClass secondValue = new() { Name = "Second" }; additionalProperties.Add(firstValue); additionalProperties.TryAdd(secondValue); // Act bool result = additionalProperties.TryGetValue(out TestClass? actualValue); // Assert Assert.Single(additionalProperties); Assert.True(result); Assert.Same(firstValue, actualValue); } #endregion #region Contains Method Tests [Fact] public void Contains_WithExistingType_ReturnsTrue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; additionalProperties.Add(value); // Act bool result = additionalProperties.Contains(); // Assert Assert.True(result); } [Fact] public void Contains_WithNonExistingType_ReturnsFalse() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); // Act bool result = additionalProperties.Contains(); // Assert Assert.False(result); } [Fact] public void Contains_WithNullDictionary_ThrowsArgumentNullException() { // Arrange AdditionalPropertiesDictionary? additionalProperties = null; // Act & Assert Assert.Throws(() => additionalProperties!.Contains()); } [Fact] public void Contains_WithDifferentType_ReturnsFalse() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; additionalProperties.Add(value); // Act bool result = additionalProperties.Contains(); // Assert Assert.False(result); } [Fact] public void Contains_AfterRemove_ReturnsFalse() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; additionalProperties.Add(value); additionalProperties.Remove(); // Act bool result = additionalProperties.Contains(); // Assert Assert.False(result); } #endregion #region Remove Method Tests [Fact] public void Remove_WithExistingType_ReturnsTrueAndRemovesValue() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; additionalProperties.Add(value); // Act bool result = additionalProperties.Remove(); // Assert Assert.True(result); Assert.Empty(additionalProperties); } [Fact] public void Remove_WithNonExistingType_ReturnsFalse() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); // Act bool result = additionalProperties.Remove(); // Assert Assert.False(result); } [Fact] public void Remove_WithNullDictionary_ThrowsArgumentNullException() { // Arrange AdditionalPropertiesDictionary? additionalProperties = null; // Act & Assert Assert.Throws(() => additionalProperties!.Remove()); } [Fact] public void Remove_OnlyRemovesSpecifiedType() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass testValue = new() { Name = "Test" }; AnotherTestClass anotherValue = new() { Id = 123 }; additionalProperties.Add(testValue); additionalProperties.Add(anotherValue); // Act bool result = additionalProperties.Remove(); // Assert Assert.True(result); Assert.Single(additionalProperties); Assert.False(additionalProperties.Contains()); Assert.True(additionalProperties.Contains()); } [Fact] public void Remove_CalledTwice_ReturnsFalseOnSecondCall() { // Arrange AdditionalPropertiesDictionary additionalProperties = new(); TestClass value = new() { Name = "Test" }; additionalProperties.Add(value); // Act bool firstResult = additionalProperties.Remove(); bool secondResult = additionalProperties.Remove(); // Assert Assert.True(firstResult); Assert.False(secondResult); } #endregion #region Test Helper Classes private sealed class TestClass { public string Name { get; set; } = string.Empty; } private sealed class AnotherTestClass { public int Id { get; set; } } #endregion }