Skip to content
Merged
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
105 changes: 51 additions & 54 deletions .github/workflows/gtc-assertion-ci-cd-nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,50 @@ on:
branches:
- main
paths:
- .github/workflows/gtc-assertion-nuget.yml
- .github/workflows/gtc-assertion-ci-cd-nuget.yml
- src/**
push:
branches:
- main
- main
paths:
- .github/workflows/gtc-assertion-nuget.yml
- src/**
- .github/workflows/gtc-assertion-ci-cd-nuget.yml
- src/**
workflow_dispatch:
inputs:
environment:
description: 'Environment to run'
description: "Environment to run"
required: true
default: 'development'
default: "development"
mode:
description: 'Running mode'
description: "Running mode"
required: true

permissions:
id-token: write
contents: read
security-events: write

env:
SCRIPTS_PATH: "./.github/scripts"
SRC_PATH: "./src"
PROJECT_PATH: "Goodtocode.Assertion"
PROJECT_FILE: "Goodtocode.Assertion.csproj"
SRC_SLN: "Goodtocode.Assertion.sln"
TEST_PATH: "Goodtocode.Assertion.Tests"
TEST_PROJECT: "Goodtocode.Assertion.Tests.csproj"

jobs:
ci:
name: 'CI Build, Test, Code QL, Publish'
name: "CI Build, Test, Code QL, Publish"
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
environment: development
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || github.event_name == 'push'
environment: development
strategy:
matrix:
DOTNET_VERSION: ['9.x']

env:
RUNTIME_ENV: 'Development'
SRC_PATH: './src'
SRC_SLN: 'Goodtocode.Assertion.sln'
PROJECT_PATH: 'Goodtocode.Assertion'
PROJECT_FILE: 'Goodtocode.Assertion.csproj'
TEST_PATH: 'Goodtocode.Assertion.Tests'
TEST_PROJECT: 'Goodtocode.Assertion.Tests.csproj'
SCRIPTS_PATH: './.github/scripts'
DOTNET_VERSION: ["9.x"]

env:
RUNTIME_ENV: "Development"

steps:
- name: checkout
Expand All @@ -58,24 +61,24 @@ jobs:

- name: Set-Version.ps1
run: |
$version = ${{ env.SCRIPTS_PATH }}/ci/Set-Version.ps1 -Path ${{ env.SRC_PATH }} -VersionToReplace 1.0.0
$version = ${{ env.SCRIPTS_PATH }}/ci/Set-Version.ps1 -Path ${{ env.SRC_PATH }} -VersionToReplace 1.0.0 -Major 1 -Minor 1
echo $version
echo "VERSION=$version" >> $GITHUB_ENV
shell: pwsh

- name: pipeline configuration secrets
- name: pipeline environment configuration
run: |
echo "ASPNETCORE_ENVIRONMENT=${{ env.RUNTIME_ENV }}" >> $GITHUB_ENV
shell: pwsh

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: csharp

- name: Build
run: |
dotnet build ${{ env.SRC_PATH }}/${{ env.SRC_SLN }} --configuration Release
dotnet build ${{ env.SRC_PATH }}/${{ env.SRC_SLN }} --configuration Release
shell: pwsh

- name: Test
Expand All @@ -84,51 +87,45 @@ jobs:
dotnet test ${{ env.SRC_PATH }}/${{ env.TEST_PATH }}/${{ env.TEST_PROJECT }} --logger "trx;LogFileName=test_results.trx" --results-directory TestResults-${{ matrix.DOTNET_VERSION }} --verbosity normal
shell: pwsh


- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: dotnet-results-${{ matrix.DOTNET_VERSION }}
path: TestResults-${{ matrix.DOTNET_VERSION }}
if: ${{ always() }}

- name: Perform CodeQL Analysis
- name: Pack NuGet package
run: |
dotnet pack ${{ env.SRC_PATH }}/${{ env.PROJECT_PATH }}/${{ env.PROJECT_FILE }} --configuration Release --no-build --output nupkg_output
shell: pwsh

- name: Upload NuGet package artifact
uses: actions/upload-artifact@v4
with:
name: nuget-package
path: nupkg_output/*.nupkg

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4

cd:
name: 'CD Pack and Publish to NuGet.org'
name: "CD Pack and Publish to NuGet.org"
runs-on: ubuntu-latest
needs: ci
if: |
github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment: production
strategy:
matrix:
DOTNET_VERSION: ['9.x']
DOTNET_VERSION: ["9.x"]
env:
SRC_PATH: './src'
PROJECT_PATH: 'Goodtocode.Assertion'
PROJECT_FILE: 'Goodtocode.Assertion.csproj'
NUGET_OUTPUT: 'nupkg_output'
NUGET_OUTPUT: "nupkg_output"
steps:
- name: checkout
uses: actions/checkout@v3

- name: Setup .NET ${{ matrix.DOTNET_VERSION }}
uses: actions/setup-dotnet@v4
- name: Download NuGet package artifact
uses: actions/download-artifact@v4
with:
dotnet-version: ${{ matrix.DOTNET_VERSION }}

- name: Restore dependencies
run: dotnet restore ${{ env.SRC_PATH }}/${{ env.PROJECT_PATH }}/${{ env.PROJECT_FILE }}

- name: Build
run: dotnet build ${{ env.SRC_PATH }}/${{ env.PROJECT_PATH }}/${{ env.PROJECT_FILE }} --configuration Release --no-restore

- name: Test
run: dotnet test ${{ env.SRC_PATH }}/${{ env.PROJECT_PATH }}/${{ env.PROJECT_FILE }} --configuration Release --no-build --verbosity normal

- name: Pack NuGet package
run: dotnet pack ${{ env.SRC_PATH }}/${{ env.PROJECT_PATH }}/${{ env.PROJECT_FILE }} --configuration Release --no-build --output ${{ env.NUGET_OUTPUT }}
name: nuget-package
path: nupkg_output

- name: Publish to NuGet.org
run: dotnet nuget push ${{ env.NUGET_OUTPUT }}/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
run: dotnet nuget push nupkg_output/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
122 changes: 120 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,120 @@
# aspect-assertion
Fluent Assertion aspect oriented library

# Goodtocode.Assertion

Fluent Assertion aspect-oriented library for .NET Standard 2.0+

[![CI/CD Build, Test and Deploy](https://github.com/goodtocode/aspect-assertion/actions/workflows/gtc-assertion-ci-cd-nuget.yml/badge.svg)](https://github.com/goodtocode/aspect-assertion/actions/workflows/gtc-assertion-ci-cd-nuget.yml)

Goodtocode.Assertion is a .NET library providing fluent assertion and validation utilities for C# projects. It enables developers to write expressive, readable, and maintainable assertions for business logic, unit tests, and runtime validation. The library is designed for extensibility and can be integrated into any .NET Standard 2.0+ project.

## Features
- Fluent assertion syntax for clear, readable code
- Customizable assertion rules and exception handling
- Assertion scopes for grouping related checks
- Lightweight, dependency-free, and compatible with .NET Standard 2.0+
- Designed for use in both production code and unit tests

## Quick-Start Steps
1. Clone this repository
```
git clone https://github.com/goodtocode/aspect-assertion.git
```
2. Install .NET SDK (latest recommended)
```
winget install Microsoft.DotNet.SDK --silent
```
3. Build the solution
```
cd src
dotnet build Goodtocode.Assertion.sln
```
4. Run tests
```
cd Goodtocode.Assertion.Tests
dotnet test
```

## Install Prerequisites
- [.NET SDK (latest)](https://dotnet.microsoft.com/en-us/download)
- Visual Studio (latest) or VS Code

## Top Use Case Examples

### 1. Basic Assertion Scope
```csharp
using Goodtocode.Assertion;

int value = 5;
AssertionScope.Begin()
.Assert(() => value > 0, "Value must be positive.")
.Assert(() => value < 10, "Value must be less than 10.")
.End();
```

### 2. Validating Object Properties
```csharp
using Goodtocode.Assertion;

var user = new User { Name = "Alice", Age = 30 };
AssertionScope.Begin()
.Assert(() => !string.IsNullOrWhiteSpace(user.Name), "Name is required.")
.Assert(() => user.Age >= 18, "User must be an adult.")
.End();
```

### 3. Custom Validator for Business Logic
```csharp
using Goodtocode.Assertion;

public class GetMyUsersPaginatedQueryValidator : Validator<GetMyUsersPaginatedQuery>
{
public GetMyUsersPaginatedQueryValidator()
{
RuleFor(v => v.StartDate).NotEmpty()
.When(v => v.EndDate != null)
.LessThanOrEqualTo(v => v.EndDate);

RuleFor(v => v.EndDate)
.NotEmpty()
.When(v => v.StartDate != null)
.GreaterThanOrEqualTo(v => v.StartDate);

RuleFor(x => x.PageNumber).NotEqual(0);
RuleFor(x => x.PageSize).NotEqual(0);
}
}
```

### 4. Unit Test Assertion
```csharp
using Goodtocode.Assertion;
using Xunit;

[Fact]
public void Should_Throw_When_Assertion_Fails()
{
Assert.Throws<AssertionFailedException>(() =>
AssertionScope.Begin()
.Assert(() => false, "This should fail.")
.End());
}
```

## Technologies
- [C# .NET](https://docs.microsoft.com/en-us/dotnet/csharp/)
- [.NET Standard](https://docs.microsoft.com/en-us/dotnet/standard/)

## Version History


| Version | Date | Release Notes |
|---------|-------------|--------------------------------------------------|
| 1.0.0 | 2026-Jan-19 | Initial release |

## License

This project is licensed with the [MIT license](https://mit-license.org/).

## Contact
- [GitHub Repo](https://github.com/goodtocode/aspect-assertion)
- [@goodtocode](https://twitter.com/goodtocode)
2 changes: 2 additions & 0 deletions src/Goodtocode.Assertion/Goodtocode.Assertion.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright © 2026 Goodtocode</Copyright>
<PackageIcon>Goodtocode-icon.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<None Include="Goodtocode-icon.png" Pack="true" PackagePath="" />
<None Include="..\..\README.md" Pack="true" PackagePath="" />
</ItemGroup>

</Project>
Loading