Bug 184817 [DataBinding] WritableMap.put(...) fires an incorrect event
The event for WritableMap.put(...) when the key already exists reverses the new and old values in the change event. The following test will fail on the old value as it will be the new value. public void testPutWithExistingKeyMapChangeEvent() throws Exception { WritableMap map = new WritableMap(); String key = "key"; String value = "value"; map.put(key, value); MapChangeEventTracker listener = new MapChangeEventTracker(); map.addMapChangeListener(listener); assertEquals(0, listener.count); String newValue = "new value"; map.put(key, newValue); assertEquals(1, listener.count); MapChangeEvent event = listener.event; Set changedKeys = event.diff.getChangedKeys(); assertEquals(1, changedKeys.size()); assertTrue(changedKeys.contains(key)); assertEquals(value, event.diff.getOldValue(key)); //<<<FAILS assertEquals(newValue, event.diff.getNewValue(key)); }
bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/map/WritableMap.java
/**
	 * Clears the map.  Must be invoked from the current realm.
	 */
	public void clear() {
		checkRealm();
		Map copy = new HashMap(wrappedMap.size());
		copy.putAll(wrappedMap);
		wrappedMap.clear();
		fireMapChange(Diffs.createMapDiffRemoveAll(copy));
	}
	/**
	 * Adds the provided <code>map</code>'s contents to this map.  Must be invoked from the current realm.
	 */
	public void putAll(Map map) {
		checkRealm();
		Set addedKeys = new HashSet(map.size());
		Map changes = new HashMap(map.size());
		for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Entry) it.next();
			Object previousValue = wrappedMap.put(entry.getKey(), entry.getValue());
			if (previousValue==null) {
				addedKeys.add(entry.getKey());
			} else {
				changes.put(entry.getKey(), previousValue);
			}
		}
		fireMapChange(Diffs.createMapDiff(addedKeys, Collections.EMPTY_SET, changes.keySet(), changes, wrappedMap));
	}
}