| /******************************************************************************* |
| * 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()); |
| } |
| } |