Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9a57c06
Add source generator for assertion methods and related tests
thomhurst Oct 12, 2025
c230bf6
Refactor assertion method generator to use core assertion classes and…
thomhurst Oct 12, 2025
91647e6
Add custom expectation message support to assertion attributes and ge…
thomhurst Oct 12, 2025
5c55681
Refactor assertions to use source-generated methods
thomhurst Oct 12, 2025
b244e9d
Migrate assertions to source-generated methods and remove legacy code
thomhurst Oct 12, 2025
241ca90
Refactor assertion infrastructure: update CheckAsync methods for asyn…
thomhurst Oct 12, 2025
0e3937d
Implement source-generated assertion extensions for CultureInfo, Enco…
thomhurst Oct 12, 2025
ea841cc
Add source-generated assertion extensions for Assembly and DateTime t…
thomhurst Oct 12, 2025
125ffd6
Implement source-generated assertion extensions for CancellationToken…
thomhurst Oct 12, 2025
456b7b2
Implement source-generated assertion extensions for Assembly and Canc…
thomhurst Oct 12, 2025
5779fba
Add source-generated assertion extensions for Guid, Stream, Task, Thr…
thomhurst Oct 12, 2025
7a17e68
Refactor source-generated assertion extensions for various types to u…
thomhurst Oct 12, 2025
270f6e9
Implement source-generated assertion extensions for CultureInfo, Date…
thomhurst Oct 12, 2025
5241c87
Add source-generated assertion extensions for DateTimeOffset, IPAddre…
thomhurst Oct 12, 2025
3a9f74d
Add source-generated assertion extensions for Array, Index, Range, an…
thomhurst Oct 12, 2025
349c2ad
Add source-generated assertion extensions for DateOnly, DirectoryInfo…
thomhurst Oct 12, 2025
f7488c2
Add source-generated assertion extensions for FileInfo, DirectoryInfo…
thomhurst Oct 12, 2025
06d4aaf
Refactor assertion extension classes to be partial and update project…
thomhurst Oct 12, 2025
f27edee
Add assertion tests for Guid, Lazy, StringBuilder, Task, and TimeSpan
thomhurst Oct 12, 2025
3efb326
Add EditorBrowsable attribute to assertion extension methods for bett…
thomhurst Oct 12, 2025
69507d2
Add EditorBrowsable attribute to source-generated assertion methods a…
thomhurst Oct 12, 2025
cceced9
Add assertion tests for Boolean, Char, DateTime, DateTimeOffset, and …
thomhurst Oct 12, 2025
0fb3319
Add assertion extensions for collection membership checks and update …
thomhurst Oct 12, 2025
6381ecb
Add comprehensive assertion tests for assembly, cancellation token, I…
thomhurst Oct 12, 2025
3e0f0eb
Add comprehensive assertion tests for various types and functionalities
thomhurst Oct 12, 2025
08ef10f
Add missing using directives for TUnit.Assertions.Extensions in vario…
thomhurst Oct 12, 2025
5c4547a
Add assertion generator tests for various types and conditions
thomhurst Oct 12, 2025
6af4911
Refactor assertion generator test classes to remove specific generato…
thomhurst Oct 12, 2025
5a8209c
Rename assertion classes and update method signatures to include type…
thomhurst Oct 12, 2025
4a4adae
Merge branch 'main' into feature/enhance-assertion-source-gen
thomhurst Oct 13, 2025
9621915
Add diagnostic messages to assertion extension generator tests
thomhurst Oct 13, 2025
5987f0a
Refactor assertion generator tests and remove diagnostic source gener…
thomhurst Oct 13, 2025
b11ffd4
Update assertion generator tests to expect zero generated files
thomhurst Oct 13, 2025
5d65398
Enhance assertion messages by adding ExpectationMessage attributes fo…
thomhurst Oct 13, 2025
d10d8f6
Update MethodAssertionGenerator to always generate extension methods …
thomhurst Oct 13, 2025
31b82a6
Refactor assertion namespaces and enhance task assertions
thomhurst Oct 13, 2025
27618ef
Refactor AsyncDelegateAssertion and TaskAssertion to avoid awaiting t…
thomhurst Oct 13, 2025
de89714
Refactor assertion tests to improve clarity and reliability by addres…
thomhurst Oct 13, 2025
8848571
Remove CleanGenerated target from SourceGenerationDebug.props to stre…
thomhurst Oct 13, 2025
3b068f6
Add RunOn attribute for Windows to relevant file and directory tests
thomhurst Oct 13, 2025
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
Prev Previous commit
Next Next commit
Add source-generated assertion extensions for FileInfo, DirectoryInfo…
…, Array, DateOnly, TimeOnly, Index, Range, TimeZoneInfo, and WeakReference types; implement various assertions for each type.
  • Loading branch information
thomhurst committed Oct 12, 2025
commit f7488c283db0d69a21d58bbc02acf819103c74e8
62 changes: 62 additions & 0 deletions TUnit.TestProject/ArrayAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using TUnit.Assertions.Extensions;

namespace TUnit.TestProject;

public class ArrayAssertionTests
{
[Test]
public async Task Test_Array_IsEmpty()
{
var array = Array.Empty<int>();
await Assert.That(array).IsEmpty();
}

[Test]
public async Task Test_Array_IsNotEmpty()
{
var array = new[] { 1, 2, 3 };
await Assert.That(array).IsNotEmpty();
}

[Test]
public async Task Test_Array_IsSingleElement()
{
var array = new[] { 42 };
await Assert.That(array).IsSingleElement();
}

[Test]
public async Task Test_Array_IsNotSingleElement_Multiple()
{
var array = new[] { 1, 2, 3 };
await Assert.That(array).IsNotSingleElement();
}

[Test]
public async Task Test_Array_IsNotSingleElement_Empty()
{
var array = Array.Empty<string>();
await Assert.That(array).IsNotSingleElement();
}

[Test]
public async Task Test_Array_IsEmpty_String()
{
var array = Array.Empty<string>();
await Assert.That(array).IsEmpty();
}

[Test]
public async Task Test_Array_IsNotEmpty_String()
{
var array = new[] { "hello", "world" };
await Assert.That(array).IsNotEmpty();
}

[Test]
public async Task Test_Array_IsSingleElement_String()
{
var array = new[] { "single" };
await Assert.That(array).IsSingleElement();
}
}
86 changes: 86 additions & 0 deletions TUnit.TestProject/DateOnlyAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#if NET6_0_OR_GREATER
using TUnit.Assertions.Extensions;

namespace TUnit.TestProject;

public class DateOnlyAssertionTests
{
[Test]
public async Task Test_DateOnly_IsToday()
{
var today = DateOnly.FromDateTime(DateTime.Today);
await Assert.That(today).IsToday();
}

[Test]
public async Task Test_DateOnly_IsNotToday()
{
var yesterday = DateOnly.FromDateTime(DateTime.Today.AddDays(-1));
await Assert.That(yesterday).IsNotToday();
}

[Test]
public async Task Test_DateOnly_IsLeapYear()
{
var leapYearDate = new DateOnly(2024, 2, 29);
await Assert.That(leapYearDate).IsLeapYear();
}

[Test]
public async Task Test_DateOnly_IsNotLeapYear()
{
var nonLeapYearDate = new DateOnly(2023, 3, 15);
await Assert.That(nonLeapYearDate).IsNotLeapYear();
}

[Test]
public async Task Test_DateOnly_IsOnWeekend()
{
// Find next Saturday
var today = DateTime.Today;
var daysUntilSaturday = ((int)DayOfWeek.Saturday - (int)today.DayOfWeek + 7) % 7;
if (daysUntilSaturday == 0) daysUntilSaturday = 7; // If today is Saturday, get next Saturday
var saturday = DateOnly.FromDateTime(today.AddDays(daysUntilSaturday));
await Assert.That(saturday).IsOnWeekend();
}

[Test]
public async Task Test_DateOnly_IsOnWeekday()
{
// Find next Monday
var today = DateTime.Today;
var daysUntilMonday = ((int)DayOfWeek.Monday - (int)today.DayOfWeek + 7) % 7;
if (daysUntilMonday == 0) daysUntilMonday = 7; // If today is Monday, get next Monday
var monday = DateOnly.FromDateTime(today.AddDays(daysUntilMonday));
await Assert.That(monday).IsOnWeekday();
}

[Test]
public async Task Test_DateOnly_IsInFuture()
{
var future = DateOnly.FromDateTime(DateTime.Today.AddDays(1));
await Assert.That(future).IsInFuture();
}

[Test]
public async Task Test_DateOnly_IsInPast()
{
var past = DateOnly.FromDateTime(DateTime.Today.AddDays(-1));
await Assert.That(past).IsInPast();
}

[Test]
public async Task Test_DateOnly_IsFirstDayOfMonth()
{
var firstDay = new DateOnly(2024, 1, 1);
await Assert.That(firstDay).IsFirstDayOfMonth();
}

[Test]
public async Task Test_DateOnly_IsLastDayOfMonth()
{
var lastDay = new DateOnly(2024, 2, 29); // Leap year
await Assert.That(lastDay).IsLastDayOfMonth();
}
}
#endif
109 changes: 109 additions & 0 deletions TUnit.TestProject/ExceptionAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using TUnit.Assertions.Extensions;

namespace TUnit.TestProject;

public class ExceptionAssertionTests
{
[Test]
public async Task Test_Exception_HasInnerException()
{
var innerException = new InvalidOperationException("Inner");
var exception = new Exception("Outer", innerException);
await Assert.That(exception).HasInnerException();
}

[Test]
public async Task Test_Exception_HasNoInnerException()
{
var exception = new Exception("No inner");
await Assert.That(exception).HasNoInnerException();
}

[Test]
public async Task Test_Exception_HasStackTrace()
{
Exception? exception = null;
try
{
throw new InvalidOperationException("Test exception");
}
catch (Exception ex)
{
exception = ex;
}

await Assert.That(exception!).HasStackTrace();
}

[Test]
public async Task Test_Exception_HasNoData()
{
var exception = new Exception("No data");
await Assert.That(exception).HasNoData();
}

[Test]
public async Task Test_Exception_HasHelpLink()
{
var exception = new Exception("With help link")
{
HelpLink = "https://example.com/help"
};
await Assert.That(exception).HasHelpLink();
}

[Test]
public async Task Test_Exception_HasNoHelpLink()
{
var exception = new Exception("No help link");
await Assert.That(exception).HasNoHelpLink();
}

[Test]
public async Task Test_Exception_HasSource()
{
var exception = new Exception("With source")
{
Source = "TestAssembly"
};
await Assert.That(exception).HasSource();
}

[Test]
public async Task Test_Exception_HasNoSource()
{
var exception = new Exception("No source")
{
Source = null
};
await Assert.That(exception).HasNoSource();
}

[Test]
public async Task Test_Exception_HasTargetSite()
{
Exception? exception = null;
try
{
ThrowException();
}
catch (Exception ex)
{
exception = ex;
}

await Assert.That(exception!).HasTargetSite();
}

[Test]
public async Task Test_Exception_HasNoTargetSite()
{
var exception = new Exception("No target site");
await Assert.That(exception).HasNoTargetSite();
}

private static void ThrowException()
{
throw new InvalidOperationException("Test");
}
}
91 changes: 91 additions & 0 deletions TUnit.TestProject/FileSystemAssertionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,95 @@ public async Task Test_FileInfo_IsNotExecutable()
var file = new FileInfo(_testFile);
await Assert.That(file).IsNotExecutable();
}

[Test]
public async Task Test_FileInfo_HasExtension()
{
var file = new FileInfo(_testFile);
await Assert.That(file).HasExtension();
}

[Test]
public async Task Test_FileInfo_HasNoExtension()
{
var fileWithoutExtension = Path.Combine(_testDirectory, "noext");
File.WriteAllText(fileWithoutExtension, "content");
var file = new FileInfo(fileWithoutExtension);
await Assert.That(file).HasNoExtension();
}

[Test]
public async Task Test_FileInfo_IsEmpty()
{
var emptyFile = Path.Combine(_testDirectory, "empty.txt");
File.WriteAllText(emptyFile, string.Empty);
var file = new FileInfo(emptyFile);
await Assert.That(file).IsEmpty();
}

[Test]
public async Task Test_FileInfo_IsArchived()
{
var file = new FileInfo(_testFile);
file.Attributes |= FileAttributes.Archive;
await Assert.That(file).IsArchived();
}

[Test]
public async Task Test_FileInfo_IsSystemFile()
{
var file = new FileInfo(_testFile);
file.Attributes |= FileAttributes.System;
file.Refresh();
await Assert.That(file).IsSystemFile();
}

[Test]
public async Task Test_DirectoryInfo_IsEmpty()
{
var emptyDir = Path.Combine(_testDirectory, "empty");
Directory.CreateDirectory(emptyDir);
var directory = new DirectoryInfo(emptyDir);
await Assert.That(directory).IsEmpty();
}

[Test]
public async Task Test_DirectoryInfo_IsNotRoot()
{
var directory = new DirectoryInfo(_testDirectory);
await Assert.That(directory).IsNotRoot();
}

[Test]
public async Task Test_DirectoryInfo_IsRoot()
{
var root = new DirectoryInfo(Path.GetPathRoot(_testDirectory)!);
await Assert.That(root).IsRoot();
}

[Test]
public async Task Test_DirectoryInfo_IsNotHidden()
{
var directory = new DirectoryInfo(_testDirectory);
await Assert.That(directory).IsNotHidden();
}

[Test]
public async Task Test_DirectoryInfo_IsHidden()
{
var hiddenDir = Path.Combine(_testDirectory, "hidden");
var directory = Directory.CreateDirectory(hiddenDir);
directory.Attributes |= FileAttributes.Hidden;
await Assert.That(directory).IsHidden();
}

[Test]
public async Task Test_DirectoryInfo_IsSystemDirectory()
{
var sysDir = Path.Combine(_testDirectory, "system");
var directory = Directory.CreateDirectory(sysDir);
directory.Attributes |= FileAttributes.System;
directory.Refresh();
await Assert.That(directory).IsSystemDirectory();
}
}
36 changes: 36 additions & 0 deletions TUnit.TestProject/IndexAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if NET6_0_OR_GREATER
using TUnit.Assertions.Extensions;

namespace TUnit.TestProject;

public class IndexAssertionTests
{
[Test]
public async Task Test_Index_IsFromEnd()
{
Index index = ^1; // Last element
await Assert.That(index).IsFromEnd();
}

[Test]
public async Task Test_Index_IsFromEnd_Explicit()
{
var index = Index.FromEnd(5);
await Assert.That(index).IsFromEnd();
}

[Test]
public async Task Test_Index_IsNotFromEnd()
{
Index index = 0; // First element
await Assert.That(index).IsNotFromEnd();
}

[Test]
public async Task Test_Index_IsNotFromEnd_Explicit()
{
var index = Index.FromStart(10);
await Assert.That(index).IsNotFromEnd();
}
}
#endif
Loading