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

AndreuCodina / CrossValidation / 5039199915

pending completion
5039199915

Pull #26

github

GitHub
Merge 4f0503a9d into 3204cbf5a
Pull Request #26: Real async

359 of 390 branches covered (92.05%)

Branch coverage included in aggregate %.

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

1080 of 1136 relevant lines covered (95.07%)

202.55 hits per line

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

94.34
/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; }
663✔
14

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

25
            _validationMode = value;
49✔
26
            ScopeCreatorValidation.Context!.ValidationMode = _validationMode;
49✔
27
        }
49✔
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 fieldFullPath = fieldName.Contains('.')
78!
42
            ? fieldName.Substring(fieldName.IndexOf('.') + 1)
78✔
43
            : fieldName;
78✔
44
        ScopeCreatorValidation!.FieldFullPath = fieldFullPath;
78✔
45
        var getFieldValue = () => field;
244✔
46
        var scopeValidation = ScopeCreatorValidation.CreateScopeValidation(getFieldValue: getFieldValue, index: null);
78✔
47
        scopeValidation.HasFailed = false;
78✔
48
        scopeValidation.GeneralizeError = false;
78✔
49
        return scopeValidation;
78✔
50
    }
51

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

69
    public abstract void CreateValidations(TModel model);
70

71
    public void Validate(TModel model)
72
    {
73
        InternalValidateAsync(model, useAsync: false)
59✔
74
            .GetAwaiter()
59✔
75
            .GetResult();
59✔
76
    }
2✔
77
    
78
    public async Task ValidateAsync(TModel model)
79
    {
80
        await InternalValidateAsync(model, useAsync: true);
17✔
81
    }
×
82

83
    private async ValueTask InternalValidateAsync(TModel model, bool useAsync)
84
    {
85
        CrossValidation.Validate.ModelNullability(model);
76✔
86
        ScopeCreatorValidation = CrossValidation.Validate
76✔
87
                .That(model);
76✔
88
        ScopeCreatorValidation.IsScopeCreator = true;
76✔
89
        ScopeCreatorValidation.SetScope(() => CreateValidations(model), ScopeType.ModelValidator);
152✔
90

91
        if (useAsync)
44✔
92
        {
93
            await ScopeCreatorValidation.ValidateAsync();
17✔
94
        }
95
        
96
        if (ScopeCreatorValidation.Context!.ErrorsCollected.Any())
40✔
97
        {
98
            if (ScopeCreatorValidation.Context.ErrorsCollected.Count == 1)
38✔
99
            {
100
                throw ScopeCreatorValidation.Context.ErrorsCollected[0].ToException();
24✔
101
            }
102
            else
103
            {
104
                foreach (var errorCollected in ScopeCreatorValidation.Context.ErrorsCollected)
96✔
105
                {
106
                    errorCollected.AddPlaceholderValues();
34✔
107
                }
108
                throw new ValidationListException(ScopeCreatorValidation.Context.ErrorsCollected);
14✔
109
            }
110
        }
111
    }
2✔
112
}
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