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

NetFabric / NetFabric.CodeAnalysis / 6277926364

22 Sep 2023 06:38PM UTC coverage: 73.953% (-9.2%) from 83.158%
6277926364

push

github

web-flow
Add IsIndexable (#28)

323 of 452 branches covered (0.0%)

Branch coverage included in aggregate %.

349 of 349 new or added lines in 18 files covered. (100.0%)

648 of 861 relevant lines covered (75.26%)

20.93 hits per line

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

86.11
/NetFabric.Reflection/Reflection/TypeExtensions.IsAsyncEnumerable.cs
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Diagnostics.CodeAnalysis;
5
using System.Threading;
6
using System.Threading.Tasks;
7

8
namespace NetFabric.Reflection;
9

10
public static partial class TypeExtensions
11
{        
12
    /// <summary>
13
    /// Gets a value indicating whether 'await foreach' considers <see cref="System.Type"/> to be enumerable.
14
    /// </summary>
15
    /// <param name="type">The <see cref="System.Type"/> to test.</param>
16
    /// <returns><c>true</c> if 'await foreach' considers <see cref="System.Type"/> to be enumerable; otherwise, <c>false</c>.</returns>
17
    public static bool IsAsyncEnumerable(this Type type)
18
        => IsAsyncEnumerable(type, out _, out _);
×
19

20
    /// <summary>
21
    /// Gets a value indicating whether 'await foreach' considers <see cref="System.Type"/> to be enumerable.
22
    /// </summary>
23
    /// <param name="type">The <see cref="System.Type"/> to test.</param>
24
    /// <param name="enumerableInfo">If methods returns <c>true</c>, contains information on the methods 'await foreach' will use to enumerate.</param>
25
    /// <returns><c>true</c> if 'await foreach' considers <see cref="System.Type"/> to be enumerable; otherwise, <c>false</c>.</returns>
26
    public static bool IsAsyncEnumerable(this Type type, [NotNullWhen(true)] out AsyncEnumerableInfo? enumerableInfo)
27
        => IsAsyncEnumerable(type, out enumerableInfo, out _);
×
28

29
    /// <summary>
30
    /// Gets a value indicating whether 'await foreach' considers <see cref="System.Type"/> to be enumerable.
31
    /// </summary>
32
    /// <param name="type">The <see cref="System.Type"/> to test.</param>
33
    /// <param name="enumerableInfo">If methods returns <c>true</c>, contains information on the methods 'await foreach' will use to enumerate.</param>
34
    /// <param name="error">Gets information on what error caused the method to return <c>false</c>.</param>
35
    /// <returns><c>true</c> if 'await foreach' considers <see cref="System.Type"/> to be enumerable; otherwise, <c>false</c>.</returns>
36
    public static bool IsAsyncEnumerable(this Type type,
37
        [NotNullWhen(true)] out AsyncEnumerableInfo? enumerableInfo,
38
        out IsAsyncEnumerableError error)
39
    {
40
        var getAsyncEnumerator = type.GetPublicMethod(NameOf.GetAsyncEnumerator, typeof(CancellationToken));
13✔
41
        getAsyncEnumerator ??= type.GetPublicMethod(NameOf.GetAsyncEnumerator);
13✔
42
        if (getAsyncEnumerator is null && !type.IsInterface && type.ImplementsInterface(typeof(IAsyncEnumerable<>), out var genericArguments))
13✔
43
        {       
44
            var interfaceType = typeof(IAsyncEnumerable<>).MakeGenericType(genericArguments); 
1✔
45
            getAsyncEnumerator ??= interfaceType.GetPublicMethod(NameOf.GetAsyncEnumerator, typeof(CancellationToken));
1✔
46
            getAsyncEnumerator ??= interfaceType.GetPublicMethod(NameOf.GetAsyncEnumerator);
1!
47
        }        
48
        if (getAsyncEnumerator is null)
13✔
49
        {
50
            enumerableInfo = default;
1✔
51
            error = IsAsyncEnumerableError.MissingGetAsyncEnumerator;
1✔
52
            return false;
1✔
53
        }
54

55
        var enumeratorType = getAsyncEnumerator.ReturnType;
12✔
56
        
57
        var current = enumeratorType.GetPublicReadProperty(NameOf.Current);
12✔
58
        var moveNextAsync = enumeratorType.GetPublicMethod(NameOf.MoveNextAsync);
12✔
59

60
        if ((current is null || moveNextAsync is null) && !type.IsInterface)
12✔
61
        {
62
            if (type.ImplementsInterface(typeof(IAsyncEnumerator<>), out genericArguments))
2!
63
            {
64
                var interfaceType = typeof(IAsyncEnumerator<>).MakeGenericType(genericArguments);
×
65
                current ??= interfaceType.GetPublicReadProperty(NameOf.Current);
×
66
                moveNextAsync ??= interfaceType.GetPublicMethod(NameOf.MoveNextAsync);
×
67
            }
68
        }
69

70
        if (current is null)
12✔
71
        {
72
            enumerableInfo = default;
1✔
73
            error = IsAsyncEnumerableError.MissingCurrent;
1✔
74
            return false;
1✔
75
        }
76
        
77
        if (moveNextAsync is null || moveNextAsync.ReturnType != typeof(ValueTask<bool>))
11✔
78
        {
79
            enumerableInfo = default;
2✔
80
            error = IsAsyncEnumerableError.MissingMoveNextAsync;
2✔
81
            return false;
2✔
82
        }
83
        
84
        _ = enumeratorType.IsAsyncDisposable(out var dispose);
9✔
85

86
        enumerableInfo = new AsyncEnumerableInfo(
9✔
87
            getAsyncEnumerator: getAsyncEnumerator,
9✔
88
            new AsyncEnumeratorInfo(current, moveNextAsync)
9✔
89
            {
9✔
90
                DisposeAsync = dispose,
9✔
91
                IsValueType = getAsyncEnumerator.ReturnType.IsValueType,
9✔
92
                IsAsyncEnumeratorInterface = enumeratorType.IsInterface,
9✔
93
            }
9✔
94
        );
9✔
95
        error = IsAsyncEnumerableError.None; 
9✔
96
        return true;
9✔
97
    }
98
}
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

© 2025 Coveralls, Inc