├── .analysis_options ├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.jenkins ├── lib ├── expect.dart ├── src │ ├── errors.dart │ └── utils.dart └── validate.dart ├── pubspec.yaml ├── test └── unit │ └── validate_test.dart └── tool └── grind.dart /.analysis_options: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Config for Analyzer 3 | # More: https://pub.dartlang.org/packages/analyzer 4 | # 5 | # Analyzer options: 6 | # https://www.dartlang.org/guides/language/analysis-options 7 | # 8 | 9 | analyzer: 10 | strong-mode: true 11 | 12 | # Exclude wegen https://github.com/dart-lang/sdk/issues/26420 13 | # und https://github.com/dart-lang/test/issues/436 14 | 15 | # exclude: 16 | # - test/** 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | packages 2 | pubspec.lock 3 | .project 4 | .children 5 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Originally written by: ??? http://commons.apache.org/ 2 | Source: http://javasourcecode.org/html/open-source/commons-lang3/commons-lang3-3.0/org/apache/commons/lang3/Validate.java.html 3 | 4 | Ported to Dart by Mike Mitterer 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log for validate 2 | This class assists in validating method arguments 3 | 4 | ## [v1.7](http://github.com/mikemitterer/dart-validate/compare/v1.6...v1.7) - 2018-08-21 5 | 6 | ### Feature 7 | * Support for GMAIL infinite mailboxes (PATTERN_EMAIL) changed. Closes #3 [4af87cb](https://github.com/mikemitterer/dart-validate/commit/4af87cb6c1892421eab1ce27cdfe4c872ddb6ef0) 8 | 9 | ## [v1.5.4](http://github.com/mikemitterer/dart-validate/compare/v1.5.3...v1.5.4) - 2017-01-31 10 | 11 | ### Docs 12 | * Added sample for testing [158f512](https://github.com/mikemitterer/dart-validate/commit/158f5124cd9db5913c05e9037a969315c455444d) 13 | 14 | ## [v1.5.3](http://github.com/mikemitterer/dart-validate/compare/v1.5.2...v1.5.3) - 2016-11-16 15 | 16 | ### Docs 17 | * Strong-Mode support [7878549](https://github.com/mikemitterer/dart-validate/commit/7878549628d44e64c627cd84d095e1e7bc1567fa) 18 | 19 | ## [v1.5.2](http://github.com/mikemitterer/dart-validate/compare/v1.5.1...v1.5.2) - 2016-07-14 20 | 21 | ### Docs 22 | * isKeyInMap shows Map as JSON-Structure [471c4e2](https://github.com/mikemitterer/dart-validate/commit/471c4e2fb5807dc660a00275840f6f00bf4dc947) 23 | 24 | ## [v1.5.1](http://github.com/mikemitterer/dart-validate/compare/v1.5.0...v1.5.1) - 2015-12-08 25 | 26 | ### Docs 27 | * Readme [40e65a6](https://github.com/mikemitterer/dart-validate/commit/40e65a60edf84faa8026c9a2dfcf46a46adc9d22) 28 | 29 | ## [v1.5.0](http://github.com/mikemitterer/dart-validate/compare/v1.4.0...v1.5.0) - 2015-12-08 30 | 31 | ### Feature 32 | * Changed to 'test', improved password-pattern [13e0926](https://github.com/mikemitterer/dart-validate/commit/13e09267655f9a059ed22fbc89ad525b22a9b98f) 33 | 34 | ### Docs 35 | * Grinder + new test format [965fa08](https://github.com/mikemitterer/dart-validate/commit/965fa08ca09ac9dae3abeb799b9c44606759fe42) 36 | 37 | 38 | This CHANGELOG.md was generated with [**Changelog for Dart**](https://pub.dartlang.org/packages/changelog) 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, Mike Mitterer 2 | 3 | Mike Mitterer: http://www.MikeMitterer.at/ 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Validate 2 | Lightweight library for validating function arguments in Dart. 3 | 4 | This library is mainly a port of Apaches org.apache.commons.lang3.Validate class 5 | 6 | Validation is necessary on most public-facing APIs. Parameter validation 7 | on non-public methods is not as important - it is often desirable to have validation occur only once, 8 | at the public 'entry point' - but if you can live with the potential performance hit, I recommend 9 | to validate parameters everywhere, as it makes code maintenance and refactoring a bit easier. 10 | 11 | For further documentation please refere to the Unit-Tests. 12 | 13 | ### History 14 | 15 | * 1.4.0 - Instance check added 16 | * 1.3.0 - Validate.isUUID added 17 | * 1.2.7 - Removed debug info from URIBuilder 18 | * 1.2.4 - Runs with Dart 1.1 + IntelliJ 13 19 | * 1.2.0 - isKeyInMap check added 20 | * 1.1.0 - isJson check added 21 | * 1.0.5 - Changed GitHub-Repository to dart-validate 22 | * 1.0.4 - Replaced NullPointerException with ArgumentError - makes more sense 23 | 24 | You can see further changes on the [CHANGELOG](https://goo.gl/2d63eC)! 25 | 26 | 27 | ### License 28 | 29 | Copyright 2018 Michael Mitterer, IT-Consulting and Development Limited, 30 | Austrian Branch 31 | 32 | Licensed under the Apache License, Version 2.0 (the "License"); 33 | you may not use this file except in compliance with the License. 34 | You may obtain a copy of the License at 35 | 36 | http://www.apache.org/licenses/LICENSE-2.0 37 | 38 | Unless required by applicable law or agreed to in writing, 39 | software distributed under the License is distributed on an 40 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 41 | either express or implied. See the License for the specific language 42 | governing permissions and limitations under the License. 43 | 44 | If this plugin is helpful for you - please [(Circle)](http://gplus.mikemitterer.at/) me. 45 | 46 | [1]: http://htmlpreview.github.io/?https://raw.github.com/MikeMitterer/dart-validate/master/docs/index.html -------------------------------------------------------------------------------- /build.jenkins: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | label 'linux' 4 | } 5 | stages { 6 | stage('Prepare') { 7 | steps { 8 | timeout(time: 15, unit: 'MINUTES') { 9 | ansiColor('xterm') { 10 | sh 'pub update' 11 | sh 'pub global activate grinder' 12 | } 13 | } 14 | } 15 | } 16 | stage('Analyze') { 17 | steps { 18 | ansiColor('xterm') { 19 | sh 'grind analyze' 20 | } 21 | } 22 | } 23 | stage('Test') { 24 | steps { 25 | ansiColor('xterm') { 26 | sh 'grind test-unit' 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/expect.dart: -------------------------------------------------------------------------------- 1 | library expect; 2 | 3 | import 'package:validate/validate.dart'; 4 | 5 | typedef String LazyMessage(); 6 | 7 | String _DEFAULT_IS_NULL_EX_MESSAGE() => Validate.DEFAULT_IS_NULL_EX_MESSAGE; 8 | String _DEFAULT_IS_TRUE_EX_MESSAGE() => Validate.DEFAULT_IS_TRUE_EX_MESSAGE; 9 | 10 | T notNull(final T object,{ final LazyMessage message = _DEFAULT_IS_NULL_EX_MESSAGE }) { 11 | if (object == null) { 12 | throw new ArgumentError(message()); 13 | } 14 | return object; 15 | } 16 | 17 | bool isTrue(final bool expression,{ final LazyMessage message = _DEFAULT_IS_TRUE_EX_MESSAGE }) { 18 | if (expression == null || expression == false) { 19 | throw new ArgumentError(message()); 20 | } 21 | return expression; 22 | } -------------------------------------------------------------------------------- /lib/src/errors.dart: -------------------------------------------------------------------------------- 1 | part of validate; 2 | /// Possible errors thrown by Validate 3 | 4 | abstract class ErrorMessage extends Error { 5 | final String message; 6 | ErrorMessage(this.message); 7 | } 8 | 9 | class IllegalStateError extends ErrorMessage { 10 | IllegalStateError(final String message) : super(message); 11 | } 12 | -------------------------------------------------------------------------------- /lib/src/utils.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Michael Mitterer (office@mikemitterer.at), 3 | * IT-Consulting and Development Limited. 4 | * 5 | * All Rights Reserved. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | part of validate; 21 | 22 | /// Helper to get the runtime-Info. 23 | class instanceCheck { 24 | final bool _strict; 25 | 26 | /// if strict is set to true List == List comparison return false 27 | instanceCheck({final bool strict: true }) : _strict = strict; 28 | 29 | bool check(final obj) { 30 | return (obj is T && _strict == false) || (_strict == true && obj is T && obj.runtimeType.toString() == type); 31 | } 32 | 33 | String get type { 34 | final String type = this.runtimeType.toString().replaceFirst(new RegExp(r'[^<]+<'),'').replaceFirst(new RegExp(r'>$'),''); 35 | //print("T $type"); 36 | return type; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /lib/validate.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Michael Mitterer (office@mikemitterer.at), 3 | * IT-Consulting and Development Limited. 4 | * 5 | * All Rights Reserved. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | library validate; 21 | 22 | import 'dart:convert'; 23 | import 'package:validate/expect.dart' as expect; 24 | 25 | part "src/errors.dart"; 26 | part "src/utils.dart"; 27 | 28 | /** 29 | * This class assists in validating arguments. The validation methods are 30 | * based along the following principles: 31 | * 32 | * Validate.isTrue(i > 0, "The value must be greater than zero"); 33 | * Validate.notNull(surname, "The surname must not be null"); 34 | * 35 | * For testing - use it like this: 36 | * class UserContext { 37 | * final String _restID; 38 | * UserContext(this._restID) { 39 | * Validate.isUUID(_restID); 40 | * } 41 | * } 42 | * test('> wrong ID ', () { 43 | * expect(() => new UserContext("abc"), 44 | * throwsArgumentError); 45 | * }); // end of 'wrong ID ' test 46 | * 47 | */ 48 | 49 | 50 | 51 | /** 52 | * Pattern-RegExp: 53 | * http://goo.gl/jxPnU3 54 | * http://www.mkyong.com/regular-expressions/how-to-validate-password-with-regular-expression/ 55 | */ 56 | abstract class Validate { 57 | static const String PATTERN_EMAIL = "^([0-9a-zA-Z]([-.+\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})\$"; 58 | static const String PATTERN_PW = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#\$%?])[0-9a-zA-Z@#\$%?]{8,15}\$"; 59 | static const String PATTERN_ALPHANUMERIC = "^[a-zA-Z0-9öäüÖÄÜß]+\$"; 60 | static const String PATTERN_HEX = "^(0x[a-fA-F0-9]+)|([a-fA-F0-9])+\$"; 61 | static const String PATTERN_UUID = "^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\$"; 62 | 63 | static const String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false"; 64 | static const String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null"; 65 | static const String DEFAULT_NOT_EMPTY_MESSAGE = "The validated value is empty"; 66 | static const String DEFAULT_NOT_BLANK_EX_MESSAGE = "The validated string is blank"; 67 | static const String DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE = "The validated array contains null element"; 68 | static const String DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE = "The validated array index is invalid"; 69 | static const String DEFAULT_VALID_STATE_EX_MESSAGE = "The validated state is false"; 70 | static const String DEFAULT_MATCHES_PATTERN_EX = "The string does not match the pattern"; 71 | static const String DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE = "The value is not in the specified inclusive range"; 72 | static const String DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE = "The value is not in the specified exclusive range"; 73 | static const String DEFAULT_JSON_MESSAGE = "The value is neither a num, String, bool, Null, List or Map"; 74 | static const String DEFAULT_KEY_IN_MAP_MESSAGE = "The key '%key%' is not available for this structure: %structure%"; 75 | 76 | static const String DEFAULT_IS_INSTANCE_OF_EX_MESSAGE = "The instance of the validated object is invalid. Should have been %wish% but was %truth%"; 77 | 78 | /// prettyPrint for JSON (Used for KeyInMap check) 79 | static const JsonEncoder _PRETTYJSON = const JsonEncoder.withIndent(' '); 80 | 81 | /* 82 | static const String _DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE = "The validated collection contains null element at specified index"; 83 | static const String _DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE = "The validated character sequence index is invalid"; 84 | static const String _DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE ="The validated collection index is invalid"; 85 | */ 86 | 87 | // isTrue 88 | //--------------------------------------------------------------------------------- 89 | 90 | /** 91 | *

Validate that the argument condition is [true] otherwise 92 | * throwing an exception with the specified message. This method is useful when 93 | * validating according to an arbitrary boolean expression, such as validating a 94 | * primitive number or using your own custom validation expression.

95 | * 96 | *
Validate.isTrue(i > 0.0, "The value must be greater than zero: $value");
97 | * 98 | * [expression] the boolean expression to check 99 | * [message] the exception message if invalid, not null 100 | * Throws [ArgumentError] if expression is [false] 101 | */ 102 | static bool isTrue(final bool expression, [ final String message = DEFAULT_IS_TRUE_EX_MESSAGE]) 103 | => expect.isTrue(expression, message: () => message); 104 | 105 | // notNull 106 | //--------------------------------------------------------------------------------- 107 | 108 | /** 109 | *

Validate that the specified argument is not [null]; 110 | * otherwise throwing an exception. 111 | * 112 | *

Validate.notNull(myObject, "The object must not be null");
113 | * 114 | *

The message of the exception is "The validated object is 115 | * null".

116 | * 117 | * [object] the object to check 118 | * Returns the validated object if not null 119 | * Throws [ArgumentError] if the object is null 120 | */ 121 | // static dynamic notNull(final object,[String message = DEFAULT_IS_NULL_EX_MESSAGE]) { 122 | // if (object == null) { 123 | // throw new ArgumentError(message); 124 | // } 125 | // return object; 126 | // } 127 | 128 | static T notNull(final T object,[String message = DEFAULT_IS_NULL_EX_MESSAGE]) 129 | => expect.notNull(object, message: () => message); 130 | 131 | 132 | // notEmpty array 133 | //--------------------------------------------------------------------------------- 134 | 135 | /** 136 | *

Validate that the specified argument is neither [null] 137 | * nor is empty (object must have isEmpty implemented); otherwise throwing an exception 138 | * with the specified message. 139 | * 140 | *

Validate.notEmpty(myArray, "The array must not be empty");
141 | * 142 | * [value] the value to check, validated not null by this method 143 | * [message] the exception message if invalid, not null 144 | * Returns the validated value (never [null] method for chaining) 145 | * Throws [ArgumentError] if the array is [null] 146 | * Throws [ArgumentError] if the array is empty 147 | */ 148 | static notEmpty(final value, [String message = DEFAULT_NOT_EMPTY_MESSAGE]) { 149 | Validate.notNull(value,message); 150 | /* 151 | if ((value is List || value is Map || value is String) && value.length == 0) { 152 | throw new ArgumentError(message); 153 | } 154 | */ 155 | if (value.isEmpty) { 156 | throw new ArgumentError(message); 157 | } 158 | 159 | return value; 160 | } 161 | 162 | 163 | // notBlank string 164 | //--------------------------------------------------------------------------------- 165 | 166 | /** 167 | *

Validate that the specified string is 168 | * neither [null], a length of zero (no characters), empty 169 | * nor whitespace; otherwise throwing an exception with the specified 170 | * message. 171 | * 172 | *

Validate.notBlank(myString, "The string must not be blank");
173 | * 174 | * [value] the string to check, validated not null by this method 175 | * [message] the exception message if invalid, not null 176 | * Returns the validated string 177 | * Throws [ArgumentError] if the character sequence is [null] 178 | * Throws [ArgumentError] if the character sequence is blank 179 | */ 180 | static String notBlank(final String value, [String message = DEFAULT_NOT_BLANK_EX_MESSAGE]) { 181 | Validate.notNull(value,message); 182 | if ((value is String) == false || value.trim().isEmpty) { 183 | throw new ArgumentError(message); 184 | } 185 | return value; 186 | } 187 | 188 | // noNullElements array 189 | //--------------------------------------------------------------------------------- 190 | 191 | /** 192 | *

Validate that the specified argument array is neither 193 | * [null] nor contains any elements that are [null]; 194 | * otherwise throwing an exception with the specified message. 195 | * 196 | *

Validate.noNullElements(myArray, "The validated array contains null element");
197 | * 198 | *

If the array is [null], then the message in the exception 199 | * is "The validated object is null".

200 | * 201 | * [iterable] the Iterable to check, validated not null by this method 202 | * [message] the exception message if invalid, not null 203 | * Returns the validated iterable (never [null] method for chaining) 204 | * Throws [ArgumentError] if the iterable is [null] 205 | * Throws [ArgumentError] if an element is [null] 206 | */ 207 | static Iterable noNullElements(Iterable iterable, [String message = DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE]) { 208 | Validate.notNull(iterable); 209 | for(var x in iterable) { 210 | if(x == null) { 211 | throw new ArgumentError(message); 212 | } 213 | } 214 | 215 | return iterable; 216 | } 217 | 218 | 219 | 220 | 221 | // validIndex array 222 | //--------------------------------------------------------------------------------- 223 | 224 | /** 225 | *

Validates that the index is within the bounds of the argument 226 | * iterable; otherwise throwing an exception with the specified message.

227 | * 228 | *
Validate.validIndex(iterable, 2, "The validated array index is invalid");
229 | * 230 | *

If the array is [null], then the message of the exception 231 | * is "The validated object is null".

232 | * 233 | * [iterable] the iterable to check, validated not null by this method 234 | * [index] the index to check 235 | * [message] the exception message if invalid, not null 236 | * Returns the validated iterable (never [null] for method chaining) 237 | * Throws [ArgumentError] if the array is [null] 238 | * Throws [RangeError] if the index is invalid 239 | */ 240 | static Iterable validIndex(Iterable iterable, int index, [String message = DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE]) { 241 | Validate.notNull(iterable); 242 | if (index < 0 || index >= iterable.length) { 243 | throw new RangeError(message); 244 | } 245 | return iterable; 246 | } 247 | 248 | 249 | 250 | // validState 251 | //--------------------------------------------------------------------------------- 252 | 253 | /** 254 | *

Validate that the stateful condition is [true] otherwise 255 | * throwing an exception. This method is useful when validating according 256 | * to an arbitrary boolean expression, such as validating a 257 | * primitive number or using your own custom validation expression.

258 | * 259 | *
260 |      * Validate.validState(field > 0);
261 |      * Validate.validState(this.isOk());
262 | * 263 | *

The message of the exception is "The validated state is 264 | * false".

265 | * 266 | * [expression] the boolean expression to check 267 | * Throws [IllegalStateException] if expression is [false] 268 | */ 269 | static void validState(bool expression,[String message = DEFAULT_VALID_STATE_EX_MESSAGE]) { 270 | if (expression == false) { 271 | throw new IllegalStateError(message); 272 | } 273 | } 274 | 275 | 276 | 277 | // matchesPattern 278 | //--------------------------------------------------------------------------------- 279 | 280 | /** 281 | *

Validate that the specified argument character sequence matches the specified regular 282 | * expression pattern; otherwise throwing an exception.

283 | * 284 | *
Validate.matchesPattern("hi", new RegExp("^test\$"));
285 | * 286 | *

The syntax of the pattern is the one used in the {@link RegExp} class.

287 | * 288 | * [input] the character sequence to validate, not null 289 | * [pattern] the regular expression pattern, not null 290 | * Throws [ArgumentError] if the character sequence does not match the pattern 291 | */ 292 | static void matchesPattern(String input, RegExp pattern,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 293 | if (pattern.hasMatch(input) == false) { 294 | throw new ArgumentError(message); 295 | } 296 | } 297 | 298 | static void isEmail(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 299 | matchesPattern(input,new RegExp(PATTERN_EMAIL),message); 300 | } 301 | 302 | static void isPassword(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 303 | matchesPattern(input,new RegExp(PATTERN_PW),message); 304 | } 305 | 306 | static void isAlphaNumeric(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 307 | matchesPattern(input,new RegExp(PATTERN_ALPHANUMERIC),message); 308 | } 309 | 310 | static void isHex(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 311 | matchesPattern(input,new RegExp(PATTERN_HEX),message); 312 | } 313 | 314 | static void isUUID(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) { 315 | matchesPattern(input,new RegExp(PATTERN_UUID),message); 316 | } 317 | 318 | // inclusiveBetween 319 | //--------------------------------------------------------------------------------- 320 | 321 | /** 322 | *

Validate that the specified argument object fall between the two 323 | * inclusive values specified; otherwise, throws an exception.

324 | * 325 | *
Validate.inclusiveBetween(0, 2, 1);
326 | * 327 | * [start] the inclusive start value, not null 328 | * [end] the inclusive end value, not null 329 | * [value] the object to validate, not null 330 | * Throws [ArgumentError] if the value falls out of the boundaries 331 | */ 332 | static void inclusiveBetween(Comparable start, Comparable end, Comparable value,[String message = DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE]) { 333 | if (value.compareTo(start) < 0 || value.compareTo(end) > 0) { 334 | throw new ArgumentError(message); 335 | } 336 | } 337 | 338 | // exclusiveBetween 339 | //--------------------------------------------------------------------------------- 340 | 341 | /** 342 | *

Validate that the specified argument object fall between the two 343 | * exclusive values specified; otherwise, throws an exception.

344 | * 345 | *
Validate.inclusiveBetween(0, 2, 1);
346 | * 347 | * [start] the exclusive start value, not null 348 | * [end] the exclusive end value, not null 349 | * [value] the object to validate, not null 350 | * Throws [ArgumentError] if the value falls out of the boundaries 351 | */ 352 | static void exclusiveBetween(Comparable start, Comparable end, Comparable value,[String message = DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE]) { 353 | if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) { 354 | throw new ArgumentError(message); 355 | } 356 | } 357 | 358 | // json Object 359 | //--------------------------------------------------------------------------------- 360 | /** 361 | *

Validate that the specified value ist either a num, String, bool, Map or List. 362 | * If the first check fails isJson checks if the value has a toJson() function - if so, the value is also valid 363 | *

364 | * 365 | * [value] the value to validate, not null 366 | * Throws [ArgumentError] if the value falls out of the boundaries 367 | */ 368 | static void isJson(final dynamic value,[String message = DEFAULT_JSON_MESSAGE]) { 369 | Validate.notNull(value, message); 370 | if(!((value is num) || (value is String) || (value is bool) || (value is List) || (value is Map))) { 371 | try { 372 | value.toJson(); 373 | } on NoSuchMethodError { 374 | throw new ArgumentError(message); 375 | } 376 | } 377 | } 378 | 379 | // Key in Map 380 | //--------------------------------------------------------------------------------- 381 | /** 382 | *

Validate that the specified key is in the map and if so the value is not null. 383 | * If %key% is found in [message] it will be replaced with [key].toString()

384 | * 385 | * [key] the key to validate, [map] to validate, must not be null 386 | * Throws [ArgumentError] if the key is not found in the map or if the value found is null. 387 | */ 388 | static void isKeyInMap(final dynamic key,final Map map,[String message = DEFAULT_KEY_IN_MAP_MESSAGE]) { 389 | Validate.notNull(map, message); 390 | if(!map.containsKey(key) || map[key] == null) { 391 | throw new ArgumentError(message.replaceFirst("%key%", key.toString()) 392 | .replaceFirst("%structure%",_PRETTYJSON.convert(map))); 393 | } 394 | } 395 | 396 | // isInstanceOf 397 | //--------------------------------------------------------------------------------- 398 | 399 | /** 400 | * Validate that the argument is an instance of the specified class; otherwise 401 | * throwing an exception. This method is useful when validating according to an arbitrary 402 | * class 403 | * 404 | * Sample: 405 | * Validate.isInstance(new instanceCheck(),"Test"); 406 | * Validate.isInstance(new instanceCheck(),myParam); 407 | * Validate.isInstance(new instanceCheck>(strict: false),new List()) 408 | */ 409 | static void isInstance(final instanceCheck instanceCheck, var obj,[String message = DEFAULT_IS_INSTANCE_OF_EX_MESSAGE]) { 410 | Validate.notNull(instanceCheck); 411 | 412 | if (!instanceCheck.check(obj)) { 413 | final String wish = instanceCheck.type; 414 | final String truth = ( obj != null ? obj.runtimeType.toString() : 'null' ); 415 | throw new ArgumentError(message.replaceAll('%wish%',wish).replaceAll('%truth%',truth)); 416 | } 417 | } 418 | } 419 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: validate 2 | version: 1.7.0 3 | author: Mike Mitterer 4 | description: This class assists in validating method arguments 5 | homepage: https://github.com/MikeMitterer/dart-validate 6 | 7 | environment: 8 | sdk: ">=2.0.0 <3.0.0" 9 | 10 | dev_dependencies: 11 | test: any 12 | grinder: any 13 | 14 | console_log_handler: ^1.0.0 15 | # path: /Volumes/Daten/DevLocal/DevDart/ConsoleLogHandler 16 | 17 | build_runner: any 18 | build_test: any 19 | build_web_compilers: any 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/unit/validate_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:validate/validate.dart'; 3 | 4 | class _NotAJsonObject { 5 | final String message = "I am not the right one"; 6 | } 7 | 8 | class _IAmAJsonObject extends _NotAJsonObject { 9 | dynamic toJson() { 10 | return [ message]; 11 | } 12 | } 13 | 14 | /// A matcher for [IllegalStateError]. 15 | const isIllegalStateError = const TypeMatcher(); 16 | 17 | /// A matcher for functions that throw IllegalStateError. 18 | // ignore: deprecated_member_use 19 | const Matcher throwsIllegalStateError = const Throws(isIllegalStateError); 20 | 21 | 22 | main() { 23 | // final _logger = new Logger('validate.testValidate'); 24 | // configLogging(); 25 | 26 | group('Validator-Test', () { 27 | test('isTrue', () { 28 | expect(() => (Validate.isTrue(true)), returnsNormally); 29 | expect(() => (Validate.isTrue(false)), throwsArgumentError); 30 | }); 31 | 32 | test('> notNull', () { 33 | expect(() => (Validate.notNull("Test")), returnsNormally); 34 | expect(() => (Validate.notNull(null)), throwsArgumentError); 35 | }); 36 | 37 | test('> notEmpty', () { 38 | expect(() => (Validate.notEmpty("Test")), returnsNormally); 39 | expect(() => (Validate.notEmpty([10, 20])), returnsNormally); 40 | 41 | final Map map = new Map(); 42 | expect(() => (Validate.notEmpty(map)), throwsArgumentError); 43 | 44 | map["Hallo"] = "Test"; 45 | expect(() => (Validate.notEmpty(map)), returnsNormally); 46 | 47 | // int has not Method "isEmpty" 48 | expect(() => (Validate.notEmpty(0)), throwsNoSuchMethodError); 49 | 50 | expect(() => (Validate.notEmpty("")), throwsArgumentError); 51 | }); 52 | 53 | test('> notBlank', () { 54 | expect(() => (Validate.notBlank("Test")), returnsNormally); 55 | expect(() => (Validate.notBlank(null)), throwsArgumentError); 56 | expect(() => (Validate.notBlank("")), throwsArgumentError); 57 | 58 | // Dart should point out at least a warning!!!! 59 | //expect(() => (Validate.notBlank(10)),throwsA(new isInstanceOf())); 60 | }); 61 | 62 | test('> noNullElements', () { 63 | expect(() => (Validate.noNullElements([1, 2, 3, 4])), returnsNormally); 64 | 65 | final List list = new List() 66 | ..addAll(["one", "two", "three"]); 67 | 68 | expect(() => (Validate.noNullElements(list)), returnsNormally); 69 | 70 | list.add(null); 71 | expect(4, list.length); 72 | expect(() => (Validate.noNullElements(list)), throwsArgumentError); 73 | 74 | expect(() => (Validate.noNullElements(new List())), returnsNormally); 75 | }); 76 | 77 | test('> validIndex', () { 78 | expect(() => (Validate.validIndex([1, 2], 1)), returnsNormally); 79 | expect(() => (Validate.validIndex([1, 2], 3)), throwsRangeError); 80 | 81 | final List list = new List() 82 | ..addAll(["one", "two", "three"]); 83 | 84 | expect(() => (Validate.validIndex(list, 1)), returnsNormally); 85 | }); 86 | 87 | test('> validState', () { 88 | expect(() => (Validate.validState(true)), returnsNormally); 89 | expect(() => (Validate.validState(false)), throwsIllegalStateError); 90 | }); 91 | 92 | test('> matchesPattern', () { 93 | expect(() => (Validate.matchesPattern("Test", new RegExp("^\\we\\w{2}\$"))), returnsNormally); 94 | expect(() => (Validate.matchesPattern("Te_st", new RegExp("^\\we\\w{2}\$"))), 95 | throwsA(new isInstanceOf())); 96 | 97 | expect(() => (Validate.isEmail("urbi@orbi.it")), returnsNormally); 98 | expect(() => (Validate.isEmail("urbi@orbit")), throwsArgumentError); 99 | 100 | expect(() => (Validate.isAlphaNumeric("123abcdö")), returnsNormally); 101 | expect(() => (Validate.isAlphaNumeric("123a#bcd")), throwsArgumentError); 102 | 103 | expect(() => (Validate.isHex("1234567890abcdef")), returnsNormally); 104 | expect(() => (Validate.isHex("0x1234567890abcdef")), returnsNormally); 105 | expect(() => (Validate.isHex("1234567890abcdefg")), throwsArgumentError); 106 | }); 107 | 108 | test('> password', () { 109 | expect(() => (Validate.isPassword("1abcdefGH#")), returnsNormally); 110 | expect(() => (Validate.isPassword("1abcdefGH?")), returnsNormally); 111 | 112 | expect(() => (Validate.isPassword("urbi@orbi.it")), throwsArgumentError); 113 | expect(() => (Validate.isPassword("1234567890abcdefGH#")), throwsArgumentError); 114 | expect(() => (Validate.isPassword("12345678aA# ")), throwsArgumentError); 115 | expect(() => (Validate.isPassword("12345678aA'")), throwsArgumentError); 116 | expect(() => (Validate.isPassword("")), throwsArgumentError); 117 | expect(() => (Validate.isPassword("1abcdefGH;")), throwsArgumentError); 118 | }); 119 | 120 | test('> inclusive', () { 121 | expect(() => (Validate.inclusiveBetween(0, 2, 2)), returnsNormally); 122 | expect(() => (Validate.inclusiveBetween(0, 2, 3)), throwsArgumentError); 123 | 124 | expect(() => (Validate.exclusiveBetween(0, 2, 2)), throwsArgumentError); 125 | expect(() => (Validate.exclusiveBetween(0, 2, 1)), returnsNormally); 126 | }); 127 | 128 | test('> json', () { 129 | expect(() => (Validate.isJson("Test")), returnsNormally); 130 | expect(() => (Validate.isJson(1)), returnsNormally); 131 | expect(() => (Validate.isJson(["3", "4"])), returnsNormally); 132 | 133 | expect(() => (Validate.isJson(new _NotAJsonObject())), throwsArgumentError); 134 | expect(() => (Validate.isJson(new _IAmAJsonObject())), returnsNormally); 135 | }); 136 | 137 | test('> key in Map', () { 138 | final Map map1ToTest = new Map(); 139 | map1ToTest.putIfAbsent("name", () => "Mike"); 140 | map1ToTest.putIfAbsent("number", () => 42); 141 | 142 | expect(() => (Validate.isKeyInMap("name", map1ToTest)), returnsNormally); 143 | expect(() => (Validate.isKeyInMap("number", map1ToTest)), returnsNormally); 144 | 145 | //expect(() => (Validate.isKeyInMap("email",map1ToTest)),returnsNormally); 146 | expect(() => (Validate.isKeyInMap("email", map1ToTest)), throwsArgumentError); 147 | 148 | try { 149 | Validate.isKeyInMap("email", map1ToTest); 150 | expect(false,isTrue); 151 | 152 | } on ArgumentError catch(e) { 153 | // Strip out all whitespaces 154 | expect(e.message.replaceAll(new RegExp("\\s+")," "), 155 | "The key 'email' is not available for this structure: { \"name\": \"Mike\", \"number\": 42 }"); 156 | } 157 | }); 158 | 159 | test('> isInstanceOf', () { 160 | expect(() => (Validate.isInstance(new instanceCheck>(), new List())), 161 | throwsArgumentError); 162 | 163 | expect(() => (Validate.isInstance(new instanceCheck>(strict: false), new List())), 164 | returnsNormally); 165 | 166 | expect(() => (Validate.isInstance(new instanceCheck(), "Test")), returnsNormally); 167 | expect(() => (Validate.isInstance(new instanceCheck(), 1)), throwsArgumentError); 168 | expect(() => (Validate.isInstance(new instanceCheck(strict: false), 1)),throwsArgumentError); 169 | 170 | expect(() => (Validate.isInstance(new instanceCheck(), 29)), returnsNormally); 171 | expect(() => (Validate.isInstance(new instanceCheck(), 1)),throwsArgumentError); 172 | 173 | expect(() => (Validate.isInstance(new instanceCheck(strict: false), 29.0)), returnsNormally); 174 | expect(() => (Validate.isInstance(new instanceCheck(), 29.0)),throwsArgumentError); 175 | expect(() => (Validate.isInstance(new instanceCheck(strict: false), 29)), returnsNormally); 176 | 177 | expect(() => (Validate.isInstance(null, 29.0)), throwsArgumentError); 178 | }); 179 | }); 180 | } 181 | 182 | -------------------------------------------------------------------------------- /tool/grind.dart: -------------------------------------------------------------------------------- 1 | import 'package:grinder/grinder.dart'; 2 | 3 | main(final List args) => grind(args); 4 | 5 | @Task() 6 | @Depends(test) 7 | build() { 8 | } 9 | 10 | @Task() 11 | @Depends(analyze,testUnit) 12 | test() { } 13 | 14 | @Task() 15 | testUnit() { 16 | new TestRunner().testAsync(files: "test/unit"); 17 | 18 | // Alle test mit @TestOn("content-shell") im header 19 | // new TestRunner().test(files: "test/unit",platformSelector: "content-shell"); 20 | } 21 | 22 | @Task() 23 | analyze() { 24 | final List libs = [ 25 | "lib/validate.dart" 26 | ]; 27 | 28 | libs.forEach((final String lib) => Analyzer.analyze(lib)); 29 | Analyzer.analyze("test"); 30 | } 31 | 32 | 33 | @Task() 34 | clean() => defaultClean(); 35 | --------------------------------------------------------------------------------