< Summary

Information
Class: AsiBackbone.Testing.Contracts.AsiBackboneConstraintContract<T>
Assembly: AsiBackbone.Testing
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Testing/Contracts/AsiBackboneConstraintContract.cs
Line coverage
100%
Covered lines: 29
Uncovered lines: 0
Coverable lines: 29
Total lines: 94
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
VerifyConstraintReturnsSafeResultAsync()100%66100%
VerifyConstraintResult(...)100%1616100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Testing/Contracts/AsiBackboneConstraintContract.cs

#LineLine coverage
 1using AsiBackbone.Core.Constraints;
 2using AsiBackbone.Core.Results;
 3
 4namespace AsiBackbone.Testing.Contracts;
 5
 6/// <summary>
 7/// Reusable contract fixture for <see cref="IAsiBackboneConstraint{TContext}" /> implementations.
 8/// </summary>
 9/// <typeparam name="TContext">The framework-neutral evaluation context type.</typeparam>
 10public abstract class AsiBackboneConstraintContract<TContext>
 11{
 12    /// <summary>
 13    /// Creates the constraint implementation under test.
 14    /// </summary>
 15    /// <returns>The constraint implementation to validate.</returns>
 16    protected abstract IAsiBackboneConstraint<TContext> CreateConstraint();
 17
 18    /// <summary>
 19    /// Creates the context supplied to the constraint implementation under test.
 20    /// </summary>
 21    /// <returns>The evaluation context to validate with.</returns>
 22    protected abstract TContext CreateEvaluationContext();
 23
 24    /// <summary>
 25    /// Verifies that the constraint returns a safe, non-null result shape.
 26    /// </summary>
 27    /// <param name="cancellationToken">A token that can cancel the contract validation.</param>
 28    /// <returns>The verified constraint result.</returns>
 29    public async ValueTask<ConstraintEvaluationResult> VerifyConstraintReturnsSafeResultAsync(CancellationToken cancella
 30    {
 2831        IAsiBackboneConstraint<TContext> constraint = CreateConstraint()
 2832            ?? throw new AsiBackboneContractViolationException("Constraint contract must provide a constraint instance."
 2633        TContext context = CreateEvaluationContext()
 2634            ?? throw new AsiBackboneContractViolationException("Constraint contract must provide an evaluation context."
 35
 2436        if (string.IsNullOrWhiteSpace(constraint.Name))
 37        {
 238            throw new AsiBackboneContractViolationException("Constraint implementations must expose a stable, non-empty 
 39        }
 40
 41        try
 42        {
 2243            ConstraintEvaluationResult result = await constraint.EvaluateAsync(context, cancellationToken).ConfigureAwai
 1644            return VerifyConstraintResult(result, constraint.Name);
 45        }
 246        catch (OperationCanceledException)
 47        {
 248            throw;
 49        }
 1450        catch (AsiBackboneContractViolationException)
 51        {
 1452            throw;
 53        }
 254        catch (Exception exception)
 55        {
 256            throw new AsiBackboneContractViolationException(
 257                $"Constraint '{constraint.Name}' must not throw during normal contract validation; return Deny, Warning,
 258                exception);
 59        }
 460    }
 61
 62    private static ConstraintEvaluationResult VerifyConstraintResult(ConstraintEvaluationResult? result, string constrai
 63    {
 1664        if (result is null)
 65        {
 266            throw new AsiBackboneContractViolationException($"Constraint '{constraintName}' must return a result and mus
 67        }
 68
 1469        if (result.IsDenied || result.IsWarning)
 70        {
 1271            if (result.Reasons.Count == 0)
 72            {
 473                throw new AsiBackboneContractViolationException($"Constraint '{constraintName}' denied or warned without
 74            }
 75
 2076            for (int index = 0; index < result.Reasons.Count; index++)
 77            {
 878                OperationReason reason = result.Reasons[index] ?? throw new AsiBackboneContractViolationException($"Cons
 79
 680                if (string.IsNullOrWhiteSpace(reason.Code))
 81                {
 282                    throw new AsiBackboneContractViolationException($"Constraint '{constraintName}' returned an empty re
 83                }
 84
 485                if (string.IsNullOrWhiteSpace(reason.Message))
 86                {
 287                    throw new AsiBackboneContractViolationException($"Constraint '{constraintName}' returned an empty re
 88                }
 89            }
 90        }
 91
 492        return result;
 93    }
 94}