GroupBy.Generated.tt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. <#@ template debug="false" hostspecific="false" language="C#" #>
  5. <#@ assembly name="System.Core" #>
  6. <#@ import namespace="System.Linq" #>
  7. <#@ import namespace="System.Text" #>
  8. <#@ import namespace="System.Collections.Generic" #>
  9. <#@ output extension=".cs" #>
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using Xunit;
  16. namespace Tests
  17. {
  18. partial class GroupBy
  19. {
  20. <#
  21. foreach (var kind in new[] { "Sync", "Async", "Async_Cancel" })
  22. {
  23. string keySelectorType, elementSelectorType, resultSelectorType;
  24. string keySelectorFunc, elementSelectorFunc, resultSelectorFunc;
  25. string suffix;
  26. bool isCancel = false;
  27. switch (kind)
  28. {
  29. case "Sync":
  30. keySelectorType = elementSelectorType = "Func<int, int>";
  31. keySelectorFunc = elementSelectorFunc = "(int x) => x";
  32. resultSelectorType = "Func<int, IAsyncEnumerable<int>, int>";
  33. resultSelectorFunc = "(k, g) => 0";
  34. suffix = "";
  35. break;
  36. case "Async":
  37. keySelectorType = elementSelectorType = "Func<int, ValueTask<int>>";
  38. keySelectorFunc = elementSelectorFunc = "(int x) => new ValueTask<int>(x)";
  39. resultSelectorType = "Func<int, IAsyncEnumerable<int>, ValueTask<int>>";
  40. resultSelectorFunc = "(k, g) => new ValueTask<int>(0)";
  41. suffix = "Await";
  42. break;
  43. case "Async_Cancel":
  44. keySelectorType = elementSelectorType = "Func<int, CancellationToken, ValueTask<int>>";
  45. keySelectorFunc = elementSelectorFunc = "(int x, CancellationToken ct) => new ValueTask<int>(x)";
  46. resultSelectorType = "Func<int, IAsyncEnumerable<int>, CancellationToken, ValueTask<int>>";
  47. resultSelectorFunc = "(k, g, ct) => new ValueTask<int>(0)";
  48. suffix = "AwaitWithCancellation";
  49. isCancel = true;
  50. break;
  51. default:
  52. throw new Exception();
  53. }
  54. if (isCancel)
  55. {
  56. #>
  57. #if !NO_DEEP_CANCELLATION
  58. <#
  59. }
  60. string keySelector, elementSelector, resultSelector;
  61. switch (kind)
  62. {
  63. case "Sync":
  64. keySelector = "m => m.Name";
  65. elementSelector = "m => m.Name.ToUpper()";
  66. resultSelector = "(k, g) => k + \" - \" + g.CountAsync().Result";
  67. break;
  68. case "Async":
  69. keySelector = "m => new ValueTask<string>(m.Name)";
  70. elementSelector = "m => new ValueTask<string>(m.Name.ToUpper())";
  71. resultSelector = "async (k, g) => k + \" - \" + await g.CountAsync()";
  72. break;
  73. case "Async_Cancel":
  74. keySelector = "(m, ct) => new ValueTask<string>(m.Name)";
  75. elementSelector = "(m, ct) => new ValueTask<string>(m.Name.ToUpper())";
  76. resultSelector = "async (k, g, ct) => k + \" - \" + await g.CountAsync(ct)";
  77. break;
  78. default:
  79. throw new Exception();
  80. }
  81. #>
  82. [Fact]
  83. public void KeySelector_<#=kind#>_Null()
  84. {
  85. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>));
  86. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int>(Return42, default(<#=keySelectorType#>)));
  87. }
  88. [Fact]
  89. public async Task KeySelector_<#=kind#>_All()
  90. {
  91. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  92. var methodsA = methodsS.ToAsyncEnumerable();
  93. var resS = methodsS.GroupBy(m => m.Name);
  94. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>);
  95. await Groups_AssertCore(resS, resA);
  96. }
  97. [Fact]
  98. public void KeySelector_<#=kind#>_Comparer_Null()
  99. {
  100. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, EqualityComparer<int>.Default));
  101. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int>(Return42, default(<#=keySelectorType#>), EqualityComparer<int>.Default));
  102. }
  103. [Fact]
  104. public async Task KeySelector_<#=kind#>_Comparer_All()
  105. {
  106. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  107. var methodsA = methodsS.ToAsyncEnumerable();
  108. var eq = new StringPrefixEqualityComparer(1);
  109. var resS = methodsS.GroupBy(m => m.Name, eq);
  110. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, eq);
  111. await Groups_AssertCore(resS, resA);
  112. }
  113. [Fact]
  114. public void KeySelector_ElementSelector_<#=kind#>_Null()
  115. {
  116. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=elementSelectorFunc#>));
  117. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>));
  118. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, <#=keySelectorFunc#>, default(<#=elementSelectorType#>)));
  119. }
  120. [Fact]
  121. public async Task KeySelector_ElementSelector_<#=kind#>_All()
  122. {
  123. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  124. var methodsA = methodsS.ToAsyncEnumerable();
  125. var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper());
  126. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=elementSelector#>);
  127. await Groups_AssertCore(resS, resA);
  128. }
  129. [Fact]
  130. public void KeySelector_ElementSelector_<#=kind#>_Comparer_Null()
  131. {
  132. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, EqualityComparer<int>.Default));
  133. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, EqualityComparer<int>.Default));
  134. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, default(<#=elementSelectorType#>), EqualityComparer<int>.Default));
  135. }
  136. [Fact]
  137. public async Task KeySelector_ElementSelector_<#=kind#>_Comparer_All()
  138. {
  139. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  140. var methodsA = methodsS.ToAsyncEnumerable();
  141. var eq = new StringPrefixEqualityComparer(1);
  142. var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq);
  143. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=elementSelector#>, eq);
  144. await Groups_AssertCore(resS, resA);
  145. }
  146. [Fact]
  147. public void KeySelector_ResultSelector_<#=kind#>_Null()
  148. {
  149. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=resultSelectorFunc#>));
  150. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, default(<#=keySelectorType#>), <#=resultSelectorFunc#>));
  151. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, <#=keySelectorFunc#>, default(<#=resultSelectorType#>)));
  152. }
  153. [Fact]
  154. public async Task KeySelector_ResultSelector_<#=kind#>_All()
  155. {
  156. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  157. var methodsA = methodsS.ToAsyncEnumerable();
  158. var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count());
  159. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=resultSelector#>);
  160. await Group_Result_AssertCore(resS, resA);
  161. }
  162. [Fact]
  163. public void KeySelector_ResultSelector_<#=kind#>_Comparer_Null()
  164. {
  165. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer<int>.Default));
  166. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(Return42, default(<#=keySelectorType#>), <#=resultSelectorFunc#>, EqualityComparer<int>.Default));
  167. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, default(<#=resultSelectorType#>), EqualityComparer<int>.Default));
  168. }
  169. [Fact]
  170. public async Task KeySelector_ResultSelector_<#=kind#>_Comparer_All()
  171. {
  172. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  173. var methodsA = methodsS.ToAsyncEnumerable();
  174. var eq = new StringPrefixEqualityComparer(1);
  175. var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count(), eq);
  176. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=resultSelector#>, eq);
  177. await Group_Result_AssertCore(resS, resA);
  178. }
  179. [Fact]
  180. public void KeySelector_ElementSelector_ResultSelector_<#=kind#>_Null()
  181. {
  182. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, <#=resultSelectorFunc#>));
  183. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, <#=resultSelectorFunc#>));
  184. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(Return42, <#=keySelectorFunc#>, default(<#=elementSelectorType#>), <#=resultSelectorFunc#>));
  185. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(Return42, <#=keySelectorFunc#>, <#=elementSelectorFunc#>, default(<#=resultSelectorType#>)));
  186. }
  187. [Fact]
  188. public async Task KeySelector_ElementSelector_ResultSelector_<#=kind#>_All()
  189. {
  190. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  191. var methodsA = methodsS.ToAsyncEnumerable();
  192. var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count());
  193. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=elementSelector#>, <#=resultSelector#>);
  194. await Group_Result_AssertCore(resS, resA);
  195. }
  196. [Fact]
  197. public void KeySelector_ElementSelector_ResultSelector_<#=kind#>_Comparer_Null()
  198. {
  199. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer<int>.Default));
  200. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer<int>.Default));
  201. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, default(<#=elementSelectorType#>), <#=resultSelectorFunc#>, EqualityComparer<int>.Default));
  202. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.GroupBy<#=suffix#><int, int, int, int>(default(IAsyncEnumerable<int>), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, default(<#=resultSelectorType#>), EqualityComparer<int>.Default));
  203. }
  204. [Fact]
  205. public async Task KeySelector_ElementSelector_ResultSelector_<#=kind#>_Comparer_All()
  206. {
  207. var methodsS = typeof(Enumerable).GetMethods().AsEnumerable();
  208. var methodsA = methodsS.ToAsyncEnumerable();
  209. var eq = new StringPrefixEqualityComparer(1);
  210. var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count(), eq);
  211. var resA = methodsA.GroupBy<#=suffix#>(<#=keySelector#>, <#=elementSelector#>, <#=resultSelector#>, eq);
  212. await Group_Result_AssertCore(resS, resA);
  213. }
  214. <#
  215. if (isCancel)
  216. {
  217. #>
  218. #endif
  219. <#
  220. }
  221. #>
  222. <#
  223. }
  224. #>
  225. private async Task Groups_AssertCore<T, K>(IEnumerable<IGrouping<K, T>> resS, IAsyncEnumerable<IAsyncGrouping<K, T>> resA)
  226. {
  227. Assert.True(await AsyncEnumerable.SequenceEqualAsync(
  228. resS.Select(g => g.Key).ToAsyncEnumerable(),
  229. resA.Select(g => g.Key)
  230. ));
  231. // CountAsync
  232. Assert.Equal(resS.Count(), await resA.CountAsync());
  233. // ToArrayAsync
  234. var resArrS = resS.ToArray();
  235. var resArrA = await resA.ToArrayAsync();
  236. Assert.Equal(
  237. resArrS.Select(g => g.Key),
  238. resArrA.Select(g => g.Key)
  239. );
  240. // ToListAsync
  241. var resLstS = resS.ToList();
  242. var resLstA = await resA.ToListAsync();
  243. Assert.Equal(
  244. resLstS.Select(g => g.Key),
  245. resLstA.Select(g => g.Key)
  246. );
  247. }
  248. private async Task Group_Result_AssertCore<T>(IEnumerable<T> resS, IAsyncEnumerable<T> resA)
  249. {
  250. Assert.True(await AsyncEnumerable.SequenceEqualAsync(
  251. resS.ToAsyncEnumerable(),
  252. resA
  253. ));
  254. // CountAsync
  255. Assert.Equal(resS.Count(), await resA.CountAsync());
  256. // ToArrayAsync
  257. var resArrS = resS.ToArray();
  258. var resArrA = await resA.ToArrayAsync();
  259. Assert.Equal(resArrS, resArrA);
  260. // ToListAsync
  261. var resLstS = resS.ToList();
  262. var resLstA = await resA.ToListAsync();
  263. Assert.Equal(resLstS, resLstA);
  264. }
  265. private sealed class StringPrefixEqualityComparer : IEqualityComparer<string>
  266. {
  267. private readonly int _n;
  268. public StringPrefixEqualityComparer(int n) => _n = n;
  269. public bool Equals(string s1, string s2) => s1.Substring(0, _n) == s2.Substring(0, _n);
  270. public int GetHashCode(string s) => s.Substring(0, _n).GetHashCode();
  271. }
  272. }
  273. }