Skip to main content
Glama

Azure MCP Server

Official
MIT License
1,161
  • Linux
  • Apple
RoundedDoubleArrayConverterTests.cs16.2 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Text.Json; using System.Text.Json.Serialization; using AzureMcp.Monitor.Models; using Xunit; namespace AzureMcp.Monitor.UnitTests.Models; public class RoundedDoubleArrayConverterTests { private readonly JsonSerializerOptions _options; public RoundedDoubleArrayConverterTests() { _options = new JsonSerializerOptions(); _options.Converters.Add(new RoundedDoubleArrayConverter()); } #region Test Model private class TestModel { [JsonConverter(typeof(RoundedDoubleArrayConverter))] public double[]? Values { get; set; } } #endregion #region Serialization Tests (Write functionality) [Theory] [InlineData(new double[] { 1.234567 }, "[1.23]")] [InlineData(new double[] { 1.235 }, "[1.24]")] [InlineData(new double[] { 1.2349 }, "[1.23]")] [InlineData(new double[] { 1.2351 }, "[1.24]")] [InlineData(new double[] { -1.234567 }, "[-1.23]")] [InlineData(new double[] { -1.235 }, "[-1.24]")] public void Serialize_RoundsDoublesToTwoDecimalPlaces(double[] input, string expectedJson) { // Arrange var model = new TestModel { Values = input }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains($"\"Values\":{expectedJson}", json); } [Fact] public void Serialize_WithNullArray_WritesNull() { // Arrange var model = new TestModel { Values = null }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains("\"Values\":null", json); } [Fact] public void Serialize_WithEmptyArray_WritesEmptyArray() { // Arrange var model = new TestModel { Values = new double[0] }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains("\"Values\":[]", json); } [Fact] public void Serialize_WithNegativeZero_FormatsAsZero() { // Arrange var model = new TestModel { Values = new double[] { -0.0 } }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert // Note: -0.0 is serialized as -0 in JSON, which is valid behavior Assert.Contains("\"Values\":[-0]", json); } [Theory] [InlineData(new double[] { 0.0 }, "[0]")] [InlineData(new double[] { 1.0 }, "[1]")] [InlineData(new double[] { -1.0 }, "[-1]")] [InlineData(new double[] { 10.0 }, "[10]")] [InlineData(new double[] { 100.50 }, "[100.5]")] public void Serialize_WithWholeNumbersAndSimpleDecimals_FormatsCorrectly(double[] input, string expectedJson) { // Arrange var model = new TestModel { Values = input }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains($"\"Values\":{expectedJson}", json); } [Theory] [InlineData(new double[] { 1.234, 2.567, 3.891 }, "[1.23,2.57,3.89]")] [InlineData(new double[] { -1.234, 0.567, -3.891 }, "[-1.23,0.57,-3.89]")] [InlineData(new double[] { 1.235, 2.565, 3.895 }, "[1.24,2.56,3.9]")] public void Serialize_WithMultipleValues_RoundsEachValue(double[] input, string expectedJson) { // Arrange var model = new TestModel { Values = input }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains($"\"Values\":{expectedJson}", json); } [Theory] [InlineData(new double[] { double.MaxValue }, "[1.7976931348623157E+308]")] [InlineData(new double[] { double.MinValue }, "[-1.7976931348623157E+308]")] [InlineData(new double[] { double.Epsilon }, "[0]")] public void Serialize_WithExtremeValues_HandlesCorrectly(double[] input, string expectedJson) { // Arrange var model = new TestModel { Values = input }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains($"\"Values\":{expectedJson}", json); } [Theory] [InlineData(new double[] { double.NaN })] [InlineData(new double[] { double.PositiveInfinity })] [InlineData(new double[] { double.NegativeInfinity })] public void Serialize_WithSpecialValues_ThrowsException(double[] input) { // Arrange var model = new TestModel { Values = input }; // Act & Assert - Should throw exception for special values Assert.Throws<ArgumentException>(() => JsonSerializer.Serialize(model, _options)); } [Fact] public void Serialize_WithLargeArray_ProcessesAllElements() { // Arrange var largeArray = new double[1000]; for (int i = 0; i < largeArray.Length; i++) { largeArray[i] = i * 1.234567; } var model = new TestModel { Values = largeArray }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.NotNull(json); Assert.Contains("\"Values\":[", json); // Verify first and last elements are rounded Assert.Contains("0", json); // First element (0 * 1.234567 = 0) Assert.Contains("1233.33", json); // Last element (999 * 1.234567 ≈ 1233.33) } #endregion #region Deserialization Tests (Read functionality) [Theory] [InlineData("[1.23, 2.45, 3.67]", new double[] { 1.23, 2.45, 3.67 })] [InlineData("[0, -1, 100]", new double[] { 0, -1, 100 })] [InlineData("[1.234567, 2.891234]", new double[] { 1.234567, 2.891234 })] public void Deserialize_WithValidJsonArray_ParsesCorrectly(string jsonArray, double[] expected) { // Arrange var json = $"{{\"Values\":{jsonArray}}}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.NotNull(result.Values); Assert.Equal(expected.Length, result.Values.Length); for (int i = 0; i < expected.Length; i++) { Assert.Equal(expected[i], result.Values[i], precision: 10); } } [Fact] public void Deserialize_WithNullJson_ReturnsNull() { // Arrange var json = "{\"Values\":null}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.Null(result.Values); } [Fact] public void Deserialize_WithEmptyArray_ReturnsEmptyArray() { // Arrange var json = "{\"Values\":[]}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.NotNull(result.Values); Assert.Empty(result.Values); } [Theory] [InlineData("[1.0]", new double[] { 1.0 })] [InlineData("[1]", new double[] { 1.0 })] [InlineData("[1.0, 2, 3.5]", new double[] { 1.0, 2.0, 3.5 })] public void Deserialize_WithMixedNumberFormats_ParsesCorrectly(string jsonArray, double[] expected) { // Arrange var json = $"{{\"Values\":{jsonArray}}}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.NotNull(result.Values); Assert.Equal(expected, result.Values); } [Theory] [InlineData("[-1.23, 0, 1.23]", new double[] { -1.23, 0, 1.23 })] [InlineData("[-100.5, -0.1, 200.75]", new double[] { -100.5, -0.1, 200.75 })] public void Deserialize_WithNegativeNumbers_ParsesCorrectly(string jsonArray, double[] expected) { // Arrange var json = $"{{\"Values\":{jsonArray}}}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.NotNull(result.Values); Assert.Equal(expected, result.Values); } [Fact] public void Deserialize_WithLargeArray_ParsesAllElements() { // Arrange var jsonElements = new string[100]; var expectedValues = new double[100]; for (int i = 0; i < 100; i++) { var value = i * 0.1; jsonElements[i] = value.ToString("F1"); expectedValues[i] = value; } var jsonArray = $"[{string.Join(",", jsonElements)}]"; var json = $"{{\"Values\":{jsonArray}}}"; // Act var result = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(result); Assert.NotNull(result.Values); Assert.Equal(100, result.Values.Length); for (int i = 0; i < 100; i++) { Assert.Equal(expectedValues[i], result.Values[i], precision: 10); } } #endregion #region Round-trip Tests [Theory] [InlineData(new double[] { 1.23, 2.45, 3.67 })] [InlineData(new double[] { -1.23, 0, 1.23 })] [InlineData(new double[] { 0.1, 0.2, 0.3 })] public void RoundTrip_WithTwoDecimalPrecisionValues_PreservesValues(double[] originalValues) { // Arrange var model = new TestModel { Values = originalValues }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Equal(originalValues.Length, deserializedModel.Values.Length); for (int i = 0; i < originalValues.Length; i++) { Assert.Equal(originalValues[i], deserializedModel.Values[i], precision: 2); } } [Theory] [InlineData(new double[] { 1.234567 }, new double[] { 1.23 })] [InlineData(new double[] { 1.235 }, new double[] { 1.24 })] [InlineData(new double[] { 1.234567, 2.567891, 3.891234 }, new double[] { 1.23, 2.57, 3.89 })] public void RoundTrip_WithHighPrecisionValues_RoundsToTwoDecimals(double[] originalValues, double[] expectedRoundedValues) { // Arrange var model = new TestModel { Values = originalValues }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Equal(expectedRoundedValues.Length, deserializedModel.Values.Length); for (int i = 0; i < expectedRoundedValues.Length; i++) { Assert.Equal(expectedRoundedValues[i], deserializedModel.Values[i], precision: 2); } } [Fact] public void RoundTrip_WithNullArray_PreservesNull() { // Arrange var model = new TestModel { Values = null }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.Null(deserializedModel.Values); } [Fact] public void RoundTrip_WithEmptyArray_PreservesEmptyArray() { // Arrange var model = new TestModel { Values = new double[0] }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Empty(deserializedModel.Values); } [Fact] public void RoundTrip_WithComplexScenario_WorksCorrectly() { // Arrange - Mix of values that will and won't be rounded var originalValues = new double[] { 1.0, // No change expected 2.50, // No change expected 3.234, // Will round to 3.23 4.235, // Will round to 4.24 -5.678, // Will round to -5.68 0.0, // No change expected 100.999 // Will round to 101.00 }; var expectedValues = new double[] { 1.0, 2.50, 3.23, 4.24, -5.68, 0.0, 101.0 }; var model = new TestModel { Values = originalValues }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Equal(expectedValues.Length, deserializedModel.Values.Length); for (int i = 0; i < expectedValues.Length; i++) { Assert.Equal(expectedValues[i], deserializedModel.Values[i], precision: 2); } } #endregion #region Edge Cases [Fact] public void RoundTrip_WithVerySmallNumbers_HandlesCorrectly() { // Arrange var originalValues = new double[] { 0.001, 0.005, 0.009 }; var model = new TestModel { Values = originalValues }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Equal(originalValues.Length, deserializedModel.Values.Length); // Check actual rounding behavior: 0.001 -> 0.00, 0.005 -> 0.00 (because 0.005 rounds to even), 0.009 -> 0.01 Assert.Equal(0.0, deserializedModel.Values[0], precision: 2); // 0.001 rounds to 0.00 Assert.Equal(0.0, deserializedModel.Values[1], precision: 2); // 0.005 rounds to 0.00 (to even) Assert.Equal(0.01, deserializedModel.Values[2], precision: 2); // 0.009 rounds to 0.01 // Verify the JSON contains the rounded values Assert.Contains("0", json); // First and second values rounded to 0 Assert.Contains("0.01", json); // Third value rounded to 0.01 } [Fact] public void RoundTrip_WithMidpointRounding_UsesToEven() { // Arrange - Test .NET's default midpoint rounding behavior (to even) var originalValues = new double[] { 1.225, 1.235, 2.225, 2.235 }; var model = new TestModel { Values = originalValues }; // Act var json = JsonSerializer.Serialize(model, _options); var deserializedModel = JsonSerializer.Deserialize<TestModel>(json, _options); // Assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Values); Assert.Equal(originalValues.Length, deserializedModel.Values.Length); // Test actual rounding behavior by checking the JSON output // Based on the test output, actual behavior is: [1.23,1.24,2.22,2.24] Assert.Contains("1.23", json); // 1.225 rounds to 1.23 with Math.Round Assert.Contains("1.24", json); // 1.235 rounds to 1.24 Assert.Contains("2.22", json); // 2.225 rounds to 2.22 with Math.Round Assert.Contains("2.24", json); // 2.235 rounds to 2.24 // Verify deserialized values match what was serialized Assert.Equal(1.23, deserializedModel.Values[0], precision: 2); Assert.Equal(1.24, deserializedModel.Values[1], precision: 2); Assert.Equal(2.22, deserializedModel.Values[2], precision: 2); Assert.Equal(2.24, deserializedModel.Values[3], precision: 2); } [Fact] public void Serialize_WithSingleValue_WorksCorrectly() { // Arrange var model = new TestModel { Values = new double[] { 42.123456 } }; // Act var json = JsonSerializer.Serialize(model, _options); // Assert Assert.Contains("\"Values\":[42.12]", json); } #endregion }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Azure/azure-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server