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 AverageTests 11 { 12 // 13 // Average 14 // 15 16 // Get a set of ranges from 0 to each count, with an extra parameter containing the expected average. AverageData(int[] counts)17 public static IEnumerable<object[]> AverageData(int[] counts) 18 { 19 foreach (int count in counts) 20 { 21 yield return new object[] { count, (count - 1) / 2.0 }; 22 } 23 } 24 25 [Theory] 26 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Int(int count, double average)27 public static void Average_Int(int count, double average) 28 { 29 Assert.Equal(average, UnorderedSources.Default(count).Average()); 30 Assert.Equal((double?)average, UnorderedSources.Default(count).Select(x => (int?)x).Average()); 31 Assert.Equal(-average, UnorderedSources.Default(count).Average(x => -x)); 32 Assert.Equal(-(double?)average, UnorderedSources.Default(count).Average(x => -(int?)x)); 33 } 34 35 [Fact] 36 [OuterLoop] Average_Int_Longrunning()37 public static void Average_Int_Longrunning() 38 { 39 Average_Int(Sources.OuterLoopCount, (Sources.OuterLoopCount - 1) / 2.0); 40 } 41 42 [Theory] 43 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Int_SomeNull(int count, double average)44 public static void Average_Int_SomeNull(int count, double average) 45 { 46 Assert.Equal(Math.Truncate(average), UnorderedSources.Default(count).Select(x => (x % 2 == 0) ? (int?)x : null).Average()); 47 Assert.Equal(Math.Truncate(-average), UnorderedSources.Default(count).Average(x => (x % 2 == 0) ? -(int?)x : null)); 48 } 49 50 [Theory] 51 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Int_AllNull(int count, double average)52 public static void Average_Int_AllNull(int count, double average) 53 { 54 Assert.Null(UnorderedSources.Default(count).Select(x => (int?)null).Average()); 55 Assert.Null(UnorderedSources.Default(count).Average(x => (int?)null)); 56 } 57 58 [Theory] 59 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Long(int count, double average)60 public static void Average_Long(int count, double average) 61 { 62 Assert.Equal(average, UnorderedSources.Default(count).Select(x => (long)x).Average()); 63 Assert.Equal((double?)average, UnorderedSources.Default(count).Select(x => (long?)x).Average()); 64 Assert.Equal(-average, UnorderedSources.Default(count).Average(x => -(long)x)); 65 Assert.Equal(-(double?)average, UnorderedSources.Default(count).Average(x => -(long?)x)); 66 } 67 68 [Fact] 69 [OuterLoop] Average_Long_Longrunning()70 public static void Average_Long_Longrunning() 71 { 72 Average_Long(Sources.OuterLoopCount, (Sources.OuterLoopCount - 1) / 2.0); 73 } 74 75 [Fact] Average_Long_Overflow()76 public static void Average_Long_Overflow() 77 { 78 AssertThrows.Wrapped<OverflowException>(() => UnorderedSources.Default(2).Select(x => x == 0 ? 1 : long.MaxValue).Average()); 79 AssertThrows.Wrapped<OverflowException>(() => UnorderedSources.Default(2).Select(x => x == 0 ? (long?)1 : long.MaxValue).Average()); 80 AssertThrows.Wrapped<OverflowException>(() => UnorderedSources.Default(2).Average(x => x == 0 ? -1 : long.MinValue)); 81 AssertThrows.Wrapped<OverflowException>(() => UnorderedSources.Default(2).Average(x => x == 0 ? (long?)-1 : long.MinValue)); 82 } 83 84 [Theory] 85 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Long_SomeNull(int count, double average)86 public static void Average_Long_SomeNull(int count, double average) 87 { 88 Assert.Equal(Math.Truncate(average), UnorderedSources.Default(count).Select(x => (x % 2 == 0) ? (long?)x : null).Average()); 89 Assert.Equal(Math.Truncate(-average), UnorderedSources.Default(count).Average(x => (x % 2 == 0) ? -(long?)x : null)); 90 } 91 92 [Theory] 93 [InlineData(1)] 94 [InlineData(2)] 95 [InlineData(16)] Average_Long_AllNull(int count)96 public static void Average_Long_AllNull(int count) 97 { 98 Assert.Null(UnorderedSources.Default(count).Select(x => (long?)null).Average()); 99 Assert.Null(UnorderedSources.Default(count).Average(x => (long?)null)); 100 } 101 102 [Theory] 103 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Float(int count, float average)104 public static void Average_Float(int count, float average) 105 { 106 Assert.Equal(average, UnorderedSources.Default(count).Select(x => (float)x).Average()); 107 Assert.Equal((float?)average, UnorderedSources.Default(count).Select(x => (float?)x).Average()); 108 Assert.Equal(-average, UnorderedSources.Default(count).Average(x => -(float)x)); 109 Assert.Equal(-(float?)average, UnorderedSources.Default(count).Average(x => -(float?)x)); 110 } 111 112 [Fact] 113 [OuterLoop] Average_Float_Longrunning()114 public static void Average_Float_Longrunning() 115 { 116 Average_Float(Sources.OuterLoopCount, (Sources.OuterLoopCount - 1) / 2.0F); 117 } 118 119 [Theory] 120 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Float_SomeNull(int count, float average)121 public static void Average_Float_SomeNull(int count, float average) 122 { 123 Assert.Equal((float?)Math.Truncate(average), UnorderedSources.Default(count).Select(x => (x % 2 == 0) ? (float?)x : null).Average()); 124 Assert.Equal((float?)Math.Truncate(-average), UnorderedSources.Default(count).Average(x => (x % 2 == 0) ? -(float?)x : null)); 125 } 126 127 [Theory] 128 [InlineData(1)] 129 [InlineData(2)] 130 [InlineData(16)] Average_Float_AllNull(int count)131 public static void Average_Float_AllNull(int count) 132 { 133 Assert.Null(UnorderedSources.Default(count).Select(x => (float?)null).Average()); 134 Assert.Null(UnorderedSources.Default(count).Average(x => (float?)null)); 135 } 136 137 [Theory] 138 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Double(int count, double average)139 public static void Average_Double(int count, double average) 140 { 141 Assert.Equal(average, UnorderedSources.Default(count).Select(x => (double)x).Average()); 142 Assert.Equal((double?)average, UnorderedSources.Default(count).Select(x => (double?)x).Average()); 143 Assert.Equal(-average, UnorderedSources.Default(count).Average(x => -(double)x)); 144 Assert.Equal(-(double?)average, UnorderedSources.Default(count).Average(x => -(double?)x)); 145 } 146 147 [Fact] 148 [OuterLoop] Average_Double_Longrunning()149 public static void Average_Double_Longrunning() 150 { 151 Average_Double(Sources.OuterLoopCount, (Sources.OuterLoopCount - 1) / 2.0); 152 } 153 154 [Theory] 155 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Double_SomeNull(int count, double average)156 public static void Average_Double_SomeNull(int count, double average) 157 { 158 Assert.Equal(Math.Truncate(average), UnorderedSources.Default(count).Select(x => (x % 2 == 0) ? (double?)x : null).Average()); 159 Assert.Equal(Math.Truncate(-average), UnorderedSources.Default(count).Average(x => (x % 2 == 0) ? -(double?)x : null)); 160 } 161 162 [Theory] 163 [InlineData(1)] 164 [InlineData(2)] 165 [InlineData(16)] Average_Double_AllNull(int count)166 public static void Average_Double_AllNull(int count) 167 { 168 Assert.Null(UnorderedSources.Default(count).Select(x => (double?)null).Average()); 169 Assert.Null(UnorderedSources.Default(count).Average(x => (double?)null)); 170 } 171 172 [Theory] 173 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Decimal(int count, decimal average)174 public static void Average_Decimal(int count, decimal average) 175 { 176 Assert.Equal(average, UnorderedSources.Default(count).Select(x => (decimal)x).Average()); 177 Assert.Equal((decimal?)average, UnorderedSources.Default(count).Select(x => (decimal?)x).Average()); 178 Assert.Equal(-average, UnorderedSources.Default(count).Average(x => -(decimal)x)); 179 Assert.Equal(-(decimal?)average, UnorderedSources.Default(count).Average(x => -(decimal?)x)); 180 } 181 182 [Fact] 183 [OuterLoop] Average_Decimal_Longrunning()184 public static void Average_Decimal_Longrunning() 185 { 186 Average_Decimal(Sources.OuterLoopCount, (Sources.OuterLoopCount - 1) / 2.0M); 187 } 188 189 [Theory] 190 [MemberData(nameof(AverageData), new[] { 1, 2, 16 })] Average_Decimal_SomeNull(int count, decimal average)191 public static void Average_Decimal_SomeNull(int count, decimal average) 192 { 193 Assert.Equal(Math.Truncate(average), UnorderedSources.Default(count).Select(x => (x % 2 == 0) ? (decimal?)x : null).Average()); 194 Assert.Equal(Math.Truncate(-average), UnorderedSources.Default(count).Average(x => (x % 2 == 0) ? -(decimal?)x : null)); 195 } 196 197 [Theory] 198 [InlineData(1)] 199 [InlineData(2)] 200 [InlineData(16)] Average_Decimal_AllNull(int count)201 public static void Average_Decimal_AllNull(int count) 202 { 203 Assert.Null(UnorderedSources.Default(count).Select(x => (decimal?)null).Average()); 204 Assert.Null(UnorderedSources.Default(count).Average(x => (decimal?)null)); 205 } 206 207 [Fact] Average_InvalidOperationException()208 public static void Average_InvalidOperationException() 209 { 210 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<int>().Average()); 211 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<int>().Average(x => x)); 212 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<long>().Average()); 213 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<long>().Average(x => x)); 214 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<float>().Average()); 215 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<float>().Average(x => x)); 216 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<double>().Average()); 217 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<double>().Average(x => x)); 218 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<decimal>().Average()); 219 Assert.Throws<InvalidOperationException>(() => ParallelEnumerable.Empty<decimal>().Average(x => x)); 220 // Nullables return null when empty 221 Assert.Null(ParallelEnumerable.Empty<int?>().Average()); 222 Assert.Null(ParallelEnumerable.Empty<int?>().Average(x => x)); 223 Assert.Null(ParallelEnumerable.Empty<long?>().Average()); 224 Assert.Null(ParallelEnumerable.Empty<long?>().Average(x => x)); 225 Assert.Null(ParallelEnumerable.Empty<float?>().Average()); 226 Assert.Null(ParallelEnumerable.Empty<float?>().Average(x => x)); 227 Assert.Null(ParallelEnumerable.Empty<double?>().Average()); 228 Assert.Null(ParallelEnumerable.Empty<double?>().Average(x => x)); 229 Assert.Null(ParallelEnumerable.Empty<decimal?>().Average()); 230 Assert.Null(ParallelEnumerable.Empty<decimal?>().Average(x => x)); 231 } 232 233 [Fact] Average_OperationCanceledException()234 public static void Average_OperationCanceledException() 235 { 236 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return x; })); 237 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (int?)x; })); 238 239 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (long)x; })); 240 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (long?)x; })); 241 242 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (float)x; })); 243 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (float?)x; })); 244 245 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (double)x; })); 246 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (double?)x; })); 247 248 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal)x; })); 249 AssertThrows.EventuallyCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal?)x; })); 250 } 251 252 [Fact] Average_AggregateException_Wraps_OperationCanceledException()253 public static void Average_AggregateException_Wraps_OperationCanceledException() 254 { 255 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return x; })); 256 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (int?)x; })); 257 258 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (long)x; })); 259 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (long?)x; })); 260 261 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (float)x; })); 262 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (float?)x; })); 263 264 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (double)x; })); 265 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (double?)x; })); 266 267 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal)x; })); 268 AssertThrows.OtherTokenCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal?)x; })); 269 270 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return x; })); 271 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (int?)x; })); 272 273 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (long)x; })); 274 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (long?)x; })); 275 276 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (float)x; })); 277 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (float?)x; })); 278 279 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (double)x; })); 280 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (double?)x; })); 281 282 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal)x; })); 283 AssertThrows.SameTokenNotCanceled((source, canceler) => source.Average(x => { canceler(); return (decimal?)x; })); 284 } 285 286 [Fact] Average_OperationCanceledException_PreCanceled()287 public static void Average_OperationCanceledException_PreCanceled() 288 { 289 AssertThrows.AlreadyCanceled(source => source.Average(x => x)); 290 AssertThrows.AlreadyCanceled(source => source.Average(x => (int?)x)); 291 292 AssertThrows.AlreadyCanceled(source => source.Average(x => (long)x)); 293 AssertThrows.AlreadyCanceled(source => source.Average(x => (long?)x)); 294 295 AssertThrows.AlreadyCanceled(source => source.Average(x => (float)x)); 296 AssertThrows.AlreadyCanceled(source => source.Average(x => (float?)x)); 297 298 AssertThrows.AlreadyCanceled(source => source.Average(x => (double)x)); 299 AssertThrows.AlreadyCanceled(source => source.Average(x => (double?)x)); 300 301 AssertThrows.AlreadyCanceled(source => source.Average(x => (decimal)x)); 302 AssertThrows.AlreadyCanceled(source => source.Average(x => (decimal?)x)); 303 } 304 305 [Fact] Average_AggregateException()306 public static void Average_AggregateException() 307 { 308 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, int>)(x => { throw new DeliberateTestException(); }))); 309 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, int?>)(x => { throw new DeliberateTestException(); }))); 310 311 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, long>)(x => { throw new DeliberateTestException(); }))); 312 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, long?>)(x => { throw new DeliberateTestException(); }))); 313 314 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, float>)(x => { throw new DeliberateTestException(); }))); 315 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, float?>)(x => { throw new DeliberateTestException(); }))); 316 317 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, double>)(x => { throw new DeliberateTestException(); }))); 318 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, double?>)(x => { throw new DeliberateTestException(); }))); 319 320 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, decimal>)(x => { throw new DeliberateTestException(); }))); 321 AssertThrows.Wrapped<DeliberateTestException>(() => UnorderedSources.Default(1).Average((Func<int, decimal?>)(x => { throw new DeliberateTestException(); }))); 322 } 323 324 [Fact] Average_ArgumentNullException()325 public static void Average_ArgumentNullException() 326 { 327 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<int>)null).Average()); 328 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat(0, 1).Average((Func<int, int>)null)); 329 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<int?>)null).Average()); 330 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((int?)0, 1).Average((Func<int?, int?>)null)); 331 332 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<long>)null).Average()); 333 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((long)0, 1).Average((Func<long, long>)null)); 334 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<long?>)null).Average()); 335 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((long?)0, 1).Average((Func<long?, long?>)null)); 336 337 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<float>)null).Average()); 338 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((float)0, 1).Average((Func<float, float>)null)); 339 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<float?>)null).Average()); 340 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((float?)0, 1).Average((Func<float?, float?>)null)); 341 342 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<double>)null).Average()); 343 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((double)0, 1).Average((Func<double, double>)null)); 344 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<double?>)null).Average()); 345 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((double?)0, 1).Average((Func<double?, double?>)null)); 346 347 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<decimal>)null).Average()); 348 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((decimal)0, 1).Average((Func<decimal, decimal>)null)); 349 AssertExtensions.Throws<ArgumentNullException>("source", () => ((ParallelQuery<decimal?>)null).Average()); 350 AssertExtensions.Throws<ArgumentNullException>("selector", () => ParallelEnumerable.Repeat((decimal?)0, 1).Average((Func<decimal?, decimal?>)null)); 351 } 352 } 353 } 354