1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using Xunit;
7 
8 namespace System.Linq.Parallel.Tests
9 {
10     public static class CountLongCountTests
11     {
OnlyOneData(int[] counts)12         public static IEnumerable<object[]> OnlyOneData(int[] counts)
13         {
14             foreach (int count in counts.DefaultIfEmpty(Sources.OuterLoopCount))
15             {
16                 foreach (int position in new[] { 0, count / 2, Math.Max(0, count - 1) }.Distinct())
17                 {
18                     yield return new object[] { count, position };
19                 }
20             }
21         }
22 
23         //
24         // Count and LongCount
25         //
26         [Theory]
27         [InlineData(0)]
28         [InlineData(1)]
29         [InlineData(2)]
30         [InlineData(16)]
Count_All(int count)31         public static void Count_All(int count)
32         {
33             Assert.Equal(count, ParallelEnumerable.Range(0, count).Count());
34             Assert.Equal(count, ParallelEnumerable.Range(0, count).Count(i => i < count));
35         }
36 
37         [Fact]
38         [OuterLoop]
Count_All_Longrunning()39         public static void Count_All_Longrunning()
40         {
41             Count_All(Sources.OuterLoopCount);
42         }
43 
44         [Theory]
45         [InlineData(0)]
46         [InlineData(1)]
47         [InlineData(2)]
48         [InlineData(16)]
LongCount_All(int count)49         public static void LongCount_All(int count)
50         {
51             Assert.Equal(count, ParallelEnumerable.Range(0, count).LongCount());
52             Assert.Equal(count, ParallelEnumerable.Range(0, count).LongCount(i => i < count));
53         }
54 
55         [Fact]
56         [OuterLoop]
LongCount_All_Longrunning()57         public static void LongCount_All_Longrunning()
58         {
59             LongCount_All(Sources.OuterLoopCount);
60         }
61 
62         [Theory]
63         [InlineData(0)]
64         [InlineData(1)]
65         [InlineData(2)]
66         [InlineData(16)]
Count_None(int count)67         public static void Count_None(int count)
68         {
69             Assert.Equal(0, ParallelEnumerable.Range(0, count).Count(i => i == -1));
70         }
71 
72         [Fact]
73         [OuterLoop]
Count_None_Longrunning()74         public static void Count_None_Longrunning()
75         {
76             Count_None(Sources.OuterLoopCount);
77         }
78 
79         [Theory]
80         [InlineData(0)]
81         [InlineData(1)]
82         [InlineData(2)]
83         [InlineData(16)]
LongCount_None(int count)84         public static void LongCount_None(int count)
85         {
86             Assert.Equal(0, ParallelEnumerable.Range(0, count).LongCount(i => i == -1));
87         }
88 
89         [Fact]
90         [OuterLoop]
LongCount_None_Longrunning()91         public static void LongCount_None_Longrunning()
92         {
93             LongCount_None(Sources.OuterLoopCount);
94         }
95 
96         [Theory]
97         [MemberData(nameof(OnlyOneData), new[] { 0, 1, 2, 16 })]
Count_One(int count, int position)98         public static void Count_One(int count, int position)
99         {
100             Assert.Equal(Math.Min(1, count), ParallelEnumerable.Range(0, count).Count(i => i == position));
101         }
102 
103         [Theory]
104         [OuterLoop]
105         [MemberData(nameof(OnlyOneData), new int[] { /* Sources.OuterLoopCount */ })]
Count_One_Longrunning(int count, int position)106         public static void Count_One_Longrunning(int count, int position)
107         {
108             Count_One(count, position);
109         }
110 
111         [Theory]
112         [MemberData(nameof(OnlyOneData), new[] { 0, 1, 2, 16 })]
LongCount_One(int count, long position)113         public static void LongCount_One(int count, long position)
114         {
115             Assert.Equal(Math.Min(1, count), ParallelEnumerable.Range(0, count).LongCount(i => i == position));
116         }
117 
118         [Theory]
119         [OuterLoop]
120         [MemberData(nameof(OnlyOneData), new int[] { /* Sources.OuterLoopCount */ })]
LongCount_One_Longrunning(int count, long position)121         public static void LongCount_One_Longrunning(int count, long position)
122         {
123             LongCount_One(count, position);
124         }
125 
126         [Fact]
Count_OperationCanceledException()127         public static void Count_OperationCanceledException()
128         {
129             AssertThrows.EventuallyCanceled((source, canceler) => source.Count(x => { canceler(); return true; }));
130             AssertThrows.EventuallyCanceled((source, canceler) => source.LongCount(x => { canceler(); return true; }));
131         }
132 
133         [Fact]
Count_AggregateException_Wraps_OperationCanceledException()134         public static void Count_AggregateException_Wraps_OperationCanceledException()
135         {
136             AssertThrows.OtherTokenCanceled((source, canceler) => source.Count(x => { canceler(); return true; }));
137             AssertThrows.OtherTokenCanceled((source, canceler) => source.LongCount(x => { canceler(); return true; }));
138             AssertThrows.SameTokenNotCanceled((source, canceler) => source.Count(x => { canceler(); return true; }));
139             AssertThrows.SameTokenNotCanceled((source, canceler) => source.LongCount(x => { canceler(); return true; }));
140         }
141 
142         [Fact]
CountLongCount_OperationCanceledException_PreCanceled()143         public static void CountLongCount_OperationCanceledException_PreCanceled()
144         {
145             AssertThrows.AlreadyCanceled(source => source.Count());
146             AssertThrows.AlreadyCanceled(source => source.Count(x => true));
147 
148             AssertThrows.AlreadyCanceled(source => source.LongCount());
149             AssertThrows.AlreadyCanceled(source => source.LongCount(x => true));
150         }
151 
152         [Fact]
CountLongCount_AggregateException()153         public static void CountLongCount_AggregateException()
154         {
155             AssertThrows.Wrapped<DeliberateTestException>(() => ParallelEnumerable.Range(0, 1).Count(x => { throw new DeliberateTestException(); }));
156             AssertThrows.Wrapped<DeliberateTestException>(() => ParallelEnumerable.Range(0, 1).LongCount(x => { throw new DeliberateTestException(); }));
157         }
158 
159         [Fact]
CountLongCount_ArgumentNullException()160         public static void CountLongCount_ArgumentNullException()
161         {
162             AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<bool>)null).Count());
163             AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<bool>)null).Count(x => x));
164             AssertExtensions.Throws<ArgumentNullException>("predicate", () => ParallelEnumerable.Empty<bool>().Count(null));
165 
166             AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<bool>)null).LongCount());
167             AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<bool>)null).LongCount(x => x));
168             AssertExtensions.Throws<ArgumentNullException>("predicate", () => ParallelEnumerable.Empty<bool>().LongCount(null));
169         }
170     }
171 }
172