tests(calendar): Add calendar render tests (#3)

- updates calendar to support overriding the current day when rendering
- supports current culture when rendering
- renames Calendar to CalendarGenerator
This commit is contained in:
Scott 2026-08-05 06:15:53 +00:00
commit 3547e32b6e
29 changed files with 542 additions and 19 deletions

View file

@ -1,10 +1,9 @@
using System.Globalization;
using System.IO.MemoryMappedFiles;
using System.Text;
namespace ModuleCore.Calendar;
public sealed class Calendar
public sealed class CalendarGenerator
{
public const string DefaultMarkedOffSymbol = "x";
public const DayOfWeek DefaultStartOfWeek = DayOfWeek.Monday;
@ -30,7 +29,7 @@ public sealed class Calendar
private readonly string _rolloverDaySymbol = "";
public Calendar(string? markedDaySymbol = null, DayOfWeek? startOfWeek = null)
public CalendarGenerator(string? markedDaySymbol = null, DayOfWeek? startOfWeek = null)
{
_markedOffSymbol = markedDaySymbol ?? DefaultMarkedOffSymbol;
_startOfWeek = startOfWeek ?? DefaultStartOfWeek;
@ -38,10 +37,7 @@ public sealed class Calendar
// Generate localised day of week lookup table
_daysOfWeekLookup = new List<string>(7);
_dayWidth = _markedOffSymbol.Length;
// TODO: make this passed in from configuration, and if its invalid default it to
// CultureInfo.CurrentCulture
// TODO: test if its possible to determine if a culture string is invalid and what happens
_cultureInfo = new CultureInfo("en-AU");
_cultureInfo = CultureInfo.CurrentCulture;
for (var i = 0; i < 7; i++)
{
var localisedDayAbbreviation = _cultureInfo.DateTimeFormat.GetAbbreviatedDayName((DayOfWeek)i);
@ -68,13 +64,19 @@ public sealed class Calendar
_dayWidth += 2;
}
public string RenderCalendar(DateTime month)
/// <summary>
/// Renders the configured calendar for the given datetime
/// </summary>
/// <param name="month"></param>
/// <param name="todayOverride">Defaults to <see cref="DateTime.Now"/>, used to display elapsed days</param>
/// <returns></returns>
public string Render(DateTime month, DateTime? todayOverride = null)
{
var sb = new StringBuilder();
// Generate the header for the month/days of week
GenerateHeader(sb, month);
var calendarForMonth = GenerateCalendarForMonth(month, _markedOffSymbol, _startOfWeek, _rolloverDaySymbol);
var calendarForMonth = GenerateCalendarForMonth(month, _markedOffSymbol, _startOfWeek, _rolloverDaySymbol, todayOverride ?? DateTime.Now);
for (var i = 0; i < calendarForMonth.WeeksInMonth; i++)
{
@ -168,9 +170,10 @@ public sealed class Calendar
}
}
private MonthCalendar GenerateCalendarForMonth(DateTime month, string markedOffSymbol, DayOfWeek calendarStartOfWeek, string rolloverDaySymbol)
private MonthCalendar GenerateCalendarForMonth(DateTime month, string markedOffSymbol, DayOfWeek calendarStartOfWeek, string rolloverDaySymbol, DateTime today)
{
// TODO: use startOfWeek to offset the start of the calendar later
// TODO: I think I meant the calendar name header?
// Reset the month to the start
var startOfMonth = new DateTime(month.Year, month.Month, 1);
@ -218,7 +221,6 @@ public sealed class Calendar
cal.Add(rolloverDaySymbol);
}
var today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
// If we're in the same year and month, any days already elapsed should be marked off,
// otherwise we display all days.
// If the DateTime we're rendering is in the past we render all days as marked off