File: EnumerableExtensionsTests.cs
Web Access
Project: src\src\Razor\src\Shared\Microsoft.AspNetCore.Razor.Utilities.Shared.UnitTests\Microsoft.AspNetCore.Razor.Utilities.Shared.UnitTests.csproj (Microsoft.AspNetCore.Razor.Utilities.Shared.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using Xunit;
using SR = Microsoft.AspNetCore.Razor.Utilities.Shared.Resources.SR;
 
namespace Microsoft.AspNetCore.Razor.Utilities.Shared.Test;
 
public class EnumerableExtensionsTests
{
    [Fact]
    public void CopyTo_ImmutableArray()
    {
        Span<int> source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var immutableArray = ImmutableArray.Create(source);
 
        AssertCopyToCore(immutableArray, immutableArray.Length);
    }
 
    [Fact]
    public void CopyTo_ImmutableArrayBuilder()
    {
        Span<int> source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var builder = ImmutableArray.CreateBuilder<int>();
        builder.AddRange(source);
 
        AssertCopyToCore(builder, builder.Count);
    }
 
    [Fact]
    public void CopyTo_List()
    {
        IEnumerable<int> source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var list = new List<int>(source);
 
        AssertCopyToCore(list, list.Count);
    }
 
    [Fact]
    public void CopyTo_HashSet()
    {
        IEnumerable<int> source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var set = new HashSet<int>(source);
 
        AssertCopyToCore(set, set.Count);
    }
 
    [Fact]
    public void CopyTo_Array()
    {
        int[] array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
        AssertCopyToCore(array, array.Length);
    }
 
    [Fact]
    public void CopyTo_CustomEnumerable()
    {
        CustomEnumerable custom = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
        AssertCopyToCore(custom, 10);
    }
 
    [Fact]
    public void CopyTo_CustomReadOnlyCollection()
    {
        CustomReadOnlyCollection custom = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
        AssertCopyToCore(custom, 10);
    }
 
    private static void AssertCopyToCore(IEnumerable<int> sequence, int count)
    {
        var destination1 = new int[count - 1];
        var exception = Assert.Throws<ArgumentException>(() => sequence.CopyTo(destination1.AsSpan()));
        Assert.StartsWith(SR.Destination_is_too_short, exception.Message);
 
        Span<int> destination2 = stackalloc int[count];
        sequence.CopyTo(destination2);
        AssertElementsEqual(sequence, destination2);
 
        Span<int> destination3 = stackalloc int[count + 1];
        sequence.CopyTo(destination3);
        AssertElementsEqual(sequence, destination3);
 
        static void AssertElementsEqual<T>(IEnumerable<T> sequence, ReadOnlySpan<T> span)
        {
            var index = 0;
 
            foreach (var item in sequence)
            {
                Assert.Equal(item, span[index++]);
            }
        }
    }
 
    [CollectionBuilder(typeof(CustomEnumerable), "Create")]
    private sealed class CustomEnumerable(params ReadOnlySpan<int> values) : IEnumerable<int>
    {
        private readonly int[] _values = values.ToArray();
 
        public IEnumerator<int> GetEnumerator()
        {
            foreach (var value in _values)
            {
                yield return value;
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator()
            => GetEnumerator();
 
        public static CustomEnumerable Create(ReadOnlySpan<int> span)
            => new(span);
    }
 
    [CollectionBuilder(typeof(CustomReadOnlyCollection), "Create")]
    private sealed class CustomReadOnlyCollection(params ReadOnlySpan<int> values) : IReadOnlyCollection<int>
    {
        private readonly int[] _values = values.ToArray();
 
        public int Count => _values.Length;
 
        public IEnumerator<int> GetEnumerator()
        {
            foreach (var value in _values)
            {
                yield return value;
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator()
            => GetEnumerator();
 
        public static CustomReadOnlyCollection Create(ReadOnlySpan<int> span)
            => new(span);
    }
 
    [Fact]
    public void SelectAsArray()
    {
        IEnumerable<int> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        ImmutableArray<int> expected = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
 
        var actual = data.SelectAsArray(static x => x * 2);
        Assert.Equal<int>(expected, actual);
    }
 
    [Fact]
    public void SelectAsArray_Index()
    {
        IEnumerable<int> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        ImmutableArray<int> expected = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
 
        var actual = data.SelectAsArray(static (x, index) => x + index);
        Assert.Equal<int>(expected, actual);
    }
}