/Bin/nmock/src/src/NMock/Constraints/Constraints.cs

https://github.com/sillsdev/FieldWorks · C# · 513 lines · 421 code · 82 blank · 10 comment · 25 complexity · 9d8554aed770a7288e7180dfc57bc871 MD5 · raw file

  1. // Copyright c 2002, Joe Walnes, Chris Stevenson, Owen Rogers
  2. // See LICENSE.txt for details.
  3. using System;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Reflection;
  7. using System.Collections;
  8. namespace NMock.Constraints
  9. {
  10. public abstract class BaseConstraint : IConstraint
  11. {
  12. public virtual object ExtractActualValue(object actual)
  13. {
  14. return actual;
  15. }
  16. public abstract bool Eval(object val);
  17. public abstract string Message { get; }
  18. }
  19. public class IsNull : BaseConstraint
  20. {
  21. public override bool Eval(object val)
  22. {
  23. return ExtractActualValue(val) == null;
  24. }
  25. public override string Message
  26. {
  27. get { return "null"; }
  28. }
  29. }
  30. public class IsAnything : BaseConstraint
  31. {
  32. public override bool Eval(object val)
  33. {
  34. return true;
  35. }
  36. public override string Message
  37. {
  38. get { return ""; }
  39. }
  40. }
  41. public class IsIn : BaseConstraint
  42. {
  43. private object[] inList;
  44. public IsIn(params object[] inList)
  45. {
  46. if (inList.Length == 1 && inList[0].GetType().IsArray)
  47. {
  48. Array arr = (Array)inList[0];
  49. this.inList = new object[arr.Length];
  50. arr.CopyTo(this.inList, 0);
  51. }
  52. else
  53. {
  54. this.inList = inList;
  55. }
  56. }
  57. public override bool Eval(object val)
  58. {
  59. foreach (object o in inList)
  60. {
  61. if (o.Equals(ExtractActualValue(val)))
  62. {
  63. return true;
  64. }
  65. }
  66. return false;
  67. }
  68. public override string Message
  69. {
  70. get
  71. {
  72. StringBuilder builder = new StringBuilder("IN ");
  73. foreach (object o in inList)
  74. {
  75. builder.Append('<');
  76. builder.Append(o);
  77. builder.Append(">, ");
  78. }
  79. string result = builder.ToString();
  80. if (result.EndsWith(", "))
  81. {
  82. result = result.Substring(0, result.Length - 2);
  83. }
  84. return result;
  85. }
  86. }
  87. }
  88. public class IsEqual : BaseConstraint {
  89. private object compare;
  90. public IsEqual(object compare)
  91. {
  92. this.compare = compare;
  93. }
  94. public override bool Eval(object val)
  95. {
  96. if ((val != null) && (val.GetType().IsArray) && (compare.GetType().IsArray))
  97. {
  98. return ArrayCompare((System.Array)val, (System.Array)compare);
  99. }
  100. else
  101. {
  102. return compare.Equals(ExtractActualValue(val));
  103. }
  104. }
  105. private bool ArrayCompare(System.Array a1, System.Array a2)
  106. {
  107. if(a1.Length != a2.Length) return false;
  108. for(int i=0; i < a1.Length; i++)
  109. {
  110. if(!a1.GetValue(i).Equals(a2.GetValue(i))) return false;
  111. }
  112. return true;
  113. }
  114. public override string Message
  115. {
  116. get { return "<" + compare + ">"; }
  117. }
  118. }
  119. public class IsTypeOf : BaseConstraint
  120. {
  121. private Type type;
  122. public IsTypeOf(Type type)
  123. {
  124. this.type = type;
  125. }
  126. public override bool Eval(object val)
  127. {
  128. object actualValue = ExtractActualValue(val);
  129. return actualValue == null ? false : type.IsAssignableFrom(actualValue.GetType());
  130. }
  131. public override string Message
  132. {
  133. get { return "typeof <" + type.FullName + ">"; }
  134. }
  135. }
  136. public class Not : BaseConstraint
  137. {
  138. private IConstraint p;
  139. public Not(IConstraint p)
  140. {
  141. this.p = p;
  142. }
  143. public override bool Eval(object val)
  144. {
  145. return !p.Eval(ExtractActualValue(val));
  146. }
  147. public override string Message
  148. {
  149. get { return "NOT " + p.Message; }
  150. }
  151. }
  152. public class And : BaseConstraint
  153. {
  154. private IConstraint p1, p2;
  155. public And(IConstraint p1, IConstraint p2)
  156. {
  157. this.p1 = p1;
  158. this.p2 = p2;
  159. }
  160. public override bool Eval(object val)
  161. {
  162. object actualValue = ExtractActualValue(val);
  163. return p1.Eval(actualValue) && p2.Eval(actualValue);
  164. }
  165. public override string Message
  166. {
  167. get { return p1.Message + " AND " + p2.Message; }
  168. }
  169. }
  170. public class Or : BaseConstraint
  171. {
  172. private IConstraint p1, p2;
  173. public Or(IConstraint p1, IConstraint p2)
  174. {
  175. this.p1 = p1;
  176. this.p2 = p2;
  177. }
  178. public override bool Eval(object val)
  179. {
  180. object actualValue = ExtractActualValue(val);
  181. return p1.Eval(actualValue) || p2.Eval(actualValue);
  182. }
  183. public override string Message
  184. {
  185. get { return p1.Message + " OR " + p2.Message; }
  186. }
  187. }
  188. public class NotNull : BaseConstraint
  189. {
  190. public override bool Eval(object val)
  191. {
  192. return ExtractActualValue(val) != null;
  193. }
  194. public override string Message
  195. {
  196. get { return "NOT null"; }
  197. }
  198. }
  199. public class NotEqual : BaseConstraint
  200. {
  201. private IConstraint p;
  202. public NotEqual(object compare)
  203. {
  204. p = new Not(new IsEqual(compare));
  205. }
  206. public override bool Eval(object val)
  207. {
  208. return p.Eval(ExtractActualValue(val));
  209. }
  210. public override string Message
  211. {
  212. get { return p.Message; }
  213. }
  214. }
  215. public class NotIn : BaseConstraint
  216. {
  217. private IConstraint p;
  218. public NotIn(params object[] inList)
  219. {
  220. p = new Not(new IsIn(inList));
  221. }
  222. public override bool Eval(object val)
  223. {
  224. return p.Eval(ExtractActualValue(val));
  225. }
  226. public override string Message
  227. {
  228. get { return p.Message; }
  229. }
  230. }
  231. public class IsEqualIgnoreCase : BaseConstraint
  232. {
  233. private IConstraint p;
  234. public IsEqualIgnoreCase(object compare)
  235. {
  236. p = new IsEqual(compare.ToString().ToLower());
  237. }
  238. public override bool Eval(object val)
  239. {
  240. return p.Eval(ExtractActualValue(val).ToString().ToLower());
  241. }
  242. public override string Message
  243. {
  244. get { return p.Message; }
  245. }
  246. }
  247. public class IsEqualIgnoreWhiteSpace : BaseConstraint
  248. {
  249. private IConstraint p;
  250. public IsEqualIgnoreWhiteSpace(object compare)
  251. {
  252. p = new IsEqual(StripSpace(compare.ToString()));
  253. }
  254. public override bool Eval(object val)
  255. {
  256. return p.Eval(StripSpace(ExtractActualValue(val).ToString()));
  257. }
  258. public static string StripSpace(string s)
  259. {
  260. StringBuilder result = new StringBuilder();
  261. bool lastWasSpace = true;
  262. foreach(char c in s)
  263. {
  264. if (Char.IsWhiteSpace(c))
  265. {
  266. if (!lastWasSpace)
  267. {
  268. result.Append(' ');
  269. }
  270. lastWasSpace = true;
  271. }
  272. else
  273. {
  274. result.Append(c);
  275. lastWasSpace = false;
  276. }
  277. }
  278. return result.ToString().Trim();
  279. }
  280. public override string Message
  281. {
  282. get { return p.Message; }
  283. }
  284. }
  285. public class IsMatch : BaseConstraint
  286. {
  287. private Regex regex;
  288. public IsMatch(Regex regex)
  289. {
  290. this.regex = regex;
  291. }
  292. public IsMatch(String regex) : this(new Regex(regex))
  293. {
  294. }
  295. public IsMatch(String regex, bool ignoreCase) :
  296. this(new Regex(regex, ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None))
  297. {
  298. }
  299. public override bool Eval(object val)
  300. {
  301. object actualValue = ExtractActualValue(val);
  302. return actualValue == null ? false : regex.IsMatch(actualValue.ToString());
  303. }
  304. public override string Message
  305. {
  306. get { return "<" + regex.ToString() + ">"; }
  307. }
  308. }
  309. public class IsCloseTo : BaseConstraint
  310. {
  311. private double expected;
  312. private double error;
  313. public IsCloseTo(double expected, double error)
  314. {
  315. this.expected = expected;
  316. this.error = error;
  317. }
  318. public override bool Eval(object val)
  319. {
  320. try
  321. {
  322. double actual = Convert.ToDouble(ExtractActualValue(val));
  323. return Math.Abs(actual - expected) <= error;
  324. }
  325. catch (FormatException)
  326. {
  327. return false;
  328. }
  329. }
  330. public override string Message
  331. {
  332. get { return "<" + expected + ">"; }
  333. }
  334. }
  335. public class StartsWith : BaseConstraint
  336. {
  337. private string expected;
  338. public StartsWith(string startsWithPattern)
  339. {
  340. this.expected = startsWithPattern;
  341. }
  342. public override bool Eval(object val)
  343. {
  344. return ((string)val).StartsWith(expected);
  345. }
  346. public override string Message
  347. {
  348. get { return "StartsWith<" + expected + ">"; }
  349. }
  350. }
  351. /// <summary>
  352. /// This constraint decorates another constraint, allowing it to test
  353. /// a property of the object, rather than the property itself.
  354. ///
  355. /// Properties of properties can be specified by using the
  356. /// "Property.SubProperty" notation.
  357. /// </summary>
  358. public class PropertyIs : BaseConstraint
  359. {
  360. private string property;
  361. private IConstraint constraint;
  362. public PropertyIs(string property, object expected)
  363. {
  364. this.property = property;
  365. constraint = expected as IConstraint;
  366. if (constraint == null)
  367. {
  368. constraint = new IsEqual(expected);
  369. }
  370. }
  371. public override bool Eval(object val)
  372. {
  373. object actualValue = ExtractActualValue(val);
  374. if (actualValue == null)
  375. {
  376. return false;
  377. }
  378. // split "a.b.c" into "a", "b", "c"
  379. object propertyValue = actualValue;
  380. foreach(string propertyBit in property.Split(new char[] {'.'}))
  381. {
  382. propertyValue = getProperty(propertyValue, propertyBit);
  383. }
  384. return constraint.Eval(propertyValue);
  385. }
  386. private object getProperty(object val, string property)
  387. {
  388. Type type = val.GetType();
  389. PropertyInfo propertyInfo = type.GetProperty(property);
  390. return propertyInfo.GetValue(val, null);
  391. }
  392. public override string Message
  393. {
  394. get { return String.Format("Property {0}: {1}", property, constraint.Message); }
  395. }
  396. }
  397. public class Constraint : BaseConstraint
  398. {
  399. public delegate bool Method(object val);
  400. private Method m;
  401. public Constraint(Method m)
  402. {
  403. this.m = m;
  404. }
  405. public override bool Eval(object val)
  406. {
  407. return m(ExtractActualValue(val));
  408. }
  409. public override string Message
  410. {
  411. get { return "Custom Constraint"; }
  412. }
  413. }
  414. public class CollectingConstraint : BaseConstraint
  415. {
  416. private object parameter;
  417. public object Parameter
  418. {
  419. get { return parameter; }
  420. }
  421. public override bool Eval(object val)
  422. {
  423. parameter = ExtractActualValue(val);
  424. return true;
  425. }
  426. public override string Message
  427. {
  428. get { return "Collecting Constraint"; }
  429. }
  430. }
  431. }