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

@ -0,0 +1,48 @@
using ModuleCore.Calendar;
using ModuleTests.Calendar.TestData;
using System.Globalization;
namespace ModuleTests.Calendar;
public class BasicRenderTest
{
private static readonly VerifySettings Settings;
static BasicRenderTest()
{
Settings = new VerifySettings();
var testBaseDirectory = Path.Join(TestConstants.SnapshotFolderName, nameof(BasicRenderTest));
Settings.UseDirectory(testBaseDirectory);
Settings.DisableDiff();
}
[Theory]
[ClassData(typeof(CalendarTestDates))]
public Task BasicCalendarRender(DateTime month)
{
Settings.UseFileName($"{month:yyyy-MM-dd}");
var calendar = new CalendarGenerator();
// Render the calendar with the start of the month as the today date so no elapsed marks are shown
var renderedMonth = calendar.Render(month, new DateTime(month.Year, month.Month, 1));
return Verify(renderedMonth, Settings);
}
[Theory]
[ClassData(typeof(CultureCodeTestData))]
public Task CultureInfoCalendarRender(string cultureCode)
{
Settings.UseFileName($"{cultureCode}");
Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureCode);
var month = new DateTime(2026, 8, 1);
var calendar = new CalendarGenerator();
// Render the calendar with the start of the month as the today date so no elapsed marks are shown
var renderedMonth = calendar.Render(month, new DateTime(month.Year, month.Month, 1));
return Verify(renderedMonth, Settings);
}
}

View file

@ -0,0 +1,86 @@
using System.Text;
using ModuleCore.Calendar;
namespace ModuleTests.Calendar;
public class MarkedDayRenderTests
{
private static readonly VerifySettings Settings;
static MarkedDayRenderTests()
{
Settings = new VerifySettings();
var testBaseDirectory = Path.Join(TestConstants.SnapshotFolderName, nameof(MarkedDayRenderTests));
Settings.UseDirectory(testBaseDirectory);
Settings.DisableDiff();
}
[Fact]
public Task DefaultMarkedDayRender()
{
Settings.UseFileName(nameof(DefaultMarkedDayRender));
var date = new DateTime(2026, 8, 1);
var calendar = new CalendarGenerator();
var renderedMonth = calendar.Render(date, date.AddDays(15));
return Verify(renderedMonth, Settings);
}
[Fact]
public Task SimpleMarkedDayRender()
{
Settings.UseFileName(nameof(SimpleMarkedDayRender));
var date = new DateTime(2026, 8, 1);
var calendar = new CalendarGenerator("|");
var renderedMonth = calendar.Render(date, date.AddDays(15));
return Verify(renderedMonth, Settings);
}
[Fact]
public Task LongMarkedDayRender()
{
Settings.UseFileName(nameof(LongMarkedDayRender));
var date = new DateTime(2026, 8, 1);
var calendar = new CalendarGenerator("passed");
var renderedMonth = calendar.Render(date, date.AddDays(15));
return Verify(renderedMonth, Settings);
}
[Fact]
public Task EmojiMarkedDayRender()
{
Settings.UseFileName(nameof(EmojiMarkedDayRender));
var date = new DateTime(2026, 8, 1);
var calendar = new CalendarGenerator("🤫");
var sb = new StringBuilder();
sb.AppendLine("Emojis will display incorrectly in text but output correctly in terminals with UTF-8 encoding.")
.AppendLine(calendar.Render(date, date.AddDays(15)));
return Verify(sb, Settings);
}
[Fact]
public Task DoubleWideMarkedDayRender()
{
Settings.UseFileName(nameof(DoubleWideMarkedDayRender));
var date = new DateTime(2026, 8, 1);
// Using an asian-character to have a test covering the unfortunate reality of character rendering of
// characters that are visually 1 character in width, but render as double width or some other cursed form.
// Written language was a mistake but trying to render it on computers alongside a different one
// is arguably worse.
var calendar = new CalendarGenerator("火");
var sb = new StringBuilder();
sb.AppendLine("Double-wide characters will display incorrectly but still tested until rendering can be improved")
.AppendLine(calendar.Render(date, date.AddDays(15)));
return Verify(sb, Settings);
}
}

View file

@ -0,0 +1,35 @@
using System.Text;
using ModuleCore.Calendar;
namespace ModuleTests.Calendar;
public class StartDayOfWeekTests
{
private static readonly VerifySettings Settings;
static StartDayOfWeekTests()
{
Settings = new VerifySettings();
var testBaseDirectory = Path.Join(TestConstants.SnapshotFolderName, nameof(StartDayOfWeekTests));
Settings.UseDirectory(testBaseDirectory);
Settings.DisableDiff();
}
[Fact]
public Task StartOfDayRender()
{
Settings.UseFileName(nameof(StartOfDayRender));
var date = new DateTime(2026, 8, 1);
var sb = new StringBuilder();
foreach (var dayOfWeek in Enum.GetValues<DayOfWeek>())
{
var calendar = new CalendarGenerator(startOfWeek: dayOfWeek);
sb.AppendLine($"Start Day: {dayOfWeek}");
sb.AppendLine(calendar.Render(date, date));
}
return Verify(sb, Settings);
}
}

View file

@ -0,0 +1,14 @@
namespace ModuleTests.Calendar.TestData;
public class CalendarTestDates : TestDataEnumerator<DateTime>
{
public CalendarTestDates()
{
Data =
[
new DateTime(2026, 06, 01),
new DateTime(2026, 07, 01),
new DateTime(2026, 08, 01),
];
}
}

View file

@ -0,0 +1,19 @@
namespace ModuleTests.Calendar.TestData;
public class CultureCodeTestData : TestDataEnumerator<string>
{
public CultureCodeTestData()
{
Data =
[
"da-DK",
"en-AU",
"cs-CZ",
"es-PR",
"fr-LU",
"nl-NL",
// Will render unaligned due to the character encoding, here to catch if I fix this later
"te-IN"
];
}
}

View file

@ -0,0 +1,11 @@
┌─────────────────────────────────────────┐
│ June 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
│ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │
│ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │
│ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │
│ 29 │ 30 │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,11 @@
┌─────────────────────────────────────────┐
│ July 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ 1 │ 2 │ 3 │ 4 │ 5 │
│ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │
│ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │
│ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │
│ 27 │ 28 │ 29 │ 30 │ 31 │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,12 @@
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,12 @@
┌──────────────────────────────────┐
│ srpen 2026 │
├────┬────┬────┬────┬────┬────┬────┤
│ po │ út │ st │ čt │ pá │ so │ ne │
├────┼────┼────┼────┼────┼────┼────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘

View file

@ -0,0 +1,12 @@
┌─────────────────────────────────────────┐
│ august 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ man │ tir │ ons │ tor │ fre │ lør │ søn │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,12 @@
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,12 @@
┌────────────────────────────────────────────────┐
│ agosto 2026 │
├──────┬──────┬──────┬──────┬──────┬──────┬──────┤
│ lun. │ mar. │ mié. │ jue. │ vie. │ sáb. │ dom. │
├──────┼──────┼──────┼──────┼──────┼──────┼──────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┘

View file

@ -0,0 +1,12 @@
┌────────────────────────────────────────────────┐
│ août 2026 │
├──────┬──────┬──────┬──────┬──────┬──────┬──────┤
│ lun. │ mar. │ mer. │ jeu. │ ven. │ sam. │ dim. │
├──────┼──────┼──────┼──────┼──────┼──────┼──────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┘

View file

@ -0,0 +1,12 @@
┌──────────────────────────────────┐
│ augustus 2026 │
├────┬────┬────┬────┬────┬────┬────┤
│ ma │ di │ wo │ do │ vr │ za │ zo │
├────┼────┼────┼────┼────┼────┼────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘

View file

@ -0,0 +1,12 @@
┌───────────────────────────────────────────────────────┐
│ ఆగస్టు 2026 │
├───────┬───────┬───────┬───────┬───────┬───────┬───────┤
│ సోమ │ మంగళ │ బుధ │ గురు │ శుక్ర │ శని │ ఆది │
├───────┼───────┼───────┼───────┼───────┼───────┼───────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└───────┴───────┴───────┴───────┴───────┴───────┴───────┘

View file

@ -0,0 +1,12 @@
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ x │ x │
│ x │ x │ x │ x │ x │ x │ x │
│ x │ x │ x │ x │ x │ x │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,13 @@
Double-wide characters will display incorrectly but still tested until rendering can be improved
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 火 │ 火 │
│ 火 │ 火 │ 火 │ 火 │ 火 │ 火 │ 火 │
│ 火 │ 火 │ 火 │ 火 │ 火 │ 火 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,13 @@
Emojis will display incorrectly in text but output correctly in terminals with UTF-8 encoding.
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 🤫 │ 🤫 │
│ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 🤫 │
│ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 🤫 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,12 @@
┌──────────────────────────────────────────────────────────────┐
│ August 2026 │
├────────┬────────┬────────┬────────┬────────┬────────┬────────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│ │ │ │ │ │ passed │ passed │
│ passed │ passed │ passed │ passed │ passed │ passed │ passed │
│ passed │ passed │ passed │ passed │ passed │ passed │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└────────┴────────┴────────┴────────┴────────┴────────┴────────┘

View file

@ -0,0 +1,12 @@
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ | │ | │
│ | │ | │ | │ | │ | │ | │ | │
│ | │ | │ | │ | │ | │ | │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,86 @@
Start Day: Sunday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ │ 1 │
│ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
│ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │
│ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │
│ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │
│ 30 │ 31 │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Monday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ │ 1 │ 2 │
│ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
│ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
│ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
│ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
│ 31 │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Tuesday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │ Mon │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ 1 │ 2 │ 3 │
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Wednesday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Wed │ Thu │ Fri │ Sat │ Sun │ Mon │ Tue │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ 1 │ 2 │ 3 │ 4 │
│ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
│ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │
│ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │
│ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Thursday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Thu │ Fri │ Sat │ Sun │ Mon │ Tue │ Wed │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ 1 │ 2 │ 3 │ 4 │ 5 │
│ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │
│ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │
│ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │
│ 27 │ 28 │ 29 │ 30 │ 31 │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Friday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Fri │ Sat │ Sun │ Mon │ Tue │ Wed │ Thu │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
│ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │
│ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │
│ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │
│ 28 │ 29 │ 30 │ 31 │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Start Day: Saturday
┌─────────────────────────────────────────┐
│ August 2026 │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Sat │ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
│ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │
│ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │
│ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │
│ 29 │ 30 │ 31 │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

View file

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Using Include="Xunit"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Verify.XunitV3" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ModuleCore\ModuleCore.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
namespace ModuleTests;
public class TestConstants
{
public const string SnapshotFolderName = "Snapshots";
}

View file

@ -0,0 +1,15 @@
using System.Collections;
namespace ModuleTests;
public abstract class TestDataEnumerator<T> : IEnumerable<TheoryDataRow<T>>
{
protected IEnumerable<T> Data { get; init; } = [];
public IEnumerator<TheoryDataRow<T>> GetEnumerator()
{
return Data.Select(data => new TheoryDataRow<T>(data)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}