Skip to content

Commit c6df4e6

Browse files
implement transform and validate validator
1 parent 0e4e89a commit c6df4e6

File tree

3 files changed

+118
-1
lines changed

3 files changed

+118
-1
lines changed

lib/new_api_prototype/core_validators/check_list_remaining_core_validators.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
- [X] validate with default value validator
77
- [X] Required/optional validators
88
- [X] Add tests to override error msg validator
9-
- [ ] Transform validator
9+
- [ ] Type validators
10+
- [X] Transform validator
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import '../constants.dart';
2+
3+
String errorTransformAndValidateTemporary<T>(
4+
T userInput, String? transformedResultTypeDescription) {
5+
if (transformedResultTypeDescription != null) {
6+
// An example, it will print the error message: "Hello" is not a valid integer.
7+
return '"${userInput.toString()}" is not a valid $transformedResultTypeDescription';
8+
}
9+
10+
return '"${userInput.toString()}" is not able to be transformed.';
11+
}
12+
13+
/// This function returns a validator which transforms the user input.
14+
/// If the transformation fails, it returns a transformation error message.
15+
/// Otherwise, it passes the input to the `next` validator, if it was provided,
16+
/// or, if `next` was not provided, it returns `null`.
17+
///
18+
/// # Parameters
19+
/// - `String?` `transformedResultTypeDescription`: This parameter helps improving
20+
/// the readability of the error message. If provided, the error message can
21+
/// specify what is the expected type/result of the transformation. For example,
22+
/// if 'positive integer' is provided, it can return a message like:
23+
/// '"hello" is not a valid positive integer'. Otherwise, if this parameter is
24+
/// not provided, the default error message will be more generic.
25+
/// - `String` `Function(IN)?` `transformAndValidateMsg`: this is the custom message
26+
/// for the validation error message. It is a function that receives the user
27+
/// input as argument and returns a String, the error message.
28+
///
29+
/// # Transformation
30+
/// This process transforms the user input from the type `IN` to the type `OUT`.
31+
/// Its failure is considered a validation failure, and, when it happens, a
32+
/// validation failure message is returned.
33+
///
34+
/// # Example
35+
/// ```dart
36+
///
37+
/// ```
38+
Validator<IN> transformAndValidate<IN extends Object?, OUT extends Object?>(
39+
OUT Function(IN) transformFunction, {
40+
Validator<OUT>? next,
41+
String Function(IN)? transformAndValidateMsg,
42+
String? transformedResultTypeDescription,
43+
}) {
44+
return (IN input) {
45+
try {
46+
final OUT transformedValue = transformFunction(input);
47+
return next?.call(transformedValue);
48+
} catch (_) {
49+
return transformAndValidateMsg?.call(input) ??
50+
errorTransformAndValidateTemporary(
51+
input.toString(), transformedResultTypeDescription);
52+
}
53+
};
54+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:form_builder_validators/new_api_prototype/constants.dart';
3+
import 'package:form_builder_validators/new_api_prototype/core_validators/transform_validator.dart';
4+
5+
void main() {
6+
const String defaultMsg = 'default error msg';
7+
String? isEvenGreaterThan56(int input) {
8+
return input > 56 && (input % 2 == 0) ? null : defaultMsg;
9+
}
10+
11+
group('Validator: transformAndValidate', () {
12+
test('Should check if the String input is integer, transforming it', () {
13+
final Validator<String> v = transformAndValidate(int.parse);
14+
15+
expect(v('12'), isNull);
16+
expect(v('not integer'),
17+
errorTransformAndValidateTemporary('not integer', null));
18+
});
19+
test('Should transform and apply a next validator', () {
20+
final Validator<String> v =
21+
transformAndValidate(int.parse, next: isEvenGreaterThan56);
22+
23+
expect(v('12'), defaultMsg);
24+
expect(v('56'), defaultMsg);
25+
expect(v('59'), defaultMsg);
26+
expect(v('60'), isNull);
27+
expect(v('not integer'),
28+
errorTransformAndValidateTemporary('not integer', null));
29+
});
30+
test('Should return a custom transformation error message', () {
31+
const String customErrorMsg = 'custom error msg';
32+
final Validator<String> v = transformAndValidate(
33+
int.parse,
34+
next: isEvenGreaterThan56,
35+
transformAndValidateMsg: (_) => customErrorMsg,
36+
);
37+
38+
expect(v('12'), defaultMsg);
39+
expect(v('56'), defaultMsg);
40+
expect(v('59'), defaultMsg);
41+
expect(v('60'), isNull);
42+
expect(v('not integer'), customErrorMsg);
43+
});
44+
test(
45+
'Should return an error message with transformed result type description',
46+
() {
47+
const String t = 'integer';
48+
final Validator<String> v = transformAndValidate(
49+
int.parse,
50+
next: isEvenGreaterThan56,
51+
transformedResultTypeDescription: t,
52+
);
53+
54+
expect(v('12'), defaultMsg);
55+
expect(v('56'), defaultMsg);
56+
expect(v('59'), defaultMsg);
57+
expect(v('60'), isNull);
58+
expect(v('not integer'),
59+
errorTransformAndValidateTemporary('not integer', t));
60+
});
61+
});
62+
}

0 commit comments

Comments
 (0)