1
0

Solution restructured to use multiple test projects

This commit is contained in:
2024-07-04 18:22:26 +02:00
parent 508379d704
commit df6763b99b
144 changed files with 387 additions and 1693 deletions

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class CollectionExtensionsTest
{
[TestMethod]
public void ShouldAddItem()
{
// Arrange
var item = new TestItem { Number = 10, Text = "Ten" };
ICollection<TestItem> list = new List<TestItem>
{
new() {
Number = 1,
Text = "One"
}
};
// Act
list.AddIfNotNull(item);
// Assert
Assert.AreEqual(2, list.Count);
}
[TestMethod]
public void ShouldNotAddItem()
{
// Arrange
TestItem item = null;
ICollection<TestItem> list = new List<TestItem>
{
new() {
Number = 1,
Text = "One"
}
};
// Act
list.AddIfNotNull(item);
// Assert
Assert.AreEqual(1, list.Count);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowArgumentNullExceptionForNullList()
{
// Arrange
var item = new TestItem { Number = 10, Text = "Ten" };
ICollection<TestItem> list = null;
// Act
list.AddIfNotNull(item);
// Assert - ArgumentNullException
}
[TestMethod]
public void ShouldAddRange()
{
// Arrange
ICollection<TestItem> items = new List<TestItem>
{
new() { Number = 10, Text = "Ten" },
new() { Number = 11, Text = "Eleven" },
};
ICollection<TestItem> list = new List<TestItem>
{
new() { Number = 1, Text = "One" },
};
// Act
list.AddRange(items);
// Assert
Assert.AreEqual(3, list.Count);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowArgumentNullExceptionForList()
{
// Arrange
ICollection<TestItem> items = new List<TestItem>
{
new() { Number = 10, Text = "Ten" },
new() { Number = 11, Text = "Eleven" },
};
ICollection<TestItem> list = null;
// Act
list.AddRange(items);
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowArgumentNullExceptionForItems()
{
// Arrange
ICollection<TestItem> items = null;
ICollection<TestItem> list = new List<TestItem>
{
new() { Number = 1, Text = "One" },
};
// Act
list.AddRange(items);
// Assert - ArgumentNullException
}
[TestMethod]
public void ShouldNotAddRange()
{
// Arrange
ICollection<TestItem> list = new List<TestItem>
{
new() { Number = 1, Text = "One" },
};
// Act
list.AddRange(list);
// Assert
Assert.AreEqual(1, list.Count);
}
private class TestItem
{
public int Number { get; set; }
public string Text { get; set; }
}
}
}

View File

@@ -0,0 +1,72 @@
using System.Security.Cryptography;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class CryptographyHelperExtensionsTest
{
[TestMethod]
public void ShouldReturnMd5Hash()
{
// arrange
string str = "Hello World!";
byte[] bytes = [0xaf, 0xfe];
// act
string strHash = str.Md5();
string byteHash = bytes.Md5();
// assert
Assert.AreEqual("ed076287532e86365e841e92bfc50d8c", strHash);
Assert.AreEqual("63c983de427ce9e2430ba8554d2a822f", byteHash);
}
[TestMethod]
public void ShouldReturnSha1Hash()
{
// arrange
string str = "Hello World!";
byte[] bytes = [0xaf, 0xfe];
// act
string strHash = str.Sha1();
string byteHash = bytes.Sha1();
// assert
Assert.AreEqual("2ef7bde608ce5404e97d5f042f95f89f1c232871", strHash);
Assert.AreEqual("ec2c39d500316044fa49f6c8f471ddec8b4fb9d1", byteHash);
}
[TestMethod]
public void ShouldReturnSha256Hash()
{
// arrange
string str = "Hello World!";
byte[] bytes = [0xaf, 0xfe];
// act
string strHash = str.Sha256();
string byteHash = bytes.Sha256();
// assert
Assert.AreEqual("7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069", strHash);
Assert.AreEqual("4e0da689dc7a51957be426d6cfb1bd860169cb25dd1ac946a2f141228217804a", byteHash);
}
[TestMethod]
public void ShouldReturnSha512Hash()
{
// arrange
string str = "Hello World!";
byte[] bytes = [0xaf, 0xfe];
// act
string strHash = str.Sha512();
string byteHash = bytes.Sha512();
// assert
Assert.AreEqual("861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8", strHash);
Assert.AreEqual("591098c5d470a09f0ff48a4fdb7769ab89f803eae9e23b6f9f69dd228cca46c074bbc11a5fceaa8a5f48d14d2bf19a83a629266c2c5b7d9ef34623b64cb2f8e7", byteHash);
}
}
}

View File

@@ -0,0 +1,362 @@
using System;
using AMWD.Common.Tests.Utils;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class DateTimeExtensionsTest
{
[TestMethod]
public void ShouldReturnUtc()
{
// arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
using var _ = TimeZoneInfoLocalMock.Create(timeZoneInfo);
var utc = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Utc);
var local = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Local);
var unspecified = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Unspecified);
// act
var utcCorrected = utc.AsUtc();
var localCorrected = local.AsUtc();
var unspecifiedCorrected = unspecified.AsUtc();
// assert
Assert.AreEqual(DateTimeKind.Utc, utcCorrected.Kind);
Assert.AreEqual(DateTimeKind.Utc, localCorrected.Kind);
Assert.AreEqual(DateTimeKind.Utc, unspecifiedCorrected.Kind);
Assert.AreEqual(utc, utcCorrected);
Assert.AreEqual(utc.AddHours(-1), localCorrected);
Assert.AreEqual(utc, unspecifiedCorrected);
}
[TestMethod]
public void ShouldReturnLocal()
{
// arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
using var _ = TimeZoneInfoLocalMock.Create(timeZoneInfo);
var utc = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Utc);
var local = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Local);
var unspecified = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Unspecified);
// act
var utcCorrected = utc.AsLocal();
var localCorrected = local.AsLocal();
var unspecifiedCorrected = unspecified.AsLocal();
// assert
Assert.AreEqual(DateTimeKind.Local, utcCorrected.Kind);
Assert.AreEqual(DateTimeKind.Local, localCorrected.Kind);
Assert.AreEqual(DateTimeKind.Local, unspecifiedCorrected.Kind);
Assert.AreEqual(local.AddHours(1), utcCorrected);
Assert.AreEqual(local, localCorrected);
Assert.AreEqual(local, unspecifiedCorrected);
}
[TestMethod]
public void ShouldReturnCorrectUtcAlignmentDaylightSavingEnd()
{
// arrange
var dateTime = new DateTime(2021, 10, 30, 12, 15, 30, 45, DateTimeKind.Utc);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(dateTime);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(dateTime);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(dateTime);
var diffDay = intervalDay.GetAlignedInterval(dateTime);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(dateTime, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(dateTime, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("15:44:29.955"), diffDayOffset); // must be the same whether daylight saving has ended
}
[TestMethod]
public void ShouldReturnCorrectUtcAlignmentDaylightSavingStart()
{
// arrange
var dateTime = new DateTime(2022, 3, 26, 12, 15, 30, 45, DateTimeKind.Utc);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(dateTime);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(dateTime);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(dateTime);
var diffDay = intervalDay.GetAlignedInterval(dateTime);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(dateTime, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(dateTime, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("15:44:29.955"), diffDayOffset); // must be the same whether daylight saving has started
}
[TestMethod]
public void ShouldReturnCorrectLocalAlignmentDaylightSavingEnd()
{
// arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
using var _ = TimeZoneInfoLocalMock.Create(timeZoneInfo);
var dateTime = new DateTime(2021, 10, 30, 12, 15, 30, 45, DateTimeKind.Local);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(dateTime);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(dateTime);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(dateTime);
var diffDay = intervalDay.GetAlignedInterval(dateTime);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(dateTime, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(dateTime, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("14:44:29.955"), diffDayOffset); // has to be minus one hour due to daylight saving ended
}
[TestMethod]
public void ShouldReturnCorrectLocalAlignmentDaylightSavingStart()
{
// arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
using var _ = TimeZoneInfoLocalMock.Create(timeZoneInfo);
var dateTime = new DateTime(2022, 3, 26, 12, 15, 30, 45, DateTimeKind.Local);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(dateTime);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(dateTime);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(dateTime);
var diffDay = intervalDay.GetAlignedInterval(dateTime);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(dateTime, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(dateTime, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("16:44:29.955"), diffDayOffset); // has to be plus one hour due to daylight saving started
}
[TestMethod]
public void ShouldReturnCorrectAlignment()
{
// arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
using var _ = TimeZoneInfoLocalMock.Create(timeZoneInfo);
var interval = TimeSpan.FromDays(1);
// act
var intervalUtc = interval.GetAlignedIntervalUtc();
var expectedUtc = DateTime.UtcNow.TimeOfDay;
var intervalLocal = interval.GetAlignedIntervalLocal();
var expectedLocal = DateTime.Now.TimeOfDay;
// assert
Assert.AreEqual(expectedUtc.RoundToSecond(), (interval - intervalUtc).RoundToSecond());
Assert.AreEqual(expectedLocal.RoundToSecond(), (interval - intervalLocal).RoundToSecond());
if (DateTime.Now.TimeOfDay < DateTime.UtcNow.TimeOfDay) // case when local time has new day but UTC not
{
Assert.AreEqual((DateTime.Now - DateTime.UtcNow).RoundToSecond(), interval - (intervalLocal - intervalUtc).RoundToSecond());
}
else
{
Assert.AreEqual((DateTime.Now - DateTime.UtcNow).RoundToSecond(), (intervalUtc - intervalLocal).RoundToSecond());
}
}
[TestMethod]
public void ShouldReturnCorrectShortStringForTimeSpan()
{
// arrange
var timeSpan = TimeSpan.Parse("1.10:11:12.345");
var negativeTimeSpan = TimeSpan.FromDays(-1.234);
// act
string shortString = timeSpan.ToShortString(withMilliseconds: false);
string shortStringWithMillis = timeSpan.ToShortString(withMilliseconds: true);
string shortStringNegative = negativeTimeSpan.ToShortString(withMilliseconds: true);
// assert
Assert.AreEqual("1d 10h 11m 12s", shortString);
Assert.AreEqual("1d 10h 11m 12s 345ms", shortStringWithMillis);
Assert.AreEqual("-1d 5h 36m 57s 600ms", shortStringNegative);
}
[TestMethod]
public void ShouldRoundToSecond()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 15, 30, 500);
var timestampDown = new DateTime(2021, 11, 16, 20, 15, 30, 499);
var timespanUp = new TimeSpan(1, 2, 3, 4, 500);
var timespanDown = new TimeSpan(1, 2, 3, 4, 499);
// act
var timestampUpRounded = timestampUp.RoundToSecond();
var timestampDownRounded = timestampDown.RoundToSecond();
var timespanUpRounded = timespanUp.RoundToSecond();
var timespanDownRounded = timespanDown.RoundToSecond();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:31.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:30.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:05.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:04.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToMinute()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 15, 30, 0);
var timestampDown = new DateTime(2021, 11, 16, 20, 15, 29, 999);
var timespanUp = new TimeSpan(1, 2, 3, 30, 0);
var timespanDown = new TimeSpan(1, 2, 3, 29, 999);
// act
var timestampUpRounded = timestampUp.RoundToMinute();
var timestampDownRounded = timestampDown.RoundToMinute();
var timespanUpRounded = timespanUp.RoundToMinute();
var timespanDownRounded = timespanDown.RoundToMinute();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:16:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:04:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:00.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToHour()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 30, 0, 0);
var timestampDown = new DateTime(2021, 11, 16, 20, 29, 59, 999);
var timespanUp = new TimeSpan(1, 2, 30, 0, 0);
var timespanDown = new TimeSpan(1, 2, 29, 59, 999);
// act
var timestampUpRounded = timestampUp.RoundToHour();
var timestampDownRounded = timestampDown.RoundToHour();
var timespanUpRounded = timespanUp.RoundToHour();
var timespanDownRounded = timespanDown.RoundToHour();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 21:00:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:00:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.03:00:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:00:00.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToDay()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 12, 0, 0, 0);
var timestampDown = new DateTime(2021, 11, 16, 11, 59, 59, 999);
var timespanUp = new TimeSpan(1, 12, 0, 0, 0);
var timespanDown = new TimeSpan(1, 11, 59, 59, 999);
// act
var timestampUpRounded = timestampUp.RoundToDay();
var timestampDownRounded = timestampDown.RoundToDay();
var timespanUpRounded = timespanUp.RoundToDay();
var timespanDownRounded = timespanDown.RoundToDay();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-17 00:00:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 00:00:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("2.00:00:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.00:00:00.000"), timespanDownRounded);
}
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Linq;
using AMWD.Common.Tests.Utils;
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class EnumExtensionsTest
{
[TestMethod]
public void ShouldReturnEmptyList()
{
// arrange
var enumValue = TestEnum.Two;
// act
var customList = enumValue.GetAttributes<CustomMultipleAttribute>();
var descriptionList = enumValue.GetAttributes<DescriptionAttribute>();
// assert
Assert.IsNotNull(customList);
Assert.IsFalse(customList.Any());
Assert.IsNotNull(descriptionList);
Assert.IsFalse(descriptionList.Any());
}
[TestMethod]
public void ShouldReturnList()
{
// arrange
var enumValue = TestEnum.Zero;
// act
var customList = enumValue.GetAttributes<CustomMultipleAttribute>();
var descriptionList = enumValue.GetAttributes<DescriptionAttribute>();
// assert
Assert.IsNotNull(customList);
Assert.IsTrue(customList.Any());
Assert.AreEqual(2, customList.Count());
Assert.IsNotNull(descriptionList);
Assert.IsTrue(descriptionList.Any());
Assert.AreEqual(1, descriptionList.Count());
}
[TestMethod]
public void ShouldReturnNothing()
{
// arrange
var enumValue = TestEnum.Two;
// act
var customAttribute = enumValue.GetAttribute<CustomMultipleAttribute>();
var descriptionAttribute = enumValue.GetAttribute<DescriptionAttribute>();
// assert
Assert.IsNull(customAttribute);
Assert.IsNull(descriptionAttribute);
}
[TestMethod]
public void ShouldReturnFirstAttribute()
{
// arrange
var enumValue = TestEnum.Zero;
// act
var customAttribute = enumValue.GetAttribute<CustomMultipleAttribute>();
var descriptionAttribute = enumValue.GetAttribute<DescriptionAttribute>();
// assert
Assert.IsNotNull(customAttribute);
Assert.AreEqual("nix", customAttribute.Name);
Assert.IsNotNull(descriptionAttribute);
Assert.AreEqual("Null", descriptionAttribute.Description);
}
[TestMethod]
public void ShouldReturnDescriptionOrStringRepresentation()
{
// arrange
var enumWithDescription = TestEnum.One;
var enumWithoutDescripton = TestEnum.Two;
// act
string description = enumWithDescription.GetDescription();
string noDescription = enumWithoutDescripton.GetDescription();
// assert
Assert.AreEqual("Eins", description);
Assert.AreEqual(enumWithoutDescripton.ToString(), noDescription);
}
[TestMethod]
public void ShouldReturnEmptyListOnNotDefinedEnumValue()
{
// arrange
var notDefinedEnum = (TestEnum)10;
// act
var list = notDefinedEnum.GetAttributes<DescriptionAttribute>();
// assert
Assert.IsFalse(list.Any());
}
internal enum TestEnum
{
[CustomMultiple("nix")]
[CustomMultiple("Null")]
[Description("Null")]
Zero,
[Description("Eins")]
One,
Two,
}
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class ExceptionExtensionsTest
{
[TestMethod]
public void ShouldReturnExceptionMessage()
{
// arrange
var exception = new Exception("This is a message.");
// act
string message = exception.GetMessage();
// assert
Assert.AreEqual(exception.Message, message);
}
[TestMethod]
public void ShouldReturnInnerExceptionMessage()
{
// arrange
var innerException = new Exception("Message from the inner side.");
var outerException = new Exception("Message from the outer side.", innerException);
// act
string message = outerException.GetMessage();
// assert
Assert.AreEqual(innerException.Message, message);
}
[TestMethod]
public void ShouldReturnRecursiveExceptionMessageFoInnerException()
{
// arrange
var innerException = new Exception("Message from the inner side.");
var outerException = new Exception("Message from the outer side. See the inner exception for details.", innerException);
string expectedMessage = $"Message from the outer side. Message from the inner side.";
// act
string message = outerException.GetRecursiveMessage();
// assert
Assert.AreEqual(expectedMessage, message);
}
[TestMethod]
public void ShouldReturnRecursiveExceptionMessageFoInnerExceptions()
{
// arrange
var innerExceptions = new List<Exception>
{
new("Inner Exception 1."),
new("Inner Exception 2. See the inner exception for details.", new Exception("Inner Exception of Exception 2.")),
new("Inner Exception 3."),
new("Inner Exception 4."),
new("Inner Exception 5.")
};
var aggregateException = new AggregateException("Lots of exceptions.", innerExceptions);
string expectedMessage = "Inner Exception 1. Inner Exception 2. Inner Exception of Exception 2. Inner Exception 3.";
// act
string message = aggregateException.GetRecursiveMessage();
// assert
Assert.AreEqual(expectedMessage, message);
}
}
}

View File

@@ -0,0 +1,86 @@
using System.Net;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class IPAddressExtensionsTest
{
[TestMethod]
public void ShouldIncrementLastByte()
{
// arrange
var ipAddress = IPAddress.Parse("192.168.178.22");
// act
var incremented = ipAddress.Increment();
// assert
Assert.AreEqual("192.168.178.23", incremented.ToString());
}
[TestMethod]
public void ShouldIncrementAllBytes()
{
// arrange
var ipAddress = IPAddress.Parse("192.255.255.255");
// act
var incremented = ipAddress.Increment();
// assert
Assert.AreEqual("193.0.0.0", incremented.ToString());
}
[TestMethod]
public void ShouldIncrementOverflow()
{
// arrange
var ipAddress = IPAddress.Parse("255.255.255.255");
// act
var incremented = ipAddress.Increment();
// assert
Assert.AreEqual("0.0.0.0", incremented.ToString());
}
[TestMethod]
public void ShouldDecrementLastByte()
{
// arrange
var ipAddress = IPAddress.Parse("192.168.178.22");
// act
var decremented = ipAddress.Decrement();
// assert
Assert.AreEqual("192.168.178.21", decremented.ToString());
}
[TestMethod]
public void ShouldDecrementAllBytes()
{
// arrange
var ipAddress = IPAddress.Parse("192.0.0.0");
// act
var decremented = ipAddress.Decrement();
// assert
Assert.AreEqual("191.255.255.255", decremented.ToString());
}
[TestMethod]
public void ShouldDecrementUnderflow()
{
// arrange
var ipAddress = IPAddress.Parse("0.0.0.0");
// act
var decremented = ipAddress.Decrement();
// assert
Assert.AreEqual("255.255.255.255", decremented.ToString());
}
}
}

View File

@@ -0,0 +1,339 @@
using System;
using System.Collections;
using AMWD.Common.Tests.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class JsonExtensionsTest
{
[TestMethod]
public void ShouldReturnJson()
{
// arrange
var testObject = new JsonTestClass();
string expected = @"{""stringValue"":""Hello World!"",""isBoolTrue"":true,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":42.21,""localTimestamp"":""2021-11-16T20:15:34+01:00"",""utcTimestamp"":""2021-11-16T20:15:34Z"",""object"":{""integerValue"":42,""stringValue"":""Foo-Bar""}}";
// act
string json = testObject.SerializeJson();
// assert
Assert.IsFalse(string.IsNullOrWhiteSpace(json));
Assert.AreEqual(expected, json);
}
[TestMethod]
public void ShouldReturnJsonIndented()
{
// arrange
var testObject = new JsonTestClass();
string expected = @"{
""stringValue"": ""Hello World!"",
""isBoolTrue"": true,
""floatValue"": 12.34,
""doubleValue"": 21.42,
""decimalValue"": 42.21,
""localTimestamp"": ""2021-11-16T20:15:34+01:00"",
""utcTimestamp"": ""2021-11-16T20:15:34Z"",
""object"": {
""integerValue"": 42,
""stringValue"": ""Foo-Bar""
}
}";
// act
string json = testObject.SerializeJson(indented: true);
// assert
Assert.IsFalse(string.IsNullOrWhiteSpace(json));
Assert.AreEqual(expected.Replace("\r", ""), json.Replace("\r", ""));
}
[TestMethod]
public void ShouldReturnJsonWithSingleQuotes()
{
// arrange
var testObject = new JsonTestClass
{
StringValue = "Sam's Pub"
};
string expected = "{'stringValue':'Sam\\'s Pub','isBoolTrue':true,'floatValue':12.34,'doubleValue':21.42,'decimalValue':42.21,'localTimestamp':'2021-11-16T20:15:34+01:00','utcTimestamp':'2021-11-16T20:15:34Z','object':{'integerValue':42,'stringValue':'Foo-Bar'}}";
// act
string json = testObject.SerializeJson(useSingleQuotes: true);
// assert
Assert.IsFalse(string.IsNullOrWhiteSpace(json));
Assert.AreEqual(expected, json);
}
[TestMethod]
public void ShouldReturnJsonWithoutCamelCase()
{
// arrange
var testObject = new JsonTestClass();
string expected = @"{""StringValue"":""Hello World!"",""IsBoolTrue"":true,""FloatValue"":12.34,""DoubleValue"":21.42,""DecimalValue"":42.21,""LocalTimestamp"":""2021-11-16T20:15:34+01:00"",""UtcTimestamp"":""2021-11-16T20:15:34Z"",""Object"":{""IntegerValue"":42,""StringValue"":""Foo-Bar""}}";
// act
string json = testObject.SerializeJson(useCamelCase: false);
// assert
Assert.IsFalse(string.IsNullOrWhiteSpace(json));
Assert.AreEqual(expected, json);
}
[TestMethod]
public void ShouldReturnJsonWithType()
{
// arrange
var testObject = new JsonTestClass();
string expected = @"{""$type"":""AMWD.Common.Tests.Utils.JsonTestClass, AMWD.Common.Tests"",""stringValue"":""Hello World!"",""isBoolTrue"":true,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":42.21,""localTimestamp"":""2021-11-16T20:15:34+01:00"",""utcTimestamp"":""2021-11-16T20:15:34Z"",""object"":{""$type"":""AMWD.Common.Tests.Utils.JsonTestSubClass, AMWD.Common.Tests"",""integerValue"":42,""stringValue"":""Foo-Bar""}}";
// act
string json = testObject.SerializeJson(includeType: true);
// assert
Assert.IsFalse(string.IsNullOrWhiteSpace(json));
Assert.AreEqual(expected, json);
}
[TestMethod]
public void ShouldDeserializeWithoutFallback()
{
// arrange
string workingJson = @"{""stringValue"":""Some fancy string"",""isBoolTrue"":false,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":123.45,""localTimestamp"":""2021-11-15T20:15:34+01:00"",""utcTimestamp"":""2021-10-16T20:15:34Z"",""object"":{""integerValue"":21,""stringValue"":""FooBar""}}";
string brokenJson = @"{""strValue"":""Some fancy string"",""isBoolTrue"":false,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":123.45,""localTimestamp"":""2021-11-15T20:15:34+01:00"",""utcTimestamp"":""2021-10-16T20:15:34Z"",""object"":{""integerValue"":21.12,""stringValue"":""FooBar""}}";
string emptyString = "";
// act
var workingObj = workingJson.DeserializeJson<JsonTestClass>();
var emptyObj = emptyString.DeserializeJson<JsonTestClass>();
try
{
var brokenObj = brokenJson.DeserializeJson<JsonTestClass>();
Assert.Fail();
}
catch (JsonReaderException)
{ }
// assert
Assert.IsNotNull(workingObj);
Assert.IsNull(emptyObj);
Assert.AreEqual("Some fancy string", workingObj.StringValue);
Assert.IsFalse(workingObj.IsBoolTrue);
Assert.AreEqual(123.45m, workingObj.DecimalValue);
Assert.AreEqual(DateTimeKind.Local, workingObj.LocalTimestamp.Kind);
Assert.AreEqual("15.11.2021 20:15:34", workingObj.LocalTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
Assert.AreEqual(DateTimeKind.Utc, workingObj.UtcTimestamp.Kind);
Assert.AreEqual("16.10.2021 20:15:34", workingObj.UtcTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
}
[TestMethod]
public void ShouldDeserializeWithFallback()
{
// arrange
string workingJson = @"{""stringValue"":""Some fancy string"",""isBoolTrue"":false,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":123.45,""localTimestamp"":""2021-11-15T20:15:34+01:00"",""utcTimestamp"":""2021-10-16T20:15:34Z"",""object"":{""integerValue"":21,""stringValue"":""FooBar""}}";
string brokenJson = @"{""strValue"":""Some fancy string"",""isBoolTrue"":false,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":123.45,""localTimestamp"":""2021-11-15T20:15:34+01:00"",""utcTimestamp"":""2021-10-16T20:15:34Z"",""object"":{""integerValue"":21.12,""stringValue"":""FooBar""}}";
string emptyString = "";
var fallback = new JsonTestClass
{
DoubleValue = 0.815
};
// act
var workingObj = workingJson.DeserializeJson(fallback);
var brokenObj = brokenJson.DeserializeJson(fallback);
var emptyObj = emptyString.DeserializeJson(fallback);
// assert
Assert.IsNotNull(workingObj);
Assert.IsNotNull(brokenObj);
Assert.IsNull(emptyObj);
Assert.AreEqual("Some fancy string", workingObj.StringValue);
Assert.IsFalse(workingObj.IsBoolTrue);
Assert.AreEqual(123.45m, workingObj.DecimalValue);
Assert.AreEqual(21.42, workingObj.DoubleValue);
Assert.AreEqual(DateTimeKind.Local, workingObj.LocalTimestamp.Kind);
Assert.AreEqual("15.11.2021 20:15:34", workingObj.LocalTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
Assert.AreEqual(DateTimeKind.Utc, workingObj.UtcTimestamp.Kind);
Assert.AreEqual("16.10.2021 20:15:34", workingObj.UtcTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
Assert.AreEqual(fallback.StringValue, brokenObj.StringValue);
Assert.AreEqual(fallback.IsBoolTrue, brokenObj.IsBoolTrue);
Assert.AreEqual(fallback.DecimalValue, brokenObj.DecimalValue);
Assert.AreEqual(fallback.DoubleValue, brokenObj.DoubleValue);
Assert.AreEqual(fallback.LocalTimestamp.Kind, brokenObj.LocalTimestamp.Kind);
Assert.AreEqual(fallback.LocalTimestamp, brokenObj.LocalTimestamp);
Assert.AreEqual(fallback.UtcTimestamp.Kind, brokenObj.UtcTimestamp.Kind);
Assert.AreEqual(fallback.UtcTimestamp, brokenObj.UtcTimestamp);
}
[TestMethod]
public void ShouldDeserializeUsingPopulate()
{
// arrange
string json = @"{""stringValue"":""Some fancy string"",""isBoolTrue"":false,""floatValue"":12.34,""doubleValue"":21.42,""decimalValue"":123.45,""localTimestamp"":""2021-11-15T20:15:34+01:00"",""utcTimestamp"":""2021-10-16T20:15:34Z"",""object"":{""integerValue"":21,""stringValue"":""FooBar""}}";
var obj = new JsonTestClass();
// act
obj.DeserializeJson(json);
// assert
Assert.AreEqual("Some fancy string", obj.StringValue);
Assert.IsFalse(obj.IsBoolTrue);
Assert.AreEqual(123.45m, obj.DecimalValue);
Assert.AreEqual(21.42, obj.DoubleValue);
Assert.AreEqual(DateTimeKind.Local, obj.LocalTimestamp.Kind);
Assert.AreEqual("15.11.2021 20:15:34", obj.LocalTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
Assert.AreEqual(DateTimeKind.Utc, obj.UtcTimestamp.Kind);
Assert.AreEqual("16.10.2021 20:15:34", obj.UtcTimestamp.ToString("dd.MM.yyyy HH:mm:ss"));
}
[TestMethod]
public void ShouldConvertToJObject()
{
// arrange
var obj = new JsonTestClass
{
StringValue = "Hello JSON",
DecimalValue = 0.815m
};
// act
var jObj = obj.ConvertToJObject();
// assert
Assert.IsNotNull(jObj);
Assert.AreEqual(typeof(JObject), jObj.GetType());
Assert.AreEqual(obj.StringValue, jObj.Value<string>("stringValue"));
Assert.AreEqual(obj.DecimalValue, jObj.Value<decimal>("decimalValue"));
Assert.AreEqual(obj.LocalTimestamp.Kind, jObj.Value<DateTime>("localTimestamp").Kind);
Assert.AreEqual(obj.LocalTimestamp, jObj.Value<DateTime>("localTimestamp"));
Assert.AreEqual(obj.UtcTimestamp.Kind, jObj.Value<DateTime>("utcTimestamp").Kind);
Assert.AreEqual(obj.UtcTimestamp, jObj.Value<DateTime>("utcTimestamp"));
}
[TestMethod]
public void ShouldConvertToJArray()
{
// arrange
string[] stringArray = ["one", "two", "three"];
var objectArray = new[]
{
new JsonTestClass { StringValue = "One" },
new JsonTestClass { StringValue = "Two" },
new JsonTestClass { StringValue = "Three" }
};
// act
var stringJArray = stringArray.ConvertToJArray();
var objectJArray = objectArray.ConvertToJArray();
// assert
Assert.IsNotNull(stringJArray);
Assert.AreEqual(typeof(JArray), stringJArray.GetType());
Assert.AreEqual(stringArray[0], stringJArray[0]);
Assert.AreEqual(stringArray[1], stringJArray[1]);
Assert.AreEqual(stringArray[2], stringJArray[2]);
Assert.IsNotNull(objectJArray);
Assert.AreEqual(typeof(JArray), objectJArray.GetType());
Assert.AreEqual(objectArray[0].StringValue, objectJArray[0].Value<string>("stringValue"));
Assert.AreEqual(objectArray[1].StringValue, objectJArray[1].Value<string>("stringValue"));
Assert.AreEqual(objectArray[2].StringValue, objectJArray[2].Value<string>("stringValue"));
}
[TestMethod]
public void ShouldRunJsonTreeWithoutDefault()
{
// arrange
var obj = new JsonTestClass { StringValue = "Running Json", Object = new JsonTestSubClass { IntegerValue = 4711 } };
var jObj = obj.ConvertToJObject();
// act
string topLevelString = jObj.GetValue<string>("stringValue");
decimal topLevelDecimal = jObj.GetValue<decimal>("decimalValue");
int subLevelInteger = jObj.GetValue<int>("object:IntegerValue");
string subLevelString = jObj.GetValue<string>("object:stringValue");
string notExistingOnTopLevel = jObj.GetValue<string>("fancyValue");
string notExistingOnSubLevel = jObj.GetValue<string>("object:fancyValue");
int? notExistingLevel = jObj.GetValue<int?>("fancy:int");
// assert
Assert.AreEqual(obj.StringValue, topLevelString);
Assert.AreEqual(obj.DecimalValue, topLevelDecimal);
Assert.AreEqual(obj.Object.IntegerValue, subLevelInteger);
Assert.AreEqual(obj.Object.StringValue, subLevelString);
Assert.IsNull(notExistingOnTopLevel);
Assert.IsNull(notExistingOnSubLevel);
Assert.IsNull(notExistingLevel);
}
[TestMethod]
public void ShouldRunJsonTreeWithDefault()
{
// arrange
var obj = new JsonTestClass { StringValue = "Running Json", Object = new JsonTestSubClass { IntegerValue = 4711 } };
var jObj = obj.ConvertToJObject();
// act
string topLevelString = jObj.GetValue("stringValue", "Test String");
decimal topLevelDecimal = jObj.GetValue("decimalValue", 13.24m);
int subLevelInteger = jObj.GetValue("object:IntegerValue", 55);
string subLevelString = jObj.GetValue("object:stringValue", "Yeah!");
string notExistingOnTopLevel = jObj.GetValue("fancyValue", "Party!");
string notExistingOnSubLevel = jObj.GetValue("object:fancyValue", "Well Done");
int? notExistingLevel = jObj.GetValue<int?>("fancy:int", 13);
// assert
Assert.AreEqual(obj.StringValue, topLevelString);
Assert.AreEqual(obj.DecimalValue, topLevelDecimal);
Assert.AreEqual(obj.Object.IntegerValue, subLevelInteger);
Assert.AreEqual(obj.Object.StringValue, subLevelString);
Assert.AreEqual("Party!", notExistingOnTopLevel);
Assert.AreEqual("Well Done", notExistingOnSubLevel);
Assert.AreEqual(13, notExistingLevel);
}
[TestMethod]
public void ShouldReturnNull()
{
// arrange
object obj = null;
IEnumerable list = null;
JObject jObj = null;
// act
var objTest = obj.ConvertToJObject();
var listTest = list.ConvertToJArray();
object getTest = jObj.GetValue<object>("Nothing");
// assert
Assert.IsNull(objTest);
Assert.IsNull(listTest);
Assert.IsNull(getTest);
}
[TestMethod]
public void ShouldHandleSerializationError()
{
// arrange
var obj = new JsonErrorClass();
// act
string json = obj.SerializeJson();
// assert
Assert.AreEqual("{}", json);
}
}
}

View File

@@ -0,0 +1,219 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class ReaderWriterLockSlimExtensionsTest
{
[TestMethod]
public void ShouldEnterReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
// act
using var disposable = rwLock.GetReadLock();
// assert
Assert.IsNotNull(disposable);
Assert.IsTrue(rwLock.IsReadLockHeld);
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
Assert.IsFalse(rwLock.IsWriteLockHeld);
}
[TestMethod]
public void ShouldEnterUpgradeableReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
// act
using var disposable = rwLock.GetUpgradeableReadLock();
// assert
Assert.IsNotNull(disposable);
Assert.IsFalse(rwLock.IsReadLockHeld);
Assert.IsTrue(rwLock.IsUpgradeableReadLockHeld);
Assert.IsFalse(rwLock.IsWriteLockHeld);
}
[TestMethod]
public void ShouldAllowWriteLockAfterUpgradableReadLock()
{
// arrange
var rwLockUsing = new ReaderWriterLockSlim();
var rwLockClassic = new ReaderWriterLockSlim();
// act
using var disposableReadUsing = rwLockUsing.GetUpgradeableReadLock();
using (rwLockUsing.GetWriteLock())
{
// assert
Assert.IsTrue(rwLockUsing.IsUpgradeableReadLockHeld);
Assert.IsTrue(rwLockUsing.IsWriteLockHeld);
}
// assert
Assert.IsTrue(rwLockUsing.IsUpgradeableReadLockHeld);
Assert.IsFalse(rwLockUsing.IsWriteLockHeld);
// act
using (rwLockClassic.GetUpgradeableReadLock())
{
rwLockClassic.EnterWriteLock();
// assert
Assert.IsTrue(rwLockClassic.IsUpgradeableReadLockHeld);
Assert.IsTrue(rwLockClassic.IsWriteLockHeld);
}
// assert
Assert.IsFalse(rwLockClassic.IsUpgradeableReadLockHeld);
Assert.IsFalse(rwLockClassic.IsWriteLockHeld);
}
[TestMethod]
public void ShouldEnterWriteLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
// act
using var disposable = rwLock.GetWriteLock();
// assert
Assert.IsNotNull(disposable);
Assert.IsFalse(rwLock.IsReadLockHeld);
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
Assert.IsTrue(rwLock.IsWriteLockHeld);
}
[TestMethod]
public void ShouldNotAllowWriteLockAfterReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
// act
using var disposableRead = rwLock.GetReadLock();
try
{
using var disposaleWrite = rwLock.GetWriteLock();
Assert.Fail();
}
catch (LockRecursionException)
{ }
// assert
Assert.IsNotNull(disposableRead);
Assert.IsTrue(rwLock.IsReadLockHeld);
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
Assert.IsFalse(rwLock.IsWriteLockHeld);
}
[TestMethod]
public void ShouldAllowWriteLockAfterUpgradeableReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
// act
using var disposableRead = rwLock.GetUpgradeableReadLock();
using var disposableWrite = rwLock.GetWriteLock();
// assert
Assert.IsNotNull(disposableRead);
Assert.IsNotNull(disposableWrite);
Assert.IsFalse(rwLock.IsReadLockHeld);
Assert.IsTrue(rwLock.IsUpgradeableReadLockHeld);
Assert.IsTrue(rwLock.IsWriteLockHeld);
}
[TestMethod]
public void ShouldGetTimeoutOnReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
bool isTimeout = false;
// act
using var disposableRead = rwLock.GetWriteLock();
var awaitableTask = Task.Run(() =>
{
try
{
using var disposableRead = rwLock.GetReadLock(10);
Assert.Fail();
}
catch (TimeoutException)
{
isTimeout = true;
}
catch (Exception)
{ /* keep it quiet */ }
});
awaitableTask.Wait();
// assert
Assert.IsTrue(isTimeout);
}
[TestMethod]
public void ShouldGetTimeoutOnUpgradeableReadLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
bool isTimeout = false;
// act
using var disposableRead = rwLock.GetWriteLock();
var awaitableTask = Task.Run(() =>
{
try
{
using var disposableRead = rwLock.GetUpgradeableReadLock(10);
Assert.Fail();
}
catch (TimeoutException)
{
isTimeout = true;
}
catch (Exception)
{ /* keep it quiet */ }
});
awaitableTask.Wait();
// assert
Assert.IsTrue(isTimeout);
}
[TestMethod]
public void ShouldGetTimeoutOnWriteLock()
{
// arrange
var rwLock = new ReaderWriterLockSlim();
bool isTimeout = false;
// act
using var disposableRead = rwLock.GetReadLock();
var awaitableTask = Task.Run(() =>
{
try
{
using var disposableRead = rwLock.GetWriteLock(10);
Assert.Fail();
}
catch (TimeoutException)
{
isTimeout = true;
}
catch (Exception)
{ /* keep it quiet */ }
});
awaitableTask.Wait();
// assert
Assert.IsTrue(isTimeout);
}
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class StreamExtensionsTest
{
[TestMethod]
public void ShouldReadLineFromStreamSynchronous()
{
// arrange
var sb = new StringBuilder();
sb.AppendLine("First Line");
sb.AppendLine("Second Line");
byte[] buffer = Encoding.UTF8.GetBytes(sb.ToString().Trim());
var stream = new MemoryStream(buffer);
// act
string line = stream.ReadLine();
// assert
Assert.AreEqual("First Line", line);
stream.Dispose();
}
[TestMethod]
public void ShouldReadUntilEndAsLineSynchronous()
{
// arrange
byte[] buffer = Encoding.UTF8.GetBytes("Single Line");
var stream = new MemoryStream(buffer);
// act
string line = stream.ReadLine();
// assert
Assert.AreEqual("Single Line", line);
stream.Dispose();
}
[TestMethod]
public void ShouldReturnNullWhenNotReadableSynchronous()
{
// arrange
var stream = new WriteOnlyStream();
// act
string line = stream.ReadLine();
// assert
Assert.IsNull(line);
stream.Dispose();
}
[TestMethod]
public async Task ShouldReadLineFromStreamAsynchronous()
{
// arrange
var sb = new StringBuilder();
sb.AppendLine("First Line");
sb.AppendLine("Second Line");
byte[] buffer = Encoding.UTF8.GetBytes(sb.ToString().Trim());
var stream = new MemoryStream(buffer);
// act
string line = await stream.ReadLineAsync();
// assert
Assert.AreEqual("First Line", line);
stream.Dispose();
}
[TestMethod]
public async Task ShouldReadUntilEndAsLineAsynchronous()
{
// arrange
byte[] buffer = Encoding.UTF8.GetBytes("Single Line");
var stream = new MemoryStream(buffer);
// act
string line = await stream.ReadLineAsync();
// assert
Assert.AreEqual("Single Line", line);
stream.Dispose();
}
[TestMethod]
public async Task ShouldReturnNullWhenNotReadableAsynchronous()
{
// arrange
var stream = new WriteOnlyStream();
// act
string line = await stream.ReadLineAsync();
// assert
Assert.IsNull(line);
stream.Dispose();
}
private class WriteOnlyStream : Stream
{
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => 0;
public override long Position { get => 0; set => throw new NotImplementedException(); }
public override void Flush()
{ }
public override int Read(byte[] buffer, int offset, int count) => 0;
public override long Seek(long offset, SeekOrigin origin) => 0;
public override void SetLength(long value)
{ }
public override void Write(byte[] buffer, int offset, int count)
{ }
}
}
}

View File

@@ -0,0 +1,351 @@
using System;
using System.Linq;
using System.Net;
using System.Text;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class StringExtensionsTest
{
[TestMethod]
public void ShouldReturnEmptyList()
{
// arrange
string hex = "";
// act
var bytes = hex.HexToBytes();
// assert
Assert.IsNotNull(bytes);
Assert.IsFalse(bytes.Any());
}
[TestMethod]
public void ShouldReturnEmptyListWhenInvalid()
{
// arrange
string hex1 = "aff";
string hex2 = "de:ad:be:e";
string hex3 = "hell";
// act
var bytes1 = hex1.HexToBytes();
var bytes2 = hex2.HexToBytes(":");
var bytes3 = hex3.HexToBytes();
// assert
Assert.IsNotNull(bytes1);
Assert.IsFalse(bytes1.Any());
Assert.IsNotNull(bytes2);
Assert.IsFalse(bytes2.Any());
Assert.IsNotNull(bytes3);
Assert.IsFalse(bytes3.Any());
}
[TestMethod]
public void ShouldConvertHexToBytes()
{
// arrange
string hex = "deadbeef";
// act
var bytes = hex.HexToBytes();
// assert
Assert.IsNotNull(bytes);
Assert.AreEqual(4, bytes.Count());
Assert.AreEqual(0xde, bytes.ElementAt(0));
Assert.AreEqual(0xad, bytes.ElementAt(1));
Assert.AreEqual(0xbe, bytes.ElementAt(2));
Assert.AreEqual(0xef, bytes.ElementAt(3));
}
[TestMethod]
public void ShouldConvertHexToBytesWithDelimiter()
{
// arrange
string hex = "af:fe";
// act
var bytes = hex.HexToBytes(":");
// assert
Assert.IsNotNull(bytes);
Assert.AreEqual(2, bytes.Count());
Assert.AreEqual(0xaf, bytes.ElementAt(0));
Assert.AreEqual(0xfe, bytes.ElementAt(1));
}
[TestMethod]
public void ShouldReturnNullWhenInvalid()
{
// arrange
byte[] bytes1 = null;
byte[] bytes2 = [];
// act
string hex1 = bytes1.BytesToHex();
string hex2 = bytes2.BytesToHex();
// assert
Assert.IsNull(hex1);
Assert.IsNull(hex2);
}
[TestMethod]
public void ShouldReturnHexString()
{
// arrange
byte[] bytes = [0xaf, 0xfe];
// act
string hex = bytes.BytesToHex();
// assert
Assert.IsNotNull(hex);
Assert.AreEqual("affe", hex);
}
[TestMethod]
public void ShouldReturnHexStringWithDelimiter()
{
// arrange
byte[] bytes = [0xde, 0xad, 0xbe, 0xef];
// act
string hex = bytes.BytesToHex("_");
// assert
Assert.IsNotNull(hex);
Assert.AreEqual("de_ad_be_ef", hex);
}
[TestMethod]
public void ShouldEncodeStringToHex()
{
// arrange
string plain = "Hello";
// act
string hex1 = plain.HexEncode();
string hex2 = plain.HexEncode(Encoding.Default);
// assert
Assert.AreEqual("48656c6c6f", hex1);
Assert.AreEqual("48656c6c6f", hex2);
}
[TestMethod]
public void ShouldDecodeStringFromHex()
{
// arrange
string hex = "48656c6c6f";
// act
string plain1 = hex.HexDecode();
string plain2 = hex.HexDecode(Encoding.Default);
// assert
Assert.AreEqual("Hello", plain1);
Assert.AreEqual("Hello", plain2);
}
[TestMethod]
public void ShouldEncodeStringToBase64()
{
// arrange
string plain = "Hello";
// act
string base641 = plain.Base64Encode();
string base642 = plain.Base64Encode(Encoding.Default);
// assert
Assert.AreEqual("SGVsbG8=", base641);
Assert.AreEqual("SGVsbG8=", base642);
}
[TestMethod]
public void ShouldDecodeStringFromBase64()
{
// arrange
string base64 = "SGVsbG8=";
// act
string plain1 = base64.Base64Decode();
string plain2 = base64.Base64Decode(Encoding.Default);
// assert
Assert.AreEqual("Hello", plain1);
Assert.AreEqual("Hello", plain2);
}
[TestMethod]
public void ShouldReplaceStart()
{
// arrange
string str = "Hello World!";
// act
string test1 = str.ReplaceStart("Hello", "Bye");
string test2 = str.ReplaceStart("World!", "Mars?");
// assert
Assert.AreNotEqual(str, test1);
Assert.AreEqual("Bye World!", test1);
Assert.AreEqual(str, test2);
Assert.AreNotEqual("Hello Mars?", test2);
}
[TestMethod]
public void ShouldReplaceEnd()
{
// arrange
string str = "Hello World!";
// act
string test1 = str.ReplaceEnd("Hello", "Bye");
string test2 = str.ReplaceEnd("World!", "Mars?");
// assert
Assert.AreEqual(str, test1);
Assert.AreNotEqual("Bye World!", test1);
Assert.AreNotEqual(str, test2);
Assert.AreEqual("Hello Mars?", test2);
}
[TestMethod]
public void ShouldParseDecimal()
{
// arrange
decimal number = 1234.56m;
string stringNumberEn = "1234.56";
string stringNumberDe = "1234,56";
// act
decimal numberEn = stringNumberEn.ParseDecimal();
decimal numberDe = stringNumberDe.ParseDecimal();
// assert
Assert.AreEqual(number, numberEn);
Assert.AreEqual(number, numberDe);
}
[TestMethod]
public void ShouldParseDecimalWithThousandsSeparator()
{
// arrange
decimal number = 1234.56m;
string stringNumberEn = "1,234.56";
string stringNumberDe = "1.234,56";
// act
decimal numberEn = stringNumberEn.ParseDecimal();
decimal numberDe = stringNumberDe.ParseDecimal();
// assert
Assert.AreEqual(number, numberEn);
Assert.AreEqual(number, numberDe);
}
[TestMethod]
public void ShouldValidateEmailAddressWithoutRecordCheck()
{
// arrange
string validEmailWithoutTag = "test@gmail.com";
string validEmailWithTag = "test+tag@not.exists";
string invalidEmailWithoutTag = "<Test Account> test@gmail.com";
string invalidEmailWithTag = "<Test Account> test+tag@not.exists";
string nullStr = null;
// act
bool validWithoutTag = validEmailWithoutTag.IsValidEmailAddress(checkForDnsRecord: false);
bool validWithTag = validEmailWithTag.IsValidEmailAddress(checkForDnsRecord: false);
bool invalidWithoutTag = !invalidEmailWithoutTag.IsValidEmailAddress(checkForDnsRecord: false);
bool invalidWithTag = !invalidEmailWithTag.IsValidEmailAddress(checkForDnsRecord: false);
bool nullTest = nullStr.IsValidEmailAddress(checkForDnsRecord: false);
// assert
Assert.IsTrue(validWithoutTag);
Assert.IsTrue(validWithTag);
Assert.IsTrue(invalidWithoutTag);
Assert.IsTrue(invalidWithTag);
Assert.IsFalse(nullTest);
}
[TestMethod]
public void ShouldValidateEmailAddressWithRecordCheck()
{
// arrange
string validEmail = "test@gmail.com";
string invalidEmail = "test@not.exists";
// act
bool valid = validEmail.IsValidEmailAddress(checkForDnsRecord: true);
bool invalid = !invalidEmail.IsValidEmailAddress(checkForDnsRecord: true);
// assert
Assert.IsTrue(valid);
Assert.IsTrue(invalid);
}
[TestMethod]
public void ShouldValidateEmailAddressWithRecordCheckDefinedNameservers()
{
// arrange
string validEmail = "test@gmail.com";
string invalidEmail = "test@not.exists";
var nameserver = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 53);
// act
bool valid = validEmail.IsValidEmailAddress(new[] { nameserver });
bool invalid = !invalidEmail.IsValidEmailAddress(new[] { nameserver });
// assert
Assert.IsTrue(valid);
Assert.IsTrue(invalid);
}
[TestMethod]
public void ShouldWorkWithNullOrEmptyString()
{
// arrange
string nullStr = null;
string emptyStr = "";
// act
string hexEncodeNull = nullStr.HexEncode();
string hexEncodeEmpty = emptyStr.HexEncode();
string hexDecodeNull = nullStr.HexDecode();
string hexDecodeEmpty = emptyStr.HexDecode();
// assert
Assert.IsNull(hexEncodeNull);
Assert.AreEqual("", hexEncodeEmpty);
Assert.IsNull(hexDecodeNull);
Assert.AreEqual("", hexDecodeEmpty);
}
[TestMethod]
public void ShouldAddCustomLineTermination()
{
// arrange
string value = "abc";
var sb = new StringBuilder();
// act
sb.AppendLine(value, "\r");
sb.AppendLine(value, "\r");
// assert
Assert.AreEqual($"{value}\r{value}\r", sb.ToString());
Assert.IsFalse(sb.ToString().Contains('\n'));
}
}
}