/**
* Copyright 2009 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 org.waveprotocol.wave.model.conversation;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import junit.framework.TestCase;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.SimpleMap;
import org.waveprotocol.wave.model.wave.ObservableMapImpl;
import java.util.Collection;
/**
* Tests for the {@link AnchorManager}.
*
*/
public final class AnchorManagerTest extends TestCase {
private Object parasite;
private Object[] parasites;
private SimpleMap<String, Integer> items;
private AnchorManager<String, Integer, Object> target;
@Override
protected void setUp() throws Exception {
parasite = new Object();
parasites = new Object[3];
for (int i = 0; i < parasites.length; i++) {
parasites[i] = new Object();
}
ObservableMapImpl<String, Integer> map = ObservableMapImpl.create();
items = map;
target = AnchorManager.<String, Integer, Object> create(map);
}
/**
* Creates a collection of the same implementation type as created by
* AnchorManager, in order to get .equals() to work.
*
* @param xs elements for the collection
* @return a collection describing {@code xs}.
*/
private static <T> Collection<T> collection(T... xs) {
return CollectionUtils.newHashSet(xs);
}
private static <T> Collection<T> collection(Collection<T> xs) {
return CollectionUtils.newHashSet(xs);
}
public void testAddItemThenSingleParasiteMakesAttached() {
items.put("a", 1);
target.attachParasite("a", parasite);
assertEquals(collection(parasite), target.getAttached().get(1));
}
public void testAddItemThenManyParasitesMakesAttached() {
items.put("a", 1);
for (Object parasite : parasites) {
target.attachParasite("a", parasite);
}
assertEquals(collection(parasites), target.getAttached().get(1));
}
public void testAddSingleParasiteThenItemMakesAttached() {
target.attachParasite("a", parasite);
items.put("a", 1);
assertEquals(collection(parasite), target.getAttached().get(1));
}
public void testAddManyParasitesThenItemMakesAttached() {
for (Object parasite : parasites) {
target.attachParasite("a", parasite);
}
items.put("a", 1);
assertEquals(collection(parasites), target.getAttached().get(1));
}
public void testAddNoItemParasiteMakesUnattached() {
target.attachParasite("a", parasite);
assertEquals(collection(parasite), collection(target.getUnattached()));
}
public void testAddNoLocationParasiteMakesUnattached() {
target.attachParasite(null, parasite);
assertEquals(collection(parasite), collection(target.getUnattached()));
}
public void testAddManyNoItemParasitesMakesUnattached() {
for (Object parasite : parasites) {
target.attachParasite("a", parasite);
}
assertEquals(collection(parasites), collection(target.getUnattached()));
}
public void testAddManyNoLocationParasitesMakesUnattached() {
for (Object parasite : parasites) {
target.attachParasite(null, parasite);
}
assertEquals(collection(parasites), collection(target.getUnattached()));
}
public void testRemoveItemDetaches() {
items.put("a", 1);
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
items.remove("a");
assertEquals(null, target.getAttached().get(1));
assertEquals(collection(parasites), // \u2620
CollectionUtils.newHashSet(target.getUnattached()));
}
public void testRemoveParasitesRemovesAttached() {
items.put("a", 1);
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
items.remove("a");
assertEquals(null, target.getAttached().get(1));
assertEquals(collection(parasites), // \u2620
CollectionUtils.newHashSet(target.getUnattached()));
}
//
// Events.
//
/**
* Creates and attaches a mock listener.
*/
@SuppressWarnings("unchecked") // Mocking a generic
private AnchorManager.Listener<Integer, Object> mockListener() {
AnchorManager.Listener<Integer, Object> l = mock(AnchorManager.Listener.class);
target.addListener(l);
return l;
}
public void testAddItemThenSingleParasiteBroadcastsAttachEvents() {
AnchorManager.Listener<Integer, Object> listener = mockListener();
items.put("a", 1);
target.attachParasite("a", parasite);
verify(listener).onAttached(1, collection(parasite));
verifyNoMoreInteractions(listener);
}
public void testAddParasiteThenItemBroadcastsAttachDetachAttachEvents() {
AnchorManager.Listener<Integer, Object> listener = mockListener();
target.attachParasite("a", parasite);
items.put("a", 1);
verify(listener).onAttached(null, collection(parasite));
verify(listener).onDetached(null, collection(parasite));
verify(listener).onAttached(1, collection(parasite));
verifyNoMoreInteractions(listener);
}
public void testAddParasiteThenOtherItemBroadcastsAttachEvents() {
AnchorManager.Listener<Integer, Object> listener = mockListener();
target.attachParasite("a", parasite);
items.put("b", 1);
verify(listener).onAttached(null, collection(parasite));
verifyNoMoreInteractions(listener);
}
public void testRemoveAttachedParasiteBroadcastsDetachEvents() {
// Establish attached state first.
target.attachParasite("a", parasite);
items.put("a", 1);
AnchorManager.Listener<Integer, Object> listener = mockListener();
target.detachParasite("a", parasite);
verify(listener).onDetached(1, collection(parasite));
verifyNoMoreInteractions(listener);
}
public void testRemoveItemBroadcastsDetachAttachEvents() {
// Establish attached state first.
target.attachParasite("a", parasite);
items.put("a", 1);
AnchorManager.Listener<Integer, Object> listener = mockListener();
items.remove("a");
verify(listener).onDetached(1, collection(parasite));
verify(listener).onAttached(null, collection(parasite));
verifyNoMoreInteractions(listener);
}
public void testAddItemThenManyParasitesBroadcastsAttachEvents() {
AnchorManager.Listener<Integer, Object> listener = mockListener();
items.put("a", 1);
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
verify(listener).onAttached(1, collection(parasites[0]));
verify(listener).onAttached(1, collection(parasites[1]));
verify(listener).onAttached(null, collection(parasites[2]));
verifyNoMoreInteractions(listener);
}
public void testAddManyParasitesThenItemBroadcastsAttachEvents() {
AnchorManager.Listener<Integer, Object> listener = mockListener();
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
items.put("a", 1);
verify(listener).onAttached(null, collection(parasites[0]));
verify(listener).onAttached(null, collection(parasites[1]));
verify(listener).onAttached(null, collection(parasites[2]));
verify(listener).onDetached(null, collection(parasites[0], parasites[1]));
verify(listener).onAttached(1, collection(parasites[0], parasites[1]));
verifyNoMoreInteractions(listener);
}
public void testRemoveItemFromMultiAttachedStateBroadcastsDetachAttachEvents() {
// Establish attached state before adding listener.
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
items.put("a", 1);
AnchorManager.Listener<Integer, Object> listener = mockListener();
items.remove("a");
verify(listener).onDetached(1, collection(parasites[0], parasites[1]));
verify(listener).onAttached(null, collection(parasites[0], parasites[1]));
verifyNoMoreInteractions(listener);
}
public void testRemoveParasiteFromMultiAttachedStateBroadcastsDetachEvents() {
// Establish attached state before adding listener.
target.attachParasite("a", parasites[0]);
target.attachParasite("a", parasites[1]);
target.attachParasite("b", parasites[2]);
items.put("a", 1);
AnchorManager.Listener<Integer, Object> listener = mockListener();
target.detachParasite("a", parasites[0]);
verify(listener).onDetached(1, collection(parasites[0]));
verifyNoMoreInteractions(listener);
}
}