@@ -197,6 +197,183 @@ void main() {
197197 );
198198 });
199199 });
200+
201+ testWidgets ('allowClear properly clears value' , (WidgetTester tester) async {
202+ const widgetName = 'fdtp_clear' ;
203+ final widgetKey = UniqueKey ();
204+ final initialDate = DateTime (2023 , 1 , 1 );
205+
206+ final testWidget = FormBuilderDateTimePicker (
207+ key: widgetKey,
208+ name: widgetName,
209+ initialValue: initialDate,
210+ allowClear: true ,
211+ );
212+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
213+
214+ expect (formInstantValue (widgetName), initialDate);
215+ expect (find.byIcon (Icons .clear), findsOneWidget);
216+
217+ await tester.tap (find.byIcon (Icons .clear));
218+ await tester.pumpAndSettle ();
219+
220+ expect (formInstantValue (widgetName), isNull);
221+ expect (find.byIcon (Icons .clear), findsNothing);
222+ });
223+
224+ testWidgets ('custom clearIcon is rendered' , (WidgetTester tester) async {
225+ const widgetName = 'fdtp_custom_clear' ;
226+ final initialDate = DateTime (2023 , 1 , 1 );
227+ const customIcon = Icons .delete;
228+
229+ final testWidget = FormBuilderDateTimePicker (
230+ name: widgetName,
231+ initialValue: initialDate,
232+ allowClear: true ,
233+ clearIcon: const Icon (customIcon),
234+ );
235+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
236+
237+ expect (find.byIcon (customIcon), findsOneWidget);
238+ expect (find.byIcon (Icons .clear), findsNothing);
239+ });
240+
241+ testWidgets ('InputType.date returns midnight time' , (WidgetTester tester) async {
242+ const widgetName = 'fdtp_date_only' ;
243+ final widgetKey = UniqueKey ();
244+ final dateNow = DateTime .now ();
245+ const confirmText = 'OK' ;
246+
247+ final testWidget = FormBuilderDateTimePicker (
248+ key: widgetKey,
249+ name: widgetName,
250+ inputType: InputType .date,
251+ confirmText: confirmText,
252+ );
253+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
254+
255+ await tester.tap (find.byKey (widgetKey));
256+ await tester.pumpAndSettle ();
257+
258+ final testDay = dateNow.day - 1 <= 0 ? dateNow.day + 1 : dateNow.day - 1 ;
259+ await tester.tap (find.text (testDay.toString ()));
260+ await tester.pumpAndSettle ();
261+ await tester.tap (find.text (confirmText));
262+ await tester.pumpAndSettle ();
263+
264+ expect (formSave (), isTrue);
265+ expect (
266+ formValue <DateTime >(widgetName),
267+ DateTime (dateNow.year, dateNow.month, testDay),
268+ );
269+ });
270+
271+ testWidgets ('InputType.time returns DateTime(1, 1, 1) with time' ,
272+ (WidgetTester tester) async {
273+ const widgetName = 'fdtp_time_only' ;
274+ final widgetKey = UniqueKey ();
275+ const confirmText = 'OK' ;
276+
277+ final testWidget = FormBuilderDateTimePicker (
278+ key: widgetKey,
279+ name: widgetName,
280+ inputType: InputType .time,
281+ confirmText: confirmText,
282+ );
283+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
284+
285+ await tester.tap (find.byKey (widgetKey));
286+ await tester.pumpAndSettle ();
287+
288+ await tester.tap (find.text (confirmText));
289+ await tester.pumpAndSettle ();
290+
291+ expect (formSave (), isTrue);
292+ final value = formValue <DateTime >(widgetName);
293+ expect (value! .year, 1 );
294+ expect (value.month, 1 );
295+ expect (value.day, 1 );
296+ expect (value.hour, 12 ); // Default initialTime is 12:00
297+ expect (value.minute, 0 );
298+ });
299+
300+ testWidgets ('onChanged is called when value changes' , (WidgetTester tester) async {
301+ const widgetName = 'fdtp_onChanged' ;
302+ int changedCount = 0 ;
303+ DateTime ? valueFromOnChanged;
304+
305+ final testWidget = FormBuilderDateTimePicker (
306+ name: widgetName,
307+ allowClear: true ,
308+ initialValue: DateTime (2023 , 1 , 1 ),
309+ onChanged: (val) {
310+ changedCount++ ;
311+ valueFromOnChanged = val;
312+ },
313+ );
314+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
315+
316+ await tester.tap (find.byIcon (Icons .clear));
317+ await tester.pumpAndSettle ();
318+
319+ expect (changedCount, 1 );
320+ expect (valueFromOnChanged, isNull);
321+ });
322+
323+ testWidgets ('reset() reverts value to initialValue' , (WidgetTester tester) async {
324+ const widgetName = 'fdtp_reset' ;
325+ final initialDate = DateTime (2023 , 1 , 1 );
326+
327+ final testWidget = FormBuilderDateTimePicker (
328+ name: widgetName,
329+ initialValue: initialDate,
330+ allowClear: true ,
331+ );
332+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
333+
334+ await tester.tap (find.byIcon (Icons .clear));
335+ await tester.pumpAndSettle ();
336+ expect (formInstantValue (widgetName), isNull);
337+
338+ formKey.currentState! .fields[widgetName]! .reset ();
339+ await tester.pumpAndSettle ();
340+
341+ expect (formInstantValue (widgetName), initialDate);
342+ });
343+
344+ testWidgets ('initialTime is respected for InputType.both' , (WidgetTester tester) async {
345+ const widgetName = 'fdtp_initialTime' ;
346+ final widgetKey = UniqueKey ();
347+ const confirmText = 'OK' ;
348+ final initialTime = const TimeOfDay (hour: 15 , minute: 30 );
349+
350+ final testWidget = FormBuilderDateTimePicker (
351+ key: widgetKey,
352+ name: widgetName,
353+ inputType: InputType .both,
354+ confirmText: confirmText,
355+ initialTime: initialTime,
356+ );
357+ await tester.pumpWidget (buildTestableFieldWidget (testWidget));
358+
359+ await tester.tap (find.byKey (widgetKey));
360+ await tester.pumpAndSettle ();
361+
362+ // Date picker OK
363+ await tester.tap (find.text (DateTime .now ().day.toString ()));
364+ await tester.pumpAndSettle ();
365+ await tester.tap (find.text (confirmText));
366+ await tester.pumpAndSettle ();
367+
368+ // Time picker should show 15:30.
369+ await tester.tap (find.text (confirmText));
370+ await tester.pumpAndSettle ();
371+
372+ expect (formSave (), isTrue);
373+ final value = formValue <DateTime >(widgetName);
374+ expect (value! .hour, 15 );
375+ expect (value.minute, 30 );
376+ });
200377 });
201378
202379 testWidgets ('When press tab, field will be focused' , (
0 commit comments