Skip to content

Commit 0fc0548

Browse files
committed
refactor: add more tests and keep number of programmatically set values
1 parent d399f15 commit 0fc0548

File tree

4 files changed

+158
-17
lines changed

4 files changed

+158
-17
lines changed

vaadin-date-time-picker-flow-parent/vaadin-date-time-picker-flow-integration-tests/src/main/java/com/vaadin/flow/component/datetimepicker/validation/BasicValidationPage.java

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public class BasicValidationPage
2828
public static final String MIN_INPUT = "min-input";
2929
public static final String MAX_INPUT = "max-input";
3030
public static final String CLEAR_VALUE_BUTTON = "clear-value-button";
31+
public static final String SET_VALUE_PROGRAMMATICALLY = "set-value-programmatically";
32+
public static final String CLEAR_AND_SET_VALUE_PROGRAMMATICALLY = "clear-and-set-value-programmatically";
3133

3234
public static final String REQUIRED_ERROR_MESSAGE = "Field is required";
3335
public static final String BAD_INPUT_ERROR_MESSAGE = "Invalid date format";
@@ -62,6 +64,16 @@ public BasicValidationPage() {
6264
add(createButton(CLEAR_VALUE_BUTTON, "Clear value", event -> {
6365
testField.clear();
6466
}));
67+
68+
add(createButton(SET_VALUE_PROGRAMMATICALLY,
69+
"Set value programmatically",
70+
event -> testField.setValue(LocalDateTime.now())));
71+
72+
add(createButton(CLEAR_AND_SET_VALUE_PROGRAMMATICALLY,
73+
"Clear and set value programmatically", event -> {
74+
testField.clear();
75+
testField.setValue(LocalDateTime.now());
76+
}));
6577
}
6678

6779
protected DateTimePicker createTestField() {

vaadin-date-time-picker-flow-parent/vaadin-date-time-picker-flow-integration-tests/src/test/java/com/vaadin/flow/component/datetimepicker/validation/BasicValidationIT.java

+130-10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.vaadin.flow.component.datetimepicker.validation;
1717

1818
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.BAD_INPUT_ERROR_MESSAGE;
19+
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.CLEAR_AND_SET_VALUE_PROGRAMMATICALLY;
1920
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.CLEAR_VALUE_BUTTON;
2021
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.INCOMPLETE_INPUT_ERROR_MESSAGE;
2122
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.MAX_ERROR_MESSAGE;
@@ -24,6 +25,7 @@
2425
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.MIN_INPUT;
2526
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.REQUIRED_BUTTON;
2627
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.REQUIRED_ERROR_MESSAGE;
28+
import static com.vaadin.flow.component.datetimepicker.validation.BasicValidationPage.SET_VALUE_PROGRAMMATICALLY;
2729

2830
import org.junit.Before;
2931
import org.junit.Test;
@@ -74,6 +76,17 @@ public void required_triggerBlur_assertValidity() {
7476
assertErrorMessage(null);
7577
}
7678

79+
@Test
80+
public void required_changeInputTemporarily_triggerBlur_assertValidity() {
81+
$("button").id(REQUIRED_BUTTON).click();
82+
dateInput.sendKeys("1", Keys.BACK_SPACE, Keys.ENTER);
83+
dateInput.sendKeys(Keys.TAB);
84+
timeInput.sendKeys(Keys.TAB);
85+
assertServerValid();
86+
assertClientValid();
87+
assertErrorMessage(null);
88+
}
89+
7790
@Test
7891
public void required_changeValue_assertValidity() {
7992
$("button").id(REQUIRED_BUTTON).click();
@@ -100,7 +113,7 @@ public void required_changeValue_assertValidity() {
100113
assertClientInvalid();
101114
assertErrorMessage(REQUIRED_ERROR_MESSAGE);
102115

103-
setFieldIInvalid();
116+
setFieldInvalid();
104117
assertServerInvalid();
105118
assertClientInvalid();
106119
assertErrorMessage(BAD_INPUT_ERROR_MESSAGE);
@@ -153,7 +166,6 @@ public void max_changeDateInputValue_assertValidity() {
153166
$("input").id(MAX_INPUT).sendKeys("2000-02-02T12:00", Keys.ENTER);
154167

155168
setInputValue(dateInput, "3/3/2000");
156-
setInputValue(timeInput, "13:00");
157169
assertClientInvalid();
158170
assertServerInvalid();
159171
assertErrorMessage(MAX_ERROR_MESSAGE);
@@ -199,7 +211,7 @@ public void setValue_clearValue_assertValidity() {
199211

200212
@Test
201213
public void badInput_changeValue_assertValidity() {
202-
setFieldIInvalid();
214+
setFieldInvalid();
203215
setInputValue(timeInput, "INVALID");
204216
assertServerInvalid();
205217
assertClientInvalid();
@@ -211,7 +223,7 @@ public void badInput_changeValue_assertValidity() {
211223
assertClientValid();
212224
assertErrorMessage("");
213225

214-
setFieldIInvalid();
226+
setFieldInvalid();
215227
setInputValue(timeInput, "INVALID");
216228
assertServerInvalid();
217229
assertClientInvalid();
@@ -220,7 +232,7 @@ public void badInput_changeValue_assertValidity() {
220232

221233
@Test
222234
public void badInput_setDateInputValue_blur_assertValidity() {
223-
setFieldIInvalid();
235+
setFieldInvalid();
224236
dateInput.sendKeys(Keys.TAB);
225237
timeInput.sendKeys(Keys.TAB);
226238
assertServerInvalid();
@@ -239,7 +251,7 @@ public void badInput_setTimeInputValue_blur_assertValidity() {
239251

240252
@Test
241253
public void badInput_setValue_clearValue_assertValidity() {
242-
setFieldIInvalid();
254+
setFieldInvalid();
243255
setInputValue(timeInput, "INVALID");
244256
assertServerInvalid();
245257
assertClientInvalid();
@@ -253,7 +265,7 @@ public void badInput_setValue_clearValue_assertValidity() {
253265

254266
@Test
255267
public void badInput_setDateInputValue_blur_clearValue_assertValidity() {
256-
setFieldIInvalid();
268+
setFieldInvalid();
257269
dateInput.sendKeys(Keys.TAB);
258270
timeInput.sendKeys(Keys.TAB);
259271
assertServerInvalid();
@@ -378,7 +390,7 @@ public void incompleteInput_setTimeInputValue_blur_clearValue_assertValidity() {
378390

379391
@Test
380392
public void detach_attach_preservesInvalidState() {
381-
setFieldIInvalid();
393+
setFieldInvalid();
382394

383395
detachAndReattachField();
384396

@@ -408,14 +420,116 @@ public void detach_hide_attach_showAndInvalidate_preservesInvalidState() {
408420

409421
@Test
410422
public void clientSideInvalidStateIsNotPropagatedToServer() {
411-
setFieldIInvalid();
423+
setFieldInvalid();
412424

413425
executeScript("arguments[0].invalid = false", testField);
414426

415427
assertServerInvalid();
416428
}
417429

418-
private void setFieldIInvalid() {
430+
@Test
431+
public void triggerBlurWithNoChange_fieldNotValidated() {
432+
dateInput.sendKeys(Keys.TAB);
433+
timeInput.sendKeys(Keys.TAB);
434+
assertValidationCount(0);
435+
}
436+
437+
@Test
438+
public void initiallyEmpty_setValidValue_fieldValidatedOnce() {
439+
dateInput.sendKeys("1/1/2000");
440+
dateInput.sendKeys(Keys.ENTER);
441+
dateInput.sendKeys(Keys.TAB);
442+
timeInput.sendKeys("10:00");
443+
timeInput.sendKeys(Keys.ENTER);
444+
assertValidationCount(1);
445+
}
446+
447+
@Test
448+
public void initiallyEmpty_setInvalidValue_fieldNotValidatedOnce() {
449+
dateInput.sendKeys("Invalid");
450+
dateInput.sendKeys(Keys.ENTER);
451+
assertValidationCount(1);
452+
}
453+
454+
@Test
455+
public void initiallyValidValue_clearValue_fieldValidatedOnce() {
456+
dateInput.sendKeys("1/1/2000");
457+
dateInput.sendKeys(Keys.ENTER);
458+
dateInput.sendKeys(Keys.TAB);
459+
timeInput.sendKeys("10:00");
460+
timeInput.sendKeys(Keys.ENTER);
461+
assertValidationCount(1);
462+
clearInputValue();
463+
assertValidationCount(1);
464+
}
465+
466+
@Test
467+
public void initiallyValidValue_changeValue_fieldValidatedOnce() {
468+
dateInput.sendKeys("1/1/2000");
469+
dateInput.sendKeys(Keys.ENTER);
470+
dateInput.sendKeys(Keys.TAB);
471+
timeInput.sendKeys("10:00");
472+
timeInput.sendKeys(Keys.ENTER);
473+
assertValidationCount(1);
474+
dateInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
475+
dateInput.sendKeys("1/1/2001");
476+
dateInput.sendKeys(Keys.ENTER);
477+
assertValidationCount(1);
478+
}
479+
480+
@Test
481+
public void initiallyInvalidValue_changeInvalidValue_fieldValidatedOnce() {
482+
dateInput.sendKeys("Invalid");
483+
dateInput.sendKeys(Keys.ENTER);
484+
assertValidationCount(1);
485+
dateInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
486+
dateInput.sendKeys("Not a date");
487+
dateInput.sendKeys(Keys.ENTER);
488+
assertValidationCount(1);
489+
}
490+
491+
@Test
492+
public void initiallyInvalidValue_setValidValue_fieldValidatedOnce() {
493+
dateInput.sendKeys("Invalid");
494+
dateInput.sendKeys(Keys.ENTER);
495+
assertValidationCount(1);
496+
dateInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
497+
dateInput.sendKeys("1/1/2000");
498+
timeInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
499+
timeInput.sendKeys("10:00");
500+
timeInput.sendKeys(Keys.ENTER);
501+
assertValidationCount(1);
502+
}
503+
504+
@Test
505+
public void initiallyInvalidValue_clearValue_fieldValidatedOnce() {
506+
dateInput.sendKeys("Invalid");
507+
dateInput.sendKeys(Keys.ENTER);
508+
assertValidationCount(1);
509+
clearInputValue();
510+
assertValidationCount(1);
511+
}
512+
513+
@Test
514+
public void max_setDateOutOfRange_fieldValidatedOnce() {
515+
$("input").id(MAX_INPUT).sendKeys("2000-02-02T12:00", Keys.ENTER);
516+
setInputValue(dateInput, "3/3/2000");
517+
assertValidationCount(1);
518+
}
519+
520+
@Test
521+
public void setValueProgrammatically_fieldValidatedOnce() {
522+
clickElementWithJs(SET_VALUE_PROGRAMMATICALLY);
523+
assertValidationCount(1);
524+
}
525+
526+
@Test
527+
public void clearAndSetValueProgrammatically_fieldValidatedOnce() {
528+
clickElementWithJs(CLEAR_AND_SET_VALUE_PROGRAMMATICALLY);
529+
assertValidationCount(1);
530+
}
531+
532+
private void setFieldInvalid() {
419533
setInputValue(dateInput, "INVALID");
420534
setInputValue(timeInput, "INVALID");
421535
}
@@ -428,4 +542,10 @@ private void setInputValue(TestBenchElement input, String value) {
428542
input.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
429543
input.sendKeys(value, Keys.ENTER);
430544
}
545+
546+
private void clearInputValue() {
547+
dateInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
548+
timeInput.sendKeys(Keys.chord(Keys.SHIFT, Keys.HOME), Keys.BACK_SPACE);
549+
timeInput.sendKeys(Keys.ENTER);
550+
}
431551
}

vaadin-date-time-picker-flow-parent/vaadin-date-time-picker-flow/src/main/java/com/vaadin/flow/component/datetimepicker/DateTimePicker.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public class DateTimePicker
165165

166166
private final CopyOnWriteArrayList<ValidationStatusChangeListener<LocalDateTime>> validationStatusChangeListeners = new CopyOnWriteArrayList<>();
167167

168-
private boolean programmaticallySettingValue;
168+
private int pendingInputElementValueSyncs = 0;
169169

170170
private final Validator<LocalDateTime> defaultValidator = (value,
171171
context) -> {
@@ -406,20 +406,24 @@ private void addValidationListeners() {
406406
getElement().addEventListener("change", e -> {
407407
// No need to validate since it will be validated once the
408408
// programmatically set value is updated on the client
409-
if (!programmaticallySettingValue) {
409+
if (pendingInputElementValueSyncs == 0) {
410410
validate(true);
411411
}
412412
});
413413
getElement().addEventListener("unparsable-change", e -> {
414414
// No need to validate since it will be validated once the
415415
// programmatically set value is updated on the client
416-
if (!programmaticallySettingValue) {
416+
if (pendingInputElementValueSyncs == 0) {
417417
validate(true);
418418
}
419419
});
420+
420421
getElement().addEventListener("value-programmatically-set", e -> {
421-
validate(true);
422-
programmaticallySettingValue = false;
422+
// Validate only for the final input element value sync caused by
423+
// programmatically setting values
424+
if (--pendingInputElementValueSyncs == 0) {
425+
validate(true);
426+
}
423427
});
424428
}
425429

@@ -443,7 +447,7 @@ public void setValue(LocalDateTime value) {
443447
synchronizeChildComponentValues(value);
444448
super.setValue(value);
445449
// Notify the server in order to use the formatted values in validation
446-
programmaticallySettingValue = true;
450+
pendingInputElementValueSyncs++;
447451
getElement().executeJs(
448452
"this.dispatchEvent(new CustomEvent('value-programmatically-set'));");
449453
}

vaadin-date-time-picker-flow-parent/vaadin-date-time-picker-flow/src/test/java/com/vaadin/flow/component/datetimepicker/validation/BasicValidationTest.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public void setIncompleteInputErrorMessage_errorMessageIsSet() {
120120
public void required_validate_emptyErrorMessageDisplayed() {
121121
testField.setRequiredIndicatorVisible(true);
122122
testField.setValue(LocalDateTime.now());
123+
fireValueProgrammaticallySetDomEvent();
123124
testField.setValue(null);
124125
fireValueProgrammaticallySetDomEvent();
125126
Assert.assertEquals("", testField.getErrorMessage());
@@ -131,6 +132,7 @@ public void required_setI18nErrorMessage_validate_i18nErrorMessageDisplayed() {
131132
testField.setI18n(new DateTimePicker.DateTimePickerI18n()
132133
.setRequiredErrorMessage("Field is required"));
133134
testField.setValue(LocalDateTime.now());
135+
fireValueProgrammaticallySetDomEvent();
134136
testField.setValue(null);
135137
fireValueProgrammaticallySetDomEvent();
136138
Assert.assertEquals("Field is required", testField.getErrorMessage());
@@ -179,6 +181,7 @@ public void setI18nAndCustomErrorMessage_validate_customErrorMessageDisplayed()
179181
.setRequiredErrorMessage("Field is required"));
180182
testField.setErrorMessage("Custom error message");
181183
testField.setValue(LocalDateTime.now());
184+
fireValueProgrammaticallySetDomEvent();
182185
testField.setValue(null);
183186
fireValueProgrammaticallySetDomEvent();
184187
Assert.assertEquals("Custom error message",
@@ -192,9 +195,12 @@ public void setI18nAndCustomErrorMessage_validate_removeCustomErrorMessage_valid
192195
.setRequiredErrorMessage("Field is required"));
193196
testField.setErrorMessage("Custom error message");
194197
testField.setValue(LocalDateTime.now());
198+
fireValueProgrammaticallySetDomEvent();
195199
testField.setValue(null);
200+
fireValueProgrammaticallySetDomEvent();
196201
testField.setErrorMessage("");
197202
testField.setValue(LocalDateTime.now());
203+
fireValueProgrammaticallySetDomEvent();
198204
testField.setValue(null);
199205
fireValueProgrammaticallySetDomEvent();
200206
Assert.assertEquals("Field is required", testField.getErrorMessage());
@@ -234,5 +240,4 @@ private void fireDomEvent(String eventType) {
234240
testField.getElement().getNode().getFeature(ElementListenerMap.class)
235241
.fireEvent(domEvent);
236242
}
237-
238243
}

0 commit comments

Comments
 (0)