diff --git a/lib/src/validations/range_validation.dart b/lib/src/validations/range_validation.dart index ef3d966..3a721c1 100644 --- a/lib/src/validations/range_validation.dart +++ b/lib/src/validations/range_validation.dart @@ -19,11 +19,33 @@ extension RangeValidation on SimpleValidationBuilder { /// ruleFor((user) => user.age, key: 'age') /// .range(18, 65); /// ``` - SimpleValidationBuilder range(num min, num max, {String message = r'Must be between $min and $max', String code = 'range_error'}) { - return must( - (value) => value >= min && value <= max, - message.replaceAll(r'$min', min.toString()).replaceAll('$max', max.toString()), - code, + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// - **{From}**: The minimum value of the range. + /// - **{To}**: The maximum value of the range. + /// - **{PropertyValue}**: The value of the property. + /// + SimpleValidationBuilder range(num min, num max, + {String? message, String? code}) { + return use( + (value, entity) { + if (value >= min && value <= max) return null; + + final currentCode = code ?? Language.code.range; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + 'From': '$min', + 'To': '$max', + 'PropertyValue': '$value', + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }, ); } } diff --git a/lib/src/validations/valid_cep_validation.dart b/lib/src/validations/valid_cep_validation.dart index d9753b7..b81502b 100644 --- a/lib/src/validations/valid_cep_validation.dart +++ b/lib/src/validations/valid_cep_validation.dart @@ -17,11 +17,24 @@ extension ValidCEPValidation on SimpleValidationBuilder { /// ruleFor((user) => user.cep, key: 'cep') /// .validCEP(); /// ``` - SimpleValidationBuilder validCEP({String message = 'Invalid CEP', String code = 'invalid_cep'}) { - return must( - (value) => RegExp(r'^\d{5}-?\d{3}$').hasMatch(value), - message, - code, - ); + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// + SimpleValidationBuilder validCEP({String? message, String? code}) { + return use((value, entity) { + if (RegExp(r'^\d{5}-?\d{3}$').hasMatch(value)) return null; + + final currentCode = code ?? Language.code.validCEP; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }); } } diff --git a/lib/src/validations/valid_cnpj_validation.dart b/lib/src/validations/valid_cnpj_validation.dart index dc4b293..6176cae 100644 --- a/lib/src/validations/valid_cnpj_validation.dart +++ b/lib/src/validations/valid_cnpj_validation.dart @@ -18,12 +18,25 @@ extension ValidCnpjValidation on SimpleValidationBuilder { /// ruleFor((user) => user.cnpj, key: 'cnpj') /// .validCNPJ(); /// ``` - SimpleValidationBuilder validCNPJ({String message = 'Invalid CNPJ', String code = 'invalid_cnpj'}) { - return must( - (value) => _validateCNPJ(value), - message, - code, - ); + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// + SimpleValidationBuilder validCNPJ({String? message, String? code}) { + return use((value, entity) { + if (_validateCNPJ(value)) return null; + + final currentCode = code ?? Language.code.validCNPJ; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }); } bool _validateCNPJ(String cnpj) { diff --git a/lib/src/validations/valid_cpf_validation.dart b/lib/src/validations/valid_cpf_validation.dart index 6916be3..8702ca2 100644 --- a/lib/src/validations/valid_cpf_validation.dart +++ b/lib/src/validations/valid_cpf_validation.dart @@ -18,12 +18,25 @@ extension ValidCPFValidation on SimpleValidationBuilder { /// ruleFor((user) => user.cpf, key: 'cpf') /// .validCPF(); /// ``` - SimpleValidationBuilder validCPF({String message = 'Invalid CPF', String code = 'invalid_cpf'}) { - return must( - (value) => _validateCPF(value), - message, - code, - ); + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// + SimpleValidationBuilder validCPF({String? message, String? code}) { + return use((value, entity) { + if (_validateCPF(value)) return null; + + final currentCode = code ?? Language.code.validCPF; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }); } bool _validateCPF(String cpf) { diff --git a/lib/src/validations/valid_creditcard_validation.dart b/lib/src/validations/valid_creditcard_validation.dart index 094ce9f..779e575 100644 --- a/lib/src/validations/valid_creditcard_validation.dart +++ b/lib/src/validations/valid_creditcard_validation.dart @@ -17,18 +17,34 @@ extension ValidCreditCardValidation on SimpleValidationBuilder { /// ruleFor((user) => user.creditCard, key: 'creditCard') /// .validCreditCard(); /// ``` - SimpleValidationBuilder validCreditCard({String message = 'Invalid credit card number', String code = 'invalid_credit_card'}) { - return must( - (value) => _validateCreditCard(value), - message, - code, - ); + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// + SimpleValidationBuilder validCreditCard( + {String? message, String? code}) { + return use((value, entity) { + if (_validateCreditCard(value)) return null; + + final currentCode = code ?? Language.code.validCreditCard; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }); } bool _validateCreditCard(String number) { // Remove non-numeric characters number = number.replaceAll(RegExp(r'[^0-9]'), ''); - if (number.isEmpty || number.length < 13 || number.length > 19) return false; + if (number.isEmpty || number.length < 13 || number.length > 19) { + return false; + } int sum = 0; bool alternate = false; diff --git a/lib/src/validations/valid_email_validation.dart b/lib/src/validations/valid_email_validation.dart index 2e80063..1642e07 100644 --- a/lib/src/validations/valid_email_validation.dart +++ b/lib/src/validations/valid_email_validation.dart @@ -18,11 +18,26 @@ extension ValidEmailValidation on SimpleValidationBuilder { /// ruleFor((user) => user.email, key: 'email') /// .validEmail(); /// ``` - SimpleValidationBuilder validEmail({String message = 'Invalid email address', String code = 'invalid_email'}) { - return must( - (value) => RegExp(r'^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$').hasMatch(value), - message, - code, - ); + /// + /// String format args: + /// - **{PropertyName}**: The name of the property. + /// + SimpleValidationBuilder validEmail({String? message, String? code}) { + return use((value, entity) { + if (RegExp(r'^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$').hasMatch(value)) { + return null; + } + + final currentCode = code ?? Language.code.validEmail; + final currentMessage = LucidValidation.global.languageManager.translate( + currentCode, + parameters: { + 'PropertyName': key, + }, + defaultMessage: message, + ); + + return ValidationError(message: currentMessage, code: currentCode); + }); } } diff --git a/test/lucid_validation_test.dart b/test/lucid_validation_test.dart index 3184baa..96583c4 100644 --- a/test/lucid_validation_test.dart +++ b/test/lucid_validation_test.dart @@ -3,7 +3,9 @@ import 'package:test/test.dart'; import 'mocks/mocks.dart'; void main() { - test('when validating [UserEntityMock] should return a list of error messages for the email field', () { + test( + 'when validating [UserEntityMock] should return a list of error messages for the email field', + () { final validator = UserValidator(); final userEntity = UserModel() ..age = 18 @@ -20,7 +22,9 @@ void main() { expect(errors[1].message, 'Invalid email address'); }); - test('when validating [UserModel] should return a list of error messages for the password field', () { + test( + 'when validating [UserModel] should return a list of error messages for the password field', + () { final validator = UserValidator(); final userEntity = UserModel() ..age = 18 @@ -41,7 +45,9 @@ void main() { expect(errors[5].message, 'Must contain at least one special character'); }); - test('when validating [UserModel] should return a list of error messages for the age field', () { + test( + 'when validating [UserModel] should return a list of error messages for the age field', + () { final validator = UserValidator(); final userEntity = UserModel() ..age = 15 @@ -57,7 +63,9 @@ void main() { expect(errors.first.message, 'Minimum age is 18 years'); }); - test('when validating [UserModel] should return a list of error messages for the phone field', () { + test( + 'when validating [UserModel] should return a list of error messages for the phone field', + () { final validator = UserValidator(); final userEntity = UserModel() @@ -74,7 +82,9 @@ void main() { expect(errors.first.message, 'Phone invalid format'); }); - test('when validating [UserModel] should return a list of error messages for all fields', () { + test( + 'when validating [UserModel] should return a list of error messages for all fields', + () { final validator = UserValidator(); final userEntity = UserModel()..age = 15; @@ -114,6 +124,7 @@ void main() { country: 'Brazil', postcode: '12345-678', ), + cnpj: '12345678901234', ); final validator = CustomerValidator(); diff --git a/test/mocks/mocks.dart b/test/mocks/mocks.dart index 44d6fc6..47e9f67 100644 --- a/test/mocks/mocks.dart +++ b/test/mocks/mocks.dart @@ -8,6 +8,7 @@ class UserModel { String? description; int age = 0; String phone = ''; + String cpf = ''; } class UserValidator extends LucidValidator { @@ -24,6 +25,10 @@ class UserValidator extends LucidValidator { ruleFor((user) => user.phone, key: 'phone') // .customValidPhone('Phone invalid format'); + + ruleFor((user) => user.cpf, key: 'cpf') // + .notEmpty() + .validCPF(); } } @@ -37,7 +42,8 @@ extension CustomValidPhoneValidator on LucidValidationBuilder { } } -extension CustomValidPasswordValidator on LucidValidationBuilder { +extension CustomValidPasswordValidator + on LucidValidationBuilder { LucidValidationBuilder customValidPassword() { return notEmpty() // .minLength(5, message: 'Must be at least 8 characters long') @@ -80,10 +86,13 @@ class CredentialsRegisterValidator extends LucidValidator { ruleFor((credentials) => credentials.password, key: 'password') // .customValidPassword() - .equalTo((entity) => entity.confirmPassword, message: 'Must be equal to confirmPassword'); + .equalTo((entity) => entity.confirmPassword, + message: 'Must be equal to confirmPassword'); - ruleFor((credentials) => credentials.confirmPassword, key: 'confirmPassword') // - .equalTo((entity) => entity.password, message: 'Must be equal to password'); + ruleFor((credentials) => credentials.confirmPassword, + key: 'confirmPassword') // + .equalTo((entity) => entity.password, + message: 'Must be equal to password'); } } @@ -110,10 +119,12 @@ class AddressValidator extends LucidValidator
{ class Customer { String name; Address address; + String cnpj; Customer({ required this.name, required this.address, + required this.cnpj, }); } @@ -126,6 +137,22 @@ class CustomerValidator extends LucidValidator { ruleFor((customer) => customer.address, key: 'address') // .setValidator(addressValidator); + + ruleFor((customer) => customer.cnpj, key: 'cnpj') // + .notEmpty() + .validCNPJ(); + } +} + +class CreditCardModel { + String number = ''; +} + +class CreditCardValidator extends LucidValidator { + CreditCardValidator() { + ruleFor((card) => card.number, key: 'number') // + .notEmpty() + .validCreditCard(); } } diff --git a/test/src/validations/range_validation_test.dart b/test/src/validations/range_validation_test.dart new file mode 100644 index 0000000..ad117e6 --- /dev/null +++ b/test/src/validations/range_validation_test.dart @@ -0,0 +1,26 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('range validation ...', () { + final validator = TestLucidValidator(); + + validator + .ruleFor((e) => e.age, key: 'age') // + .range(18, 60); + + var user = UserModel()..age = 17; + + final result = validator.validate(user); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'age' must be between 18 and 60. You entered 17."); + }); +} diff --git a/test/src/validations/valid_cep_validation_test.dart b/test/src/validations/valid_cep_validation_test.dart new file mode 100644 index 0000000..026b72d --- /dev/null +++ b/test/src/validations/valid_cep_validation_test.dart @@ -0,0 +1,29 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('valid cep validation ...', () { + final validator = TestLucidValidator
(); + + validator + .ruleFor((e) => e.postcode, key: 'postcode') // + .validCEP(); + + var customer = Address( + country: 'Brazil', + postcode: '1234578', + ); + + final result = validator.validate(customer); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'postcode' is not a valid CEP."); + }); +} diff --git a/test/src/validations/valid_cnpj_validation_test.dart b/test/src/validations/valid_cnpj_validation_test.dart new file mode 100644 index 0000000..a9de084 --- /dev/null +++ b/test/src/validations/valid_cnpj_validation_test.dart @@ -0,0 +1,33 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('valid cnpj validation ...', () { + final validator = TestLucidValidator(); + + validator + .ruleFor((e) => e.cnpj, key: 'cnpj') // + .validCNPJ(); + + var customer = Customer( + name: 'John Doe', + address: Address( + country: 'Brazil', + postcode: '12345-678', + ), + cnpj: '12345678901234', + ); + + final result = validator.validate(customer); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'cnpj' is not a valid CNPJ."); + }); +} diff --git a/test/src/validations/valid_cpf_validation_test.dart b/test/src/validations/valid_cpf_validation_test.dart new file mode 100644 index 0000000..7eba209 --- /dev/null +++ b/test/src/validations/valid_cpf_validation_test.dart @@ -0,0 +1,26 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('valid cpf validation ...', () { + final validator = TestLucidValidator(); + + validator + .ruleFor((e) => e.cpf, key: 'cpf') // + .validCPF(); + + final user = UserModel()..cpf = '1'; + + final result = validator.validate(user); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'cpf' is not a valid CPF."); + }); +} diff --git a/test/src/validations/valid_creditcard_validation_test.dart b/test/src/validations/valid_creditcard_validation_test.dart new file mode 100644 index 0000000..89f0792 --- /dev/null +++ b/test/src/validations/valid_creditcard_validation_test.dart @@ -0,0 +1,26 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('valid creditcard validation ...', () { + final validator = TestLucidValidator(); + + validator + .ruleFor((e) => e.number, key: 'number') // + .validCreditCard(); + + final creditCard = CreditCardModel()..number = '1'; + + final result = validator.validate(creditCard); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'number' is not a valid credit card number."); + }); +} diff --git a/test/src/validations/valid_email_validation_test.dart b/test/src/validations/valid_email_validation_test.dart new file mode 100644 index 0000000..e0fd477 --- /dev/null +++ b/test/src/validations/valid_email_validation_test.dart @@ -0,0 +1,26 @@ +import 'package:lucid_validation/lucid_validation.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mocks.dart'; + +void main() { + test('valid email validation ...', () { + final validator = TestLucidValidator(); + + validator + .ruleFor((e) => e.email, key: 'email') // + .validEmail(); + + final user = UserModel()..email = 'testtest.com'; + + final result = validator.validate(user); + + expect(result.isValid, false); + + expect(result.errors.length, 1); + + final error = result.errors.first; + + expect(error.message, "'email' is not a valid email address."); + }); +}