2
0

Quick.Conditions.pas 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. { ***************************************************************************
  2. Copyright (c) 2016-2021 Kike Pérez
  3. Unit : Quick.Conditions
  4. Description : Conditions validator
  5. Author : Kike Pérez
  6. Version : 2.0
  7. Created : 05/05/2021
  8. Modified : 11/05/2021
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Conditions;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. System.SysUtils,
  26. System.StrUtils,
  27. Quick.Commons;
  28. type
  29. ICondition = interface
  30. ['{54F1E937-CE14-426A-9FC5-C6C7944915A2}']
  31. end;
  32. TCondition = class(TInterfacedObject,ICondition)
  33. protected
  34. fName : string;
  35. fExceptionClass : ExceptClass;
  36. fPostCondition : Boolean;
  37. public
  38. constructor Create;
  39. procedure ThrowException(const aMsg : string); overload;
  40. procedure ThrowException(const aMsg : string; aValues : array of const); overload;
  41. procedure ThrowException(aExceptionClass : ExceptClass; const aMsg : string); overload;
  42. end;
  43. IStringCondition = interface(ICondition)
  44. ['{B9591175-22E0-4624-94E2-B183DEE1F793}']
  45. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IStringCondition;
  46. function IsEmpty : IStringCondition; overload;
  47. function IsEmpty(const aCustomMessage : string) : IStringCondition; overload;
  48. function IsNotEmpty : IStringCondition; overload;
  49. function IsNotEmpty(const aCustomMessage : string) : IStringCondition; overload;
  50. function StartsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  51. function StartsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False): IStringCondition; overload;
  52. function DoesNotStartsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  53. function DoesNotStartsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  54. function EndsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  55. function EndsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  56. function DoesNotEndsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  57. function DoesNotEndsWith(const aText,aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  58. function Contains(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  59. function Contains(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  60. function DoesNotContains(const aText: string; aIgnoreCase: Boolean = False): IStringCondition; overload;
  61. function DoesNotContains(const aText, aCustomMessage: string; aIgnoreCase: Boolean = False): IStringCondition; overload;
  62. function HasLength(aLen : Integer) : IStringCondition; overload;
  63. function HasLength(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  64. function DoesNotHasLength(aLen : Integer) : IStringCondition; overload;
  65. function DoesNotHasLength(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  66. function IsLongerThan(aLen : Integer) : IStringCondition; overload;
  67. function IsLongerThan(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  68. function IsLongerOrEqual(aLen : Integer) : IStringCondition; overload;
  69. function IsLongerOrEqual(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  70. function IsShorterThan(aLen : Integer) : IStringCondition; overload;
  71. function IsShorterThan(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  72. function IsShorterOrEqual(aLen : Integer) : IStringCondition; overload;
  73. function IsShorterOrEqual(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  74. function HasLengthRange(aMin, aMax : Integer) : IStringCondition; overload;
  75. function HasLengthRange(aMin, aMax : Integer; const aCustomMessage : string) : IStringCondition; overload;
  76. function IsUpperCase : IStringCondition; overload;
  77. function IsUpperCase(const aCustomMessage : string) : IStringCondition; overload;
  78. function IsLowerCase : IStringCondition; overload;
  79. function IsLowerCase(const aCustomMessage : string) : IStringCondition; overload;
  80. function IsNotUpperCase : IStringCondition; overload;
  81. function IsNotUpperCase(const aCustomMessage : string) : IStringCondition; overload;
  82. function IsNotLowerCase : IStringCondition; overload;
  83. function IsNotLowerCase(const aCustomMessage : string) : IStringCondition; overload;
  84. function Evaluate(aExpression : Boolean) : IStringCondition; overload;
  85. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IStringCondition; overload;
  86. end;
  87. IIntegerCondition = interface(ICondition)
  88. ['{A34856DD-175B-40BB-BC64-CF131CB448C7}']
  89. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IIntegerCondition;
  90. function IsInRange(aMin, aMax : Int64) : IIntegerCondition; overload;
  91. function IsInRange(aMin, aMax : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  92. function IsNotInRange(aMin, aMax : Int64) : IIntegerCondition; overload;
  93. function IsNotInRange(aMin, aMax : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  94. function IsEqualTo(aValue : Int64) : IIntegerCondition; overload;
  95. function IsEqualTo(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  96. function IsNotEqualTo(aValue : Int64) : IIntegerCondition; overload;
  97. function IsNotEqualTo(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  98. function IsGreaterThan(aValue : Int64) : IIntegerCondition; overload;
  99. function IsGreaterThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  100. function IsNotGreaterThan(aValue : Int64) : IIntegerCondition; overload;
  101. function IsNotGreaterThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  102. function IsGreaterOrEqual(aValue : Int64) : IIntegerCondition; overload;
  103. function IsGreaterOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  104. function IsNotGreaterOrEqual(aValue : Int64) : IIntegerCondition; overload;
  105. function IsNotGreaterOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  106. function IsLessThan(aValue : Int64) : IIntegerCondition; overload;
  107. function IsLessThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  108. function IsNotLessThan(aValue : Int64) : IIntegerCondition; overload;
  109. function IsNotLessThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  110. function IsLessOrEqual(aValue : Int64) : IIntegerCondition; overload;
  111. function IsLessOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  112. function IsNotLessOrEqual(aValue : Int64) : IIntegerCondition; overload;
  113. function IsNotLessOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  114. function Evaluate(aExpression : Boolean) : IIntegerCondition; overload;
  115. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IIntegerCondition; overload;
  116. end;
  117. IFloatCondition = interface(ICondition)
  118. ['{D0237A24-A00F-4B96-BA7B-0FF9BE7363E5}']
  119. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IFloatCondition;
  120. function IsInRange(aMin, aMax : Extended) : IFloatCondition; overload;
  121. function IsInRange(aMin, aMax : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  122. function IsNotInRange(aMin, aMax : Extended) : IFloatCondition; overload;
  123. function IsNotInRange(aMin, aMax : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  124. function IsEqualTo(aValue : Extended) : IFloatCondition; overload;
  125. function IsEqualTo(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  126. function IsNotEqualTo(aValue : Extended) : IFloatCondition; overload;
  127. function IsNotEqualTo(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  128. function IsGreaterThan(aValue : Extended) : IFloatCondition; overload;
  129. function IsGreaterThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  130. function IsNotGreaterThan(aValue : Extended) : IFloatCondition; overload;
  131. function IsNotGreaterThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  132. function IsGreaterOrEqual(aValue : Extended) : IFloatCondition; overload;
  133. function IsGreaterOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  134. function IsNotGreaterOrEqual(aValue : Extended) : IFloatCondition; overload;
  135. function IsNotGreaterOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  136. function IsLessThan(aValue : Extended) : IFloatCondition; overload;
  137. function IsLessThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  138. function IsNotLessThan(aValue : Extended) : IFloatCondition; overload;
  139. function IsNotLessThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  140. function IsLessOrEqual(aValue : Extended) : IFloatCondition; overload;
  141. function IsLessOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  142. function IsNotLessOrEqual(aValue : Extended) : IFloatCondition; overload;
  143. function IsNotLessOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  144. function Evaluate(aExpression : Boolean) : IFloatCondition; overload;
  145. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IFloatCondition; overload;
  146. end;
  147. IObjectCondition = interface(ICondition)
  148. ['{497E21D2-7780-4C3B-B51E-921847491FC1}']
  149. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IObjectCondition;
  150. function IsNull : IObjectCondition; overload;
  151. function IsNull(const aCustomMessage : string): IObjectCondition; overload;
  152. function IsNotNull : IObjectCondition; overload;
  153. function IsNotNull(const aCustomMessage : string) : IObjectCondition; overload;
  154. function IsOfType(aClass : TClass) : IObjectCondition; overload;
  155. function IsOfType(aClass : TClass; const aCustomMessage : string) : IObjectCondition; overload;
  156. function DoesNotOfType(aClass : TClass) : IObjectCondition; overload;
  157. function DoesNotOfType(aClass : TClass; const aCustomMessage : string) : IObjectCondition; overload;
  158. function Evaluate(aExpression : Boolean) : IObjectCondition; overload;
  159. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IObjectCondition; overload;
  160. end;
  161. TStringCondition = class(TCondition,IStringCondition)
  162. private
  163. fValue : string;
  164. public
  165. constructor Create(const aValue : string; const aName : string; aPostCondition : Boolean);
  166. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IStringCondition;
  167. function IsEmpty : IStringCondition; overload;
  168. function IsEmpty(const aCustomMessage : string) : IStringCondition; overload;
  169. function IsNotEmpty : IStringCondition; overload;
  170. function IsNotEmpty(const aCustomMessage : string) : IStringCondition; overload;
  171. function StartsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  172. function StartsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False): IStringCondition; overload;
  173. function DoesNotStartsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  174. function DoesNotStartsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  175. function EndsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  176. function EndsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  177. function DoesNotEndsWith(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  178. function DoesNotEndsWith(const aText,aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  179. function Contains(const aText : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  180. function Contains(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False) : IStringCondition; overload;
  181. function DoesNotContains(const aText: string; aIgnoreCase: Boolean = False): IStringCondition; overload;
  182. function DoesNotContains(const aText, aCustomMessage: string; aIgnoreCase: Boolean = False): IStringCondition; overload;
  183. function HasLength(aLen : Integer) : IStringCondition; overload;
  184. function HasLength(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  185. function DoesNotHasLength(aLen : Integer) : IStringCondition; overload;
  186. function DoesNotHasLength(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  187. function IsLongerThan(aLen : Integer) : IStringCondition; overload;
  188. function IsLongerThan(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  189. function IsLongerOrEqual(aLen : Integer) : IStringCondition; overload;
  190. function IsLongerOrEqual(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  191. function IsShorterThan(aLen : Integer) : IStringCondition; overload;
  192. function IsShorterThan(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  193. function IsShorterOrEqual(aLen : Integer) : IStringCondition; overload;
  194. function IsShorterOrEqual(aLen : Integer; const aCustomMessage : string) : IStringCondition; overload;
  195. function HasLengthRange(aMin, aMax : Integer) : IStringCondition; overload;
  196. function HasLengthRange(aMin, aMax : Integer; const aCustomMessage : string) : IStringCondition; overload;
  197. function IsUpperCase : IStringCondition; overload;
  198. function IsUpperCase(const aCustomMessage : string) : IStringCondition; overload;
  199. function IsLowerCase : IStringCondition; overload;
  200. function IsLowerCase(const aCustomMessage : string) : IStringCondition; overload;
  201. function IsNotUpperCase : IStringCondition; overload;
  202. function IsNotUpperCase(const aCustomMessage : string) : IStringCondition; overload;
  203. function IsNotLowerCase : IStringCondition; overload;
  204. function IsNotLowerCase(const aCustomMessage : string) : IStringCondition; overload;
  205. function Evaluate(aExpression : Boolean) : IStringCondition; overload;
  206. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IStringCondition; overload;
  207. end;
  208. TIntegerCondition = class(TCondition,IIntegerCondition)
  209. private
  210. fValue : Int64;
  211. public
  212. constructor Create(const aValue : Int64; const aName : string; aPostCondition : Boolean);
  213. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IIntegerCondition;
  214. function IsInRange(aMin, aMax : Int64) : IIntegerCondition; overload;
  215. function IsInRange(aMin, aMax : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  216. function IsNotInRange(aMin, aMax : Int64) : IIntegerCondition; overload;
  217. function IsNotInRange(aMin, aMax : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  218. function IsEqualTo(aValue : Int64) : IIntegerCondition; overload;
  219. function IsEqualTo(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  220. function IsNotEqualTo(aValue : Int64) : IIntegerCondition; overload;
  221. function IsNotEqualTo(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  222. function IsGreaterThan(aValue : Int64) : IIntegerCondition; overload;
  223. function IsGreaterThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  224. function IsNotGreaterThan(aValue : Int64) : IIntegerCondition; overload;
  225. function IsNotGreaterThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  226. function IsGreaterOrEqual(aValue : Int64) : IIntegerCondition; overload;
  227. function IsGreaterOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  228. function IsNotGreaterOrEqual(aValue : Int64) : IIntegerCondition; overload;
  229. function IsNotGreaterOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  230. function IsLessThan(aValue : Int64) : IIntegerCondition; overload;
  231. function IsLessThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  232. function IsNotLessThan(aValue : Int64) : IIntegerCondition; overload;
  233. function IsNotLessThan(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  234. function IsLessOrEqual(aValue : Int64) : IIntegerCondition; overload;
  235. function IsLessOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  236. function IsNotLessOrEqual(aValue : Int64) : IIntegerCondition; overload;
  237. function IsNotLessOrEqual(aValue : Int64; const aCustomMessage : string) : IIntegerCondition; overload;
  238. function Evaluate(aExpression : Boolean) : IIntegerCondition; overload;
  239. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IIntegerCondition; overload;
  240. end;
  241. TFloatCondition = class(TCondition,IFloatCondition)
  242. private
  243. fValue : Extended;
  244. public
  245. constructor Create(const aValue : Extended; const aName : string; aPostCondition : Boolean);
  246. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IFloatCondition;
  247. function IsInRange(aMin, aMax : Extended) : IFloatCondition; overload;
  248. function IsInRange(aMin, aMax : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  249. function IsNotInRange(aMin, aMax : Extended) : IFloatCondition; overload;
  250. function IsNotInRange(aMin, aMax : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  251. function IsEqualTo(aValue : Extended) : IFloatCondition; overload;
  252. function IsEqualTo(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  253. function IsNotEqualTo(aValue : Extended) : IFloatCondition; overload;
  254. function IsNotEqualTo(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  255. function IsGreaterThan(aValue : Extended) : IFloatCondition; overload;
  256. function IsGreaterThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  257. function IsNotGreaterThan(aValue : Extended) : IFloatCondition; overload;
  258. function IsNotGreaterThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  259. function IsGreaterOrEqual(aValue : Extended) : IFloatCondition; overload;
  260. function IsGreaterOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  261. function IsNotGreaterOrEqual(aValue : Extended) : IFloatCondition; overload;
  262. function IsNotGreaterOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  263. function IsLessThan(aValue : Extended) : IFloatCondition; overload;
  264. function IsLessThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  265. function IsNotLessThan(aValue : Extended) : IFloatCondition; overload;
  266. function IsNotLessThan(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  267. function IsLessOrEqual(aValue : Extended) : IFloatCondition; overload;
  268. function IsLessOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  269. function IsNotLessOrEqual(aValue : Extended) : IFloatCondition; overload;
  270. function IsNotLessOrEqual(aValue : Extended; const aCustomMessage : string) : IFloatCondition; overload;
  271. function Evaluate(aExpression : Boolean) : IFloatCondition; overload;
  272. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IFloatCondition; overload;
  273. end;
  274. TObjectCondition = class(TCondition,IObjectCondition)
  275. private
  276. fValue : TObject;
  277. public
  278. constructor Create(const aValue : TObject; const aName : string; aPostCondition : Boolean);
  279. function WithExceptionOnFailure(aExceptionClass : ExceptClass) : IObjectCondition;
  280. function IsNull : IObjectCondition; overload;
  281. function IsNull(const aCustomMessage : string): IObjectCondition; overload;
  282. function IsNotNull : IObjectCondition; overload;
  283. function IsNotNull(const aCustomMessage : string) : IObjectCondition; overload;
  284. function IsOfType(aClass : TClass) : IObjectCondition; overload;
  285. function IsOfType(aClass : TClass; const aCustomMessage : string) : IObjectCondition; overload;
  286. function DoesNotOfType(aClass : TClass) : IObjectCondition; overload;
  287. function DoesNotOfType(aClass : TClass; const aCustomMessage : string) : IObjectCondition; overload;
  288. function Evaluate(aExpression : Boolean) : IObjectCondition; overload;
  289. function Evaluate(aExpression : Boolean; const aCustomMessage : string) : IObjectCondition; overload;
  290. end;
  291. IConditionValidator = interface
  292. ['{F707606E-7603-4690-BE76-2443B0A36D5F}']
  293. function Requires(const aValue : string; const aName : string = '') : IStringCondition; overload;
  294. function Requires(const aValue : Int64; const aName : string = '') : IIntegerCondition; overload;
  295. function Requires(const aValue : Extended; const aName : string = '') : IFloatCondition; overload;
  296. function Requires(const aValue : TObject; const aName : string = '') : IObjectCondition; overload;
  297. function Ensures(const aValue : string; const aName : string = '') : IStringCondition; overload;
  298. function Ensures(const aValue : Int64; const aName : string = '') : IIntegerCondition; overload;
  299. function Ensures(const aValue : Extended; const aName : string = '') : IFloatCondition; overload;
  300. function Ensures(const aValue : TObject; const aName : string = '') : IObjectCondition; overload;
  301. end;
  302. TConditionValidator = class(TInterfacedObject,IConditionValidator)
  303. public
  304. function Requires(const aValue : string; const aName : string = '') : IStringCondition; overload;
  305. function Requires(const aValue : Int64; const aName : string = '') : IIntegerCondition; overload;
  306. function Requires(const aValue : Extended; const aName : string = '') : IFloatCondition; overload;
  307. function Requires(const aValue : TObject; const aName : string = '') : IObjectCondition; overload;
  308. function Ensures(const aValue : string; const aName : string = '') : IStringCondition; overload;
  309. function Ensures(const aValue : Int64; const aName : string = '') : IIntegerCondition; overload;
  310. function Ensures(const aValue : Extended; const aName : string = '') : IFloatCondition; overload;
  311. function Ensures(const aValue : TObject; const aName : string = '') : IObjectCondition; overload;
  312. end;
  313. EPreConditionError = class(Exception);
  314. EPostConditionError = class(Exception);
  315. function Condition : IConditionValidator;
  316. implementation
  317. function Condition : IConditionValidator;
  318. begin
  319. Result := TConditionValidator.Create;
  320. end;
  321. { TEvaluator }
  322. function TConditionValidator.Requires(const aValue: string; const aName : string = ''): IStringCondition;
  323. begin
  324. Result := TStringCondition.Create(aValue,aName,False);
  325. end;
  326. function TConditionValidator.Requires(const aValue: Int64; const aName : string = ''): IIntegerCondition;
  327. begin
  328. Result := TIntegerCondition.Create(aValue,aName,False);
  329. end;
  330. function TConditionValidator.Requires(const aValue: Extended; const aName : string = ''): IFloatCondition;
  331. begin
  332. Result := TFloatCondition.Create(aValue,aName,False);
  333. end;
  334. function TConditionValidator.Requires(const aValue: TObject; const aName : string = ''): IObjectCondition;
  335. begin
  336. Result := TObjectCondition.Create(aValue,aName,False);
  337. end;
  338. function TConditionValidator.Ensures(const aValue, aName: string): IStringCondition;
  339. begin
  340. Result := TStringCondition.Create(aValue,aName,True);
  341. end;
  342. function TConditionValidator.Ensures(const aValue: Int64; const aName: string): IIntegerCondition;
  343. begin
  344. Result := TIntegerCondition.Create(aValue,aName,True);
  345. end;
  346. function TConditionValidator.Ensures(const aValue: Extended; const aName: string): IFloatCondition;
  347. begin
  348. Result := TFloatCondition.Create(aValue,aName,True);
  349. end;
  350. function TConditionValidator.Ensures(const aValue: TObject; const aName: string): IObjectCondition;
  351. begin
  352. Result := TObjectCondition.Create(aValue,aName,True);
  353. end;
  354. { TStringCondition }
  355. constructor TStringCondition.Create(const aValue: string; const aName : string; aPostCondition : Boolean);
  356. begin
  357. fName := aName;
  358. fValue := aValue;
  359. fPostCondition := aPostCondition;
  360. end;
  361. function TStringCondition.WithExceptionOnFailure(aExceptionClass: ExceptClass): IStringCondition;
  362. begin
  363. fExceptionClass := aExceptionClass;
  364. Result := Self;
  365. end;
  366. function TStringCondition.IsEmpty: IStringCondition;
  367. begin
  368. Result := Self.IsEmpty('');
  369. end;
  370. function TStringCondition.IsEmpty(const aCustomMessage : string): IStringCondition;
  371. begin
  372. if not fValue.IsEmpty then
  373. begin
  374. if not aCustomMessage.IsEmpty then ThrowException(EArgumentNilException,aCustomMessage)
  375. else ThrowException('must be empty');
  376. end;
  377. Result := Self;
  378. end;
  379. function TStringCondition.IsNotEmpty: IStringCondition;
  380. begin
  381. Result := Self.IsNotEmpty('');
  382. end;
  383. function TStringCondition.IsNotEmpty(const aCustomMessage : string): IStringCondition;
  384. begin
  385. if fValue.IsEmpty then
  386. begin
  387. if not aCustomMessage.IsEmpty then ThrowException(EArgumentNilException,aCustomMessage)
  388. else ThrowException('should not be empty');
  389. end;
  390. Result := Self;
  391. end;
  392. function TStringCondition.StartsWith(const aText: string; aIgnoreCase : Boolean = False): IStringCondition;
  393. begin
  394. Result := Self.StartsWith(aText,'',aIgnoreCase);
  395. end;
  396. function TStringCondition.StartsWith(const aText, aCustomMessage : string; aIgnoreCase : Boolean = False): IStringCondition;
  397. begin
  398. if not fValue.StartsWith(aText,aIgnoreCase) then
  399. begin
  400. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  401. else ThrowException('must start with "%s"',[aText])
  402. end;
  403. Result := Self;
  404. end;
  405. function TStringCondition.DoesNotStartsWith(const aText: string; aIgnoreCase: Boolean): IStringCondition;
  406. begin
  407. Result := Self.DoesNotStartsWith(aText,'',aIgnoreCase);
  408. end;
  409. function TStringCondition.DoesNotStartsWith(const aText, aCustomMessage: string; aIgnoreCase: Boolean): IStringCondition;
  410. begin
  411. if fValue.StartsWith(aText,aIgnoreCase) then
  412. begin
  413. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  414. else ThrowException('should not start with "%s"',[aText]);
  415. end;
  416. Result := Self;
  417. end;
  418. function TStringCondition.EndsWith(const aText: string; aIgnoreCase : Boolean = False): IStringCondition;
  419. begin
  420. Result := Self.EndsWith(aText,'',aIgnoreCase);
  421. end;
  422. function TStringCondition.EndsWith(const aText, aCustomMessage: string; aIgnoreCase : Boolean = False): IStringCondition;
  423. begin
  424. if not fValue.EndsWith(aText,aIgnoreCase) then
  425. begin
  426. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  427. else ThrowException('must end with "%s"',[aText]);
  428. end;
  429. Result := Self;
  430. end;
  431. function TStringCondition.DoesNotEndsWith(const aText: string; aIgnoreCase: Boolean): IStringCondition;
  432. begin
  433. Result := Self.DoesNotEndsWith(aText,'',aIgnoreCase);
  434. end;
  435. function TStringCondition.DoesNotEndsWith(const aText, aCustomMessage: string; aIgnoreCase: Boolean): IStringCondition;
  436. begin
  437. if fValue.EndsWith(aText,aIgnoreCase) then
  438. begin
  439. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  440. else ThrowException('should not be end with "%s"',[aText]);
  441. end;
  442. Result := Self;
  443. end;
  444. function TStringCondition.Contains(const aText: string; aIgnoreCase: Boolean): IStringCondition;
  445. begin
  446. Result := Self.Contains(aText,'',aIgnoreCase);
  447. end;
  448. function TStringCondition.Contains(const aText, aCustomMessage: string; aIgnoreCase: Boolean): IStringCondition;
  449. begin
  450. if aIgnoreCase then
  451. begin
  452. if not ContainsText(fValue,aText) then
  453. begin
  454. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  455. else ThrowException('must contain "%s"',[aText]);
  456. end;
  457. end
  458. else
  459. begin
  460. if not fValue.Contains(aText) then
  461. begin
  462. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  463. else ThrowException('must contain "%s"',[aText]);
  464. end;
  465. end;
  466. Result := Self;
  467. end;
  468. function TStringCondition.DoesNotContains(const aText: string; aIgnoreCase: Boolean = False): IStringCondition;
  469. begin
  470. Result := Self.DoesNotContains(aText,'',aIgnoreCase);
  471. end;
  472. function TStringCondition.DoesNotContains(const aText, aCustomMessage: string; aIgnoreCase: Boolean = False): IStringCondition;
  473. begin
  474. if aIgnoreCase then
  475. begin
  476. if ContainsText(fValue,aText) then
  477. begin
  478. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  479. else ThrowException('should not contain "%s"',[aText]);
  480. end;
  481. end
  482. else
  483. begin
  484. if fValue.Contains(aText) then
  485. begin
  486. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  487. else ThrowException('should not contain "%s"',[aText]);
  488. end;
  489. end;
  490. Result := Self;
  491. end;
  492. function TStringCondition.HasLength(aLen: Integer): IStringCondition;
  493. begin
  494. Result := Self.HasLength(aLen,'');
  495. end;
  496. function TStringCondition.HasLength(aLen: Integer; const aCustomMessage : string): IStringCondition;
  497. begin
  498. if fValue.Length <> aLen then
  499. begin
  500. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  501. else ThrowException('must be %d length',[aLen]);
  502. end;
  503. Result := Self;
  504. end;
  505. function TStringCondition.DoesNotHasLength(aLen: Integer): IStringCondition;
  506. begin
  507. Result := Self.DoesNotHasLength(aLen,'');
  508. end;
  509. function TStringCondition.DoesNotHasLength(aLen: Integer; const aCustomMessage : string): IStringCondition;
  510. begin
  511. if fValue.Length = aLen then
  512. begin
  513. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  514. else ThrowException('should not be %d length',[aLen]);
  515. end;
  516. Result := Self;
  517. end;
  518. function TStringCondition.IsShorterThan(aLen: Integer): IStringCondition;
  519. begin
  520. Result := Self.IsShorterThan(aLen,'');
  521. end;
  522. function TStringCondition.IsShorterThan(aLen: Integer; const aCustomMessage : string): IStringCondition;
  523. begin
  524. if fValue.Length >= aLen then
  525. begin
  526. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  527. else ThrowException('must be shorten than %d',[aLen]);
  528. end;
  529. Result := Self;
  530. end;
  531. function TStringCondition.IsShorterOrEqual(aLen: Integer): IStringCondition;
  532. begin
  533. Result := Self.IsShorterOrEqual(aLen,'');
  534. end;
  535. function TStringCondition.IsShorterOrEqual(aLen: Integer; const aCustomMessage : string): IStringCondition;
  536. begin
  537. if fValue.Length > aLen then
  538. begin
  539. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  540. else ThrowException('must be shorter or equal to %d',[aLen]);
  541. end;
  542. Result := Self;
  543. end;
  544. function TStringCondition.IsLongerOrEqual(aLen: Integer): IStringCondition;
  545. begin
  546. Result := Self.IsLongerOrEqual(aLen,'');
  547. end;
  548. function TStringCondition.IsLongerOrEqual(aLen: Integer; const aCustomMessage : string): IStringCondition;
  549. begin
  550. if fValue.Length < aLen then
  551. begin
  552. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  553. else ThrowException('must be longer or equal to %d',[aLen]);
  554. end;
  555. Result := Self;
  556. end;
  557. function TStringCondition.IsLongerThan(aLen: Integer): IStringCondition;
  558. begin
  559. Result := Self.IsLongerThan(aLen,'');
  560. end;
  561. function TStringCondition.IsLongerThan(aLen: Integer; const aCustomMessage : string): IStringCondition;
  562. begin
  563. if fValue.Length <= aLen then
  564. begin
  565. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  566. else ThrowException('must be longer than %d',[aLen]);
  567. end;
  568. Result := Self;
  569. end;
  570. function TStringCondition.HasLengthRange(aMin, aMax: Integer): IStringCondition;
  571. begin
  572. Result := Self.HasLengthRange(aMin,aMax,'');
  573. end;
  574. function TStringCondition.HasLengthRange(aMin, aMax: Integer; const aCustomMessage : string): IStringCondition;
  575. begin
  576. if (fValue.Length < aMin) or (fValue.Length > aMax) then
  577. begin
  578. if not aCustomMessage.IsEmpty then ThrowException(EArgumentOutOfRangeException,aCustomMessage)
  579. else ThrowException('must be in %d-%d length range',[aMin,aMax]);
  580. end;
  581. Result := Self;
  582. end;
  583. function TStringCondition.IsUpperCase: IStringCondition;
  584. begin
  585. Result := Self.IsUpperCase('');
  586. end;
  587. function TStringCondition.IsUpperCase(const aCustomMessage : string): IStringCondition;
  588. begin
  589. if fValue.ToUpper <> fValue then
  590. begin
  591. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  592. else ThrowException('must be upper case');
  593. end;
  594. Result := Self;
  595. end;
  596. function TStringCondition.IsLowerCase: IStringCondition;
  597. begin
  598. Result := Self.IsLowerCase('');
  599. end;
  600. function TStringCondition.IsLowerCase(const aCustomMessage : string): IStringCondition;
  601. begin
  602. if fValue.ToLower <> fValue then
  603. begin
  604. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  605. else ThrowException('must be lower case');
  606. end;
  607. Result := Self;
  608. end;
  609. function TStringCondition.IsNotUpperCase: IStringCondition;
  610. begin
  611. Result := Self.IsNotUpperCase('');
  612. end;
  613. function TStringCondition.IsNotUpperCase(const aCustomMessage : string): IStringCondition;
  614. begin
  615. if fValue.ToUpper = fValue then
  616. begin
  617. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  618. else ThrowException('should not be upper case');
  619. end;
  620. Result := Self;
  621. end;
  622. function TStringCondition.IsNotLowerCase: IStringCondition;
  623. begin
  624. Result := Self.IsNotLowerCase('');
  625. end;
  626. function TStringCondition.IsNotLowerCase(const aCustomMessage : string): IStringCondition;
  627. begin
  628. if fValue.ToLower = fValue then
  629. begin
  630. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  631. else ThrowException('should not be lower case');
  632. end;
  633. Result := Self;
  634. end;
  635. function TStringCondition.Evaluate(aExpression: Boolean): IStringCondition;
  636. begin
  637. Result := Self.Evaluate(aExpression,'');
  638. end;
  639. function TStringCondition.Evaluate(aExpression: Boolean; const aCustomMessage : string): IStringCondition;
  640. begin
  641. if not aExpression then
  642. begin
  643. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  644. else ThrowException('must meet condition');
  645. end;
  646. end;
  647. { TIntegerCondition }
  648. constructor TIntegerCondition.Create(const aValue: Int64; const aName : string; aPostCondition : Boolean);
  649. begin
  650. fName := aName;
  651. fValue := aValue;
  652. fPostCondition := aPostCondition;
  653. end;
  654. function TIntegerCondition.WithExceptionOnFailure(aExceptionClass: ExceptClass): IIntegerCondition;
  655. begin
  656. fExceptionClass := aExceptionClass;
  657. Result := Self;
  658. end;
  659. function TIntegerCondition.IsEqualTo(aValue: Int64): IIntegerCondition;
  660. begin
  661. Result := Self.IsEqualTo(aValue,'');
  662. end;
  663. function TIntegerCondition.IsEqualTo(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  664. begin
  665. if fValue <> aValue then
  666. begin
  667. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  668. else ThrowException('must be equal to %d',[aValue]);
  669. end;
  670. Result := Self;
  671. end;
  672. function TIntegerCondition.IsGreaterOrEqual(aValue: Int64): IIntegerCondition;
  673. begin
  674. Result := Self.IsGreaterOrEqual(aValue,'');
  675. end;
  676. function TIntegerCondition.IsGreaterOrEqual(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  677. begin
  678. if fValue < aValue then
  679. begin
  680. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  681. else ThrowException('must be greather or equal to %d',[aValue]);
  682. end;
  683. Result := Self;
  684. end;
  685. function TIntegerCondition.IsGreaterThan(aValue: Int64): IIntegerCondition;
  686. begin
  687. Result := Self.IsGreaterThan(aValue,'');
  688. end;
  689. function TIntegerCondition.IsGreaterThan(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  690. begin
  691. if fValue <= aValue then
  692. begin
  693. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  694. else ThrowException('must be greather than %d',[aValue]);
  695. end;
  696. Result := Self;
  697. end;
  698. function TIntegerCondition.IsInRange(aMin, aMax: Int64): IIntegerCondition;
  699. begin
  700. Result := Self.IsInRange(aMin,aMax,'');
  701. end;
  702. function TIntegerCondition.IsInRange(aMin, aMax: Int64; const aCustomMessage : string): IIntegerCondition;
  703. begin
  704. if (fValue < aMin) or (fValue > aMax) then
  705. begin
  706. if not aCustomMessage.IsEmpty then ThrowException(EArgumentOutOfRangeException,aCustomMessage)
  707. else ThrowException('must be in %d-%d range',[aMin,aMax]);
  708. end;
  709. Result := Self;
  710. end;
  711. function TIntegerCondition.IsLessOrEqual(aValue: Int64): IIntegerCondition;
  712. begin
  713. Result := Self.IsLessOrEqual(aValue,'');
  714. end;
  715. function TIntegerCondition.IsLessOrEqual(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  716. begin
  717. if fValue > aValue then
  718. begin
  719. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  720. else ThrowException('must be less or equal to %d',[aValue]);
  721. end;
  722. Result := Self;
  723. end;
  724. function TIntegerCondition.IsLessThan(aValue: Int64): IIntegerCondition;
  725. begin
  726. Result := Self.IsLessThan(aValue,'');
  727. end;
  728. function TIntegerCondition.IsLessThan(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  729. begin
  730. if fValue >= aValue then
  731. begin
  732. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  733. else ThrowException('must be less than %d',[aValue]);
  734. end;
  735. Result := Self;
  736. end;
  737. function TIntegerCondition.IsNotEqualTo(aValue: Int64): IIntegerCondition;
  738. begin
  739. Result := Self.IsNotEqualTo(aValue,'');
  740. end;
  741. function TIntegerCondition.IsNotEqualTo(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  742. begin
  743. if fValue = aValue then
  744. begin
  745. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  746. else ThrowException('should not be equal to %d',[aValue]);
  747. end;
  748. Result := Self;
  749. end;
  750. function TIntegerCondition.IsNotGreaterOrEqual(aValue: Int64): IIntegerCondition;
  751. begin
  752. Result := Self.IsNotGreaterOrEqual(aValue,'');
  753. end;
  754. function TIntegerCondition.IsNotGreaterOrEqual(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  755. begin
  756. if fValue >= aValue then
  757. begin
  758. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  759. else ThrowException('should not be greater or equal to %d',[aValue]);
  760. end;
  761. Result := Self;
  762. end;
  763. function TIntegerCondition.IsNotGreaterThan(aValue: Int64): IIntegerCondition;
  764. begin
  765. Result := Self.IsNotGreaterThan(aValue,'');
  766. end;
  767. function TIntegerCondition.IsNotGreaterThan(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  768. begin
  769. if fValue > aValue then
  770. begin
  771. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  772. else ThrowException('should not be greater than %d',[aValue]);
  773. end;
  774. Result := Self;
  775. end;
  776. function TIntegerCondition.IsNotInRange(aMin, aMax: Int64): IIntegerCondition;
  777. begin
  778. Result := Self.IsNotInRange(aMin,aMax,'');
  779. end;
  780. function TIntegerCondition.IsNotInRange(aMin, aMax: Int64; const aCustomMessage : string): IIntegerCondition;
  781. begin
  782. if (fValue >= aMin) and (fValue <= aMax) then
  783. begin
  784. if not aCustomMessage.IsEmpty then ThrowException(EArgumentOutOfRangeException,aCustomMessage)
  785. else ThrowException('should not be in range %d-%d',[aMin,aMax]);
  786. end;
  787. Result := Self;
  788. end;
  789. function TIntegerCondition.IsNotLessOrEqual(aValue: Int64): IIntegerCondition;
  790. begin
  791. Result := Self.IsNotLessOrEqual(aValue,'');
  792. end;
  793. function TIntegerCondition.IsNotLessOrEqual(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  794. begin
  795. if fValue <= aValue then
  796. begin
  797. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  798. else ThrowException('should not be less or equal to %d',[aValue]);
  799. end;
  800. Result := Self;
  801. end;
  802. function TIntegerCondition.IsNotLessThan(aValue: Int64): IIntegerCondition;
  803. begin
  804. Result := Self.IsNotLessThan(aValue,'');
  805. end;
  806. function TIntegerCondition.IsNotLessThan(aValue: Int64; const aCustomMessage : string): IIntegerCondition;
  807. begin
  808. if fValue < aValue then
  809. begin
  810. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  811. else ThrowException('should not be less than %d',[aValue]);
  812. end;
  813. Result := Self;
  814. end;
  815. function TIntegerCondition.Evaluate(aExpression: Boolean): IIntegerCondition;
  816. begin
  817. Result := Self.Evaluate(aExpression,'');
  818. end;
  819. function TIntegerCondition.Evaluate(aExpression: Boolean; const aCustomMessage : string): IIntegerCondition;
  820. begin
  821. if not aExpression then
  822. begin
  823. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  824. else ThrowException('must meet condition');
  825. end;
  826. end;
  827. { TFloatCondition }
  828. constructor TFloatCondition.Create(const aValue: Extended; const aName : string; aPostCondition : Boolean);
  829. begin
  830. fName := aName;
  831. fValue := aValue;
  832. fPostCondition := aPostCondition;
  833. end;
  834. function TFloatCondition.WithExceptionOnFailure(aExceptionClass: ExceptClass): IFloatCondition;
  835. begin
  836. fExceptionClass := aExceptionClass;
  837. Result := Self;
  838. end;
  839. function TFloatCondition.IsEqualTo(aValue: Extended): IFloatCondition;
  840. begin
  841. Result := Self.IsEqualTo(aValue,'');
  842. end;
  843. function TFloatCondition.IsEqualTo(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  844. begin
  845. if fValue <> aValue then
  846. begin
  847. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  848. else ThrowException('must be equal to %d',[aValue]);
  849. end;
  850. Result := Self;
  851. end;
  852. function TFloatCondition.IsGreaterOrEqual(aValue: Extended): IFloatCondition;
  853. begin
  854. Result := Self.IsGreaterOrEqual(aValue,'');
  855. end;
  856. function TFloatCondition.IsGreaterOrEqual(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  857. begin
  858. if fValue < aValue then
  859. begin
  860. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  861. else ThrowException('must be greather or equal to %d',[aValue]);
  862. end;
  863. Result := Self;
  864. end;
  865. function TFloatCondition.IsGreaterThan(aValue: Extended): IFloatCondition;
  866. begin
  867. Result := Self.IsGreaterThan(aValue,'');
  868. end;
  869. function TFloatCondition.IsGreaterThan(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  870. begin
  871. if fValue <= aValue then
  872. begin
  873. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  874. else ThrowException('must be greather than %d',[aValue]);
  875. end;
  876. Result := Self;
  877. end;
  878. function TFloatCondition.IsInRange(aMin, aMax: Extended): IFloatCondition;
  879. begin
  880. Result := Self.IsInRange(aMin,aMax,'');
  881. end;
  882. function TFloatCondition.IsInRange(aMin, aMax: Extended; const aCustomMessage : string): IFloatCondition;
  883. begin
  884. if (fValue < aMin) or (fValue > aMax) then
  885. begin
  886. if not aCustomMessage.IsEmpty then ThrowException(EArgumentOutOfRangeException,aCustomMessage)
  887. else ThrowException('must be in %d-%d range',[aMin,aMax]);
  888. end;
  889. Result := Self;
  890. end;
  891. function TFloatCondition.IsLessOrEqual(aValue: Extended): IFloatCondition;
  892. begin
  893. Result := Self.IsLessOrEqual(aValue,'');
  894. end;
  895. function TFloatCondition.IsLessOrEqual(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  896. begin
  897. if fValue > aValue then
  898. begin
  899. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  900. else ThrowException('must be less or equal to %d',[aValue]);
  901. end;
  902. Result := Self;
  903. end;
  904. function TFloatCondition.IsLessThan(aValue: Extended): IFloatCondition;
  905. begin
  906. Result := Self.IsLessThan(aValue,'');
  907. end;
  908. function TFloatCondition.IsLessThan(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  909. begin
  910. if fValue >= aValue then
  911. begin
  912. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  913. else ThrowException('must be less than %d',[aValue]);
  914. end;
  915. Result := Self;
  916. end;
  917. function TFloatCondition.IsNotEqualTo(aValue: Extended): IFloatCondition;
  918. begin
  919. Result := Self.IsNotEqualTo(aValue,'');
  920. end;
  921. function TFloatCondition.IsNotEqualTo(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  922. begin
  923. if fValue = aValue then
  924. begin
  925. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  926. else ThrowException('should not be equal to %d',[aValue]);
  927. end;
  928. Result := Self;
  929. end;
  930. function TFloatCondition.IsNotGreaterOrEqual(aValue: Extended): IFloatCondition;
  931. begin
  932. Result := Self.IsNotGreaterOrEqual(aValue,'');
  933. end;
  934. function TFloatCondition.IsNotGreaterOrEqual(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  935. begin
  936. if fValue >= aValue then
  937. begin
  938. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  939. else ThrowException('should not be greater or equal to %d',[aValue]);
  940. end;
  941. Result := Self;
  942. end;
  943. function TFloatCondition.IsNotGreaterThan(aValue: Extended): IFloatCondition;
  944. begin
  945. Result := Self.IsNotGreaterThan(aValue,'');
  946. end;
  947. function TFloatCondition.IsNotGreaterThan(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  948. begin
  949. if fValue > aValue then
  950. begin
  951. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  952. else ThrowException('should not be greater than %d',[aValue]);
  953. end;
  954. Result := Self;
  955. end;
  956. function TFloatCondition.IsNotInRange(aMin, aMax: Extended): IFloatCondition;
  957. begin
  958. Result := Self.IsNotInRange(aMin,aMax,'');
  959. end;
  960. function TFloatCondition.IsNotInRange(aMin, aMax: Extended; const aCustomMessage : string): IFloatCondition;
  961. begin
  962. if (fValue >= aMin) and (fValue <= aMax) then
  963. begin
  964. if not aCustomMessage.IsEmpty then ThrowException(EArgumentOutOfRangeException,aCustomMessage)
  965. else ThrowException('should not be in range %d-%d',[aMin,aMax]);
  966. end;
  967. Result := Self;
  968. end;
  969. function TFloatCondition.IsNotLessOrEqual(aValue: Extended): IFloatCondition;
  970. begin
  971. Result := Self.IsNotLessOrEqual(aValue,'');
  972. end;
  973. function TFloatCondition.IsNotLessOrEqual(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  974. begin
  975. if fValue <= aValue then
  976. begin
  977. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  978. else ThrowException('should not be less or equal to %d',[aValue]);
  979. end;
  980. Result := Self;
  981. end;
  982. function TFloatCondition.IsNotLessThan(aValue: Extended): IFloatCondition;
  983. begin
  984. Result := Self.IsNotLessThan(aValue,'');
  985. end;
  986. function TFloatCondition.IsNotLessThan(aValue: Extended; const aCustomMessage : string): IFloatCondition;
  987. begin
  988. if fValue < aValue then
  989. begin
  990. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  991. else ThrowException('should not be less than %d',[aValue]);
  992. end;
  993. Result := Self;
  994. end;
  995. function TFloatCondition.Evaluate(aExpression: Boolean): IFloatCondition;
  996. begin
  997. Result := Self.Evaluate(aExpression,'');
  998. end;
  999. function TFloatCondition.Evaluate(aExpression: Boolean; const aCustomMessage : string): IFloatCondition;
  1000. begin
  1001. if not aExpression then
  1002. begin
  1003. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  1004. else ThrowException('must meet condition');
  1005. end;
  1006. end;
  1007. { TObjectCondition }
  1008. constructor TObjectCondition.Create(const aValue: TObject; const aName: string; aPostCondition : Boolean);
  1009. begin
  1010. fName := aName;
  1011. fValue := aValue;
  1012. fPostCondition := aPostCondition;
  1013. end;
  1014. function TObjectCondition.WithExceptionOnFailure(aExceptionClass: ExceptClass): IObjectCondition;
  1015. begin
  1016. fExceptionClass := aExceptionClass;
  1017. Result := Self;
  1018. end;
  1019. function TObjectCondition.IsNull: IObjectCondition;
  1020. begin
  1021. Result := Self.IsNull('');
  1022. end;
  1023. function TObjectCondition.IsNull(const aCustomMessage: string): IObjectCondition;
  1024. begin
  1025. if fValue <> nil then
  1026. begin
  1027. if not aCustomMessage.IsEmpty then ThrowException(EArgumentNilException,aCustomMessage)
  1028. else ThrowException('must be null');
  1029. end;
  1030. Result := Self;
  1031. end;
  1032. function TObjectCondition.IsNotNull: IObjectCondition;
  1033. begin
  1034. Result := Self.IsNotNull('');
  1035. end;
  1036. function TObjectCondition.IsNotNull(const aCustomMessage: string): IObjectCondition;
  1037. begin
  1038. if fValue = nil then
  1039. begin
  1040. if not aCustomMessage.IsEmpty then ThrowException(EArgumentNilException,aCustomMessage)
  1041. else ThrowException('should not be null');
  1042. end;
  1043. Result := Self;
  1044. end;
  1045. function TObjectCondition.IsOfType(aClass: TClass): IObjectCondition;
  1046. begin
  1047. Result := Self.IsOfType(aClass,'');
  1048. end;
  1049. function TObjectCondition.IsOfType(aClass: TClass; const aCustomMessage: string): IObjectCondition;
  1050. begin
  1051. if not(fValue is aClass) then
  1052. begin
  1053. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  1054. else ThrowException('must be of type "%s"',[aClass.ClassName]);
  1055. end;
  1056. Result := Self;
  1057. end;
  1058. function TObjectCondition.DoesNotOfType(aClass: TClass): IObjectCondition;
  1059. begin
  1060. Result := Self.DoesNotOfType(aClass,'');
  1061. end;
  1062. function TObjectCondition.DoesNotOfType(aClass: TClass; const aCustomMessage: string): IObjectCondition;
  1063. begin
  1064. if fValue is aClass then
  1065. begin
  1066. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  1067. else ThrowException('should not be of type "%s"',[aClass.ClassName]);
  1068. end;
  1069. Result := Self;
  1070. end;
  1071. function TObjectCondition.Evaluate(aExpression: Boolean): IObjectCondition;
  1072. begin
  1073. Result := Self.Evaluate(aExpression,'');
  1074. end;
  1075. function TObjectCondition.Evaluate(aExpression: Boolean; const aCustomMessage: string): IObjectCondition;
  1076. begin
  1077. if not aExpression then
  1078. begin
  1079. if not aCustomMessage.IsEmpty then ThrowException(EArgumentException,aCustomMessage)
  1080. else ThrowException('must meet condition');
  1081. end;
  1082. Result := Self;
  1083. end;
  1084. { TCondition }
  1085. constructor TCondition.Create;
  1086. begin
  1087. fName := '';
  1088. fExceptionClass := nil;
  1089. fPostCondition := False;
  1090. end;
  1091. procedure TCondition.ThrowException(const aMsg: string);
  1092. var
  1093. rexception : ExceptClass;
  1094. begin
  1095. if fExceptionClass <> nil then raise fExceptionClass.Create(aMsg)
  1096. else
  1097. begin
  1098. if fPostCondition then rexception := EPostConditionError
  1099. else rexception := EPreConditionError;
  1100. if fName.IsEmpty then raise rexception.Create(aMsg)
  1101. else raise rexception.CreateFmt('[%s] %s',[fName,aMsg]);
  1102. end;
  1103. end;
  1104. procedure TCondition.ThrowException(const aMsg: string; aValues: array of const);
  1105. begin
  1106. if fExceptionClass <> nil then raise fExceptionClass.Create(aMsg)
  1107. else ThrowException(Format(aMsg,aValues));
  1108. end;
  1109. procedure TCondition.ThrowException(aExceptionClass : ExceptClass; const aMsg : string);
  1110. begin
  1111. if fExceptionClass <> nil then raise fExceptionClass.Create(aMsg)
  1112. else raise aExceptionClass.Create(aMsg);
  1113. end;
  1114. end.