Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

BinderConverterValidatorTest.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.data;
  17. import static org.junit.Assert.assertEquals;
  18. import static org.junit.Assert.assertFalse;
  19. import static org.junit.Assert.assertNotNull;
  20. import static org.junit.Assert.assertNull;
  21. import static org.junit.Assert.assertTrue;
  22. import java.util.List;
  23. import java.util.concurrent.atomic.AtomicBoolean;
  24. import org.junit.Assert;
  25. import org.junit.Before;
  26. import org.junit.Test;
  27. import com.vaadin.data.Binder.Binding;
  28. import com.vaadin.data.util.converter.StringToIntegerConverter;
  29. import com.vaadin.data.validator.NotEmptyValidator;
  30. import com.vaadin.server.AbstractErrorMessage;
  31. import com.vaadin.server.ErrorMessage;
  32. import com.vaadin.server.SerializablePredicate;
  33. import com.vaadin.server.UserError;
  34. import com.vaadin.tests.data.bean.Person;
  35. import com.vaadin.ui.Label;
  36. import com.vaadin.ui.TextField;
  37. public class BinderConverterValidatorTest
  38. extends BinderTestBase<Binder<Person>, Person> {
  39. private static class StatusBean {
  40. private String status;
  41. public String getStatus() {
  42. return status;
  43. }
  44. public void setStatus(String status) {
  45. this.status = status;
  46. }
  47. }
  48. @Before
  49. public void setUp() {
  50. binder = new Binder<>();
  51. item = new Person();
  52. item.setFirstName("Johannes");
  53. item.setAge(32);
  54. }
  55. @Test
  56. public void validate_notBound_noErrors() {
  57. BinderValidationStatus<Person> status = binder.validate();
  58. assertTrue(status.isOk());
  59. }
  60. @Test
  61. public void bound_validatorsAreOK_noErrors() {
  62. Binding<Person, String, String> binding = binder.forField(nameField);
  63. binding.withValidator(Validator.alwaysPass()).bind(Person::getFirstName,
  64. Person::setFirstName);
  65. nameField.setComponentError(new UserError(""));
  66. BinderValidationStatus<Person> status = binder.validate();
  67. assertTrue(status.isOk());
  68. assertNull(nameField.getComponentError());
  69. }
  70. @SuppressWarnings("serial")
  71. @Test
  72. public void bound_validatorsFail_errors() {
  73. Binding<Person, String, String> binding = binder.forField(nameField);
  74. binding.withValidator(Validator.alwaysPass());
  75. String msg1 = "foo";
  76. String msg2 = "bar";
  77. binding.withValidator(new Validator<String>() {
  78. @Override
  79. public Result<String> apply(String value) {
  80. return new SimpleResult<>(null, msg1);
  81. }
  82. });
  83. binding.withValidator(value -> false, msg2);
  84. binding.bind(Person::getFirstName, Person::setFirstName);
  85. BinderValidationStatus<Person> status = binder.validate();
  86. List<ValidationStatus<?>> errors = status.getFieldValidationErrors();
  87. assertEquals(1, errors.size());
  88. ValidationStatus<?> validationStatus = errors.stream().findFirst()
  89. .get();
  90. String msg = validationStatus.getMessage().get();
  91. assertEquals(msg1, msg);
  92. HasValue<?> field = validationStatus.getField();
  93. assertEquals(nameField, field);
  94. ErrorMessage componentError = nameField.getComponentError();
  95. assertNotNull(componentError);
  96. assertEquals("foo",
  97. ((AbstractErrorMessage) componentError).getMessage());
  98. }
  99. @Test
  100. public void validatorForSuperTypeCanBeUsed() {
  101. // Validates that a validator for a super type can be used, e.g.
  102. // validator for Number can be used on a Double
  103. TextField salaryField = new TextField();
  104. Validator<Number> positiveNumberValidator = value -> {
  105. if (value.doubleValue() >= 0) {
  106. return Result.ok(value);
  107. } else {
  108. return Result.error(NEGATIVE_ERROR_MESSAGE);
  109. }
  110. };
  111. binder.forField(salaryField)
  112. .withConverter(Double::valueOf, String::valueOf)
  113. .withValidator(positiveNumberValidator)
  114. .bind(Person::getSalaryDouble, Person::setSalaryDouble);
  115. Person person = new Person();
  116. binder.bind(person);
  117. salaryField.setValue("10");
  118. assertEquals(10, person.getSalaryDouble(), 0);
  119. salaryField.setValue("-1"); // Does not pass validator
  120. assertEquals(10, person.getSalaryDouble(), 0);
  121. }
  122. @Test
  123. public void convertInitialValue() {
  124. bindAgeWithValidatorConverterValidator();
  125. assertEquals("32", ageField.getValue());
  126. }
  127. @Test
  128. public void convertToModelValidAge() {
  129. bindAgeWithValidatorConverterValidator();
  130. ageField.setValue("33");
  131. assertEquals(33, item.getAge());
  132. }
  133. @Test
  134. public void convertToModelNegativeAgeFailsOnFirstValidator() {
  135. bindAgeWithValidatorConverterValidator();
  136. ageField.setValue("");
  137. assertEquals(32, item.getAge());
  138. assertValidationErrors(binder.validate(), EMPTY_ERROR_MESSAGE);
  139. }
  140. private void assertValidationErrors(
  141. List<ValidationStatus<?>> validationErrors,
  142. String... errorMessages) {
  143. assertEquals(errorMessages.length, validationErrors.size());
  144. for (int i = 0; i < errorMessages.length; i++) {
  145. assertEquals(errorMessages[i],
  146. validationErrors.get(i).getMessage().get());
  147. }
  148. }
  149. private void assertValidationErrors(BinderValidationStatus<Person> status,
  150. String... errorMessages) {
  151. assertValidationErrors(status.getFieldValidationErrors(),
  152. errorMessages);
  153. }
  154. @Test
  155. public void convertToModelConversionFails() {
  156. bindAgeWithValidatorConverterValidator();
  157. ageField.setValue("abc");
  158. assertEquals(32, item.getAge());
  159. assertValidationErrors(binder.validate(), NOT_NUMBER_ERROR_MESSAGE);
  160. }
  161. @Test
  162. public void convertToModelNegativeAgeFailsOnIntegerValidator() {
  163. bindAgeWithValidatorConverterValidator();
  164. ageField.setValue("-5");
  165. assertEquals(32, item.getAge());
  166. assertValidationErrors(binder.validate(), NEGATIVE_ERROR_MESSAGE);
  167. }
  168. @Test
  169. public void convertDataToField() {
  170. bindAgeWithValidatorConverterValidator();
  171. binder.getBean().get().setAge(12);
  172. binder.load(binder.getBean().get());
  173. assertEquals("12", ageField.getValue());
  174. }
  175. @Test
  176. public void convertNotValidatableDataToField() {
  177. bindAgeWithValidatorConverterValidator();
  178. binder.getBean().get().setAge(-12);
  179. binder.load(binder.getBean().get());
  180. assertEquals("-12", ageField.getValue());
  181. }
  182. @Test(expected = IllegalArgumentException.class)
  183. public void convertInvalidDataToField() {
  184. TextField field = new TextField();
  185. StatusBean bean = new StatusBean();
  186. bean.setStatus("1");
  187. Binder<StatusBean> binder = new Binder<>();
  188. Binding<StatusBean, String, String> binding = binder.forField(field)
  189. .withConverter(presentation -> {
  190. if (presentation.equals("OK")) {
  191. return "1";
  192. } else if (presentation.equals("NOTOK")) {
  193. return "2";
  194. }
  195. throw new IllegalArgumentException(
  196. "Value must be OK or NOTOK");
  197. }, model -> {
  198. if (model.equals("1")) {
  199. return "OK";
  200. } else if (model.equals("2")) {
  201. return "NOTOK";
  202. } else {
  203. throw new IllegalArgumentException(
  204. "Value in model must be 1 or 2");
  205. }
  206. });
  207. binding.bind(StatusBean::getStatus, StatusBean::setStatus);
  208. binder.bind(bean);
  209. bean.setStatus("3");
  210. binder.load(bean);
  211. }
  212. @Test
  213. public void validate_failedBeanValidatorWithoutFieldValidators() {
  214. binder.forField(nameField).bind(Person::getFirstName,
  215. Person::setFirstName);
  216. String msg = "foo";
  217. binder.withValidator(Validator.from(bean -> false, msg));
  218. Person person = new Person();
  219. binder.bind(person);
  220. List<ValidationStatus<?>> errors = binder.validate()
  221. .getFieldValidationErrors();
  222. assertEquals(0, errors.size());
  223. }
  224. @Test
  225. public void validate_failedBeanValidatorWithFieldValidator() {
  226. String msg = "foo";
  227. Binding<Person, String, String> binding = binder.forField(nameField)
  228. .withValidator(new NotEmptyValidator<>(msg));
  229. binding.bind(Person::getFirstName, Person::setFirstName);
  230. binder.withValidator(Validator.from(bean -> false, msg));
  231. Person person = new Person();
  232. binder.bind(person);
  233. List<ValidationStatus<?>> errors = binder.validate()
  234. .getFieldValidationErrors();
  235. assertEquals(1, errors.size());
  236. ValidationStatus<?> error = errors.get(0);
  237. assertEquals(msg, error.getMessage().get());
  238. assertEquals(nameField, error.getField());
  239. }
  240. @Test
  241. public void validate_failedBothBeanValidatorAndFieldValidator() {
  242. String msg1 = "foo";
  243. Binding<Person, String, String> binding = binder.forField(nameField)
  244. .withValidator(new NotEmptyValidator<>(msg1));
  245. binding.bind(Person::getFirstName, Person::setFirstName);
  246. String msg2 = "bar";
  247. binder.withValidator(Validator.from(bean -> false, msg2));
  248. Person person = new Person();
  249. binder.bind(person);
  250. List<ValidationStatus<?>> errors = binder.validate()
  251. .getFieldValidationErrors();
  252. assertEquals(1, errors.size());
  253. ValidationStatus<?> error = errors.get(0);
  254. assertEquals(msg1, error.getMessage().get());
  255. assertEquals(nameField, error.getField());
  256. }
  257. @Test
  258. public void validate_okBeanValidatorWithoutFieldValidators() {
  259. binder.forField(nameField).bind(Person::getFirstName,
  260. Person::setFirstName);
  261. String msg = "foo";
  262. binder.withValidator(Validator.from(bean -> true, msg));
  263. Person person = new Person();
  264. binder.bind(person);
  265. assertFalse(binder.validate().hasErrors());
  266. assertTrue(binder.validate().isOk());
  267. }
  268. @Test
  269. public void binder_saveIfValid() {
  270. String msg1 = "foo";
  271. Binding<Person, String, String> binding = binder.forField(nameField)
  272. .withValidator(new NotEmptyValidator<>(msg1));
  273. binding.bind(Person::getFirstName, Person::setFirstName);
  274. String beanValidatorErrorMessage = "bar";
  275. binder.withValidator(
  276. Validator.from(bean -> false, beanValidatorErrorMessage));
  277. Person person = new Person();
  278. String firstName = "first name";
  279. person.setFirstName(firstName);
  280. binder.load(person);
  281. nameField.setValue("");
  282. assertFalse(binder.saveIfValid(person));
  283. // check that field level-validation failed and bean is not updated
  284. assertEquals(firstName, person.getFirstName());
  285. nameField.setValue("new name");
  286. assertFalse(binder.saveIfValid(person));
  287. // Bean is updated but reverted
  288. assertEquals(firstName, person.getFirstName());
  289. }
  290. @Test
  291. public void updateBoundField_bindingValdationFails_beanLevelValidationIsNotRun() {
  292. bindAgeWithValidatorConverterValidator();
  293. bindName();
  294. AtomicBoolean beanLevelValidationRun = new AtomicBoolean();
  295. binder.withValidator(Validator.<Person> from(
  296. bean -> beanLevelValidationRun.getAndSet(true), ""));
  297. ageField.setValue("not a number");
  298. assertFalse(beanLevelValidationRun.get());
  299. nameField.setValue("foo");
  300. assertFalse(beanLevelValidationRun.get());
  301. }
  302. @Test
  303. public void updateBoundField_bindingValdationSuccess_beanLevelValidationIsRun() {
  304. bindAgeWithValidatorConverterValidator();
  305. bindName();
  306. AtomicBoolean beanLevelValidationRun = new AtomicBoolean();
  307. binder.withValidator(Validator.<Person> from(
  308. bean -> beanLevelValidationRun.getAndSet(true), ""));
  309. ageField.setValue(String.valueOf(12));
  310. assertTrue(beanLevelValidationRun.get());
  311. }
  312. @Test
  313. public void binderHasChanges() throws ValidationException {
  314. binder.forField(nameField)
  315. .withValidator(Validator.from(name -> !"".equals(name),
  316. "Name can't be empty"))
  317. .bind(Person::getFirstName, Person::setFirstName);
  318. assertFalse(binder.hasChanges());
  319. binder.bind(item);
  320. assertFalse(binder.hasChanges());
  321. nameField.setValue("foo");
  322. assertTrue(binder.hasChanges());
  323. binder.load(item);
  324. assertFalse(binder.hasChanges());
  325. nameField.setValue("bar");
  326. binder.saveIfValid(new Person());
  327. assertFalse(binder.hasChanges());
  328. nameField.setValue("baz");
  329. binder.save(new Person());
  330. assertFalse(binder.hasChanges());
  331. nameField.setValue("");
  332. binder.saveIfValid(new Person());
  333. assertTrue(binder.hasChanges());
  334. }
  335. @Test(expected = ValidationException.class)
  336. public void save_fieldValidationErrors() throws ValidationException {
  337. Binder<Person> binder = new Binder<>();
  338. String msg = "foo";
  339. binder.forField(nameField).withValidator(new NotEmptyValidator<>(msg))
  340. .bind(Person::getFirstName, Person::setFirstName);
  341. Person person = new Person();
  342. String firstName = "foo";
  343. person.setFirstName(firstName);
  344. nameField.setValue("");
  345. try {
  346. binder.save(person);
  347. } finally {
  348. // Bean should not have been updated
  349. Assert.assertEquals(firstName, person.getFirstName());
  350. }
  351. }
  352. @Test(expected = ValidationException.class)
  353. public void save_beanValidationErrors() throws ValidationException {
  354. Binder<Person> binder = new Binder<>();
  355. binder.forField(nameField).withValidator(new NotEmptyValidator<>("a"))
  356. .bind(Person::getFirstName, Person::setFirstName);
  357. binder.withValidator(Validator.from(person -> false, "b"));
  358. Person person = new Person();
  359. nameField.setValue("foo");
  360. try {
  361. binder.save(person);
  362. } finally {
  363. // Bean should have been updated for item validation but reverted
  364. Assert.assertNull(person.getFirstName());
  365. }
  366. }
  367. @Test
  368. public void save_fieldsAndBeanLevelValidation() throws ValidationException {
  369. binder.forField(nameField).withValidator(new NotEmptyValidator<>("a"))
  370. .bind(Person::getFirstName, Person::setFirstName);
  371. binder.withValidator(
  372. Validator.from(person -> person.getLastName() != null, "b"));
  373. Person person = new Person();
  374. person.setLastName("bar");
  375. nameField.setValue("foo");
  376. binder.save(person);
  377. Assert.assertEquals(nameField.getValue(), person.getFirstName());
  378. Assert.assertEquals("bar", person.getLastName());
  379. }
  380. @Test
  381. public void saveIfValid_fieldValidationErrors() {
  382. String msg = "foo";
  383. binder.forField(nameField).withValidator(new NotEmptyValidator<>(msg))
  384. .bind(Person::getFirstName, Person::setFirstName);
  385. Person person = new Person();
  386. person.setFirstName("foo");
  387. nameField.setValue("");
  388. Assert.assertFalse(binder.saveIfValid(person));
  389. Assert.assertEquals("foo", person.getFirstName());
  390. }
  391. @Test
  392. public void saveIfValid_noValidationErrors() {
  393. String msg = "foo";
  394. binder.forField(nameField).withValidator(new NotEmptyValidator<>(msg))
  395. .bind(Person::getFirstName, Person::setFirstName);
  396. Person person = new Person();
  397. person.setFirstName("foo");
  398. nameField.setValue("bar");
  399. Assert.assertTrue(binder.saveIfValid(person));
  400. Assert.assertEquals("bar", person.getFirstName());
  401. }
  402. @Test
  403. public void saveIfValid_beanValidationErrors() {
  404. Binder<Person> binder = new Binder<>();
  405. binder.forField(nameField).bind(Person::getFirstName,
  406. Person::setFirstName);
  407. String msg = "foo";
  408. binder.withValidator(Validator.<Person> from(
  409. prsn -> prsn.getAddress() != null || prsn.getEmail() != null,
  410. msg));
  411. Person person = new Person();
  412. person.setFirstName("foo");
  413. nameField.setValue("");
  414. Assert.assertFalse(binder.saveIfValid(person));
  415. Assert.assertEquals("foo", person.getFirstName());
  416. }
  417. @Test
  418. public void save_null_beanIsUpdated() throws ValidationException {
  419. Binder<Person> binder = new Binder<>();
  420. binder.forField(nameField).withConverter(fieldValue -> {
  421. if ("null".equals(fieldValue)) {
  422. return null;
  423. } else {
  424. return fieldValue;
  425. }
  426. }, model -> {
  427. return model;
  428. }).bind(Person::getFirstName, Person::setFirstName);
  429. Person person = new Person();
  430. person.setFirstName("foo");
  431. nameField.setValue("null");
  432. binder.save(person);
  433. Assert.assertNull(person.getFirstName());
  434. }
  435. @Test
  436. public void save_validationErrors_exceptionContainsErrors()
  437. throws ValidationException {
  438. String msg = "foo";
  439. Binding<Person, String, String> nameBinding = binder.forField(nameField)
  440. .withValidator(new NotEmptyValidator<>(msg));
  441. nameBinding.bind(Person::getFirstName, Person::setFirstName);
  442. Binding<Person, String, Integer> ageBinding = binder.forField(ageField)
  443. .withConverter(stringToInteger).withValidator(notNegative);
  444. ageBinding.bind(Person::getAge, Person::setAge);
  445. Person person = new Person();
  446. nameField.setValue("");
  447. ageField.setValue("-1");
  448. try {
  449. binder.save(person);
  450. Assert.fail();
  451. } catch (ValidationException exception) {
  452. List<ValidationStatus<?>> validationErrors = exception
  453. .getFieldValidationErrors();
  454. Assert.assertEquals(2, validationErrors.size());
  455. ValidationStatus<?> error = validationErrors.get(0);
  456. Assert.assertEquals(nameField, error.getField());
  457. Assert.assertEquals(msg, error.getMessage().get());
  458. error = validationErrors.get(1);
  459. Assert.assertEquals(ageField, error.getField());
  460. Assert.assertEquals(NEGATIVE_ERROR_MESSAGE,
  461. error.getMessage().get());
  462. }
  463. }
  464. @Test
  465. public void binderBindAndLoad_clearsErrors() {
  466. Binding<Person, String, String> binding = binder.forField(nameField)
  467. .withValidator(notEmpty);
  468. binding.bind(Person::getFirstName, Person::setFirstName);
  469. binder.withValidator(bean -> bean.getFirstName().contains("error")
  470. ? Result.error("error") : Result.ok(bean));
  471. Person person = new Person();
  472. person.setFirstName("");
  473. binder.bind(person);
  474. // initial value is invalid but no error
  475. Assert.assertNull(nameField.getComponentError());
  476. // make error show
  477. nameField.setValue("foo");
  478. nameField.setValue("");
  479. Assert.assertNotNull(nameField.getComponentError());
  480. // bind to another person to see that error is cleared
  481. person = new Person();
  482. person.setFirstName("");
  483. binder.bind(person);
  484. // error has been cleared
  485. Assert.assertNull(nameField.getComponentError());
  486. // make show error
  487. nameField.setValue("foo");
  488. nameField.setValue("");
  489. Assert.assertNotNull(nameField.getComponentError());
  490. // load should also clear error
  491. binder.load(person);
  492. Assert.assertNull(nameField.getComponentError());
  493. // bind a new field that has invalid value in bean
  494. TextField lastNameField = new TextField();
  495. person.setLastName("");
  496. Binding<Person, String, String> binding2 = binder
  497. .forField(lastNameField).withValidator(notEmpty);
  498. binding2.bind(Person::getLastName, Person::setLastName);
  499. // should not have error shown
  500. Assert.assertNull(lastNameField.getComponentError());
  501. // add status label to show bean level error
  502. Label statusLabel = new Label();
  503. binder.setStatusLabel(statusLabel);
  504. nameField.setValue("error");
  505. // no error shown yet because second field validation doesn't pass
  506. Assert.assertEquals("", statusLabel.getValue());
  507. // make second field validation pass to get bean validation error
  508. lastNameField.setValue("foo");
  509. Assert.assertEquals("error", statusLabel.getValue());
  510. // reload bean to clear error
  511. binder.load(person);
  512. Assert.assertEquals("", statusLabel.getValue());
  513. // unbind() should clear all errors and status label
  514. nameField.setValue("");
  515. lastNameField.setValue("");
  516. Assert.assertNotNull(nameField.getComponentError());
  517. Assert.assertNotNull(lastNameField.getComponentError());
  518. statusLabel.setComponentError(new UserError("ERROR"));
  519. binder.unbind();
  520. Assert.assertNull(nameField.getComponentError());
  521. Assert.assertNull(lastNameField.getComponentError());
  522. Assert.assertEquals("", statusLabel.getValue());
  523. }
  524. @Test
  525. public void binderLoad_withCrossFieldValidation_clearsErrors() {
  526. TextField lastNameField = new TextField();
  527. final SerializablePredicate<String> lengthPredicate = v -> v
  528. .length() > 2;
  529. Binding<Person, String, String> firstNameBinding = binder
  530. .forField(nameField).withValidator(lengthPredicate, "length");
  531. firstNameBinding.bind(Person::getFirstName, Person::setFirstName);
  532. Binding<Person, String, String> lastNameBinding = binder
  533. .forField(lastNameField)
  534. .withValidator(v -> !nameField.getValue().isEmpty()
  535. || lengthPredicate.test(v), "err")
  536. .withValidator(lengthPredicate, "length");
  537. lastNameBinding.bind(Person::getLastName, Person::setLastName);
  538. // this will be triggered as a new bean is bound with binder.bind(),
  539. // causing a validation error to be visible until reset is done
  540. nameField.addValueChangeListener(v -> lastNameBinding.validate());
  541. Person person = new Person();
  542. binder.bind(person);
  543. Assert.assertNull(nameField.getComponentError());
  544. Assert.assertNull(lastNameField.getComponentError());
  545. nameField.setValue("x");
  546. Assert.assertNotNull(nameField.getComponentError());
  547. Assert.assertNotNull(lastNameField.getComponentError());
  548. binder.bind(person);
  549. Assert.assertNull(nameField.getComponentError());
  550. Assert.assertNull(lastNameField.getComponentError());
  551. }
  552. protected void bindName() {
  553. binder.bind(nameField, Person::getFirstName, Person::setFirstName);
  554. binder.bind(item);
  555. }
  556. protected void bindAgeWithValidatorConverterValidator() {
  557. binder.forField(ageField).withValidator(notEmpty)
  558. .withConverter(stringToInteger).withValidator(notNegative)
  559. .bind(Person::getAge, Person::setAge);
  560. binder.bind(item);
  561. }
  562. @Test(expected = ValidationException.class)
  563. public void save_beanValidationErrorsWithConverter()
  564. throws ValidationException {
  565. Binder<Person> binder = new Binder<>();
  566. binder.forField(ageField)
  567. .withConverter(new StringToIntegerConverter("Can't convert"))
  568. .bind(Person::getAge, Person::setAge);
  569. binder.withValidator(Validator.from(person -> false, "b"));
  570. Person person = new Person();
  571. ageField.setValue("1");
  572. try {
  573. binder.save(person);
  574. } finally {
  575. // Bean should have been updated for item validation but reverted
  576. Assert.assertEquals(0, person.getAge());
  577. }
  578. }
  579. }