Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
<PackageVersion Include="Microsoft.Data.Services.Client" Version="5.8.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.8" />
Expand Down
60 changes: 60 additions & 0 deletions SharedCode.Core.Tests/Attributes/AttributeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
namespace SharedCode.Tests.Attributes;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedCode.Attributes;

using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Tests for the attribute classes.
/// </summary>
[TestClass]
[SuppressMessage("Maintainability", "CA1515:Consider making public types internal", Justification = "<Pending>")]
public class AttributeTests
{
[TestMethod]
public void StringValueAttribute_StoresValue()
{
var attr = new StringValueAttribute("my-value");
Assert.AreEqual("my-value", attr.Value);
}

[TestMethod]
public void StringValueAttribute_NullValue_ThrowsArgumentNullException()
{
_ = Assert.ThrowsExactly<ArgumentNullException>(() => new StringValueAttribute(null!));
}

[TestMethod]
public void DataFormatAttribute_StoresFormat()
{
var attr = new DataFormatAttribute("yyyy-MM-dd");
Assert.AreEqual("yyyy-MM-dd", attr.Format);
}

[TestMethod]
public void DataFormatAttribute_NullFormat_ThrowsArgumentNullException()
{
_ = Assert.ThrowsExactly<ArgumentNullException>(() => new DataFormatAttribute(null!));
}

[TestMethod]
public void DataWidthAttribute_StoresWidth()
{
var attr = new DataWidthAttribute(10);
Assert.AreEqual(10, attr.Width);
}

[TestMethod]
public void DataWidthAttribute_ZeroWidth_ThrowsArgumentException()
{
_ = Assert.ThrowsExactly<ArgumentException>(() => new DataWidthAttribute(0));
}

[TestMethod]
public void DataWidthAttribute_NegativeWidth_ThrowsArgumentException()
{
_ = Assert.ThrowsExactly<ArgumentException>(() => new DataWidthAttribute(-5));
}
}
67 changes: 67 additions & 0 deletions SharedCode.Core.Tests/BaseExceptionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace SharedCode.Tests;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using System.Collections;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Tests for the <see cref="BaseException"/> class.
/// </summary>
[TestClass]
[SuppressMessage("Maintainability", "CA1515:Consider making public types internal", Justification = "<Pending>")]
public class BaseExceptionTests
{
[TestMethod]
public void DefaultConstructor_CreatesException()
{
var ex = new BaseException();
Assert.IsNotNull(ex);
Assert.IsNull(ex.InnerException);
}

[TestMethod]
public void MessageConstructor_SetsMessage()
{
var ex = new BaseException("test message");
Assert.AreEqual("test message", ex.Message);
}

[TestMethod]
public void MessageAndInnerExceptionConstructor_SetsMessageAndInner()
{
var inner = new InvalidOperationException("inner error");
var ex = new BaseException("outer message", inner);
Assert.AreEqual("outer message", ex.Message);
Assert.AreSame(inner, ex.InnerException);
}

[TestMethod]
public void InnerExceptionAndDataConstructor_SetsMessageFromInnerAndData()
{
var inner = new InvalidOperationException("inner error");
var data = new Hashtable { { "key", "value" } };
var ex = new BaseException(inner, data);
Assert.AreEqual("inner error", ex.Message);
Assert.AreSame(inner, ex.InnerException);
Assert.IsTrue(ex.Data.Contains("key"));
}

[TestMethod]
public void MessageInnerExceptionAndDataConstructor_SetsAll()
{
var inner = new InvalidOperationException("inner");
var data = new Hashtable { { "errorCode", "42" } };
var ex = new BaseException("outer message", inner, data);
Assert.AreEqual("outer message", ex.Message);
Assert.AreSame(inner, ex.InnerException);
Assert.IsTrue(ex.Data.Contains("errorCode"));
}

[TestMethod]
public void BaseException_IsException()
{
var ex = new BaseException("test");
Assert.IsInstanceOfType<Exception>(ex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
namespace SharedCode.Tests.Calendar;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedCode.Calendar;

using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Tests for the <see cref="DateTimeOffsetExtensions"/> class in the Calendar namespace.
/// </summary>
[TestClass]
[SuppressMessage("Maintainability", "CA1515:Consider making public types internal", Justification = "<Pending>")]
public class DateTimeOffsetCalendarExtensionsTests
{
[TestMethod]
public void FirstDayOfMonth_ReturnsFirstDayOfTheMonth()
{
var date = new DateTimeOffset(2023, 5, 15, 10, 30, 0, TimeSpan.Zero);
var result = date.FirstDayOfMonth();
Assert.AreEqual(1, result.Day);
Assert.AreEqual(5, result.Month);
Assert.AreEqual(2023, result.Year);
}

[TestMethod]
public void LastDayOfMonth_ReturnsLastDayOfTheMonth()
{
var date = new DateTimeOffset(2023, 2, 15, 0, 0, 0, TimeSpan.Zero);
var result = date.LastDayOfMonth();
Assert.AreEqual(28, result.Day);
Assert.AreEqual(2, result.Month);
Assert.AreEqual(2023, result.Year);
}

[TestMethod]
public void LastDayOfMonth_LeapYear_Returns29()
{
var date = new DateTimeOffset(2024, 2, 1, 0, 0, 0, TimeSpan.Zero);
var result = date.LastDayOfMonth();
Assert.AreEqual(29, result.Day);
}

[TestMethod]
public void IsWeekend_SaturdayDate_ReturnsTrue()
{
var saturday = new DateTimeOffset(2023, 12, 9, 0, 0, 0, TimeSpan.Zero); // Saturday
Assert.IsTrue(saturday.IsWeekend());
}

[TestMethod]
public void IsWeekend_SundayDate_ReturnsTrue()
{
var sunday = new DateTimeOffset(2023, 12, 10, 0, 0, 0, TimeSpan.Zero); // Sunday
Assert.IsTrue(sunday.IsWeekend());
}

[TestMethod]
public void IsWeekend_MondayDate_ReturnsFalse()
{
var monday = new DateTimeOffset(2023, 12, 11, 0, 0, 0, TimeSpan.Zero); // Monday
Assert.IsFalse(monday.IsWeekend());
}

[TestMethod]
public void IsBetween_DateInRange_ReturnsTrue()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 12, 31, 0, 0, 0, TimeSpan.Zero);
var middle = new DateTimeOffset(2023, 6, 15, 0, 0, 0, TimeSpan.Zero);
Assert.IsTrue(middle.IsBetween(start, end));
}

[TestMethod]
public void IsBetween_DateOutOfRange_ReturnsFalse()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 6, 30, 0, 0, 0, TimeSpan.Zero);
var outside = new DateTimeOffset(2023, 7, 1, 0, 0, 0, TimeSpan.Zero);
Assert.IsFalse(outside.IsBetween(start, end));
}

[TestMethod]
public void IsBetween_WithCompareTime_DateInRange_ReturnsTrue()
{
var start = new DateTimeOffset(2023, 6, 1, 9, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 6, 1, 17, 0, 0, TimeSpan.Zero);
var middle = new DateTimeOffset(2023, 6, 1, 12, 0, 0, TimeSpan.Zero);
Assert.IsTrue(middle.IsBetween(start, end, compareTime: true));
}

[TestMethod]
public void Intersects_RangesOverlap_ReturnsTrue()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 6, 30, 0, 0, 0, TimeSpan.Zero);
var intersectStart = new DateTimeOffset(2023, 3, 1, 0, 0, 0, TimeSpan.Zero);
var intersectEnd = new DateTimeOffset(2023, 9, 30, 0, 0, 0, TimeSpan.Zero);
Assert.IsTrue(start.Intersects(end, intersectStart, intersectEnd));
}

[TestMethod]
public void Intersects_RangesDoNotOverlap_ReturnsFalse()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 3, 31, 0, 0, 0, TimeSpan.Zero);
var intersectStart = new DateTimeOffset(2023, 5, 1, 0, 0, 0, TimeSpan.Zero);
var intersectEnd = new DateTimeOffset(2023, 9, 30, 0, 0, 0, TimeSpan.Zero);
Assert.IsFalse(start.Intersects(end, intersectStart, intersectEnd));
}

[TestMethod]
public void GetDateRangeTo_ReturnsCorrectNumberOfDates()
{
var from = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var to = new DateTimeOffset(2023, 1, 5, 0, 0, 0, TimeSpan.Zero);
var range = from.GetDateRangeTo(to).ToList();
Assert.AreEqual(4, range.Count);
}

[TestMethod]
public void DateDiff_DayPart_ReturnsExpectedDays()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 1, 11, 0, 0, 0, TimeSpan.Zero);
Assert.AreEqual(10L, start.DateDiff("day", end));
Assert.AreEqual(10L, start.DateDiff("dd", end));
Assert.AreEqual(10L, start.DateDiff("d", end));
}

[TestMethod]
public void DateDiff_YearPart_ReturnsExpectedYears()
{
var start = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
Assert.AreEqual(3L, start.DateDiff("year", end));
Assert.AreEqual(3L, start.DateDiff("yy", end));
Assert.AreEqual(3L, start.DateDiff("yyyy", end));
}

[TestMethod]
public void DateDiff_MonthPart_ReturnsExpectedMonths()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 4, 1, 0, 0, 0, TimeSpan.Zero);
Assert.AreEqual(3L, start.DateDiff("month", end));
Assert.AreEqual(3L, start.DateDiff("mm", end));
}

[TestMethod]
public void DateDiff_HourPart_ReturnsExpectedHours()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 1, 1, 3, 0, 0, TimeSpan.Zero);
Assert.AreEqual(3L, start.DateDiff("hour", end));
Assert.AreEqual(3L, start.DateDiff("hh", end));
}

[TestMethod]
public void DateDiff_UnknownPart_ThrowsException()
{
var start = new DateTimeOffset(2023, 1, 1, 0, 0, 0, TimeSpan.Zero);
var end = new DateTimeOffset(2023, 1, 2, 0, 0, 0, TimeSpan.Zero);
_ = Assert.ThrowsExactly<Exception>(() => start.DateDiff("unknown", end));
}

[TestMethod]
public void ComputeTimeZoneVariance_UtcOffset_ReturnsZero()
{
var utcDate = new DateTimeOffset(2023, 6, 1, 12, 0, 0, TimeSpan.Zero);
Assert.AreEqual(0, utcDate.ComputeTimeZoneVariance());
}

[TestMethod]
public void ToUnixTimestamp_UnixEpoch_ReturnsZeroOrNearZero()
{
// Unix epoch: 1970-01-01 00:00:00 UTC (using local offset)
var localOffset = DateTimeOffset.UtcNow.Offset;
var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, localOffset);
Assert.AreEqual(0L, epoch.ToUnixTimestamp());
}

[TestMethod]
public void AddWorkdays_AddsPositiveWorkdays()
{
var monday = new DateTimeOffset(2023, 12, 11, 0, 0, 0, TimeSpan.Zero); // Monday
var result = monday.AddWorkdays(5);
Assert.AreEqual(DayOfWeek.Monday, result.DayOfWeek);
Assert.AreEqual(18, result.Day);
}
}
53 changes: 53 additions & 0 deletions SharedCode.Core.Tests/Calendar/DayOfWeekExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace SharedCode.Tests.Calendar;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedCode.Calendar;

using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Tests for the <see cref="SharedCode.Calendar.DayOfWeekExtensions"/> class.
/// </summary>
[TestClass]
[SuppressMessage("Maintainability", "CA1515:Consider making public types internal", Justification = "<Pending>")]
public class DayOfWeekExtensionsTests
{
[TestMethod]
[DataRow(DayOfWeek.Monday)]
[DataRow(DayOfWeek.Tuesday)]
[DataRow(DayOfWeek.Wednesday)]
[DataRow(DayOfWeek.Thursday)]
[DataRow(DayOfWeek.Friday)]
public void IsWeekday_WeekdayDays_ReturnsTrue(DayOfWeek day)
{
Assert.IsTrue(day.IsWeekday());
}

[TestMethod]
[DataRow(DayOfWeek.Saturday)]
[DataRow(DayOfWeek.Sunday)]
public void IsWeekday_WeekendDays_ReturnsFalse(DayOfWeek day)
{
Assert.IsFalse(day.IsWeekday());
}

[TestMethod]
[DataRow(DayOfWeek.Saturday)]
[DataRow(DayOfWeek.Sunday)]
public void IsWeekend_WeekendDays_ReturnsTrue(DayOfWeek day)
{
Assert.IsTrue(day.IsWeekend());
}

[TestMethod]
[DataRow(DayOfWeek.Monday)]
[DataRow(DayOfWeek.Tuesday)]
[DataRow(DayOfWeek.Wednesday)]
[DataRow(DayOfWeek.Thursday)]
[DataRow(DayOfWeek.Friday)]
public void IsWeekend_WeekdayDays_ReturnsFalse(DayOfWeek day)
{
Assert.IsFalse(day.IsWeekend());
}
}
Loading
Loading