PageRenderTime 58ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Tests/DynamicWhereClause/DynamicWhereClauseTests.cs

http://tgh.codeplex.com
C# | 2149 lines | 1619 code | 383 blank | 147 comment | 288 complexity | 014102bfd85c1adf0ad223d540d174d2 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. using AutoMapper;
  5. using FluentAssertions;
  6. using NUnit.Framework;
  7. using Telerik.Web.Mvc;
  8. using TelerikMvcGridCustomBindingHelper;
  9. using TelerikMvcGridCustomBindingHelper.DynamicQuery;
  10. using TelerikMvcGridCustomBindingHelper.Mapper;
  11. using TelerikMvcGridCustomBindingHelper.Util;
  12. using Tests.Entity;
  13. using Tests.ViewModel;
  14. namespace Tests.DynamicWhereClause
  15. {
  16. public class ExpressionWhereClauseWithBooleanSubstituteTests
  17. {
  18. //todo: CustomExpressions
  19. [SetUp]
  20. public void SetUp()
  21. {
  22. Mapper.Reset();
  23. GridModelMapper.Reset();
  24. GridModelMapper.CreateMap<Foo, FooModel>()
  25. // Add a BooleanSubstitute to a single property
  26. .MapProperty(foo => foo.EnabledFlag, model => model.Enabled, options => options.SetBooleanSubstitute<BooleanSubstitute>());
  27. //todo: .MapProperty(foo => foo.EnabledFlag == "" && foo.EnabledFlag == "", model => model.ComplexEnabled, options => options.SetBooleanSubstitute<BooleanSubstitute>());
  28. // GlobalBooleanSubstitutes have lower precedence
  29. GridModelMapper.Configuration.SetGlobalBooleanSubstitute<EfBooleanSubstitute>();
  30. }
  31. private class BooleanSubstitute : IBooleanSubstitute
  32. {
  33. public IList<object> TrueValues()
  34. {
  35. return new[] { "Y" };
  36. }
  37. public IList<object> FalseValues()
  38. {
  39. return new[] { "N", null };
  40. }
  41. }
  42. private class EfBooleanSubstitute : IBooleanSubstitute
  43. {
  44. public IList<object> TrueValues()
  45. {
  46. return new object[] { true };
  47. }
  48. public IList<object> FalseValues()
  49. {
  50. return new object[] { false, null };
  51. }
  52. }
  53. #region ExpressionCases
  54. // ReSharper disable InconsistentNaming
  55. // ReSharper disable NegativeEqualityExpression
  56. static readonly Expression<Func<Foo, bool>> Exp_IsEqualToTrue = foo => foo.EnabledFlag == "Y";
  57. static readonly Expression<Func<Foo, bool>> Exp_IsNotEqualToTrue = foo => !(foo.EnabledFlag == "Y");
  58. static readonly Expression<Func<Foo, bool>> Exp_IsEqualToFalse = foo => foo.EnabledFlag == null || foo.EnabledFlag == "N";
  59. static readonly Expression<Func<Foo, bool>> Exp_IsNotEqualToFalse = foo => !(foo.EnabledFlag == null) || !(foo.EnabledFlag == "N");
  60. static readonly Expression<Func<Foo, bool>> Exp_EfIsEqualToTrue = foo => foo.EfEnabled == true;
  61. static readonly Expression<Func<Foo, bool>> Exp_EfIsNotEqualToTrue = foo => !(foo.EfEnabled == true);
  62. static readonly Expression<Func<Foo, bool>> Exp_EfIsEqualToFalse = foo => foo.EfEnabled == null || foo.EfEnabled == false;
  63. static readonly Expression<Func<Foo, bool>> Exp_EfIsNotEqualToFalse = foo => !(foo.EfEnabled == null) || !(foo.EfEnabled == false);
  64. static readonly object[] ExpressionCases =
  65. {
  66. new object[] { "EnabledFlag", FilterOperator.IsEqualTo, Exp_IsEqualToTrue, true },
  67. new object[] { "EnabledFlag", FilterOperator.IsNotEqualTo, Exp_IsNotEqualToTrue, true},
  68. new object[] { "EnabledFlag", FilterOperator.IsEqualTo, Exp_IsEqualToFalse, false },
  69. new object[] { "EnabledFlag", FilterOperator.IsNotEqualTo, Exp_IsNotEqualToFalse, false},
  70. new object[] { "EnabledFlag", FilterOperator.IsEqualTo, Exp_IsEqualToFalse, null},
  71. new object[] { "EnabledFlag", FilterOperator.IsNotEqualTo, Exp_IsNotEqualToFalse, null},
  72. new object[] { "EfEnabled", FilterOperator.IsEqualTo, Exp_EfIsEqualToTrue, true },
  73. new object[] { "EfEnabled", FilterOperator.IsNotEqualTo, Exp_EfIsNotEqualToTrue, true},
  74. new object[] { "EfEnabled", FilterOperator.IsEqualTo, Exp_EfIsEqualToFalse, false },
  75. new object[] { "EfEnabled", FilterOperator.IsNotEqualTo, Exp_EfIsNotEqualToFalse, false},
  76. new object[] { "EfEnabled", FilterOperator.IsEqualTo, Exp_EfIsEqualToFalse, null},
  77. new object[] { "EfEnabled", FilterOperator.IsNotEqualTo, Exp_EfIsNotEqualToFalse, null}
  78. };
  79. // ReSharper restore NegativeEqualityExpression
  80. // ReSharper restore InconsistentNaming
  81. #endregion
  82. [TestCaseSource("ExpressionCases")]
  83. public void expressionWhereClause_single_expressions_with_booleanSubstitute(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  84. {
  85. var filter = new FilterDescriptor(member, @operator, value);
  86. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  87. expressionWhereClause.Predicate.ToString().Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithBooleanSubstituteTests+Foo", "foo").Should().Be(exp.ToString());
  88. }
  89. [TestCaseSource("ExpressionCases")]
  90. public void expressionWhereClause_double_expressions_with_orElse_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  91. {
  92. var filter = new FilterDescriptor(member, @operator, value);
  93. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  94. expressionWhereClause.Predicate.ToString().Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithBooleanSubstituteTests+Foo", "foo").Should().Be(exp.ToString());
  95. expressionWhereClause.OrElse(expressionWhereClause);
  96. expressionWhereClause.Predicate.ToString().Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithBooleanSubstituteTests+Foo", "foo").Should().Be(exp.OrElse(exp).ToString());
  97. }
  98. [TestCaseSource("ExpressionCases")]
  99. public void expressionWhereClause_double_expressions_with_andAlso_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  100. {
  101. var filter = new FilterDescriptor(member, @operator, value);
  102. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  103. expressionWhereClause.Predicate.ToString().Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithBooleanSubstituteTests+Foo", "foo").Should().Be(exp.ToString());
  104. expressionWhereClause.AndAlso(expressionWhereClause);
  105. expressionWhereClause.Predicate.ToString().Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithBooleanSubstituteTests+Foo", "foo").Should().Be(exp.AndAlso(exp).ToString());
  106. }
  107. #region Test models
  108. // ReSharper disable ClassNeverInstantiated.Global
  109. // ReSharper disable UnusedAutoPropertyAccessor.Global
  110. // ReSharper disable ClassNeverInstantiated.Local
  111. // ReSharper disable UnusedAutoPropertyAccessor.Local
  112. // ReSharper disable UnusedMember.Local
  113. public class Foo
  114. {
  115. public bool? EfEnabled { get; set; }
  116. public string EnabledFlag { get; set; }
  117. }
  118. private class FooModel
  119. {
  120. public bool? EfEnabled { get; set; }
  121. public bool Enabled { get; set; }
  122. public bool ComplexEnabled { get; set; }
  123. }
  124. // ReSharper restore UnusedMember.Local
  125. // ReSharper restore UnusedAutoPropertyAccessor.Local
  126. // ReSharper restore ClassNeverInstantiated.Local
  127. // ReSharper restore UnusedAutoPropertyAccessor.Global
  128. // ReSharper restore ClassNeverInstantiated.Global
  129. #endregion
  130. }
  131. public class ExpressionWhereClauseWithNullSubstituteTests
  132. {
  133. //todo: CustomExpressions
  134. [SetUp]
  135. public void SetUp()
  136. {
  137. Mapper.Reset(); GridModelMapper.Reset();
  138. //GridModelMapper.CreateMap<Foo, FooModel>()
  139. // .MapProperty(foo => foo.FirstName + " " + foo.LastName, model => model.FullName)
  140. // .MapProperty(foo => foo.UnitPrice + foo.UnitsInStock, model => model.TotalPrice);
  141. GridModelMapper.CreateMap<Foo, FooModel>();
  142. // Can be set globally, per property, or in per query basis
  143. GridModelMapper.Configuration.SetGlobalNullSubstitute<NullSubstitute>();
  144. }
  145. private class NullSubstitute : INullSubstitute
  146. {
  147. public bool IsCaseInsensitive { get { return false; } }
  148. public IList<object> NullValues()
  149. {
  150. return new object[] { "none", string.Empty, 0, new DateTime(), null };
  151. }
  152. }
  153. #region ExpressionCases
  154. // ReSharper disable InconsistentNaming
  155. // ReSharper disable NegativeEqualityExpression
  156. static readonly Expression<Func<Foo, bool>> Exp_NullableIsEqualTo = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value == 0;
  157. static readonly Expression<Func<Foo, bool>> Exp_StringIsEqualTo = foo => foo.Name == "none" || foo.Name == "" || foo.Name == "0" || foo.Name == "01/01/0001 00:00:00" || foo.Name == null;
  158. static readonly Expression<Func<Foo, bool>> Exp_StringIsNotEqualTo = foo => !(foo.Name == "none") || !(foo.Name == "") || !(foo.Name == "0") || !(foo.Name == "01/01/0001 00:00:00") || !(foo.Name == null);
  159. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsEqualTo = foo => foo.NotNullableDecimal == 0;
  160. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsNotEqualTo = foo => foo.NotNullableDecimal != 0;
  161. static readonly Expression<Func<Foo, bool>> Exp_NotSubstituteIsEqualTo = foo => foo.Name == "value";
  162. static readonly Expression<Func<Foo, bool>> Exp_NotSubstituteIsNotEqualTo = foo => foo.Name != "value";
  163. static readonly Expression<Func<Foo, bool>> Exp_DateTimeIsEqualTo = foo => foo.DateTime == new DateTime(2012, 10, 19);
  164. static readonly Expression<Func<Foo, bool>> Exp_DateTimeIsNotEqualTo = foo => foo.DateTime != new DateTime(2012, 10, 19);
  165. static readonly object[] ExpressionCases =
  166. {
  167. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsEqualTo, null },
  168. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsEqualTo, null },
  169. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsEqualTo, null },
  170. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsEqualTo, null },
  171. new object[] { "Name", FilterOperator.StartsWith, Exp_StringIsEqualTo, null },
  172. new object[] { "Name", FilterOperator.EndsWith, Exp_StringIsEqualTo, null },
  173. new object[] { "Name", FilterOperator.Contains, Exp_StringIsEqualTo, null },
  174. new object[] { "Name", FilterOperator.DoesNotContain, Exp_StringIsNotEqualTo, null },
  175. new object[] { "Name", FilterOperator.IsEqualTo, Exp_StringIsEqualTo, null },
  176. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_StringIsNotEqualTo, null },
  177. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableIsEqualTo, null },
  178. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableIsNotEqualTo, null },
  179. new object[] { "Name", FilterOperator.IsEqualTo, Exp_NotSubstituteIsEqualTo, "value" },
  180. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_NotSubstituteIsNotEqualTo, "value" },
  181. new object[] { "DateTime", FilterOperator.IsEqualTo, Exp_DateTimeIsEqualTo, new DateTime(2012, 10, 19) },
  182. new object[] { "DateTime", FilterOperator.IsNotEqualTo, Exp_DateTimeIsNotEqualTo, new DateTime(2012, 10, 19) }
  183. };
  184. // ReSharper restore NegativeEqualityExpression
  185. // ReSharper restore InconsistentNaming
  186. #endregion
  187. [TestCaseSource("ExpressionCases")]
  188. public void expressionWhereClause_single_expressions_with_booleanSubstitute(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  189. {
  190. var filter = new FilterDescriptor(member, @operator, value);
  191. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  192. expressionWhereClause.Predicate.ToString()
  193. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteTests+Foo", "foo")
  194. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  195. }
  196. [TestCaseSource("ExpressionCases")]
  197. public void expressionWhereClause_double_expressions_with_orElse_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  198. {
  199. var filter = new FilterDescriptor(member, @operator, value);
  200. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  201. expressionWhereClause.Predicate.ToString()
  202. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteTests+Foo", "foo")
  203. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  204. expressionWhereClause.OrElse(expressionWhereClause);
  205. expressionWhereClause.Predicate.ToString()
  206. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteTests+Foo", "foo")
  207. .Should().Be(exp.OrElse(exp).ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  208. }
  209. [TestCaseSource("ExpressionCases")]
  210. public void expressionWhereClause_double_expressions_with_andAlso_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  211. {
  212. var filter = new FilterDescriptor(member, @operator, value);
  213. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  214. expressionWhereClause.Predicate.ToString()
  215. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteTests+Foo", "foo")
  216. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  217. expressionWhereClause.AndAlso(expressionWhereClause);
  218. expressionWhereClause.Predicate.ToString()
  219. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteTests+Foo", "foo")
  220. .Should().Be(exp.AndAlso(exp).ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  221. }
  222. #region Test models
  223. // ReSharper disable ClassNeverInstantiated.Global
  224. // ReSharper disable UnusedAutoPropertyAccessor.Global
  225. // ReSharper disable ClassNeverInstantiated.Local
  226. // ReSharper disable UnusedAutoPropertyAccessor.Local
  227. // ReSharper disable UnusedMember.Local
  228. public class Foo
  229. {
  230. public string Name { get; set; }
  231. public decimal? NullableDecimal { get; set; }
  232. public decimal NotNullableDecimal { get; set; }
  233. public DateTime DateTime { get; set; }
  234. }
  235. private class FooModel
  236. {
  237. public string Name { get; set; }
  238. public decimal? NullableDecimal { get; set; }
  239. public decimal NotNullableDecimal { get; set; }
  240. public DateTime DateTime { get; set; }
  241. }
  242. // ReSharper restore UnusedMember.Local
  243. // ReSharper restore UnusedAutoPropertyAccessor.Local
  244. // ReSharper restore ClassNeverInstantiated.Local
  245. // ReSharper restore UnusedAutoPropertyAccessor.Global
  246. // ReSharper restore ClassNeverInstantiated.Global
  247. #endregion
  248. }
  249. public class ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests
  250. {
  251. //todo: CustomExpressions
  252. [SetUp]
  253. public void SetUp()
  254. {
  255. Mapper.Reset(); GridModelMapper.Reset();
  256. //GridModelMapper.CreateMap<Foo, FooModel>()
  257. // .MapProperty(foo => foo.FirstName + " " + foo.LastName, model => model.FullName)
  258. // .MapProperty(foo => foo.UnitPrice + foo.UnitsInStock, model => model.TotalPrice);
  259. GridModelMapper.CreateMap<Foo, FooModel>();
  260. // Can be set globally, per property, or in per query basis
  261. GridModelMapper.Configuration.SetGlobalNullSubstitute<NullSubstitute>();
  262. }
  263. private class NullSubstitute : INullSubstitute
  264. {
  265. public bool IsCaseInsensitive { get { return true; } }
  266. public IList<object> NullValues()
  267. {
  268. return new object[] { "NoNe", string.Empty, 0, new DateTime(), null };
  269. }
  270. }
  271. #region ExpressionCases
  272. // ReSharper disable InconsistentNaming
  273. // ReSharper disable NegativeEqualityExpression
  274. static readonly Expression<Func<Foo, bool>> Exp_NullableIsEqualTo = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value == 0;
  275. static readonly Expression<Func<Foo, bool>> Exp_StringIsEqualTo = foo => foo.Name.ToLowerInvariant() == "none" || foo.Name.ToLowerInvariant() == "" || foo.Name.ToLowerInvariant() == "0" || foo.Name.ToLowerInvariant() == "01/01/0001 00:00:00" || foo.Name == null;
  276. static readonly Expression<Func<Foo, bool>> Exp_StringIsNotEqualTo = foo => !(foo.Name.ToLowerInvariant() == "none") || !(foo.Name.ToLowerInvariant() == "") || !(foo.Name.ToLowerInvariant() == "0") || !(foo.Name.ToLowerInvariant() == "01/01/0001 00:00:00") || !(foo.Name == null);
  277. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsEqualTo = foo => foo.NotNullableDecimal == 0;
  278. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsNotEqualTo = foo => foo.NotNullableDecimal != 0;
  279. static readonly Expression<Func<Foo, bool>> Exp_NotSubstituteIsEqualTo = foo => foo.Name == "value";
  280. static readonly Expression<Func<Foo, bool>> Exp_NotSubstituteIsNotEqualTo = foo => foo.Name != "value";
  281. static readonly Expression<Func<Foo, bool>> Exp_DateTimeIsEqualTo = foo => foo.DateTime == new DateTime(2012, 10, 19);
  282. static readonly Expression<Func<Foo, bool>> Exp_DateTimeIsNotEqualTo = foo => foo.DateTime != new DateTime(2012, 10, 19);
  283. static readonly object[] ExpressionCases =
  284. {
  285. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsEqualTo, null },
  286. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsEqualTo, null },
  287. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsEqualTo, null },
  288. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsEqualTo, null },
  289. new object[] { "Name", FilterOperator.StartsWith, Exp_StringIsEqualTo, null },
  290. new object[] { "Name", FilterOperator.EndsWith, Exp_StringIsEqualTo, null },
  291. new object[] { "Name", FilterOperator.Contains, Exp_StringIsEqualTo, null },
  292. new object[] { "Name", FilterOperator.DoesNotContain, Exp_StringIsNotEqualTo, null },
  293. new object[] { "Name", FilterOperator.IsEqualTo, Exp_StringIsEqualTo, null },
  294. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_StringIsNotEqualTo, null },
  295. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableIsEqualTo, null },
  296. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableIsNotEqualTo, null },
  297. new object[] { "Name", FilterOperator.IsEqualTo, Exp_NotSubstituteIsEqualTo, "value" },
  298. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_NotSubstituteIsNotEqualTo, "value" },
  299. new object[] { "DateTime", FilterOperator.IsEqualTo, Exp_DateTimeIsEqualTo, new DateTime(2012, 10, 19) },
  300. new object[] { "DateTime", FilterOperator.IsNotEqualTo, Exp_DateTimeIsNotEqualTo, new DateTime(2012, 10, 19) }
  301. };
  302. // ReSharper restore NegativeEqualityExpression
  303. // ReSharper restore InconsistentNaming
  304. #endregion
  305. [TestCaseSource("ExpressionCases")]
  306. public void expressionWhereClause_single_expressions_with_booleanSubstitute(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  307. {
  308. var filter = new FilterDescriptor(member, @operator, value);
  309. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  310. expressionWhereClause.Predicate.ToString()
  311. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests+Foo", "foo")
  312. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  313. }
  314. [TestCaseSource("ExpressionCases")]
  315. public void expressionWhereClause_double_expressions_with_orElse_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  316. {
  317. var filter = new FilterDescriptor(member, @operator, value);
  318. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  319. expressionWhereClause.Predicate.ToString()
  320. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests+Foo", "foo")
  321. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  322. expressionWhereClause.OrElse(expressionWhereClause);
  323. expressionWhereClause.Predicate.ToString()
  324. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests+Foo", "foo")
  325. .Should().Be(exp.OrElse(exp).ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  326. }
  327. [TestCaseSource("ExpressionCases")]
  328. public void expressionWhereClause_double_expressions_with_andAlso_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  329. {
  330. var filter = new FilterDescriptor(member, @operator, value);
  331. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  332. expressionWhereClause.Predicate.ToString()
  333. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests+Foo", "foo")
  334. .Should().Be(exp.ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  335. expressionWhereClause.AndAlso(expressionWhereClause);
  336. expressionWhereClause.Predicate.ToString()
  337. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullSubstituteWithCaseInsensitiveTests+Foo", "foo")
  338. .Should().Be(exp.AndAlso(exp).ToString().Replace(".Value", "").Replace("new DateTime(2012, 10, 19)", "19/10/2012 00:00:00"));
  339. }
  340. #region Test models
  341. // ReSharper disable ClassNeverInstantiated.Global
  342. // ReSharper disable UnusedAutoPropertyAccessor.Global
  343. // ReSharper disable ClassNeverInstantiated.Local
  344. // ReSharper disable UnusedAutoPropertyAccessor.Local
  345. // ReSharper disable UnusedMember.Local
  346. public class Foo
  347. {
  348. public string Name { get; set; }
  349. public decimal? NullableDecimal { get; set; }
  350. public decimal NotNullableDecimal { get; set; }
  351. public DateTime DateTime { get; set; }
  352. }
  353. private class FooModel
  354. {
  355. public string Name { get; set; }
  356. public decimal? NullableDecimal { get; set; }
  357. public decimal NotNullableDecimal { get; set; }
  358. public DateTime DateTime { get; set; }
  359. }
  360. // ReSharper restore UnusedMember.Local
  361. // ReSharper restore UnusedAutoPropertyAccessor.Local
  362. // ReSharper restore ClassNeverInstantiated.Local
  363. // ReSharper restore UnusedAutoPropertyAccessor.Global
  364. // ReSharper restore ClassNeverInstantiated.Global
  365. #endregion
  366. }
  367. public class ExpressionWhereClauseWithNullAliasTests
  368. {
  369. //todo: CustomExpressions
  370. [SetUp]
  371. public void SetUp()
  372. {
  373. Mapper.Reset(); GridModelMapper.Reset();
  374. //GridModelMapper.CreateMap<Foo, FooModel>()
  375. // .MapProperty(foo => foo.FirstName + " " + foo.LastName, model => model.FullName)
  376. // .MapProperty(foo => foo.UnitPrice + foo.UnitsInStock, model => model.TotalPrice);
  377. GridModelMapper.CreateMap<Foo, FooModel>();
  378. GridModelMapper.Configuration.SetGlobalNullAlias<NullAlias>();
  379. }
  380. private class NullAlias : INullAlias
  381. {
  382. public bool IsCaseInsensitive { get { return false; } }
  383. //the query should contain these aliases explicitly?
  384. public bool SearchExplicit { get { return false; } }
  385. public IList<object> Aliases()
  386. {
  387. return new object[] { "none", "empty", -1, null };
  388. }
  389. }
  390. #region ExpressionCases
  391. // ReSharper disable InconsistentNaming
  392. // ReSharper disable NegativeEqualityExpression
  393. static readonly Expression<Func<Foo, bool>> Exp_NullableIsEqualTo = foo => foo.NullableDecimal == null;
  394. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsLessThan = foo => foo.NullableDecimal.Value < 10;
  395. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsLessThanOrEqualTo = foo => foo.NullableDecimal.Value <= 10;
  396. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsGreaterThanOrEqualTo = foo => foo.NullableDecimal.Value >= 10;
  397. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsGreaterThan = foo => foo.NullableDecimal.Value > 10;
  398. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsEqualTo = foo => foo.NullableDecimal.Value == 10;
  399. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsNotEqualTo = foo => foo.NullableDecimal.Value != 10;
  400. static readonly Expression<Func<Foo, bool>> Exp_IsEqualTo = foo => foo.Name == null;
  401. static readonly Expression<Func<Foo, bool>> Exp_IsNotEqualTo = foo => !(foo.Name == null);
  402. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsEqualTo = foo => foo.Name == "value";
  403. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsNotEqualTo = foo => foo.Name != "value";
  404. static readonly Expression<Func<Foo, bool>> Exp_CaseSensitiveIsEqualTo = foo => foo.Name == "NoNe";
  405. static readonly Expression<Func<Foo, bool>> Exp_CaseSensitiveIsNotEqualTo = foo => foo.Name != "EmPtY";
  406. static readonly Expression<Func<Foo, bool>> Exp_NotNullableNullValueIsEqualTo = foo => foo.NotNullableDecimal == 0;
  407. static readonly Expression<Func<Foo, bool>> Exp_NotNullableNullValueIsNotEqualTo = foo => foo.NotNullableDecimal != 0;
  408. static readonly Expression<Func<Foo, bool>> Exp_NotNullableValidValueIsEqualTo = foo => foo.NotNullableDecimal == -1;
  409. static readonly Expression<Func<Foo, bool>> Exp_NotNullableValidValueIsNotEqualTo = foo => foo.NotNullableDecimal != -1;
  410. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsEqualTo = foo => foo.NotNullableDecimal == 10;
  411. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsNotEqualTo = foo => foo.NotNullableDecimal != 10;
  412. static readonly object[] ExpressionCases =
  413. {
  414. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsEqualTo, null },
  415. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsEqualTo, null },
  416. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsEqualTo, null },
  417. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsEqualTo, null },
  418. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsEqualTo, -1 },
  419. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsEqualTo, -1 },
  420. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsEqualTo, -1 },
  421. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsEqualTo, -1 },
  422. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableValidValueIsLessThan, 10 },
  423. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableValidValueIsLessThanOrEqualTo, 10 },
  424. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableValidValueIsGreaterThanOrEqualTo, 10 },
  425. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableValidValueIsGreaterThan, 10 },
  426. new object[] { "NullableDecimal", FilterOperator.IsEqualTo, Exp_NullableValidValueIsEqualTo, 10 },
  427. new object[] { "NullableDecimal", FilterOperator.IsNotEqualTo, Exp_NullableValidValueIsNotEqualTo, 10 },
  428. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableNullValueIsEqualTo, null },
  429. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableNullValueIsNotEqualTo, null },
  430. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableNullValueIsEqualTo, "invalid-value" },
  431. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableNullValueIsNotEqualTo, "invalid-value" },
  432. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableValidValueIsEqualTo, -1 },
  433. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableValidValueIsNotEqualTo, -1 },
  434. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableIsEqualTo, 10 },
  435. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableIsNotEqualTo, 10 },
  436. new object[] { "Name", FilterOperator.StartsWith, Exp_IsEqualTo, "none" },
  437. new object[] { "Name", FilterOperator.EndsWith, Exp_IsEqualTo, "none" },
  438. new object[] { "Name", FilterOperator.Contains, Exp_IsEqualTo, "none" },
  439. new object[] { "Name", FilterOperator.DoesNotContain, Exp_IsNotEqualTo, "none" },
  440. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, null },
  441. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, null },
  442. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, "none" },
  443. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, "empty" },
  444. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, "none" },
  445. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, "empty" },
  446. new object[] { "Name", FilterOperator.IsEqualTo, Exp_NotValidAliasIsEqualTo, "value" },
  447. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_NotValidAliasIsNotEqualTo, "value" },
  448. new object[] { "Name", FilterOperator.IsEqualTo, Exp_CaseSensitiveIsEqualTo, "NoNe" },
  449. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_CaseSensitiveIsNotEqualTo, "EmPtY" }
  450. };
  451. // ReSharper restore NegativeEqualityExpression
  452. // ReSharper restore InconsistentNaming
  453. #endregion
  454. [TestCaseSource("ExpressionCases")]
  455. public void single_expressions(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  456. {
  457. var filter = new FilterDescriptor(member, @operator, value);
  458. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  459. expressionWhereClause.Predicate.ToString()
  460. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasTests+Foo", "foo")
  461. .Should().Be(exp.ToString().Replace(".Value", ""));
  462. }
  463. [TestCaseSource("ExpressionCases")]
  464. public void double_expressions_with_orElse_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  465. {
  466. var filter = new FilterDescriptor(member, @operator, value);
  467. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  468. expressionWhereClause.Predicate.ToString()
  469. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasTests+Foo", "foo")
  470. .Should().Be(exp.ToString().Replace(".Value", ""));
  471. expressionWhereClause.OrElse(expressionWhereClause);
  472. expressionWhereClause.Predicate.ToString()
  473. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasTests+Foo", "foo")
  474. .Should().Be(exp.OrElse(exp).ToString().Replace(".Value", ""));
  475. }
  476. [TestCaseSource("ExpressionCases")]
  477. public void double_expressions_with_andAlso_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  478. {
  479. var filter = new FilterDescriptor(member, @operator, value);
  480. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  481. expressionWhereClause.Predicate.ToString()
  482. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasTests+Foo", "foo")
  483. .Should().Be(exp.ToString().Replace(".Value", ""));
  484. expressionWhereClause.AndAlso(expressionWhereClause);
  485. expressionWhereClause.Predicate.ToString()
  486. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasTests+Foo", "foo")
  487. .Should().Be(exp.AndAlso(exp).ToString().Replace(".Value", ""));
  488. }
  489. #region Test models
  490. // ReSharper disable ClassNeverInstantiated.Global
  491. // ReSharper disable UnusedAutoPropertyAccessor.Global
  492. // ReSharper disable ClassNeverInstantiated.Local
  493. // ReSharper disable UnusedAutoPropertyAccessor.Local
  494. // ReSharper disable UnusedMember.Local
  495. // ReSharper disable UnusedMember.Global
  496. public class Foo
  497. {
  498. public string Name { get; set; }
  499. public decimal? NullableDecimal { get; set; }
  500. public decimal NotNullableDecimal { get; set; }
  501. public DateTime DateTime { get; set; }
  502. }
  503. private class FooModel
  504. {
  505. public string Name { get; set; }
  506. public decimal? NullableDecimal { get; set; }
  507. public decimal NotNullableDecimal { get; set; }
  508. public DateTime DateTime { get; set; }
  509. }
  510. // ReSharper restore UnusedMember.Global
  511. // ReSharper restore UnusedMember.Local
  512. // ReSharper restore UnusedAutoPropertyAccessor.Local
  513. // ReSharper restore ClassNeverInstantiated.Local
  514. // ReSharper restore UnusedAutoPropertyAccessor.Global
  515. // ReSharper restore ClassNeverInstantiated.Global
  516. #endregion
  517. }
  518. public class ExpressionWhereClauseWithNullAliasAndSearchExplicitTests
  519. {
  520. //todo: CustomExpressions
  521. [SetUp]
  522. public void SetUp()
  523. {
  524. Mapper.Reset(); GridModelMapper.Reset();
  525. //GridModelMapper.CreateMap<Foo, FooModel>()
  526. // .MapProperty(foo => foo.FirstName + " " + foo.LastName, model => model.FullName)
  527. // .MapProperty(foo => foo.UnitPrice + foo.UnitsInStock, model => model.TotalPrice);
  528. GridModelMapper.CreateMap<Foo, FooModel>();
  529. GridModelMapper.Configuration.SetGlobalNullAlias<NullAlias>();
  530. }
  531. private class NullAlias : INullAlias
  532. {
  533. public bool IsCaseInsensitive { get { return false; } }
  534. //the query should contain these aliases explicitly?
  535. public bool SearchExplicit { get { return true; } }
  536. public IList<object> Aliases()
  537. {
  538. return new object[] { "none", "empty", -1, null };
  539. }
  540. }
  541. #region ExpressionCases
  542. // ReSharper disable InconsistentNaming
  543. // ReSharper disable NegativeEqualityExpression
  544. static readonly Expression<Func<Foo, bool>> Exp_NullableValidValueIsEqualTo = foo => foo.NullableDecimal.Value == 10;
  545. static readonly Expression<Func<Foo, bool>> Exp_NullableIsEqualTo = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value == -1;
  546. static readonly Expression<Func<Foo, bool>> Exp_NullableIsLessThan = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value < -1;
  547. static readonly Expression<Func<Foo, bool>> Exp_NullableIsLessThanOrEqualTo = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value <= -1;
  548. static readonly Expression<Func<Foo, bool>> Exp_NullableIsGreaterThan = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value > -1;
  549. static readonly Expression<Func<Foo, bool>> Exp_NullableIsGreaterThanOrEqualTo = foo => foo.NullableDecimal == null || foo.NullableDecimal.Value >= -1;
  550. static readonly Expression<Func<Foo, bool>> Exp_NullableIsNotEqualTo = foo => !(foo.NullableDecimal == null) && foo.NullableDecimal.Value != -1;
  551. static readonly Expression<Func<Foo, bool>> Exp_IsEqualTo = foo => foo.Name == null || (foo.Name == "none" || foo.Name == "empty");
  552. static readonly Expression<Func<Foo, bool>> Exp_Contains = foo => foo.Name == null || (foo.Name.Contains("none") || foo.Name.Contains("empty"));
  553. static readonly Expression<Func<Foo, bool>> Exp_EndsWith = foo => foo.Name == null || (foo.Name.EndsWith("none") || foo.Name.EndsWith("empty"));
  554. static readonly Expression<Func<Foo, bool>> Exp_DoesNotContain = foo => !(foo.Name == null) && (!(foo.Name.Contains("none")) && !(foo.Name.Contains("empty")));
  555. static readonly Expression<Func<Foo, bool>> Exp_StartsWith = foo => foo.Name == null || (foo.Name.StartsWith("none") || foo.Name.StartsWith("empty"));
  556. static readonly Expression<Func<Foo, bool>> Exp_IsNotEqualTo = foo => !(foo.Name == null) && (foo.Name != "none" && foo.Name != "empty");
  557. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsEqualTo = foo => foo.Name == "value";
  558. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsNotEqualTo = foo => foo.Name != "value";
  559. static readonly Expression<Func<Foo, bool>> Exp_CaseSensitiveIsEqualTo = foo => foo.Name == "NoNe";
  560. static readonly Expression<Func<Foo, bool>> Exp_CaseSensitiveIsNotEqualTo = foo => foo.Name != "EmPtY";
  561. static readonly Expression<Func<Foo, bool>> Exp_NotNullableDefaultValueIsEqualTo = foo => foo.NotNullableDecimal == 0;
  562. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsEqualTo = foo => foo.NotNullableDecimal == -1;
  563. static readonly Expression<Func<Foo, bool>> Exp_NotNullableValidValueIsEqualTo = foo => foo.NotNullableDecimal == 10;
  564. static readonly Expression<Func<Foo, bool>> Exp_NotNullableIsNotEqualTo = foo => foo.NotNullableDecimal != 0;
  565. static readonly object[] ExpressionCases =
  566. {
  567. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsLessThan, null },
  568. new object[] { "NullableDecimal", FilterOperator.IsLessThan, Exp_NullableIsLessThan, -1 },
  569. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsLessThanOrEqualTo, null },
  570. new object[] { "NullableDecimal", FilterOperator.IsLessThanOrEqualTo, Exp_NullableIsLessThanOrEqualTo, -1 },
  571. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsGreaterThan, null },
  572. new object[] { "NullableDecimal", FilterOperator.IsGreaterThan, Exp_NullableIsGreaterThan, -1 },
  573. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsGreaterThanOrEqualTo, null },
  574. new object[] { "NullableDecimal", FilterOperator.IsGreaterThanOrEqualTo, Exp_NullableIsGreaterThanOrEqualTo, -1 },
  575. new object[] { "NullableDecimal", FilterOperator.IsEqualTo, Exp_NullableIsEqualTo, null },
  576. new object[] { "NullableDecimal", FilterOperator.IsEqualTo, Exp_NullableIsEqualTo, -1 },
  577. new object[] { "NullableDecimal", FilterOperator.IsNotEqualTo, Exp_NullableIsNotEqualTo, null },
  578. new object[] { "NullableDecimal", FilterOperator.IsNotEqualTo, Exp_NullableIsNotEqualTo, -1 },
  579. new object[] { "NullableDecimal", FilterOperator.IsEqualTo, Exp_NullableValidValueIsEqualTo, 10 },
  580. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableValidValueIsEqualTo, 10 },
  581. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableIsEqualTo, -1 },
  582. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableDefaultValueIsEqualTo, null },
  583. new object[] { "NotNullableDecimal", FilterOperator.IsEqualTo, Exp_NotNullableDefaultValueIsEqualTo, "none" },
  584. new object[] { "NotNullableDecimal", FilterOperator.IsNotEqualTo, Exp_NotNullableIsNotEqualTo, null },
  585. new object[] { "Name", FilterOperator.StartsWith, Exp_StartsWith, "none" },
  586. new object[] { "Name", FilterOperator.EndsWith, Exp_EndsWith, "none" },
  587. new object[] { "Name", FilterOperator.Contains, Exp_Contains, "none" },
  588. new object[] { "Name", FilterOperator.DoesNotContain, Exp_DoesNotContain, "none" },
  589. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, null },
  590. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, null },
  591. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, "none" },
  592. new object[] { "Name", FilterOperator.IsEqualTo, Exp_IsEqualTo, "empty" },
  593. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, "none" },
  594. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_IsNotEqualTo, "empty" },
  595. new object[] { "Name", FilterOperator.IsEqualTo, Exp_NotValidAliasIsEqualTo, "value" },
  596. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_NotValidAliasIsNotEqualTo, "value" },
  597. new object[] { "Name", FilterOperator.IsEqualTo, Exp_CaseSensitiveIsEqualTo, "NoNe" },
  598. new object[] { "Name", FilterOperator.IsNotEqualTo, Exp_CaseSensitiveIsNotEqualTo, "EmPtY" }
  599. };
  600. // ReSharper restore NegativeEqualityExpression
  601. // ReSharper restore InconsistentNaming
  602. #endregion
  603. [TestCaseSource("ExpressionCases")]
  604. public void single_expressions(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  605. {
  606. var filter = new FilterDescriptor(member, @operator, value);
  607. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  608. expressionWhereClause.Predicate.ToString()
  609. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasAndSearchExplicitTests+Foo", "foo")
  610. .Should().Be(exp.ToString().Replace(".Value", ""));
  611. }
  612. [TestCaseSource("ExpressionCases")]
  613. public void double_expressions_with_orElse_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  614. {
  615. var filter = new FilterDescriptor(member, @operator, value);
  616. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  617. expressionWhereClause.Predicate.ToString()
  618. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasAndSearchExplicitTests+Foo", "foo")
  619. .Should().Be(exp.ToString().Replace(".Value", ""));
  620. expressionWhereClause.OrElse(expressionWhereClause);
  621. expressionWhereClause.Predicate.ToString()
  622. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasAndSearchExplicitTests+Foo", "foo")
  623. .Should().Be(exp.OrElse(exp).ToString().Replace(".Value", ""));
  624. }
  625. [TestCaseSource("ExpressionCases")]
  626. public void double_expressions_with_andAlso_operator(string member, FilterOperator @operator, Expression<Func<Foo, bool>> exp, object value)
  627. {
  628. var filter = new FilterDescriptor(member, @operator, value);
  629. var expressionWhereClause = new ExpressionWhereClause<Foo, FooModel>(filter, null, false, null);
  630. expressionWhereClause.Predicate.ToString()
  631. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasAndSearchExplicitTests+Foo", "foo")
  632. .Should().Be(exp.ToString().Replace(".Value", ""));
  633. expressionWhereClause.AndAlso(expressionWhereClause);
  634. expressionWhereClause.Predicate.ToString()
  635. .Replace("Tests.DynamicWhereClause.ExpressionWhereClauseWithNullAliasAndSearchExplicitTests+Foo", "foo")
  636. .Should().Be(exp.AndAlso(exp).ToString().Replace(".Value", ""));
  637. }
  638. #region Test models
  639. // ReSharper disable ClassNeverInstantiated.Global
  640. // ReSharper disable UnusedAutoPropertyAccessor.Global
  641. // ReSharper disable ClassNeverInstantiated.Local
  642. // ReSharper disable UnusedAutoPropertyAccessor.Local
  643. // ReSharper disable UnusedMember.Local
  644. // ReSharper disable UnusedMember.Global
  645. public class Foo
  646. {
  647. public string Name { get; set; }
  648. public decimal? NullableDecimal { get; set; }
  649. public decimal NotNullableDecimal { get; set; }
  650. public DateTime DateTime { get; set; }
  651. }
  652. private class FooModel
  653. {
  654. public string Name { get; set; }
  655. public decimal? NullableDecimal { get; set; }
  656. public decimal NotNullableDecimal { get; set; }
  657. public DateTime DateTime { get; set; }
  658. }
  659. // ReSharper restore UnusedMember.Global
  660. // ReSharper restore UnusedMember.Local
  661. // ReSharper restore UnusedAutoPropertyAccessor.Local
  662. // ReSharper restore ClassNeverInstantiated.Local
  663. // ReSharper restore UnusedAutoPropertyAccessor.Global
  664. // ReSharper restore ClassNeverInstantiated.Global
  665. #endregion
  666. }
  667. public class ExpressionWhereClauseWithNullAliasAndCaseInsensitiveTests
  668. {
  669. [SetUp]
  670. public void SetUp()
  671. {
  672. Mapper.Reset();
  673. GridModelMapper.Reset();
  674. GridModelMapper.CreateMap<Foo, FooModel>()
  675. .MapProperty(foo => foo.FirstName + " " + foo.LastName, model => model.FullName)
  676. .MapProperty(foo => foo.NullableDecimal + foo.NullableDecimal, model => model.NullableTotalPrice)
  677. .MapProperty(foo => foo.NotNullableDecimal + foo.NotNullableDecimal, model => model.NotNullableTotalPrice);
  678. GridModelMapper.Configuration.SetGlobalNullAlias<NullAlias>();
  679. }
  680. private class NullAlias : INullAlias
  681. {
  682. public bool IsCaseInsensitive { get { return true; } }
  683. //the query should contain these aliases explicitly?
  684. public bool SearchExplicit { get { return false; } }
  685. public IList<object> Aliases()
  686. {
  687. return new object[] { "NoNe", "eMpTy", -1, null };
  688. }
  689. }
  690. #region ExpressionCases
  691. // ReSharper disable InconsistentNaming
  692. // ReSharper disable NegativeEqualityExpression
  693. static readonly Expression<Func<Foo, bool>> Exp_NullableIsEqualTo = foo => foo.NullableDecimal == null;
  694. static readonly Expression<Func<Foo, bool>> Exp_IsEqualTo = foo => foo.Name == null;
  695. static readonly Expression<Func<Foo, bool>> Exp_IsNotEqualTo = foo => !(foo.Name == null);
  696. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsEqualTo = foo => foo.Name == "value";
  697. static readonly Expression<Func<Foo, bool>> Exp_NotValidAliasIsNotEqualTo = foo => foo.Name != "value";
  698. static readonly Expression<Func<Foo, bool>> Exp_NotNullableWithNullValueIsEqualTo = foo => foo.NotNullableDecimal == 0;
  699. static readonly Expression<Func<Foo, bool>> Exp_NotNullableWithNullValueIsNotEqualTo = foo => foo.NotNullableDecimal != 0;

Large files files are truncated, but you can click here to view the full file