blob: 52433deef96785e59d6c8c68074ed76a51102116 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Ovidio Mallo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ovidio Mallo - initial API and implementation (bug 305367)
******************************************************************************/
package org.eclipse.core.tests.internal.databinding.observable.masterdetail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.map.WritableMap;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.internal.databinding.observable.masterdetail.MapDetailValueObservableMap;
import org.eclipse.jface.databinding.conformance.util.MapChangeEventTracker;
import org.eclipse.jface.examples.databinding.model.SimplePerson;
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
import org.junit.Test;
/**
* @since 1.3
*/
public class MapDetailValueObservableMapTest extends
AbstractDefaultRealmTestCase {
@Test
public void testGetKeyType() {
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
new WritableMap(SimplePerson.class, SimplePerson.class),
BeansObservables.valueFactory("name"), String.class);
assertSame(SimplePerson.class, mdom.getKeyType());
}
@Test
public void testGetValueType() {
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
new WritableMap(), BeansObservables.valueFactory("name"),
String.class);
assertSame(String.class, mdom.getValueType());
}
@Test
public void testGetObserved() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// The observed object is the master key set.
assertSame(masterMap, mdom.getObserved());
}
@Test
public void testMasterSetInitiallyNotEmpty() {
WritableMap masterMap = new WritableMap();
SimplePerson person = new SimplePerson();
person.setName("name");
masterMap.put(person, person);
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Make sure that a non-empty master key set is initialized correctly.
assertEquals(masterMap.size(), mdom.size());
assertEquals(person.getName(), mdom.get(person));
}
@Test
public void testAddRemove() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Initially, the detail map is empty.
assertTrue(mdom.isEmpty());
// Add a first person and check that its name is in the detail map.
SimplePerson p1 = new SimplePerson();
p1.setName("name1");
masterMap.put(p1, p1);
assertEquals(masterMap.size(), mdom.size());
assertEquals(p1.getName(), mdom.get(p1));
// Add a second person and check that it's name is in the detail map.
SimplePerson p2 = new SimplePerson();
p2.setName("name2");
masterMap.put(p2, p2);
assertEquals(masterMap.size(), mdom.size());
assertEquals(p2.getName(), mdom.get(p2));
// Remove the first person from the master map and check that we still
// have the name of the second person in the detail map.
masterMap.remove(p1);
assertEquals(masterMap.size(), mdom.size());
assertEquals(p2.getName(), mdom.get(p2));
// Remove the second person as well.
masterMap.remove(p2);
assertTrue(mdom.isEmpty());
}
@Test
public void testChangeDetail() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Change the detail attribute explicitly.
SimplePerson p1 = new SimplePerson();
p1.setName("name1");
masterMap.put(p1, p1);
assertEquals(p1.getName(), mdom.get(p1));
p1.setName("name2");
assertEquals(p1.getName(), mdom.get(p1));
// Change the detail attribute by changing the master.
SimplePerson p2 = new SimplePerson();
p2.setName("name3");
masterMap.put(p1, p2);
assertEquals(p2.getName(), mdom.get(p1));
}
@Test
public void testPut() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Change the detail attribute explicitly.
SimplePerson person = new SimplePerson();
person.setName("name1");
masterMap.put(person, person);
assertEquals(person.getName(), mdom.get(person));
// Set a new name on the detail map.
mdom.put(person, "name2");
// Check that the name has been propagated to the master.
assertEquals("name2", person.getName());
assertEquals(person.getName(), mdom.get(person));
}
@Test
public void testContainsValue() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Add a person with a given name.
SimplePerson person = new SimplePerson();
person.setName("name");
masterMap.put(person, person);
// Make sure the name of the person is contained.
assertTrue(mdom.containsValue(person.getName()));
// Remove the person and make sure that it's name cannot be found
// anymore.
masterMap.remove(person);
assertFalse(mdom.containsValue(person.getName()));
}
@Test
public void testRemove() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Add two person objects to the map.
SimplePerson p1 = new SimplePerson();
SimplePerson p2 = new SimplePerson();
masterMap.put(p1, p1);
masterMap.put(p2, p2);
// Initially, both person objects should be contained in the detail map.
assertTrue(mdom.containsKey(p1));
assertTrue(mdom.containsKey(p2));
// Remove one person and check that it is not contained anymore.
mdom.remove(p1);
assertFalse(mdom.containsKey(p1));
assertTrue(mdom.containsKey(p2));
// Trying to remove a non-existent is allowed but has no effect.
mdom.remove(p1);
assertFalse(mdom.containsKey(p1));
assertTrue(mdom.containsKey(p2));
}
@Test
public void testDetailObservableChangeEvent() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
MapChangeEventTracker changeTracker = MapChangeEventTracker
.observe(mdom);
SimplePerson person = new SimplePerson();
person.setName("old name");
// Initially, we should not have received any event.
assertEquals(0, changeTracker.count);
// Add the person and check that we receive an addition event on the
// correct index and with the correct value.
masterMap.put(person, person);
assertEquals(1, changeTracker.count);
assertEquals(1, changeTracker.event.diff.getAddedKeys().size());
assertEquals(0, changeTracker.event.diff.getRemovedKeys().size());
assertEquals(0, changeTracker.event.diff.getChangedKeys().size());
assertSame(person, changeTracker.event.diff.getAddedKeys().iterator()
.next());
assertNull(changeTracker.event.diff.getOldValue(person));
assertEquals("old name", changeTracker.event.diff.getNewValue(person));
// Change the detail property and check that we receive a replace
person.setName("new name");
assertEquals(2, changeTracker.count);
assertEquals(0, changeTracker.event.diff.getAddedKeys().size());
assertEquals(0, changeTracker.event.diff.getRemovedKeys().size());
assertEquals(1, changeTracker.event.diff.getChangedKeys().size());
assertSame(person, changeTracker.event.diff.getChangedKeys().iterator()
.next());
assertEquals("old name", changeTracker.event.diff.getOldValue(person));
assertEquals("new name", changeTracker.event.diff.getNewValue(person));
}
@Test
public void testMasterNull() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Make sure null values are handled gracefully.
masterMap.put(null, null);
assertEquals(1, mdom.size());
assertNull(mdom.get(null));
}
@Test
public void testDetailObservableValuesAreDisposed() {
final Map detailObservables = new HashMap();
IObservableFactory detailValueFactory = new IObservableFactory() {
@Override
public IObservable createObservable(Object target) {
WritableValue detailObservable = new WritableValue();
// Remember the created observables.
detailObservables.put(target, detailObservable);
return detailObservable;
}
};
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, detailValueFactory, null);
Object master1 = new Object();
Object master2 = new Object();
masterMap.put(master1, master1);
masterMap.put(master2, master2);
// Attach a listener in order to ensure that all detail observables are
// actually created.
MapChangeEventTracker.observe(mdom);
assertEquals(mdom.size(), detailObservables.size());
// No detail observables should be disposed yet.
assertFalse(((WritableValue) detailObservables.get(master1))
.isDisposed());
assertFalse(((WritableValue) detailObservables.get(master2))
.isDisposed());
// Only the detail observable for the removed master should be disposed.
masterMap.remove(master2);
assertFalse(((WritableValue) detailObservables.get(master1))
.isDisposed());
assertTrue(((WritableValue) detailObservables.get(master2))
.isDisposed());
// After disposing the detail map, all detail observables should be
// disposed.
mdom.dispose();
assertTrue(((WritableValue) detailObservables.get(master1))
.isDisposed());
assertTrue(((WritableValue) detailObservables.get(master2))
.isDisposed());
}
@Test
public void testDisposeOnMasterDisposed() {
WritableMap masterMap = new WritableMap();
MapDetailValueObservableMap mdom = new MapDetailValueObservableMap(
masterMap, BeansObservables.valueFactory("name"), String.class);
// Initially, nothing should be disposed.
assertFalse(masterMap.isDisposed());
assertFalse(mdom.isDisposed());
// Upon disposing the master map, the detail map should be disposed as
// well.
masterMap.dispose();
assertTrue(masterMap.isDisposed());
assertTrue(mdom.isDisposed());
}
}