1
0

Moved all UnitTests to a single project. Implemented parts of AspNetCore UnitTests.

This commit is contained in:
2022-07-17 12:21:05 +02:00
parent 73038bbe5a
commit a26d6a0036
46 changed files with 2411 additions and 105 deletions

View File

@@ -0,0 +1,74 @@
using System.Security.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class CryptographyHelperExtensionsTests
{
[TestMethod]
public void ShouldReturnMd5Hash()
{
// arrange
string str = "Hello World!";
byte[] bytes = new byte[] { 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 = new byte[] { 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 = new byte[] { 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 = new byte[] { 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,355 @@
using System;
using UnitTests.Common.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class DateTimeExtensionsTests
{
[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 intervalLocal = interval.GetAlignedIntervalLocal();
// assert
Assert.AreEqual(DateTime.UtcNow.TimeOfDay.RoundToSecond(), (interval - intervalUtc).RoundToSecond());
Assert.AreEqual(DateTime.Now.TimeOfDay.RoundToSecond(), (interval - intervalLocal).RoundToSecond());
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,121 @@
using System;
using System.Linq;
using UnitTests.Common.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class EnumExtensionsTests
{
[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,75 @@
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class ExceptionExtensionsTests
{
[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 Exception("Inner Exception 1."),
new Exception("Inner Exception 2. See the inner exception for details.", new Exception("Inner Exception of Exception 2.")),
new Exception("Inner Exception 3."),
new Exception("Inner Exception 4."),
new Exception("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,341 @@
using System;
using System.Collections;
using UnitTests.Common.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class JsonExtensionsTests
{
[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"":""UnitTests.Common.Utils.JsonTestClass, UnitTests"",""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"":""UnitTests.Common.Utils.JsonTestSubClass, UnitTests"",""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 = new[] { "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,221 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class ReaderWriterLockSlimExtensionsTests
{
[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 */ }
});
Task.WaitAll(awaitableTask);
// 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 */ }
});
Task.WaitAll(awaitableTask);
// 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 */ }
});
Task.WaitAll(awaitableTask);
// assert
Assert.IsTrue(isTimeout);
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class StreamExtensionsTests
{
[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,353 @@
using System;
using System.Linq;
using System.Net;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Extensions
{
[TestClass]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class StringExtensionsTests
{
[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 = Array.Empty<byte>();
// act
string hex1 = bytes1.BytesToHex();
string hex2 = bytes2.BytesToHex();
// assert
Assert.IsNull(hex1);
Assert.IsNull(hex2);
}
[TestMethod]
public void ShouldReturnHexString()
{
// arrange
byte[] bytes = new byte[] { 0xaf, 0xfe };
// act
string hex = bytes.BytesToHex();
// assert
Assert.IsNotNull(hex);
Assert.AreEqual("affe", hex);
}
[TestMethod]
public void ShouldReturnHexStringWithDelimiter()
{
// arrange
byte[] bytes = new byte[] { 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(checkRecordExists: false);
bool validWithTag = validEmailWithTag.IsValidEmailAddress(checkRecordExists: false);
bool invalidWithoutTag = !invalidEmailWithoutTag.IsValidEmailAddress(checkRecordExists: false);
bool invalidWithTag = !invalidEmailWithTag.IsValidEmailAddress(checkRecordExists: false);
bool nullTest = nullStr.IsValidEmailAddress(checkRecordExists: 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(checkRecordExists: true);
bool invalid = !invalidEmail.IsValidEmailAddress(checkRecordExists: 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'));
}
}
}