Skip to content

Commit

Permalink
feat: add assertion for HasAttribute and DoesNotHaveAttribute for fil…
Browse files Browse the repository at this point in the history
…es (#33)

Add assertions for attributes on files.

Co-authored-by: Valentin Breuß <v.breuss@tig.at>
  • Loading branch information
vbreuss and vbtig authored Aug 21, 2023
1 parent 6a04680 commit f196f11
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 3 deletions.
51 changes: 48 additions & 3 deletions Source/Testably.Abstractions.FluentAssertions/FileAssertions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.IO;
using System.Linq;
using System.Text;

namespace Testably.Abstractions.FluentAssertions;
Expand All @@ -17,6 +18,50 @@ internal FileAssertions(IFileInfo? instance)
{
}

/// <summary>
/// Asserts that the current file does not have the given <paramref name="attribute" />.
/// </summary>
public AndConstraint<FileAssertions> DoesNotHaveAttribute(
FileAttributes attribute, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.WithDefaultIdentifier(Identifier)
.BecauseOf(because, becauseArgs)
.ForCondition(Subject != null)
.FailWith(
$"You can't assert that the file does not have attribute {attribute} if it is null")
.Then
.Given(() => Subject!)
.ForCondition(fileInfo => !fileInfo.Attributes.HasFlag(attribute))
.FailWith(
$"Expected {{context}} {{0}} not to have attribute {attribute}{{reason}}, but it did.",
fileInfo => fileInfo.Name);

return new AndConstraint<FileAssertions>(this);
}

/// <summary>
/// Asserts that the current file has the given <paramref name="attribute" />.
/// </summary>
public AndConstraint<FileAssertions> HasAttribute(
FileAttributes attribute, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.WithDefaultIdentifier(Identifier)
.BecauseOf(because, becauseArgs)
.ForCondition(Subject != null)
.FailWith(
$"You can't assert that the file has attribute {attribute} if it is null")
.Then
.Given(() => Subject!)
.ForCondition(fileInfo => fileInfo.Attributes.HasFlag(attribute))
.FailWith(
$"Expected {{context}} {{0}} to have attribute {attribute}{{reason}}, but it did not.",
fileInfo => fileInfo.Name);

return new AndConstraint<FileAssertions>(this);
}

/// <summary>
/// Asserts that the binary content of the current file is equivalent to the given <paramref name="bytes" />.
/// </summary>
Expand Down Expand Up @@ -99,7 +144,7 @@ public AndConstraint<FileAssertions> IsNotReadOnly(
.BecauseOf(because, becauseArgs)
.ForCondition(Subject != null)
.FailWith(
"You can't assert that the file is not read-only if the FileInfo is null")
"You can't assert that the file is not read-only if it is null")
.Then
.Given(() => Subject!)
.ForCondition(fileInfo => !fileInfo.IsReadOnly)
Expand All @@ -121,7 +166,7 @@ public AndConstraint<FileAssertions> IsReadOnly(
.BecauseOf(because, becauseArgs)
.ForCondition(Subject != null)
.FailWith(
"You can't assert that the file is read-only if the FileInfo is null")
"You can't assert that the file is read-only if it is null")
.Then
.Given(() => Subject!)
.ForCondition(fileInfo => fileInfo.IsReadOnly)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IO;
using System.Text;

namespace Testably.Abstractions.FluentAssertions;
Expand Down Expand Up @@ -26,6 +27,16 @@ public AndConstraint<FileInfoAssertions> BeReadOnly(
return new AndConstraint<FileInfoAssertions>(this);
}

/// <summary>
/// Asserts that the current file has the given <paramref name="attribute" />.
/// </summary>
public AndConstraint<FileInfoAssertions> HaveAttribute(
FileAttributes attribute, string because = "", params object[] becauseArgs)
{
new FileAssertions(Subject).HasAttribute(attribute, because, becauseArgs);
return new AndConstraint<FileInfoAssertions>(this);
}

/// <summary>
/// Asserts that the binary content of the current file is equivalent to the given <paramref name="bytes" />.
/// </summary>
Expand Down Expand Up @@ -66,4 +77,14 @@ public AndConstraint<FileInfoAssertions> NotBeReadOnly(
new FileAssertions(Subject).IsNotReadOnly(because, becauseArgs);
return new AndConstraint<FileInfoAssertions>(this);
}

/// <summary>
/// Asserts that the current file does not have the given <paramref name="attribute" />.
/// </summary>
public AndConstraint<FileInfoAssertions> NotHaveAttribute(
FileAttributes attribute, string because = "", params object[] becauseArgs)
{
new FileAssertions(Subject).DoesNotHaveAttribute(attribute, because, becauseArgs);
return new AndConstraint<FileInfoAssertions>(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using AutoFixture.Xunit2;
using FluentAssertions;
using System;
using System.IO;
using System.Linq;
using System.Text;
using Testably.Abstractions.Testing;
Expand All @@ -11,6 +12,79 @@ namespace Testably.Abstractions.FluentAssertions.Tests;

public class FileAssertionsTests
{
[Theory]
[AutoData]
public void DoesNotHaveAttribute_WithAttribute_ShouldThrow(
FileDescription fileDescription,
string because)
{
fileDescription.IsReadOnly = true;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
FileAssertions? sut = fileSystem.Should().HaveFile(fileDescription.Name).Which;

Exception? exception = Record.Exception(() =>
{
sut.DoesNotHaveAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should()
.Be(
$"Expected file \"{fileDescription.Name}\" not to have attribute {FileAttributes.ReadOnly} {because}, but it did.");
}

[Theory]
[AutoData]
public void DoesNotHaveAttribute_WithoutAttribute_ShouldNotThrow(
FileDescription fileDescription)
{
fileDescription.IsReadOnly = false;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
FileAssertions? sut = fileSystem.Should().HaveFile(fileDescription.Name).Which;

sut.DoesNotHaveAttribute(FileAttributes.ReadOnly);
}

[Theory]
[AutoData]
public void HasAttribute_WithAttribute_ShouldNotThrow(FileDescription fileDescription)
{
fileDescription.IsReadOnly = true;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
FileAssertions? sut = fileSystem.Should().HaveFile(fileDescription.Name).Which;

sut.HasAttribute(FileAttributes.ReadOnly);
}

[Theory]
[AutoData]
public void HasAttribute_WithoutAttribute_ShouldThrow(
FileDescription fileDescription,
string because)
{
fileDescription.IsReadOnly = false;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
FileAssertions? sut = fileSystem.Should().HaveFile(fileDescription.Name).Which;

Exception? exception = Record.Exception(() =>
{
sut.HasAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should()
.Be(
$"Expected file \"{fileDescription.Name}\" to have attribute {FileAttributes.ReadOnly} {because}, but it did not.");
}

[Theory]
[AutoData]
public void HasContent_Bytes_FullContent_ShouldNotThrow(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using AutoFixture.Xunit2;
using FluentAssertions;
using System;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -64,6 +65,58 @@ public void BeReadOnly_WithWritableFile_ShouldThrow(
$"Expected file \"{fileDescription.Name}\" to be read-only {because}, but it was not.");
}

[Theory]
[AutoData]
public void HaveAttribute_Null_ShouldThrow(string because)
{
IFileInfo? sut = null;

Exception? exception = Record.Exception(() =>
{
sut.Should().HaveAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should().Contain("null");
exception.Message.Should().NotContain(because);
}

[Theory]
[AutoData]
public void HaveAttribute_WithAttribute_ShouldNotThrow(FileDescription fileDescription)
{
fileDescription.IsReadOnly = true;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
IFileInfo sut = fileSystem.FileInfo.New(fileDescription.Name);

sut.Should().HaveAttribute(FileAttributes.ReadOnly);
}

[Theory]
[AutoData]
public void HaveAttribute_WithoutAttribute_ShouldThrow(
FileDescription fileDescription,
string because)
{
fileDescription.IsReadOnly = false;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
IFileInfo sut = fileSystem.FileInfo.New(fileDescription.Name);

Exception? exception = Record.Exception(() =>
{
sut.Should().HaveAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should()
.Be(
$"Expected file \"{fileDescription.Name}\" to have attribute {FileAttributes.ReadOnly} {because}, but it did not.");
}

[Theory]
[AutoData]
public void HaveContent_Bytes_FullContent_ShouldNotThrow(
Expand Down Expand Up @@ -320,4 +373,56 @@ public void NotBeReadOnly_WithWritableFile_ShouldNotThrow(FileDescription fileDe

sut.Should().NotBeReadOnly();
}

[Theory]
[AutoData]
public void NotHaveAttribute_Null_ShouldThrow(string because)
{
IFileInfo? sut = null;

Exception? exception = Record.Exception(() =>
{
sut.Should().NotHaveAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should().Contain("null");
exception.Message.Should().NotContain(because);
}

[Theory]
[AutoData]
public void NotHaveAttribute_WithAttribute_ShouldThrow(
FileDescription fileDescription,
string because)
{
fileDescription.IsReadOnly = true;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
IFileInfo sut = fileSystem.FileInfo.New(fileDescription.Name);

Exception? exception = Record.Exception(() =>
{
sut.Should().NotHaveAttribute(FileAttributes.ReadOnly, because);
});

exception.Should().NotBeNull();
exception!.Message.Should()
.Be(
$"Expected file \"{fileDescription.Name}\" not to have attribute {FileAttributes.ReadOnly} {because}, but it did.");
}

[Theory]
[AutoData]
public void NotHaveAttribute_WithoutAttribute_ShouldNotThrow(FileDescription fileDescription)
{
fileDescription.IsReadOnly = false;
MockFileSystem fileSystem = new();
fileSystem.Initialize()
.With(fileDescription);
IFileInfo sut = fileSystem.FileInfo.New(fileDescription.Name);

sut.Should().NotHaveAttribute(FileAttributes.ReadOnly);
}
}

0 comments on commit f196f11

Please sign in to comment.