Skip to content

Commit

Permalink
Adds test for utils + minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
adams85 committed Nov 7, 2023
1 parent 24ac423 commit cb464fd
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 3 deletions.
126 changes: 124 additions & 2 deletions src/ConfigCat.Client.Tests/UtilsTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using ConfigCat.Client.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand All @@ -12,9 +15,35 @@ public class UtilsTest
[DataRow(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, "0123456789abcdef")]
[DataRow(new byte[] { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, "fedcba9876543210")]
[DataTestMethod]
public void ArrayUtils_ToHexString_Works(byte[] bytes, string expected)
public void ArrayUtils_ToHexString_Works(byte[] bytes, string expectedResult)
{
Assert.AreEqual(expected, bytes.ToHexString());
Assert.AreEqual(expectedResult, bytes.ToHexString());
}

[DataRow(new byte[] { }, "", true)]
[DataRow(new byte[] { }, "00", false)]
[DataRow(new byte[] { }, " ", null)]
[DataRow(new byte[] { }, "0", null)]
[DataRow(new byte[] { 0 }, "00", true)]
[DataRow(new byte[] { 0 }, "0000", false)]
[DataRow(new byte[] { 0 }, "01", false)]
[DataRow(new byte[] { 0 }, "000", null)]
[DataRow(new byte[] { 0 }, " 00 ", null)]
[DataRow(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, "0123456789abcdef", true)]
[DataRow(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, "0123456789abcdee", false)]
[DataRow(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, "0123456789abcdeg", null)]
[DataRow(new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, "0123456789a_bcde", null)]
[DataTestMethod]
public void ArrayUtils_EqualsToHexString_Works(byte[] bytes, string hexString, bool? expectedResult)
{
if (expectedResult is not null)
{
Assert.AreEqual(expectedResult, bytes.Equals(hexString.AsSpan()));
}
else
{
Assert.ThrowsException<FormatException>(() => bytes.Equals(hexString.AsSpan()));
}
}

[DataRow("-62135596800001", -1L)]
Expand Down Expand Up @@ -42,4 +71,97 @@ public void DateTimeUtils_UnixTimeStampConversion_Works(string dateString, long
Assert.IsFalse(success);
}
}

[DataRow(-62135596800.001, -1L)]
[DataRow(-62135596800.000, 0L)]
[DataRow(0, 621355968000000000L)]
[DataRow(+253402300799.999, 3155378975999990000L)]
[DataRow(+253402300800.000, -1L)]
[DataTestMethod]
public void DateTimeUtils_UnixTimeSecondsConversion_Works(double seconds, long ticks)
{
var success = DateTimeUtils.TryConvertFromUnixTimeSeconds(seconds, out var dateTime);
if (ticks >= 0)
{
Assert.IsTrue(success);
Assert.AreEqual(ticks, dateTime.Ticks);
}
else
{
Assert.IsFalse(success);
}
}

[DataRow(new string[] { }, 0, false, null, "")]
[DataRow(new string[] { }, 1, true, null, "")]
[DataRow(new string[] { "a" }, 0, false, null, "'a'")]
[DataRow(new string[] { "a" }, 1, true, null, "'a'")]
[DataRow(new string[] { "a" }, 1, true, "a", "'a'")]
[DataRow(new string[] { "a", "b", "c" }, 0, false, null, "'a', 'b', 'c'")]
[DataRow(new string[] { "a", "b", "c" }, 3, false, null, "'a', 'b', 'c'")]
[DataRow(new string[] { "a", "b", "c" }, 2, false, null, "'a', 'b'")]
[DataRow(new string[] { "a", "b", "c" }, 2, true, null, "'a', 'b', ...1 item(s) omitted")]
[DataRow(new string[] { "a", "b", "c" }, 0, true, "a", "'a' -> 'b' -> 'c'")]
[DataTestMethod]
public void StringListFormatter_ToString_Works(string[] items, int maxLength, bool addOmittedItemsText, string? format, string expectedResult)
{
var actualResult = new StringListFormatter(items, maxLength, addOmittedItemsText ? static (count) => $", ...{count} item(s) omitted" : null)
.ToString(format, CultureInfo.InvariantCulture);

Assert.AreEqual(expectedResult, actualResult);
}

[TestMethod]
public void ModelHelper_SetOneOf_Works()
{
object? field = null;

Assert.IsFalse(ModelHelper.IsValidOneOf(field));

ModelHelper.SetOneOf<bool?>(ref field, null);
Assert.IsNull(field);
Assert.IsFalse(ModelHelper.IsValidOneOf(field));

ModelHelper.SetOneOf(ref field, true);
Assert.AreEqual(true, field);
Assert.IsTrue(ModelHelper.IsValidOneOf(field));

ModelHelper.SetOneOf<bool?>(ref field, null);
Assert.AreEqual(true, field);
Assert.IsTrue(ModelHelper.IsValidOneOf(field));

ModelHelper.SetOneOf(ref field, true);
Assert.IsNotNull(field);
Assert.AreNotEqual(true, field);
Assert.AreNotEqual(false, field);
Assert.IsFalse(ModelHelper.IsValidOneOf(field));

ModelHelper.SetOneOf<bool?>(ref field, null);
Assert.IsNotNull(field);
Assert.AreNotEqual(true, field);
Assert.AreNotEqual(false, field);
Assert.IsFalse(ModelHelper.IsValidOneOf(field));
}

private static IEnumerable<object?[]> GetEnumValues() => Enum.GetValues(typeof(SettingType))
.Cast<SettingType>()
.Concat(new[] { Setting.UnknownType })
.Select(t => new object?[] { t });

[DataTestMethod]
[DynamicData(nameof(GetEnumValues), DynamicDataSourceType.Method)]
public void ModelHelper_SetEnum_Works(SettingType enumValue)
{
SettingType field = default;

if (Enum.IsDefined(typeof(SettingType), enumValue))
{
ModelHelper.SetEnum(ref field, enumValue);
Assert.AreEqual(enumValue, field);
}
else
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => ModelHelper.SetEnum(ref field, enumValue));
}
}
}
13 changes: 13 additions & 0 deletions src/ConfigCatClient/Utils/ArrayUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ public static bool Equals(this byte[] bytes, ReadOnlySpan<char> hexString)
{
if (bytes.Length * 2 != hexString.Length)
{
if ((hexString.Length & 1) != 0)
{
throw new FormatException();
}

for (var i = 0; i < hexString.Length; i++)
{
if (GetDigitValue(hexString[i]) < 0)
{
throw new FormatException();
}
}

return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/ConfigCatClient/Utils/ModelHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal static class ModelHelper

public static void SetOneOf<T>(ref object? field, T? value)
{
if (value is not null && !ReferenceEquals(field, value))
if (value is not null)
{
field = field is null ? value : MultipleValuesToken;
}
Expand Down

0 comments on commit cb464fd

Please sign in to comment.