/** * 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 org.waveprotocol.wave.model.adt; import junit.framework.TestCase; import org.waveprotocol.wave.model.util.CollectionUtils; import java.util.Set; /** * Base class defining common tests for the {@link ObservableBasicSet} class. * */ public abstract class ObservableBasicSetTestBase extends TestCase { /** A set listener that exposes the values it hears. */ static class Listener implements ObservableBasicSet.Listener<String> { int addCount = 0; String lastValue = null; int removeCount = 0; Listener() { } /** Checks just the number of calls to the listener. */ void check(int addCount, int removeCount) { assertEquals(addCount, this.addCount); assertEquals(removeCount, this.removeCount); } /** Checks all stored values. */ void check(int addCount, int removeCount, String lastValue) { check(addCount, removeCount); assertEquals(lastValue, this.lastValue); } @Override public void onValueAdded(String newValue) { lastValue = newValue; addCount++; } @Override public void onValueRemoved(String oldValue) { lastValue = oldValue; removeCount++; } } /** * Makes a HashSet from the given iterable. Checks that any item is only * present once. */ private static Set<String> makeHashSet(BasicSet<String> basicSet) { Set<String> result = CollectionUtils.newHashSet(); for (String s : basicSet.getValues()) { if (result.contains(s)) { fail("Value " + s + " already present in set"); } result.add(s); } return result; } /** The set on which tests are being run. */ protected ObservableBasicSet<String> set; /** Constructor. */ public ObservableBasicSetTestBase() { } @Override protected void setUp() throws Exception { super.setUp(); createEmptyMap(); } /** * Creates the ObservableBasicSet instance on which to run the tests specified * in this class. This method is called by {@link #setUp()} and should set the * {@link #set} variable. */ abstract protected void createEmptyMap(); /** Tests simple add and remove functionality. */ public void testAddRemoveContains() { assertTrue(makeHashSet(set).isEmpty()); set.add("A"); set.add("B"); set.add("C"); assertEquals(CollectionUtils.immutableSet("A", "B", "C"), makeHashSet(set)); assertTrue(set.contains("B")); assertFalse(set.contains("D")); set.add("B"); assertEquals(CollectionUtils.immutableSet("A", "B", "C"), makeHashSet(set)); set.remove("B"); assertEquals(CollectionUtils.immutableSet("A", "C"), makeHashSet(set)); assertFalse(set.contains("B")); set.remove("C"); set.remove("A"); assertTrue(makeHashSet(set).isEmpty()); } /** Tests the clear method. */ public void testClear() { Listener listener = new Listener(); set.addListener(listener); set.add("A"); set.add("B"); set.add("C"); assertEquals(CollectionUtils.immutableSet("A", "B", "C"), makeHashSet(set)); listener.check(3, 0); set.clear(); assertTrue(makeHashSet(set).isEmpty()); listener.check(3, 3); } /** Tests Listeners. */ public void testEvents() { Listener listener1 = new Listener(); Listener listener2 = new Listener(); set.addListener(listener1); listener1.check(0, 0); set.add("A"); listener1.check(1, 0, "A"); set.add("B"); listener1.check(2, 0, "B"); set.add("A"); listener1.check(2, 0); set.remove("A"); listener1.check(2, 1, "A"); set.addListener(listener2); listener2.check(0, 0); set.add("B"); listener1.check(2, 1); listener2.check(0, 0); set.add("C"); listener1.check(3, 1, "C"); listener2.check(1, 0, "C"); set.add("A"); listener1.check(4, 1, "A"); listener2.check(2, 0, "A"); set.removeListener(listener1); set.remove("A"); listener1.check(4, 1); listener2.check(2, 1, "A"); set.add("D"); listener1.check(4, 1); listener2.check(3, 1, "D"); } }