Skip to content
Closed
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
24 changes: 24 additions & 0 deletions .github/stryker/Stryker.Config.FluentAssertions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"stryker-config": {
"project-info": {
"name": "github.com/Testably/Testably.Abstractions",
"module": "Testably.Abstractions.FluentAssertions"
},
"test-projects": [
"./Testably.Abstractions.FluentAssertions.Tests/Testably.Abstractions.FluentAssertions.Tests.csproj"
],
"project": "Testably.Abstractions.FluentAssertions.csproj",
"target-framework": "net7.0",
"since": {
"ignore-changes-in": [
"**/.github/**/*.*"
]
},
"reporters": [
"html",
"progress",
"cleartext"
],
"mutation-level": "Advanced"
}
}
8 changes: 8 additions & 0 deletions .github/workflows/ci-stryker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ jobs:
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.Compression.json -v "${GITHUB_HEAD_REF}" -r "html" -r "cleartext" --since:main
mv ./StrykerOutput/**/reports/*.html ./StrykerOutput/Reports/Testably.Abstractions.Compression-report.html
- name: Analyze Testably.Abstractions.FluentAssertions
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
shell: bash
run: |
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.FluentAssertions.json -v "${GITHUB_HEAD_REF}" -r "html" -r "cleartext" --since:main
mv ./StrykerOutput/**/reports/*.html ./StrykerOutput/Reports/Testably.Abstractions.FluentAssertions-report.html
- name: Analyze Testably.Abstractions.Testing
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ jobs:
run: |
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.Compression.json -v "${GITHUB_REF#refs/heads/}" -r "Dashboard" -r "cleartext"
- name: Analyze Testably.Abstractions.FluentAssertions
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
shell: bash
run: |
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.FluentAssertions.json -v "${GITHUB_REF#refs/heads/}" -r "Dashboard" -r "cleartext"

deploy:
name: Deploy
Expand Down Expand Up @@ -298,7 +305,7 @@ jobs:
version="${GITHUB_REF#refs/heads/release/}"
# Add changelog badge to README.md
sed -i -e "2 a\[!\[Changelog](https:\/\/img\.shields\.io\/badge\/Changelog-${version}-blue)](https:\/\/github\.com\/Testably\/Testably\.Abstractions\/releases\/tag\/${version})" "./README.md"
for f in "README.md" "Docs/AccessControl.md" "Docs/Compression.md" "Docs/Interface.md" "Docs/Testing.md"
for f in "README.md" "Docs/AccessControl.md" "Docs/Compression.md" "Docs/FluentAssertions.md" "Docs/Interface.md" "Docs/Testing.md"
do
echo "Processing $f" # always double quote "$f" filename
# do something on $f
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/stryker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ jobs:
run: |
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.Compression.json -v "${GITHUB_REF#refs/heads/}" -r "Dashboard" -r "cleartext"
- name: Analyze Testably.Abstractions.FluentAssertions
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
shell: bash
run: |
cd Tests
../../tools/dotnet-stryker -f ../.github/stryker/Stryker.Config.FluentAssertions.json -v "${GITHUB_REF#refs/heads/}" -r "Dashboard" -r "cleartext"
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="System.Threading.Channels" Version="7.0.0" />
<PackageVersion Include="TestableIO.System.IO.Abstractions" Version="19.2.51" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="19.2.51" />
<PackageVersion Include="System.IO.Compression" Version="4.3.0" />
<PackageVersion Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
</ItemGroup>
Expand Down
8 changes: 8 additions & 0 deletions Docs/FluentAssertions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
![Testably.Abstractions](https://raw.githubusercontent.com/Testably/Testably.Abstractions/main/Docs/Images/social-preview.png)
[![Nuget](https://img.shields.io/nuget/v/Testably.Abstractions.Compression)](https://www.nuget.org/packages/Testably.Abstractions.Compression)
[![Build](https://github.com/Testably/Testably.Abstractions/actions/workflows/build.yml/badge.svg)](https://github.com/Testably/Testably.Abstractions/actions/workflows/build.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Testably_Testably.Abstractions&branch=main&metric=alert_status)](https://sonarcloud.io/summary/overall?id=Testably_Testably.Abstractions&branch=main)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Testably_Testably.Abstractions&branch=main&metric=coverage)](https://sonarcloud.io/summary/overall?id=Testably_Testably.Abstractions&branch=main)
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2FTestably%2FTestably.Abstractions%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/Testably/Testably.Abstractions/main)

FluentAssertions extensions for [Testably.Abstractions](../README.md).
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace Testably.Abstractions.FluentAssertions;

/// <summary>
/// Assertions on <see cref="IDirectoryInfo" />.
/// </summary>
public class DirectoryInfoAssertions :
ReferenceTypeAssertions<IDirectoryInfo, DirectoryInfoAssertions>
{
/// <inheritdoc cref="ReferenceTypeAssertions{TSubject,TAssertions}.Identifier" />
protected override string Identifier => "directory";

internal DirectoryInfoAssertions(IDirectoryInfo instance)
: base(instance)
{
}

/// <summary>
/// Asserts that the current directory has at least one file which matches the <paramref name="searchPattern" />.
/// </summary>
public AndConstraint<DirectoryInfoAssertions> HasFile(
string searchPattern = "*", string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(!string.IsNullOrEmpty(searchPattern))
.FailWith(
"You can't assert a file exist in the directory if you don't pass a proper name")
.Then
.Given(() => Subject.GetFiles(searchPattern))
.ForCondition(fileInfos => fileInfos.Length > 0)
.FailWith(
"Expected {context:directory} '{1}' to contain at least one file matching {0}{reason}, but none was found.",
_ => searchPattern, _ => Subject.Name);

return new AndConstraint<DirectoryInfoAssertions>(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace Testably.Abstractions.FluentAssertions;

/// <summary>
/// Assertions on <see cref="IFileInfo" />.
/// </summary>
public class FileInfoAssertions :
ReferenceTypeAssertions<IFileInfo, FileInfoAssertions>
{
/// <inheritdoc cref="ReferenceTypeAssertions{TSubject,TAssertions}.Identifier" />
protected override string Identifier => "file";

internal FileInfoAssertions(IFileInfo instance)
: base(instance)
{
}

/// <summary>
/// Asserts that the current file is not read-only.
/// </summary>
public AndConstraint<FileInfoAssertions> IsNotReadOnly(
string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => Subject)
.ForCondition(fileInfo => !fileInfo.IsReadOnly)
.FailWith(
"Expected {context:file} '{0}' not to be read-only {reason}, but it was.",
_ => Subject.Name);

return new AndConstraint<FileInfoAssertions>(this);
}

/// <summary>
/// Asserts that the current file is read-only.
/// </summary>
public AndConstraint<FileInfoAssertions> IsReadOnly(
string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => Subject)
.ForCondition(fileInfo => fileInfo.IsReadOnly)
.FailWith(
"Expected {context:file} '{0}' to be read-only {reason}, but it was not.",
_ => Subject.Name);

return new AndConstraint<FileInfoAssertions>(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace Testably.Abstractions.FluentAssertions;

/// <summary>
/// Assertions on <see cref="IFileSystem" />.
/// </summary>
public class FileSystemAssertions :
ReferenceTypeAssertions<IFileSystem, FileSystemAssertions>
{
/// <inheritdoc cref="ReferenceTypeAssertions{TSubject,TAssertions}.Identifier" />
protected override string Identifier => "filesystem";

internal FileSystemAssertions(IFileSystem instance)
: base(instance)
{
}

/// <summary>
/// Asserts that a directory at <paramref name="path" /> exists in the file system.
/// </summary>
public AndWhichConstraint<FileSystemAssertions, DirectoryInfoAssertions> HaveDirectory(
string path, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(!string.IsNullOrEmpty(path))
.FailWith("You can't assert a directory exist if you don't pass a proper name")
.Then
.Given(() => Subject.DirectoryInfo.New(path))
.ForCondition(directoryInfo => directoryInfo.Exists)
.FailWith(
"Expected {context:filesystem} to contain directory {0}{reason}, but it did not exist.",
_ => path, directoryInfo => directoryInfo.Name);

return new AndWhichConstraint<FileSystemAssertions, DirectoryInfoAssertions>(this,
new DirectoryInfoAssertions(Subject.DirectoryInfo.New(path)));
}

/// <summary>
/// Asserts that a file at <paramref name="path" /> exists in the file system.
/// </summary>
public AndWhichConstraint<FileSystemAssertions, FileInfoAssertions> HaveFile(
string path, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(!string.IsNullOrEmpty(path))
.FailWith("You can't assert a file exist if you don't pass a proper name")
.Then
.Given(() => Subject.FileInfo.New(path))
.ForCondition(fileInfo => fileInfo.Exists)
.FailWith(
"Expected {context:filesystem} to contain file {0}{reason}, but it did not exist.",
_ => path, fileInfo => fileInfo.Name);

return new AndWhichConstraint<FileSystemAssertions, FileInfoAssertions>(this,
new FileInfoAssertions(Subject.FileInfo.New(path)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Testably.Abstractions.FluentAssertions;

/// <summary>
/// Assertion extensions on <see cref="IFileSystem" />.
/// </summary>
public static class FileSystemExtensions
{
/// <summary>
/// Returns a <see cref="FileSystemAssertions" /> object that can be used to
/// assert the current <see cref="IFileSystem" />.
/// </summary>
public static FileSystemAssertions Should(this IFileSystem instance)
{
return new FileSystemAssertions(instance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>Testably.Abstractions.FluentAssertions</RootNamespace>
<Description>FluentAssertions extension methods for `Testably.Abstractions`.</Description>
<PackageReadmeFile>Docs/FluentAssertions.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<None Include="$(SolutionDir)Docs/FluentAssertions.md"
Pack="true" PackagePath="/Docs/"
Link="Docs\FluentAssertions.md" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Testably.Abstractions.Interface\Testably.Abstractions.Interface.csproj" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions Source/Testably.Abstractions.FluentAssertions/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global using FluentAssertions;
global using FluentAssertions.Execution;
global using FluentAssertions.Primitives;
global using System.IO.Abstractions;
17 changes: 16 additions & 1 deletion Testably.Abstractions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_", "_", "{94F99274-3518-45
.gitignore = .gitignore
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Packages.props = Directory.Packages.props
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
Feature.Flags.props = Feature.Flags.props
LICENSE = LICENSE
nuget.config = nuget.config
Expand Down Expand Up @@ -46,6 +46,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stryker", "stryker", "{4D8D
ProjectSection(SolutionItems) = preProject
.github\stryker\Stryker.Config.AccessControl.json = .github\stryker\Stryker.Config.AccessControl.json
.github\stryker\Stryker.Config.Compression.json = .github\stryker\Stryker.Config.Compression.json
.github\stryker\Stryker.Config.FluentAssertions.json = .github\stryker\Stryker.Config.FluentAssertions.json
.github\stryker\Stryker.Config.json = .github\stryker\Stryker.Config.json
.github\stryker\Stryker.Config.Testing.json = .github\stryker\Stryker.Config.Testing.json
EndProjectSection
Expand Down Expand Up @@ -74,6 +75,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{4D70CF83-2
ProjectSection(SolutionItems) = preProject
Docs\AccessControl.md = Docs\AccessControl.md
Docs\Compression.md = Docs\Compression.md
Docs\FluentAssertions.md = Docs\FluentAssertions.md
Docs\Interface.md = Docs\Interface.md
Docs\Testing.md = Docs\Testing.md
EndProjectSection
Expand All @@ -84,6 +86,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testably.Abstractions.TestH
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testably.Abstractions.Tests.SourceGenerator", "Tests\Helpers\Testably.Abstractions.Tests.SourceGenerator\Testably.Abstractions.Tests.SourceGenerator.csproj", "{97A2540A-7FB4-4D8B-B003-3F8CAA9CED87}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testably.Abstractions.FluentAssertions", "Source\Testably.Abstractions.FluentAssertions\Testably.Abstractions.FluentAssertions.csproj", "{BC318ADF-0A23-4D0F-8FBE-4E73F839450A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testably.Abstractions.FluentAssertions.Tests", "Tests\Testably.Abstractions.FluentAssertions.Tests\Testably.Abstractions.FluentAssertions.Tests.csproj", "{67F7AF4E-B807-4627-9452-E5BC50E32B90}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -138,6 +144,14 @@ Global
{97A2540A-7FB4-4D8B-B003-3F8CAA9CED87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97A2540A-7FB4-4D8B-B003-3F8CAA9CED87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97A2540A-7FB4-4D8B-B003-3F8CAA9CED87}.Release|Any CPU.Build.0 = Release|Any CPU
{BC318ADF-0A23-4D0F-8FBE-4E73F839450A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC318ADF-0A23-4D0F-8FBE-4E73F839450A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC318ADF-0A23-4D0F-8FBE-4E73F839450A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC318ADF-0A23-4D0F-8FBE-4E73F839450A}.Release|Any CPU.Build.0 = Release|Any CPU
{67F7AF4E-B807-4627-9452-E5BC50E32B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67F7AF4E-B807-4627-9452-E5BC50E32B90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67F7AF4E-B807-4627-9452-E5BC50E32B90}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67F7AF4E-B807-4627-9452-E5BC50E32B90}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -157,6 +171,7 @@ Global
{B6C45D8A-A545-402E-A6B0-47BC7D9BBCF5} = {61F335A6-9CE0-4040-A34F-E70B1A55077D}
{425BA8BA-7795-4749-BFC1-6FA853EBC6B7} = {B6C45D8A-A545-402E-A6B0-47BC7D9BBCF5}
{97A2540A-7FB4-4D8B-B003-3F8CAA9CED87} = {B6C45D8A-A545-402E-A6B0-47BC7D9BBCF5}
{67F7AF4E-B807-4627-9452-E5BC50E32B90} = {61F335A6-9CE0-4040-A34F-E70B1A55077D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EC4D8481-B9FD-41B5-832A-369210993DF4}
Expand Down
Loading