Skip to content

Commit 08bb9b8

Browse files
implement isDateTimeBetween validator
1 parent 7557dd0 commit 08bb9b8

File tree

2 files changed

+207
-0
lines changed

2 files changed

+207
-0
lines changed

lib/new_api_prototype/datetime_validators.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,33 @@ Validator<DateTime> isBefore(
4040
: isBeforeMsg?.call(reference) ?? tmpIsBeforeErrorMsg(reference);
4141
};
4242
}
43+
44+
String tmpIsDateTimeBetweenErrorMsg(DateTime left, DateTime right) {
45+
return 'The date must be after ${left.toLocal()} and before ${right.toLocal()}';
46+
}
47+
48+
/// This function returns a validator that checks if the user [DateTime] input is
49+
/// between `leftReference` and `rightReference` [DateTime]s. If the checking results
50+
/// true, the validator returns `null`. Otherwise, it returns `isDateTimeBetweenMsg`, if
51+
/// provided, or `FormBuilderLocalizations.current.isDateTimeBetweenErrorText`.
52+
Validator<DateTime> isDateTimeBetween(
53+
DateTime leftReference,
54+
DateTime rightReference, {
55+
String Function(DateTime, DateTime)? isDateTimeBetweenMsg,
56+
bool leftInclusive = false,
57+
bool rightInclusive = false,
58+
}) {
59+
assert(leftReference.isBefore(rightReference),
60+
'leftReference must be before rightReference');
61+
return (DateTime value) {
62+
return (value.isBefore(rightReference) ||
63+
(rightInclusive
64+
? value.isAtSameMomentAs(rightReference)
65+
: false)) &&
66+
(value.isAfter(leftReference) ||
67+
(leftInclusive ? value.isAtSameMomentAs(leftReference) : false))
68+
? null
69+
: isDateTimeBetweenMsg?.call(leftReference, rightReference) ??
70+
tmpIsDateTimeBetweenErrorMsg(leftReference, rightReference);
71+
};
72+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
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/datetime_validators.dart';
4+
5+
void main() {
6+
group('Validator: isDateTimeBetween', () {
7+
test('Validation for the range 1994 and 1997', () {
8+
final DateTime leftReference = DateTime(1994);
9+
final DateTime rightReference = DateTime(1997);
10+
final DateTime leftEq = leftReference.copyWith();
11+
final DateTime rightEq = rightReference.copyWith();
12+
final DateTime afterRight = DateTime(1998);
13+
final DateTime afterRight1Second =
14+
rightReference.add(const Duration(seconds: 1));
15+
final DateTime beforeRight1Second =
16+
rightReference.subtract(const Duration(seconds: 1));
17+
final DateTime between = DateTime(1995);
18+
final DateTime beforeLeft = DateTime(199);
19+
final DateTime afterLeft1Micro =
20+
leftReference.add(const Duration(microseconds: 1));
21+
final DateTime beforeLeft1Micro =
22+
leftReference.subtract(const Duration(microseconds: 1));
23+
final Validator<DateTime> v =
24+
isDateTimeBetween(leftReference, rightReference);
25+
final String errorMsg =
26+
tmpIsDateTimeBetweenErrorMsg(leftReference, rightReference);
27+
28+
expect(
29+
v(leftEq),
30+
errorMsg,
31+
reason: 'Should return error against 1994',
32+
);
33+
expect(
34+
v(rightEq),
35+
errorMsg,
36+
reason: 'Should return error against 1997',
37+
);
38+
expect(
39+
v(afterRight),
40+
errorMsg,
41+
reason: 'Should return error against 1998',
42+
);
43+
expect(
44+
v(beforeLeft),
45+
errorMsg,
46+
reason: 'Should return error against 199',
47+
);
48+
expect(
49+
v(afterRight1Second),
50+
errorMsg,
51+
reason: 'Should return error against 1997 + 1 s',
52+
);
53+
expect(
54+
v(beforeRight1Second),
55+
isNull,
56+
reason: 'Should return null against 1997 - 1 s',
57+
);
58+
expect(
59+
v(between),
60+
isNull,
61+
reason: 'Should return null against 1995',
62+
);
63+
expect(
64+
v(afterLeft1Micro),
65+
isNull,
66+
reason: 'Should return null against 1994 + 1 us',
67+
);
68+
expect(
69+
v(beforeLeft1Micro),
70+
errorMsg,
71+
reason: 'Should return error against 1994 - 1 us',
72+
);
73+
});
74+
test(
75+
'Left inclusive validation for left reference 2089, month 3, day 23, h 3, min 46, s 12, 233 ms and right reference 2089, month 3, day 23, h 7',
76+
() {
77+
final DateTime leftReference = DateTime(2089, 3, 23, 3, 46, 12, 233);
78+
final DateTime rightReference = DateTime(2089, 3, 23, 7);
79+
final DateTime between =
80+
leftReference.add(Duration(hours: 2, seconds: 10));
81+
final DateTime leftEq = leftReference.copyWith();
82+
final DateTime rightEq = rightReference.copyWith();
83+
final DateTime afterRight = rightReference.copyWith(year: 2099);
84+
final DateTime after1Ms =
85+
rightReference.add(const Duration(milliseconds: 1));
86+
final DateTime before1Year = leftReference.copyWith(year: 2088);
87+
final DateTime before1Sec =
88+
leftReference.subtract(const Duration(seconds: 1));
89+
final Validator<DateTime> v =
90+
isDateTimeBetween(leftReference, rightReference, leftInclusive: true);
91+
final String errorMsg =
92+
tmpIsDateTimeBetweenErrorMsg(leftReference, rightReference);
93+
94+
expect(
95+
v(leftEq),
96+
isNull,
97+
reason: 'Should return null against the same left datetime',
98+
);
99+
expect(
100+
v(between),
101+
isNull,
102+
reason: 'Should return null against a datetime between the references',
103+
);
104+
expect(
105+
v(rightEq),
106+
errorMsg,
107+
reason: 'Should return errorMsg against the same right datetime',
108+
);
109+
expect(
110+
v(afterRight),
111+
errorMsg,
112+
reason:
113+
'Should return error against the right reference shifted +10 years',
114+
);
115+
expect(
116+
v(after1Ms),
117+
errorMsg,
118+
reason:
119+
'Should return error against the right reference shifted +1 millisecond',
120+
);
121+
expect(
122+
v(after1Ms),
123+
errorMsg,
124+
reason: 'Should return error against the reference shifted +1 ms',
125+
);
126+
expect(
127+
v(before1Year),
128+
errorMsg,
129+
reason:
130+
'Should return error against a datetime 1 year before the left reference',
131+
);
132+
expect(
133+
v(before1Sec),
134+
errorMsg,
135+
reason:
136+
'Should return error against a datetime 1 sec before the left reference',
137+
);
138+
});
139+
140+
test('Should return a custom message after validating', () {
141+
const String errorMsg = 'error msg';
142+
final DateTime leftReference = DateTime(2);
143+
final DateTime rightReference = DateTime(5);
144+
final Validator<DateTime> v = isDateTimeBetween(
145+
leftReference, rightReference,
146+
isDateTimeBetweenMsg: (_, __) => errorMsg);
147+
148+
expect(
149+
v(rightReference.copyWith()),
150+
errorMsg,
151+
reason:
152+
'Should return custom message when input is equal to the reference',
153+
);
154+
expect(
155+
v(rightReference.subtract(const Duration(microseconds: 1))),
156+
isNull,
157+
reason:
158+
'Should return null when input is before the right reference for 1 s',
159+
);
160+
expect(
161+
v(rightReference.add(const Duration(days: 1))),
162+
errorMsg,
163+
reason:
164+
'Should return custom message when the input is after the right reference',
165+
);
166+
});
167+
168+
test(
169+
'Should throw AssertionError when the right reference is not after left reference',
170+
() {
171+
expect(
172+
() => isDateTimeBetween(
173+
DateTime(1990, 12, 23, 20), DateTime(1990, 12, 22, 20)),
174+
throwsAssertionError);
175+
});
176+
});
177+
}

0 commit comments

Comments
 (0)