Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a746248

Browse files
committed
Merge pull request #1692 from ikopylov/linq_toArray_toList_toDictionary_tests
LINQ ToArray, ToList, ToDictionary unit tests
2 parents 94c90ba + 2826954 commit a746248

File tree

8 files changed

+562
-1
lines changed

8 files changed

+562
-1
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace System.Linq.Tests.Helpers
9+
{
10+
public class TestCollection<T> : ICollection<T>
11+
{
12+
public T[] Items = new T[0];
13+
public int CountTouched = 0;
14+
public int CopyToTouched = 0;
15+
public TestCollection(T[] items) { Items = items; }
16+
17+
public virtual int Count { get { CountTouched++; return Items.Length; } }
18+
public bool IsReadOnly { get { return false; } }
19+
public void Add(T item) { throw new NotImplementedException(); }
20+
public void Clear() { throw new NotImplementedException(); }
21+
public bool Contains(T item) { return Items.Contains(item); }
22+
public bool Remove(T item) { throw new NotImplementedException(); }
23+
public void CopyTo(T[] array, int arrayIndex) { CopyToTouched++; Items.CopyTo(array, arrayIndex); }
24+
public IEnumerator<T> GetEnumerator() { return ((IEnumerable<T>)Items).GetEnumerator(); }
25+
IEnumerator IEnumerable.GetEnumerator() { return Items.GetEnumerator(); }
26+
}
27+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace System.Linq.Tests.Helpers
9+
{
10+
public class TestEnumerable<T> : IEnumerable<T>
11+
{
12+
public T[] Items = new T[0];
13+
public TestEnumerable(T[] items) { Items = items; }
14+
15+
public IEnumerator<T> GetEnumerator() { return ((IEnumerable<T>)Items).GetEnumerator(); }
16+
IEnumerator IEnumerable.GetEnumerator() { return Items.GetEnumerator(); }
17+
}
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace System.Linq.Tests.Helpers
9+
{
10+
public class TestReadOnlyCollection<T> : IReadOnlyCollection<T>
11+
{
12+
public T[] Items = new T[0];
13+
public int CountTouched = 0;
14+
public TestReadOnlyCollection(T[] items) { Items = items; }
15+
16+
public int Count { get { CountTouched++; return Items.Length; } }
17+
public IEnumerator<T> GetEnumerator() { return ((IEnumerable<T>)Items).GetEnumerator(); }
18+
IEnumerator IEnumerable.GetEnumerator() { return Items.GetEnumerator(); }
19+
}
20+
}

src/System.Linq/tests/System.Linq.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
<Compile Include="CachedEnumerator.cs" />
2222
<Compile Include="EnumerableTests.cs" />
2323
<Compile Include="EmptyEnumerable.cs" />
24+
<Compile Include="Helpers\TestCollection.cs" />
25+
<Compile Include="Helpers\TestEnumerable.cs" />
26+
<Compile Include="Helpers\TestReadOnlyCollection.cs" />
2427
<Compile Include="Performance\CastPerf.cs" />
2528
<Compile Include="Performance\LinqPerformanceCore.cs" />
2629
<Compile Include="Performance\OrderByThenByPerf.cs" />
@@ -32,6 +35,9 @@
3235
<Compile Include="RangeTests.cs" />
3336
<Compile Include="RepeatTests.cs" />
3437
<Compile Include="WhereTests.cs" />
38+
<Compile Include="ToArrayTests.cs" />
39+
<Compile Include="ToDictionaryTests.cs" />
40+
<Compile Include="ToListTests.cs" />
3541
</ItemGroup>
3642
<ItemGroup>
3743
<ProjectReference Include="..\src\System.Linq.csproj">
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Linq.Tests.Helpers;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using Xunit;
9+
10+
namespace System.Linq.Tests
11+
{
12+
public class ToArrayTests
13+
{
14+
private class TestLargeSequence : IEnumerable<byte>
15+
{
16+
public long MaxSize = 2 * (long)int.MaxValue;
17+
public IEnumerator<byte> GetEnumerator()
18+
{
19+
for (long i = 0; i < MaxSize; i++) yield return (byte)1;
20+
}
21+
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
22+
}
23+
24+
/// <summary>
25+
/// Emulation of async collection change.
26+
/// It adds a new element to the sequence each time the Count property touched,
27+
/// so the further call of CopyTo method will fail.
28+
/// </summary>
29+
private class GrowingAfterCountReadCollection : TestCollection<int>
30+
{
31+
public GrowingAfterCountReadCollection(int[] items) : base(items) { }
32+
33+
public override int Count
34+
{
35+
get
36+
{
37+
var result = base.Count;
38+
Array.Resize(ref Items, Items.Length + 1);
39+
return result;
40+
}
41+
}
42+
}
43+
44+
// =====================
45+
46+
47+
[Fact]
48+
public void ToArray_AlwaysCreateACopy()
49+
{
50+
int[] sourceArray = new int[] { 1, 2, 3, 4, 5 };
51+
int[] resultArray = sourceArray.ToArray();
52+
53+
Assert.NotSame(sourceArray, resultArray);
54+
Assert.Equal(sourceArray, resultArray);
55+
}
56+
57+
58+
private void RunToArrayOnAllCollectionTypes<T>(T[] items, Action<T[]> validation)
59+
{
60+
validation(Enumerable.ToArray(items));
61+
validation(Enumerable.ToArray(new List<T>(items)));
62+
validation(new TestEnumerable<T>(items).ToArray());
63+
validation(new TestReadOnlyCollection<T>(items).ToArray());
64+
validation(new TestCollection<T>(items).ToArray());
65+
}
66+
67+
68+
[Fact]
69+
public void ToArray_WorkWithEmptyCollection()
70+
{
71+
RunToArrayOnAllCollectionTypes(new int[0],
72+
resultArray =>
73+
{
74+
Assert.NotNull(resultArray);
75+
Assert.Equal(0, resultArray.Length);
76+
});
77+
}
78+
79+
[Fact]
80+
public void ToArray_ProduceCorrectArray()
81+
{
82+
int[] sourceArray = new int[] { 1, 2, 3, 4, 5, 6, 7 };
83+
RunToArrayOnAllCollectionTypes(sourceArray,
84+
resultArray =>
85+
{
86+
Assert.Equal(sourceArray.Length, resultArray.Length);
87+
Assert.Equal(sourceArray, resultArray);
88+
});
89+
90+
string[] sourceStringArray = new string[] { "1", "2", "3", "4", "5", "6", "7", "8" };
91+
RunToArrayOnAllCollectionTypes(sourceStringArray,
92+
resultStringArray =>
93+
{
94+
Assert.Equal(sourceStringArray.Length, resultStringArray.Length);
95+
for (int i = 0; i < sourceStringArray.Length; i++)
96+
Assert.Same(sourceStringArray[i], resultStringArray[i]);
97+
});
98+
}
99+
100+
101+
[Fact]
102+
public void ToArray_TouchCountWithICollection()
103+
{
104+
TestCollection<int> source = new TestCollection<int>(new int[] { 1, 2, 3, 4 });
105+
var resultArray = source.ToArray();
106+
107+
Assert.Equal(source, resultArray);
108+
Assert.Equal(1, source.CountTouched);
109+
}
110+
111+
112+
[Fact]
113+
public void ToArray_ThrowArgumentNullExceptionWhenSourceIsNull()
114+
{
115+
int[] source = null;
116+
Assert.Throws<ArgumentNullException>(() => source.ToArray());
117+
}
118+
119+
120+
// Later this behaviour can be changed
121+
[Fact]
122+
[ActiveIssue(1561)]
123+
public void ToArray_UseCopyToWithICollection()
124+
{
125+
TestCollection<int> source = new TestCollection<int>(new int[] { 1, 2, 3, 4 });
126+
var resultArray = source.ToArray();
127+
128+
Assert.Equal(source, resultArray);
129+
Assert.Equal(1, source.CopyToTouched);
130+
}
131+
132+
133+
[Fact]
134+
[ActiveIssue(1561)]
135+
public void ToArray_WorkWhenCountChangedAsynchronously()
136+
{
137+
GrowingAfterCountReadCollection source = new GrowingAfterCountReadCollection(new int[] { 1, 2, 3, 4 });
138+
var resultArray = source.ToArray();
139+
140+
Assert.True(resultArray.Length >= 4);
141+
Assert.Equal(1, resultArray[0]);
142+
Assert.Equal(2, resultArray[0]);
143+
Assert.Equal(3, resultArray[0]);
144+
Assert.Equal(4, resultArray[0]);
145+
}
146+
147+
148+
[Fact]
149+
[OuterLoop]
150+
public void ToArray_FailOnExtremelyLargeCollection()
151+
{
152+
TestLargeSequence largeSeq = new TestLargeSequence();
153+
var thrownException = Assert.ThrowsAny<Exception>(() => { largeSeq.ToArray(); });
154+
Assert.True(thrownException.GetType() == typeof(OverflowException) || thrownException.GetType() == typeof(OutOfMemoryException));
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)