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

AndreuCodina / CrossValidation / 5040353887

pending completion
5040353887

Pull #26

github

GitHub
Merge a4b3e61a6 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

97.78
/src/CrossValidation/Validations/ValidationExtensions.cs
1
using System.Diagnostics.CodeAnalysis;
2
using System.Numerics;
3
using CrossValidation.Validators;
4
using CrossValidation.Validators.LengthValidators;
5

6
namespace CrossValidation.Validations;
7

8
public static class ValidationExtensions
9
{
10
    public static IValidation<TField> NotNull<TField>(
11
        this IValidation<TField?> validation)
12
        where TField : class
13
    {
14

15
        return validation.SetValidator(() => new NotNullValidator<TField?>(validation.GetFieldValue()))
71✔
16
            .Transform(x => x!);
55✔
17
    }
18

19
    public static IValidation<TField> NotNull<TField>(
20
        this IValidation<TField?> validation)
21
        where TField : struct
22
    {
23
        return validation.SetValidator(() => new NotNullValidator<TField?>(validation.GetFieldValue()))
48✔
24
            .Transform(x => x!.Value);
28✔
25
    }
26

27
    public static IValidation<TField?> WhenNotNull<TField, TReturnedField>(
28
        this IValidation<TField?> validation,
29
        Func<IValidation<TField>, IValidation<TReturnedField>> action)
30
        where TField : struct
31
    {
32
        validation.Condition = () => validation.GetFieldValue() is not null;
59✔
33
        return validation.SetScope(() =>
32✔
34
        {
32✔
35
            validation.IsScopeCreator = true;
23✔
36
            var getFieldValue = () => validation.GetFieldValue()!.Value;
77✔
37
            var scopeValidation = CreateScopeValidation(
23✔
38
                validation: validation,
23✔
39
                getFieldValue: getFieldValue,
23✔
40
                index: validation.Index,
23✔
41
                fieldPathToOverride: null);
23✔
42
            action(scopeValidation);
23✔
43
        }, ScopeType.WhenNotNull);
52✔
44
    }
45

46
    public static IValidation<TField?> WhenNotNull<TField, TReturnedField>(
47
        this IValidation<TField?> validation,
48
        Func<IValidation<TField>, IValidation<TReturnedField>> action)
49
        where TField : class
50
    {
51
        validation.Condition = () => validation.GetFieldValue() is not null;
26✔
52
        return validation.SetScope(() =>
13✔
53
        {
13✔
54
            validation.IsScopeCreator = true;
11✔
55
            var getFieldValue = () => validation.GetFieldValue()!;
40✔
56
            var scopeValidation = CreateScopeValidation(
11✔
57
                validation: validation,
11✔
58
                getFieldValue: getFieldValue,
11✔
59
                index: validation.Index,
11✔
60
                fieldPathToOverride: null);
11✔
61
            action(scopeValidation);
11✔
62
        }, ScopeType.WhenNotNull);
23✔
63
    }
64

65
    public static IValidation<TField?> Null<TField>(
66
        this IValidation<TField?> validation)
67
        where TField : class
68
    {
69
        return validation.SetValidator(() => new NullValidator<TField?>(validation.GetFieldValue()));
16✔
70
    }
71

72
    public static IValidation<TField?> Null<TField>(
73
        this IValidation<TField?> validation)
74
        where TField : struct
75
    {
76
        return validation.SetValidator(() => new NullValidator<TField?>(validation.GetFieldValue()));
6✔
77
    }
78

79
    public static IValidation<TField> GreaterThan<TField>(
80
        this IValidation<TField> validation,
81
        TField valueToCompare)
82
        where TField : IComparisonOperators<TField, TField, bool>
83
    {
84
        return validation.SetValidator(() =>
116✔
85
            new GreaterThanValidator<TField>(validation.GetFieldValue(), valueToCompare));
223✔
86
    }
87

88
    public static IValidation<TField> Enum<TField>(
89
        this IValidation<TField> validation)
90
        where TField : Enum
91
    {
92
        return validation.SetValidator(() => new EnumValidator<TField>(validation.GetFieldValue(), typeof(TField)));
4✔
93
    }
94

95
    public static IValidation<TEnum> Enum<TEnum>(
96
        this IValidation<int> validation)
97
        where TEnum : Enum
98
    {
99
        return validation.SetValidator(() => new EnumValidator<int>(validation.GetFieldValue(), typeof(TEnum)))
4✔
100
            .Transform(x => (TEnum)(object)x);
2✔
101
    }
102

103
    public static IValidation<TEnum> Enum<TEnum>(
104
        this IValidation<string> validation)
105
        where TEnum : Enum
106
    {
107
        return validation.SetValidator(() => new EnumValidator<string>(validation.GetFieldValue(), typeof(TEnum)))
6✔
108
            .Transform(x => (TEnum)System.Enum.Parse(typeof(TEnum), x, ignoreCase: true));
4✔
109
    }
110

111
    public static IValidation<TField> Enum<TField>(
112
        this IValidation<TField> validation,
113
        params TField[] allowedValues)
114
        where TField : Enum
115
    {
116
        return validation.SetValidator(() =>
3✔
117
            new EnumRangeValidator<TField, TField>(validation.GetFieldValue(), allowedValues));
6✔
118
    }
119

120
    public static IValidation<TEnum> Enum<TEnum>(
121
        this IValidation<int> validation,
122
        params TEnum[] allowedValues)
123
        where TEnum : Enum
124
    {
125
        return validation
2✔
126
            .SetValidator(() => new EnumRangeValidator<int, TEnum>(validation.GetFieldValue(), allowedValues))
2✔
127
            .Transform(x => (TEnum)(object)x);
2✔
128
    }
129

130
    public static IValidation<TEnum> Enum<TEnum>(
131
        this IValidation<string> validation,
132
        params TEnum[] allowedValues)
133
        where TEnum : Enum
134
    {
135
        return validation.SetValidator(
2✔
136
                () => new EnumRangeValidator<string, TEnum>(validation.GetFieldValue(), allowedValues))
2✔
137
            .Transform(x => (TEnum)System.Enum.Parse(typeof(TEnum), x, ignoreCase: true));
2✔
138
    }
139

140
    public static IValidation<string> LengthRange(
141
        this IValidation<string> validation,
142
        int minimum,
143
        int maximum)
144
    {
145
        return validation.SetValidator(() => new LengthRangeValidator(validation.GetFieldValue(), minimum, maximum));
5✔
146
    }
147

148
    public static IValidation<string> MinimumLength(
149
        this IValidation<string> validation,
150
        int minimum)
151
    {
152
        return validation.SetValidator(() => new MinimumLengthValidator(validation.GetFieldValue(), minimum));
2✔
153
    }
154

155
    public static IValidation<IEnumerable<TInnerType>> ForEach<TInnerType, TReturnedField>(
156
        this IValidation<IEnumerable<TInnerType>> validation,
157
        Func<IValidation<TInnerType>, IValidation<TReturnedField>> action)
158
    {
159
        return validation.SetScope(() =>
42✔
160
        {
42✔
161
            validation.IsScopeCreator = true;
41✔
162
            var fieldCollection = validation.GetFieldValue()
41✔
163
                .ToList();
41✔
164
            var index = 0;
41✔
165
            var totalItems = fieldCollection.Count();
41✔
166

42✔
167
            foreach (var innerField in fieldCollection)
219!
168
            {
42✔
169
                var getFieldValue = () => innerField;
270✔
170
                var scopeValidation = CreateScopeValidation(
89✔
171
                    validation: validation,
89✔
172
                    getFieldValue: getFieldValue,
89✔
173
                    index: index,
89✔
174
                    fieldPathToOverride: validation.GetFieldPathWithIndex(validation.FieldPath, index));
89✔
175
                scopeValidation.HasFailed = false;
89✔
176
                action(scopeValidation);
89✔
177
                index++;
78✔
178
                var areAllItemsIterated = index  == totalItems;
78✔
179
                var stopWithFailedScope =
78✔
180
                    validation.HasFailed
78✔
181
                    && validation.Context!.ValidationMode is ValidationMode.AccumulateFirstErrors;
78✔
182
            
42✔
183
                if (areAllItemsIterated || stopWithFailedScope)
78✔
184
                {
42✔
185
                    validation.HasBeenExecuted = true;
30✔
186
                    break;
30✔
187
                }
42✔
188
            }
42✔
189
        }, ScopeType.ForEach);
72✔
190
    }
191

192
    public static IValidation<string> Regex(
193
        this IValidation<string> validation,
194
        [StringSyntax(StringSyntaxAttribute.Regex)]
195
        string pattern)
196
    {
197
        return validation.SetValidator(() => new RegularExpressionValidator(validation.GetFieldValue(), pattern));
×
198
    }
199

200
    internal static IValidation<TDependentField> CreateScopeValidation<TField, TDependentField>(
201
        this IValidation<TField> validation,
202
        Func<TDependentField> getFieldValue,
203
        int? index,
204
        string? fieldPathToOverride)
205
    {
206
        var scopeValidation = new Validation<TDependentField>(
230✔
207
            getFieldValue: getFieldValue,
230✔
208
            crossErrorToException: validation.CrossErrorToException,
230✔
209
            generalizeError: validation.GeneralizeError,
230✔
210
            fieldPath: fieldPathToOverride ?? validation.FieldPath,
230✔
211
            context: validation.Context,
230✔
212
            index: index,
230✔
213
            parentPath: validation.ParentPath,
230✔
214
            fixedError: validation.Context!.Error,
230✔
215
            fixedMessage: validation.Context!.Message,
230✔
216
            fixedCode: validation.Context!.Code,
230✔
217
            fixedDetails: validation.Context!.Details,
230✔
218
            fixedHttpStatusCode: validation.Context!.HttpStatusCode,
230✔
219
            fixedFieldDisplayName: validation.Context!.FieldDisplayName);
230✔
220
        scopeValidation.HasFailed = validation.HasFailed;
230✔
221
        scopeValidation.HasPendingAsyncValidation = validation.HasPendingAsyncValidation;
230✔
222
        scopeValidation.ScopeType = validation.ScopeType;
230✔
223
        scopeValidation.IsInsideScope = true;
230✔
224
        scopeValidation.ScopeCreatorValidation = validation;
230✔
225
        validation.ScopeValidations ??= new();
230✔
226
        validation.ScopeValidations.Add(scopeValidation);
230✔
227
        return scopeValidation;
230✔
228
    }
229

230
    internal static string? GetFieldPathWithIndex<TField>(
231
        this IValidation<TField> validation,
232
        string? fieldPath,
233
        int? index)
234
    {
235
        if (fieldPath is null)
89✔
236
        {
237
            return null;
36✔
238
        }
239
        
240
        var indexRepresentation = index is not null ? $"[{index}]" : null;
53!
241
        return $"{fieldPath}{indexRepresentation}";
53✔
242
    }
243
}
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