• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

AndreuCodina / CrossValidation / 5040327467

pending completion
5040327467

Pull #26

github

GitHub
Merge 362a64fcc into 3204cbf5a
Pull Request #26: Real async

360 of 392 branches covered (91.84%)

Branch coverage included in aggregate %.

607 of 607 new or added lines in 12 files covered. (100.0%)

1086 of 1163 relevant lines covered (93.38%)

192.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.92
/src/CrossValidation/ModelValidator.cs
1
using System.Diagnostics.Contracts;
2
using System.Net;
3
using System.Runtime.CompilerServices;
4
using CrossValidation.Errors;
5
using CrossValidation.Exceptions;
6
using CrossValidation.Validations;
7

8
namespace CrossValidation;
9

10
public abstract record ModelValidator<TModel>
11
{
12
    private ValidationMode _validationMode = ValidationMode.StopOnFirstError;
13
    internal IValidation<TModel>? ScopeCreatorValidation { private get; set; }
692✔
14

15
    public ValidationMode ValidationMode
16
    {
17
        get => _validationMode;
×
18
        set
19
        {
20
            if (ScopeCreatorValidation!.Context!.IsChildContext)
51✔
21
            {
22
                throw new InvalidOperationException("Cannot change the validation mode in a child model validator");
1✔
23
            }
24

25
            _validationMode = value;
50✔
26
            ScopeCreatorValidation.Context!.ValidationMode = _validationMode;
50✔
27
        }
50✔
28
    }
29

30
    [Pure]
31
    public IValidation<TField> Field<TField>(
32
        TField field,
33
        ICrossError? error = null,
34
        string? message = null,
35
        string? code = null,
36
        string? details = null,
37
        HttpStatusCode? httpStatusCode = null,
38
        string? fieldDisplayName = null,
39
        [CallerArgumentExpression(nameof(field))] string fieldName = default!)
40
    {
41
        var fieldPath = fieldName.Contains('.')
82!
42
            ? fieldName.Substring(fieldName.IndexOf('.') + 1)
82✔
43
            : fieldName;
82✔
44
        ScopeCreatorValidation!.FieldPath = fieldPath;
82✔
45
        var getFieldValue = () => field;
255✔
46
        var scopeValidation = ScopeCreatorValidation.CreateScopeValidation(
82✔
47
            getFieldValue: getFieldValue,
82✔
48
            index: null,
82✔
49
            fieldPathToOverride: null);
82✔
50
        scopeValidation.HasFailed = false;
82✔
51
        scopeValidation.GeneralizeError = false;
82✔
52
        return scopeValidation;
82✔
53
    }
54

55
    [Pure]
56
    public IValidation<TField> That<TField>(
57
        TField field,
58
        ICrossError? error = null,
59
        string? message = null,
60
        string? code = null,
61
        string? details = null,
62
        HttpStatusCode? httpStatusCode = null,
63
        string? fieldDisplayName = null)
64
    {
65
        var getFieldValue = () => field;
72✔
66
        var scopeValidation = ScopeCreatorValidation!.CreateScopeValidation(
25✔
67
            getFieldValue: getFieldValue,
25✔
68
            index: null,
25✔
69
            fieldPathToOverride: null);
25✔
70
        scopeValidation.HasFailed = false;
25✔
71
        scopeValidation.GeneralizeError = true;
25✔
72
        return scopeValidation;
25✔
73
    }
74

75
    public abstract void CreateValidations(TModel model);
76

77
    public void Validate(TModel model)
78
    {
79
        InternalValidateAsync(model, useAsync: false)
60✔
80
            .GetAwaiter()
60✔
81
            .GetResult();
60✔
82
    }
2✔
83
    
84
    public async Task ValidateAsync(TModel model)
85
    {
86
        await InternalValidateAsync(model, useAsync: true);
17✔
87
    }
×
88

89
    private async ValueTask InternalValidateAsync(TModel model, bool useAsync)
90
    {
91
        CrossValidation.Validate.ModelNullability(model);
77✔
92
        ScopeCreatorValidation = CrossValidation.Validate
77✔
93
                .That(model);
77✔
94
        ScopeCreatorValidation.IsScopeCreator = true;
77✔
95
        ScopeCreatorValidation.SetScope(() => CreateValidations(model), ScopeType.ModelValidator);
154✔
96

97
        if (useAsync)
45✔
98
        {
99
            await ScopeCreatorValidation.ValidateAsync();
17✔
100
        }
101
        
102
        if (ScopeCreatorValidation.Context!.ErrorsCollected.Any())
41✔
103
        {
104
            if (ScopeCreatorValidation.Context.ErrorsCollected.Count == 1)
39✔
105
            {
106
                throw ScopeCreatorValidation.Context.ErrorsCollected[0].ToException();
24✔
107
            }
108
            else
109
            {
110
                foreach (var errorCollected in ScopeCreatorValidation.Context.ErrorsCollected)
106✔
111
                {
112
                    errorCollected.AddPlaceholderValues();
38✔
113
                }
114
                throw new ValidationListException(ScopeCreatorValidation.Context.ErrorsCollected);
15✔
115
            }
116
        }
117
    }
2✔
118
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc