| /* |
| * Copyright 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.editor.client; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.editor.client.adapters.EditorSource; |
| import com.google.gwt.editor.client.adapters.ListEditor; |
| import com.google.gwt.junit.client.GWTTestCase; |
| import com.google.gwt.validation.client.impl.ConstraintViolationImpl; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import javax.validation.ConstraintViolation; |
| import javax.validation.Path; |
| |
| /** |
| * Tests error propagation in generated code. |
| */ |
| public class EditorErrorTest extends GWTTestCase { |
| class AddressEditorWithErrors extends AddressEditor implements |
| ValueAwareEditor<Address> { |
| |
| private EditorDelegate<Address> delegate; |
| |
| @Override |
| public void flush() { |
| delegate.recordError("Hello Errors!", null, null); |
| } |
| |
| @Override |
| public void onPropertyChange(String... paths) { |
| } |
| |
| @Override |
| public void setDelegate(EditorDelegate<Address> delegate) { |
| this.delegate = delegate; |
| } |
| |
| @Override |
| public void setValue(Address value) { |
| } |
| } |
| |
| class AddressEditorReceivesErrors extends AddressEditor implements |
| HasEditorErrors<Address> { |
| List<EditorError> errors; |
| |
| @Override |
| public void showErrors(List<EditorError> errors) { |
| this.errors = errors; |
| for (EditorError error : errors) { |
| error.setConsumed(true); |
| } |
| } |
| } |
| |
| class PersonEditorReceivesErrors extends PersonEditor implements |
| HasEditorErrors<Person> { |
| List<EditorError> errors; |
| |
| @Override |
| public void showErrors(List<EditorError> errors) { |
| this.errors = errors; |
| for (EditorError error : errors) { |
| error.setConsumed(true); |
| } |
| } |
| } |
| |
| class Workgroup { |
| List<Person> people = new ArrayList<Person>(); |
| |
| List<Person> getPeople() { |
| return people; |
| } |
| } |
| |
| class WorkgroupEditor implements HasEditorErrors<Workgroup> { |
| ListEditor<Person, PersonEditor> people = ListEditor.of(new EditorSource<PersonEditor>() { |
| @Override |
| public PersonEditor create(int index) { |
| PersonEditor toReturn = new PersonEditor(); |
| toReturn.addressEditor = new AddressEditorWithErrors(); |
| return toReturn; |
| } |
| }); |
| |
| private List<EditorError> errors; |
| |
| @Override |
| public void showErrors(List<EditorError> errors) { |
| this.errors = errors; |
| } |
| } |
| |
| interface WorkgroupEditorDriver extends |
| SimpleBeanEditorDriver<Workgroup, WorkgroupEditor> { |
| } |
| |
| class WorkgroupNestedErrorsEditor implements HasEditorErrors<Workgroup> { |
| ListEditor<Person, PersonEditorReceivesErrors> people = ListEditor.of(new EditorSource<PersonEditorReceivesErrors>() { |
| @Override |
| public PersonEditorReceivesErrors create(int index) { |
| PersonEditorReceivesErrors toReturn = new PersonEditorReceivesErrors(); |
| toReturn.addressEditor = new AddressEditorWithErrors(); |
| return toReturn; |
| } |
| }); |
| |
| List<EditorError> errors; |
| |
| @Override |
| public void showErrors(List<EditorError> errors) { |
| this.errors = errors; |
| } |
| } |
| |
| interface WorkgroupNestedErrorsEditorDriver extends |
| SimpleBeanEditorDriver<Workgroup, WorkgroupNestedErrorsEditor> { |
| } |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.editor.Editor"; |
| } |
| |
| public void testListOfErrors() { |
| Address a = new Address(); |
| Person p1 = new Person(); |
| p1.address = a; |
| |
| Person p2 = new Person(); |
| p2.address = a; |
| |
| Workgroup workgroup = new Workgroup(); |
| workgroup.people.addAll(Arrays.asList(p1, p2)); |
| |
| WorkgroupEditorDriver driver = GWT.create(WorkgroupEditorDriver.class); |
| WorkgroupEditor editor = new WorkgroupEditor(); |
| driver.initialize(editor); |
| driver.edit(workgroup); |
| driver.flush(); |
| |
| List<EditorError> errors = editor.errors; |
| assertNotNull(errors); |
| assertEquals("Wrong number of EditorErrors", 2, errors.size()); |
| assertEquals(Arrays.asList("people[0].address", "people[1].address"), |
| Arrays.asList(errors.get(0).getPath(), errors.get(1).getPath())); |
| } |
| |
| public void testNestedErrors() { |
| Address a = new Address(); |
| Person p1 = new Person(); |
| p1.address = a; |
| |
| Person p2 = new Person(); |
| p2.address = a; |
| |
| Workgroup workgroup = new Workgroup(); |
| workgroup.people.addAll(Arrays.asList(p1, p2)); |
| |
| WorkgroupNestedErrorsEditorDriver driver = GWT.create(WorkgroupNestedErrorsEditorDriver.class); |
| WorkgroupNestedErrorsEditor editor = new WorkgroupNestedErrorsEditor(); |
| driver.initialize(editor); |
| driver.edit(workgroup); |
| driver.flush(); |
| |
| // Verify the nested editors received the errors |
| List<EditorError> errors = editor.errors; |
| assertNotNull(errors); |
| assertEquals(0, errors.size()); |
| |
| List<PersonEditorReceivesErrors> editors = editor.people.getEditors(); |
| for (int i = 0, j = editors.size(); i < j; i++) { |
| PersonEditorReceivesErrors personEditor = editors.get(i); |
| assertEquals(1, personEditor.errors.size()); |
| |
| EditorError error = personEditor.errors.get(0); |
| assertNotNull(error); |
| assertEquals("people[" + i + "].address", error.getAbsolutePath()); |
| assertEquals("Hello Errors!", error.getMessage()); |
| assertEquals("address", error.getPath()); |
| assertNull(error.getUserData()); |
| assertSame(a, error.getValue()); |
| assertSame(personEditor.addressEditor, error.getEditor()); |
| } |
| } |
| |
| public void testNoErrors() { |
| Address a = new Address(); |
| Person p = new Person(); |
| p.address = a; |
| |
| PersonEditorDriver driver = GWT.create(PersonEditorDriver.class); |
| PersonEditorReceivesErrors editor = new PersonEditorReceivesErrors(); |
| driver.initialize(editor); |
| driver.edit(p); |
| driver.flush(); |
| assertEquals(0, editor.errors.size()); |
| assertFalse(driver.hasErrors()); |
| assertNotNull(driver.getErrors()); |
| assertEquals(0, driver.getErrors().size()); |
| |
| assertFalse(driver.setConstraintViolations(Collections.<ConstraintViolation<?>>emptyList())); |
| assertEquals(0, editor.errors.size()); |
| assertFalse(driver.hasErrors()); |
| assertNotNull(driver.getErrors()); |
| assertEquals(0, driver.getErrors().size()); |
| |
| // Test no NPE is thrown; see issue 6578 |
| assertFalse(driver.setConstraintViolations(null)); |
| assertEquals(0, editor.errors.size()); |
| assertFalse(driver.hasErrors()); |
| assertNotNull(driver.getErrors()); |
| assertEquals(0, driver.getErrors().size()); |
| } |
| |
| public void testSimpleError() { |
| PersonEditorReceivesErrors editor = new PersonEditorReceivesErrors(); |
| editor.addressEditor = new AddressEditorWithErrors(); |
| |
| Address a = new Address(); |
| Person p = new Person(); |
| p.address = a; |
| |
| PersonEditorDriver driver = GWT.create(PersonEditorDriver.class); |
| driver.initialize(editor); |
| driver.edit(p); |
| driver.flush(); |
| |
| List<EditorError> list = editor.errors; |
| assertNotNull(list); |
| assertEquals(1, list.size()); |
| |
| EditorError error = list.get(0); |
| assertNotNull(error); |
| assertEquals("address", error.getAbsolutePath()); |
| assertEquals("Hello Errors!", error.getMessage()); |
| assertEquals("address", error.getPath()); |
| assertNull(error.getUserData()); |
| assertSame(a, error.getValue()); |
| assertSame(editor.addressEditor, error.getEditor()); |
| } |
| |
| public void testUnmatchedConstraintViolationsHasErrors() { |
| Address a = new Address(); |
| Person p = new Person(); |
| p.address = a; |
| |
| PersonEditorDriver driver = GWT.create(PersonEditorDriver.class); |
| PersonEditor editor = new PersonEditor(); |
| driver.initialize(editor); |
| driver.edit(p); |
| driver.flush(); |
| |
| ConstraintViolation<Person> e1 = createViolation("msg1", p, "address"); |
| ConstraintViolation<Person> e2 = createViolation("msg2", p, "bogus1"); |
| ConstraintViolation<Person> e3 = createViolation("msg3", p, "address.city"); |
| ConstraintViolation<Person> e4 = |
| createViolation("msg4", p, "address.bogus2"); |
| ConstraintViolation<Person> e5 = |
| createViolation("msg5", p, "address.city.bogus3"); |
| ConstraintViolation<Person> e6 = |
| createViolation("msg6", p, "address.bogusparent.boguschild"); |
| ConstraintViolation<Person> e7 = createViolation("msg7", p, "."); |
| ConstraintViolation<Person> e8 = createViolation("msg8", p, "address."); |
| driver.setConstraintViolations( |
| Arrays.<ConstraintViolation<?>>asList(e1, e2, e3, e4, e5, e6, e7, e8)); |
| assertTrue(driver.hasErrors()); |
| assertEquals(driver.getErrors().toString(), 8, driver.getErrors().size()); |
| |
| List<EditorError> list = driver.getErrors(); |
| |
| // All the errors w/ addressEditor are collected first |
| EditorError error = list.get(0); |
| assertEquals("msg1", error.getMessage()); |
| assertEquals("address", error.getAbsolutePath()); |
| assertEquals("address", error.getPath()); |
| assertSame(e1, error.getUserData()); |
| assertSame(a, error.getValue()); |
| assertSame(editor.addressEditor, error.getEditor()); |
| |
| error = list.get(1); |
| assertEquals("msg4", error.getMessage()); |
| assertEquals("address.bogus2", error.getAbsolutePath()); |
| assertEquals("address.bogus2", error.getPath()); |
| assertSame(e4, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor.addressEditor, error.getEditor()); |
| |
| error = list.get(2); |
| assertEquals("msg6", error.getMessage()); |
| assertEquals("address.bogusparent.boguschild", error.getAbsolutePath()); |
| assertEquals("address.bogusparent.boguschild", error.getPath()); |
| assertSame(e6, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor.addressEditor, error.getEditor()); |
| |
| error = list.get(3); |
| assertEquals("msg8", error.getMessage()); |
| assertEquals("address.", error.getAbsolutePath()); |
| assertEquals("address.", error.getPath()); |
| assertSame(e8, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor.addressEditor, error.getEditor()); |
| |
| // Then the rest of the errors. |
| error = list.get(4); |
| assertEquals("msg2", error.getMessage()); |
| assertEquals("bogus1", error.getAbsolutePath()); |
| assertEquals("bogus1", error.getPath()); |
| assertSame(e2, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor, error.getEditor()); |
| |
| error = list.get(5); |
| assertEquals("msg3", error.getMessage()); |
| assertEquals("address.city", error.getAbsolutePath()); |
| assertEquals("address.city", error.getPath()); |
| assertSame(e3, error.getUserData()); |
| assertSame(a.city, error.getValue()); |
| assertSame(editor.addressEditor.city, error.getEditor()); |
| |
| error = list.get(6); |
| assertEquals("msg5", error.getMessage()); |
| assertEquals("address.city.bogus3", error.getAbsolutePath()); |
| assertEquals("address.city.bogus3", error.getPath()); |
| assertSame(e5, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor.addressEditor.city, error.getEditor()); |
| |
| error = list.get(7); |
| assertEquals("msg7", error.getMessage()); |
| assertEquals(".", error.getAbsolutePath()); |
| assertEquals(".", error.getPath()); |
| assertSame(e7, error.getUserData()); |
| assertSame(null, error.getValue()); |
| assertSame(editor, error.getEditor()); |
| } |
| |
| /** |
| * Test for IndexOutOfBoundsException in getPath() when called on a leaf editor error display. |
| * |
| * The external bug report: http://code.google.com/p/google-web-toolkit/issues/detail?id=5589 |
| */ |
| public void testSamePathHasError() { |
| PersonEditorReceivesErrors editor = new PersonEditorReceivesErrors(); |
| AddressEditorReceivesErrors addressEditor = new AddressEditorReceivesErrors(); |
| editor.addressEditor = addressEditor; |
| |
| Address a = new Address(); |
| Person p = new Person(); |
| p.address = a; |
| |
| PersonEditorDriver driver = GWT.create(PersonEditorDriver.class); |
| driver.initialize(editor); |
| driver.edit(p); |
| driver.flush(); |
| |
| driver.setConstraintViolations( |
| Arrays.<ConstraintViolation<?>>asList(createViolation("samePathError", p, "address"))); |
| assertEquals(0, driver.getErrors().size()); |
| |
| assertEquals(0, editor.errors.size()); |
| |
| |
| List<EditorError> list = addressEditor.errors; |
| assertNotNull(list); |
| assertEquals(1, list.size()); |
| |
| EditorError error = list.get(0); |
| assertNotNull(error); |
| assertEquals("address", error.getAbsolutePath()); |
| assertEquals("samePathError", error.getMessage()); |
| assertEquals("", error.getPath()); |
| assertNotNull(error.getUserData()); |
| assertSame(a, error.getValue()); |
| assertSame(addressEditor, error.getEditor()); |
| } |
| |
| private <T> ConstraintViolation<T> createViolation( |
| String msg, T rootBean, final String path) { |
| return new ConstraintViolationImpl.Builder<T>() |
| .setMessage(msg) |
| .setRootBean(rootBean) |
| .setPropertyPath(new Path() { |
| @Override |
| public Iterator<Node> iterator() { |
| return null; |
| } |
| |
| @Override |
| public String toString() { |
| return path; |
| } |
| }).build(); |
| } |
| } |