Tests.Qbservable.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. #if !SILVERLIGHTM7
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Reflection;
  8. using Microsoft.VisualStudio.TestTools.UnitTesting;
  9. using System.Runtime.CompilerServices;
  10. using System.Linq.Expressions;
  11. using System.ComponentModel;
  12. namespace Tests
  13. {
  14. public partial class Tests
  15. {
  16. [TestMethod]
  17. public void Queryable_Enumerable_Parity()
  18. {
  19. var enu = typeof(EnumerableEx).GetMethods(BindingFlags.Public | BindingFlags.Static).ToList();
  20. var qry = typeof(QueryableEx).GetMethods(BindingFlags.Public | BindingFlags.Static).ToList();
  21. var onlyInObs = enu.Select(m => m.Name).Except(qry.Select(m => m.Name)).Except(new[] { "ForEach", "ToEnumerable", "Multicast", "GetAwaiter", "ToEvent", "ToEventPattern", "ForEachAsync" }).ToList();
  22. var onlyInQbs = qry.Select(m => m.Name).Except(enu.Select(m => m.Name)).Except(new[] { "ToQueryable", "get_Provider", "Empty", "Range" }).ToList();
  23. Assert.IsTrue(onlyInObs.Count == 0, "Missing Queryable operator: " + string.Join(", ", onlyInObs.ToArray()));
  24. Assert.IsTrue(onlyInQbs.Count == 0, "Missing Enumerable operator: " + string.Join(", ", onlyInQbs.ToArray()));
  25. var enus = enu.GroupBy(m => m.Name);
  26. var qrys = qry.GroupBy(m => m.Name);
  27. var mtch = (from o in enus
  28. join q in qrys on o.Key equals q.Key
  29. select new { Name = o.Key, Enumerable = o.ToList(), Queryable = q.ToList() })
  30. .ToList();
  31. Func<Type, bool> filterReturn = t =>
  32. {
  33. if (t.IsGenericType)
  34. {
  35. var gd = t.GetGenericTypeDefinition();
  36. if (gd == typeof(IBuffer<>))
  37. return false;
  38. }
  39. return true;
  40. };
  41. Func<MethodInfo, bool> filterHelper = m =>
  42. {
  43. return !m.IsDefined(typeof(EditorBrowsableAttribute), false);
  44. };
  45. foreach (var group in mtch)
  46. {
  47. var oss = group.Enumerable.Where(m => filterReturn(m.ReturnType)).Select(m => GetSignature(m, false)).OrderBy(x => x).ToList();
  48. var qss = group.Queryable.Where(m => filterHelper(m)).Select(m => GetSignature(m, true)).OrderBy(x => x).ToList();
  49. Assert.IsTrue(oss.SequenceEqual(qss), "Mismatch between QueryableEx and EnumerableEx for " + group.Name);
  50. }
  51. }
  52. public static string GetSignature(MethodInfo m, bool correct)
  53. {
  54. var ps = m.GetParameters();
  55. var pss = ps.AsEnumerable();
  56. if (correct && ps.Length > 0 && ps[0].ParameterType == typeof(IQueryProvider))
  57. pss = pss.Skip(1);
  58. var gens = m.IsGenericMethod ? string.Format("<{0}>", string.Join(", ", m.GetGenericArguments().Select(a => GetTypeName(a, correct)).ToArray())) : "";
  59. var pars = string.Join(", ", pss.Select(p => (Attribute.IsDefined(p, typeof(ParamArrayAttribute)) ? "params " : "") + GetTypeName(p.ParameterType, correct) + " " + p.Name).ToArray());
  60. if (Attribute.IsDefined(m, typeof(ExtensionAttribute)))
  61. {
  62. if (pars.StartsWith("IQbservable") || pars.StartsWith("IQueryable"))
  63. pars = "this " + pars;
  64. }
  65. return string.Format("{0} {1}{2}({3})", GetTypeName(m.ReturnType, correct), m.Name, gens, pars);
  66. }
  67. public static string GetTypeName(Type t, bool correct)
  68. {
  69. if (t.IsGenericType)
  70. {
  71. var gtd = t.GetGenericTypeDefinition();
  72. if (gtd == typeof(Expression<>))
  73. return GetTypeName(t.GetGenericArguments()[0], false);
  74. var args = string.Join(", ", t.GetGenericArguments().Select(a => GetTypeName(a, false)).ToArray());
  75. var len = t.Name.IndexOf('`');
  76. var name = len >= 0 ? t.Name.Substring(0, len) : t.Name;
  77. if (correct && name == "IQbservable")
  78. name = "IObservable";
  79. if (correct && name == "IQueryable")
  80. name = "IEnumerable";
  81. return string.Format("{0}<{1}>", name, args);
  82. }
  83. if (t.IsArray)
  84. {
  85. return GetTypeName(t.GetElementType(), correct) + "[]";
  86. }
  87. return t.Name;
  88. }
  89. [TestMethod]
  90. public void QueryableRetarget1()
  91. {
  92. var res = QueryableEx.Provider.Empty<int>().AsEnumerable().ToList();
  93. Assert.IsTrue(res.SequenceEqual(new int[0]));
  94. }
  95. [TestMethod]
  96. public void QueryableRetarget2()
  97. {
  98. var res = QueryableEx.Provider.Return(42).AsEnumerable().ToList();
  99. Assert.IsTrue(res.SequenceEqual(new[] { 42 }));
  100. }
  101. [TestMethod]
  102. public void QueryableRetarget3()
  103. {
  104. var res = Enumerable.Range(0, 10).AsQueryable().TakeLast(2).AsEnumerable().ToList();
  105. Assert.IsTrue(res.SequenceEqual(new[] { 8, 9 }));
  106. }
  107. [TestMethod]
  108. public void QueryableRetarget4()
  109. {
  110. var res = QueryableEx.Provider.Range(0, 10).AsEnumerable().ToList();
  111. Assert.IsTrue(res.SequenceEqual(Enumerable.Range(0, 10)));
  112. }
  113. }
  114. }
  115. #endif