blob: 81be530b603734f76a0f5e13d5f8579b00515c54 [file] [log] [blame]
/*
* 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.editor.client.adapters.OptionalFieldEditor;
import com.google.gwt.editor.client.adapters.SimpleEditor;
import com.google.gwt.junit.client.GWTTestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Uses the SimpleBeanEditorTest to test core Editor behaviors as generated by
* AbstractEditorDriverGenerator.
*/
public class SimpleBeanEditorTest extends GWTTestCase {
class AddressCoEditorView extends LeafAddressEditor implements IsEditor<LeafAddressEditor> {
private LeafAddressEditor addressEditor = new LeafAddressEditor();
public LeafAddressEditor asEditor() {
return addressEditor;
}
}
class AddressEditorPartOne implements Editor<Address> {
SimpleEditor<String> city = SimpleEditor.of(UNINITIALIZED);
}
class AddressEditorPartTwo implements Editor<Address> {
SimpleEditor<String> street = SimpleEditor.of(UNINITIALIZED);
}
class AddressEditorView implements IsEditor<LeafAddressEditor> {
LeafAddressEditor addressEditor = new LeafAddressEditor();
public LeafAddressEditor asEditor() {
return addressEditor;
}
}
/**
* See <a
* href="http://code.google.com/p/google-web-toolkit/issues/detail?id=6016"
* >issue 6016</a>
*/
static class EditorWithGenericSubEditors implements Editor<Department> {
PersonGenericEditor<Manager> manager = new PersonGenericEditor<Manager>();
PersonGenericEditor<Intern> intern = new PersonGenericEditor<Intern>();
}
interface EditorWithGenericSubEditorsDriver extends
SimpleBeanEditorDriver<Department, EditorWithGenericSubEditors> {
}
class LeafAddressEditor extends AddressEditor implements LeafValueEditor<Address> {
/*
* These two fields are used to ensure that getValue() and setValue() aren't
* called excessively.
*/
int getValueCalled;
int setValueCalled;
Address value;
public Address getValue() {
getValueCalled++;
return value;
}
public void setValue(Address value) {
setValueCalled++;
value = new Address();
}
}
interface ListEditorDriver extends
SimpleBeanEditorDriver<List<String>, ListEditor<String, SimpleEditor<String>>> {
}
class PersonEditorWithAddressEditorView implements Editor<Person> {
AddressEditorView addressEditor = new AddressEditorView();
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
}
interface PersonEditorWithAddressEditorViewDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithAddressEditorView> {
}
/**
* A test for assigning the object associated with an editor to an immediate
* child editors.
*/
class PersonEditorWithAliasedSubEditors implements Editor<Person> {
@Path("")
PersonEditor e1 = new PersonEditor();
@Path("")
PersonEditor e2 = new PersonEditor();
}
interface PersonEditorWithAliasedSubEditorsDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithAliasedSubEditors> {
}
class PersonEditorWithCoAddressEditorView implements Editor<Person> {
AddressCoEditorView addressEditor = new AddressCoEditorView();
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
}
interface PersonEditorWithCoAddressEditorViewDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithCoAddressEditorView> {
}
static class PersonEditorWithDelegate extends PersonEditor implements HasEditorDelegate<Person> {
EditorDelegate<Person> delegate;
public void setDelegate(EditorDelegate<Person> delegate) {
this.delegate = delegate;
}
}
interface PersonEditorWithDelegateDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithDelegate> {
}
class PersonEditorWithLeafAddressEditor implements Editor<Person> {
LeafAddressEditor addressEditor = new LeafAddressEditor();
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
@Path("manager.name")
SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
}
interface PersonEditorWithLeafAddressEditorDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithLeafAddressEditor> {
}
class PersonEditorWithManagerNameWithDelegate implements Editor<Person> {
@Path("manager.name")
SimpleEditorWithDelegate<String> managerName = new SimpleEditorWithDelegate<String>(
UNINITIALIZED);
}
interface PersonEditorWithManagerNameWithDelegateDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithManagerNameWithDelegate> {
}
class PersonEditorWithMultipleBindings implements Editor<Person> {
@Editor.Path("address")
AddressEditorPartOne one = new AddressEditorPartOne();
@Editor.Path("address")
AddressEditorPartTwo two = new AddressEditorPartTwo();
}
interface PersonEditorWithMultipleBindingsDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithMultipleBindings> {
}
interface PersonEditorWithOptionalAddressDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithOptionalAddressEditor> {
}
static class PersonEditorWithOptionalAddressEditor implements Editor<Person> {
OptionalFieldEditor<Address, AddressEditor> address;
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
public PersonEditorWithOptionalAddressEditor(AddressEditor delegate) {
address = OptionalFieldEditor.of(delegate);
}
}
class PersonEditorWithValueAwareAddressEditor implements Editor<Person> {
ValueAwareAddressEditor addressEditor = new ValueAwareAddressEditor();
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
@Path("manager.name")
SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
}
interface PersonEditorWithValueAwareAddressEditorDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithValueAwareAddressEditor> {
}
class PersonEditorWithValueAwareLeafAddressEditor implements Editor<Person> {
ValueAwareLeafAddressEditor addressEditor = new ValueAwareLeafAddressEditor();
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
@Path("manager.name")
SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
}
interface PersonEditorWithValueAwareLeafAddressEditorDriver extends
SimpleBeanEditorDriver<Person, PersonEditorWithValueAwareLeafAddressEditor> {
}
static class PersonGenericEditor<T extends Person> implements Editor<T> {
SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
}
class PersonWithList {
String name = "PersonWithList";
List<Address> addresses = new ArrayList<Address>();
public List<Address> getAddresses() {
return addresses;
}
public String getName() {
return name;
}
}
class PersonWithListEditor implements Editor<PersonWithList> {
SimpleEditor<String> nameEditor = SimpleEditor.of(UNINITIALIZED);
ListEditor<Address, ValueAwareAddressEditor> addressesEditor = ListEditor
.of(new EditorSource<ValueAwareAddressEditor>() {
@Override
public ValueAwareAddressEditor create(int index) {
return new ValueAwareAddressEditor();
}
});
}
interface PersonWithListEditorDriver extends
SimpleBeanEditorDriver<PersonWithList, PersonWithListEditor> {
}
class SimpleEditorWithDelegate<T> extends SimpleEditor<T> implements HasEditorDelegate<T> {
EditorDelegate<T> delegate;
public SimpleEditorWithDelegate(T value) {
super(value);
}
public void setDelegate(EditorDelegate<T> delegate) {
this.delegate = delegate;
}
}
class ValueAwareAddressEditor extends AddressEditor implements ValueAwareEditor<Address> {
int flushCalled;
int setDelegateCalled;
int setValueCalled;
Address value;
public void flush() {
flushCalled++;
}
public void onPropertyChange(String... paths) {
}
public void setDelegate(EditorDelegate<Address> delegate) {
setDelegateCalled++;
}
public void setValue(Address value) {
setValueCalled++;
this.value = value;
}
}
/**
* All the mix-ins. Not that this seems like a good idea...
*/
class ValueAwareLeafAddressEditor extends LeafAddressEditor implements ValueAwareEditor<Address> {
int flushCalled;
int setDelegateCalled;
public void flush() {
flushCalled++;
}
public void onPropertyChange(String... paths) {
}
public void setDelegate(EditorDelegate<Address> delegate) {
setDelegateCalled++;
}
}
class TaggedItemAddressEditor implements Editor<TaggedItem<Address>> {
@Path("item.city") SimpleEditor<String> itemCityEditor = SimpleEditor.of(UNINITIALIZED);
@Path("item.street") SimpleEditor<String> itemStreetEditor = SimpleEditor.of(UNINITIALIZED);
@Path("tag") SimpleEditor<String> tagEditor = SimpleEditor.of(UNINITIALIZED);
}
interface TaggedItemAddressEditorDriver extends
SimpleBeanEditorDriver<TaggedItem<Address>, TaggedItemAddressEditor> {
}
Person person;
Address personAddress;
Person manager;
long now;
static final String UNINITIALIZED = "uninitialized";
@Override
public String getModuleName() {
return "com.google.gwt.editor.Editor";
}
public void test() {
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
PersonEditor editor = new PersonEditor();
driver.initialize(editor);
driver.edit(person);
assertEquals(now, editor.localTime.getValue().longValue());
assertEquals("Alice", editor.name.getValue());
assertEquals("City", editor.addressEditor.city.getValue());
assertEquals("Street", editor.addressEditor.street.getValue());
assertEquals("Bill", editor.managerName.getValue());
editor.localTime.setValue(now + 1);
editor.name.setValue("Charles");
editor.addressEditor.city.setValue("Wootville");
editor.addressEditor.street.setValue("12345");
editor.managerName.setValue("David");
driver.flush();
assertEquals(now + 1, person.localTime);
assertEquals("Charles", person.name);
assertEquals("Wootville", person.address.city);
assertEquals("12345", person.address.street);
assertEquals("David", person.manager.name);
}
public void testAliasedEditors() {
PersonEditorWithAliasedSubEditors editor = new PersonEditorWithAliasedSubEditors();
PersonEditorWithAliasedSubEditorsDriver driver =
GWT.create(PersonEditorWithAliasedSubEditorsDriver.class);
driver.initialize(editor);
driver.edit(person);
assertEquals("Alice", editor.e1.name.getValue());
assertEquals("Alice", editor.e2.name.getValue());
/*
* Expecting that aliased editors will be editing disjoint sets of
* properties, but we want to at least have a predictable behavior if two
* editors are assigned to the same property.
*/
editor.e1.name.setValue("Should not see this");
driver.flush();
assertEquals("Alice", person.getName());
editor.e2.name.setValue("Should see this");
driver.flush();
assertEquals("Should see this", person.getName());
}
public void testDelegatePath() {
PersonEditorWithManagerNameWithDelegate editor = new PersonEditorWithManagerNameWithDelegate();
PersonEditorWithManagerNameWithDelegateDriver driver =
GWT.create(PersonEditorWithManagerNameWithDelegateDriver.class);
driver.initialize(editor);
driver.edit(person);
assertEquals("manager.name", editor.managerName.delegate.getPath());
}
/**
* See <a
* href="http://code.google.com/p/google-web-toolkit/issues/detail?id=6016"
* >issue 6016</a>
*/
public void testEditorWithGenericSubEditors() {
EditorWithGenericSubEditorsDriver driver = GWT.create(EditorWithGenericSubEditorsDriver.class);
// Issue 6016 would make the above line fail (when generating the editor
// driver), but let's try editing an object too, it doesn't cost much.
driver.initialize(new EditorWithGenericSubEditors());
driver.edit(new Department());
}
public void testEditorWithNullSubEditor() {
PersonEditor editor = new PersonEditor();
editor.addressEditor = null;
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
driver.initialize(editor);
driver.edit(person);
assertEquals("Alice", editor.name.getValue());
editor.name.setValue("New name");
driver.flush();
assertEquals("New name", person.getName());
/*
* Verify that changing the editor structure without re-initializing is a
* no-op.
*/
editor.name.setValue("Should see this");
editor.addressEditor = new AddressEditor();
editor.addressEditor.city.setValue("Should not see this");
driver.flush();
assertEquals("Should see this", person.getName());
assertEquals("City", person.getAddress().getCity());
// Re-initialize and check that flushing works again
driver.initialize(editor);
driver.edit(person);
editor.addressEditor.city.setValue("Should see this");
driver.flush();
assertEquals("Should see this", person.getAddress().getCity());
}
/**
* Test the use of the IsEditor interface that allows a view object to
* encapsulate its Editor.
*/
public void testIsEditorView() {
PersonEditorWithAddressEditorView personEditor = new PersonEditorWithAddressEditorView();
PersonEditorWithAddressEditorViewDriver driver =
GWT.create(PersonEditorWithAddressEditorViewDriver.class);
testLeafAddressEditor(driver, personEditor, personEditor.addressEditor.asEditor(), true);
}
/**
* Test the use of the IsEditor interface that allows a view object to
* encapsulate its Editor as well as be an editor itself.
*/
public void testIsEditorViewWithCoEditorA() {
PersonEditorWithCoAddressEditorView personEditor = new PersonEditorWithCoAddressEditorView();
PersonEditorWithCoAddressEditorViewDriver driver =
GWT.create(PersonEditorWithCoAddressEditorViewDriver.class);
testLeafAddressEditor(driver, personEditor, personEditor.addressEditor, true);
}
/**
* Test the use of the IsEditor interface that allows a view object to
* encapsulate its Editor as well as be an editor itself.
*/
public void testIsEditorViewWithCoEditorB() {
PersonEditorWithCoAddressEditorView personEditor = new PersonEditorWithCoAddressEditorView();
PersonEditorWithCoAddressEditorViewDriver driver =
GWT.create(PersonEditorWithCoAddressEditorViewDriver.class);
testLeafAddressEditor(driver, personEditor, personEditor.addressEditor.asEditor(), true);
}
/**
* We want to verify that the sub-editors of a LeafValueEditor are not
* initialized. Additonally, we want to ensure that the instance returned from
* the LVE is assigned into the owner type.
*/
public void testLeafValueEditorDeclaredInSlot() {
PersonEditorWithLeafAddressEditor personEditor = new PersonEditorWithLeafAddressEditor();
PersonEditorWithLeafAddressEditorDriver driver =
GWT.create(PersonEditorWithLeafAddressEditorDriver.class);
LeafAddressEditor addressEditor = personEditor.addressEditor;
testLeafAddressEditor(driver, personEditor, addressEditor, true);
}
/**
* This tests a weird case where the user has put a LeafValueEditor into a
* plain Editor field. Because the Editor system relies heavily on static type
* information at compile time, this is not a supported configuration.
*/
public void testLeafValueEditorInPlainEditorSlot() {
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
PersonEditor personEditor = new PersonEditor();
LeafAddressEditor addressEditor = new LeafAddressEditor();
// Runtime assignment of unexpected LeafValueEditor
personEditor.addressEditor = addressEditor;
testLeafAddressEditor(driver, personEditor, addressEditor, true);
}
public void testLifecycle() {
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
try {
driver.edit(person);
fail("Should have thrown execption");
} catch (IllegalStateException expected) {
}
driver.initialize(new PersonEditor());
try {
driver.flush();
fail("Should have thrown exception");
} catch (IllegalStateException expected) {
}
driver.edit(person);
driver.flush();
}
/**
* Test a top-level ListEditor.
*/
public void testListEditor() {
final SortedMap<Integer, SimpleEditor<String>> positionMap =
new TreeMap<Integer, SimpleEditor<String>>();
@SuppressWarnings("unchecked")
final SimpleEditor<String>[] disposed = new SimpleEditor[1];
class StringSource extends EditorSource<SimpleEditor<String>> {
public SimpleEditor<String> create(int index) {
SimpleEditor<String> editor = SimpleEditor.of();
positionMap.put(index, editor);
return editor;
}
public void dispose(SimpleEditor<String> editor) {
disposed[0] = editor;
positionMap.values().remove(editor);
}
public void setIndex(SimpleEditor<String> editor, int index) {
positionMap.values().remove(editor);
positionMap.put(index, editor);
}
};
ListEditorDriver driver = GWT.create(ListEditorDriver.class);
ListEditor<String, SimpleEditor<String>> editor = ListEditor.of(new StringSource());
driver.initialize(editor);
List<String> rawData = new ArrayList<String>(Arrays.asList("foo", "bar", "baz"));
driver.edit(rawData);
List<SimpleEditor<String>> editors = editor.getEditors();
assertEquals(rawData.size(), editors.size());
assertEquals(rawData, Arrays.asList(editors.get(0).getValue(), editors.get(1).getValue(),
editors.get(2).getValue()));
assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
List<String> mutableList = editor.getList();
assertEquals(rawData, mutableList);
// Test through wrapped list
mutableList.set(1, "Hello");
assertEquals("Hello", editors.get(1).getValue());
// Test using editor
editors.get(2).setValue("World");
assertEquals("baz", rawData.get(2));
driver.flush();
assertEquals("World", rawData.get(2));
// Change list size
mutableList.add("quux");
assertEquals(4, editors.size());
assertEquals("quux", editors.get(3).getValue());
assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
// Delete an element
SimpleEditor<String> expectedDisposed = editors.get(0);
mutableList.remove(0);
assertSame(expectedDisposed, disposed[0]);
assertEquals(3, editors.size());
assertEquals("quux", editors.get(2).getValue());
assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
// Change list outside editor: shouldn't impact editors
rawData.clear();
rawData.addAll(Arrays.asList("able", "baker"));
List<String> expectedList = Arrays.asList("Hello", "World", "quux");
assertEquals(expectedList, editor.getList());
assertEquals(expectedList.size(), editors.size());
assertEquals(expectedList, Arrays.asList(editors.get(0).getValue(), editors.get(1).getValue(),
editors.get(2).getValue()));
assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
// Edit again: should reuse sub-editors and dispose unneeded ones
disposed[0] = null;
expectedDisposed = editors.get(2);
@SuppressWarnings("unchecked")
List<SimpleEditor<String>> expectedEditors = Arrays.asList(editors.get(0), editors.get(1));
driver.edit(rawData);
assertEquals(expectedEditors, editors);
assertEquals(expectedEditors, editor.getEditors());
assertEquals(rawData, editor.getList());
assertEquals(rawData.size(), editors.size());
assertEquals(rawData, Arrays.asList(editors.get(0).getValue(), editors.get(1).getValue()));
assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
assertEquals(expectedDisposed, disposed[0]);
}
/**
* Ensure that a ListEditor deeper in the chain is properly flushed.
*/
public void testListEditorChainFlush() {
PersonWithListEditorDriver driver = GWT.create(PersonWithListEditorDriver.class);
PersonWithList person = new PersonWithList();
Address a1 = new Address();
a1.city = "a1City";
a1.street = "a1Street";
Address a2 = new Address();
a2.city = "a2City";
a2.street = "a2Street";
person.addresses.add(a1);
person.addresses.add(a2);
PersonWithListEditor personEditor = new PersonWithListEditor();
// Initialize
driver.initialize(personEditor);
// Address editors aren't created until edit() is called
assertEquals(Collections.emptyList(), personEditor.addressesEditor.getEditors());
// Edit
driver.edit(person);
ValueAwareAddressEditor addressEditor = personEditor.addressesEditor.getEditors().get(1);
// Check that setValue is only called once on sub-editors (issue 7038)
assertEquals(1, addressEditor.setValueCalled);
assertEquals("a2City", addressEditor.city.getValue());
addressEditor.city.setValue("edited");
// Flush
driver.flush();
assertEquals("edited", person.addresses.get(1).getCity());
// Verify that setting the same list reuses sub-editors
addressEditor.setValueCalled = 0;
driver.edit(person);
assertSame(addressEditor, personEditor.addressesEditor.getEditors().get(1));
// Check that setValue has correctly been called on the sub-editor anyway
assertEquals(1, addressEditor.setValueCalled);
// Edit with a null list
person.addresses = null;
driver.edit(person);
assertNull(personEditor.addressesEditor.getList());
assertEquals(Collections.emptyList(), personEditor.addressesEditor.getEditors());
// Flushing should not throw:
driver.flush();
assertNull(person.addresses);
}
public void testMultipleBinding() {
PersonEditorWithMultipleBindingsDriver driver =
GWT.create(PersonEditorWithMultipleBindingsDriver.class);
PersonEditorWithMultipleBindings editor = new PersonEditorWithMultipleBindings();
driver.initialize(editor);
driver.edit(person);
assertEquals("City", editor.one.city.getValue());
assertEquals("Street", editor.two.street.getValue());
editor.one.city.setValue("Foo");
editor.two.street.setValue("Bar");
driver.flush();
assertEquals("Foo", person.getAddress().getCity());
assertEquals("Bar", person.getAddress().getStreet());
}
public void testOptionalField() {
PersonEditorWithOptionalAddressDriver driver =
GWT.create(PersonEditorWithOptionalAddressDriver.class);
person.address = null;
AddressEditor delegate = new AddressEditor();
PersonEditorWithOptionalAddressEditor editor =
new PersonEditorWithOptionalAddressEditor(delegate);
driver.initialize(editor);
// Make sure we don't blow up with the null field
driver.edit(person);
editor.address.setValue(personAddress);
assertEquals("City", delegate.city.getValue());
delegate.city.setValue("Hello");
driver.flush();
assertNotNull(person.address);
assertSame(personAddress, person.address);
assertEquals("Hello", personAddress.city);
editor.address.setValue(null);
driver.flush();
assertNull(person.address);
}
public void testValueAwareEditorInDeclaredSlot() {
PersonEditorWithValueAwareAddressEditorDriver driver =
GWT.create(PersonEditorWithValueAwareAddressEditorDriver.class);
PersonEditorWithValueAwareAddressEditor personEditor =
new PersonEditorWithValueAwareAddressEditor();
ValueAwareAddressEditor addressEditor = personEditor.addressEditor;
testValueAwareAddressEditor(driver, personEditor, addressEditor);
}
/**
* This is another instance of a LeafValueEditor found in a plain slot.
*/
public void testValueAwareEditorInPlainSlot() {
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
PersonEditor personEditor = new PersonEditor();
ValueAwareAddressEditor addressEditor = new ValueAwareAddressEditor();
// Runtime assignment of unexpected LeafValueEditor
personEditor.addressEditor = addressEditor;
testValueAwareAddressEditor(driver, personEditor, addressEditor);
}
public void testValueAwareLeafValueEditorInDeclaredSlot() {
PersonEditorWithValueAwareLeafAddressEditor personEditor =
new PersonEditorWithValueAwareLeafAddressEditor();
PersonEditorWithValueAwareLeafAddressEditorDriver driver =
GWT.create(PersonEditorWithValueAwareLeafAddressEditorDriver.class);
ValueAwareLeafAddressEditor addressEditor = personEditor.addressEditor;
testLeafAddressEditor(driver, personEditor, addressEditor, true);
assertEquals(1, addressEditor.flushCalled);
assertEquals(1, addressEditor.setDelegateCalled);
}
public void testValueAwareLeafValueEditorInPlainEditorSlot() {
PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
PersonEditor personEditor = new PersonEditor();
ValueAwareLeafAddressEditor addressEditor = new ValueAwareLeafAddressEditor();
// Runtime assignment of unexpected LeafValueEditor
personEditor.addressEditor = addressEditor;
testLeafAddressEditor(driver, personEditor, addressEditor, true);
assertEquals(1, addressEditor.flushCalled);
assertEquals(1, addressEditor.setDelegateCalled);
}
public void testEditorWithParameterizedModel() {
TaggedItemAddressEditorDriver driver = GWT.create(TaggedItemAddressEditorDriver.class);
TaggedItemAddressEditor editor = new TaggedItemAddressEditor();
driver.initialize(editor);
TaggedItem<Address> taggedAddress = new TaggedItem<Address>();
taggedAddress.setTag("tag1");
taggedAddress.setItem(personAddress);
driver.edit(taggedAddress);
assertEquals("tag1", editor.tagEditor.getValue());
assertEquals("City", editor.itemCityEditor.getValue());
assertEquals("Street", editor.itemStreetEditor.getValue());
editor.tagEditor.setValue("tag2");
editor.itemCityEditor.setValue("Town");
editor.itemStreetEditor.setValue("Road");
driver.flush();
assertEquals("tag2", taggedAddress.getTag());
assertEquals("Town", taggedAddress.getItem().getCity());
assertEquals("Road", taggedAddress.getItem().getStreet());
}
@Override
protected void gwtSetUp() throws Exception {
personAddress = new Address();
personAddress.city = "City";
personAddress.street = "Street";
manager = new Person();
manager.name = "Bill";
person = new Person();
person.address = personAddress;
person.name = "Alice";
person.manager = manager;
person.localTime = now = System.currentTimeMillis();
}
private <T extends Editor<Person>> void testLeafAddressEditor(
SimpleBeanEditorDriver<Person, T> driver, T personEditor, LeafAddressEditor addressEditor,
boolean declaredAsLeaf) {
Address oldAddress = person.address;
// Initialize
driver.initialize(personEditor);
assertEquals(0, addressEditor.setValueCalled);
assertEquals(0, addressEditor.getValueCalled);
// Edit
driver.edit(person);
assertEquals(1, addressEditor.setValueCalled);
// The DirtCollector will interrogate the leaf editors
assertEquals(1, addressEditor.getValueCalled);
// Flush
driver.flush();
assertEquals(1, addressEditor.setValueCalled);
assertEquals(2, addressEditor.getValueCalled);
assertNotSame(oldAddress, person.address);
assertSame(person.address, addressEditor.value);
}
private <T extends Editor<Person>> void testValueAwareAddressEditor(
SimpleBeanEditorDriver<Person, T> driver, T personEditor,
ValueAwareAddressEditor addressEditor) {
Address oldAddress = person.address;
// Initialize
driver.initialize(personEditor);
assertEquals(0, addressEditor.setValueCalled);
assertEquals(0, addressEditor.setDelegateCalled);
assertEquals(0, addressEditor.flushCalled);
// Edit
driver.edit(person);
assertEquals(1, addressEditor.setValueCalled);
assertEquals(1, addressEditor.setDelegateCalled);
assertEquals(0, addressEditor.flushCalled);
assertEquals("City", addressEditor.city.getValue());
// Flush
driver.flush();
assertEquals(1, addressEditor.setValueCalled);
assertEquals(1, addressEditor.setDelegateCalled);
assertEquals(1, addressEditor.flushCalled);
assertSame(oldAddress, person.address);
assertSame(person.address, addressEditor.value);
}
}