package org.drugis.common;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.drugis.common.beans.ObserverManager;
import org.junit.Before;
import org.junit.Test;
import com.jgoodies.binding.beans.Observable;
public class ObserverManagerTest {
private ObserverManager d_om;
private Observable d_source;
private boolean d_running;
protected Throwable d_thrown;
@Before
public void setUp() {
d_source = createMock(Observable.class);
d_om = new ObserverManager(d_source);
d_running = true;
}
@Test
public void testSingleListener() {
PropertyChangeListener listener = JUnitUtil.mockStrictListener(d_source, "test", "X", "Y");
d_om.addPropertyChangeListener(listener);
d_om.firePropertyChange("test", "X", "Y");
verify(listener);
}
@Test
public void testMultipleListener() {
PropertyChangeListener listener0 = JUnitUtil.mockStrictListener(d_source, "test", "X", "Y");
d_om.addPropertyChangeListener(listener0);
PropertyChangeListener listener1 = JUnitUtil.mockStrictListener(d_source, "test", "X", "Y");
d_om.addPropertyChangeListener(listener1);
d_om.firePropertyChange("test", "X", "Y");
verify(listener0);
verify(listener1);
}
@Test
public void testRemoveListener() {
PropertyChangeListener listener = createMock(PropertyChangeListener.class);
replay(listener);
d_om.addPropertyChangeListener(listener);
d_om.removePropertyChangeListener(listener);
d_om.firePropertyChange("test", "X", "Y");
verify(listener);
}
/**
* @see http://mantis.drugis.org/view.php?id=376
*/
@Test
public void testThreadSafety() throws Throwable {
ThreadGroup group = new ThreadGroup("happy") {
@Override
public void uncaughtException(Thread t, Throwable e) {
d_thrown = e;
}
};
// Thread that adds listeners (which run for a while to trigger race condition)
Thread listen = new Thread(group, new Runnable() {
public void run() {
while(d_running) {
d_om.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
int untilImDead = 30;
try {
Thread.sleep(untilImDead);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
});
// Thread that fires events
Thread fire = new Thread(group, new Runnable() {
public void run() {
while(d_running) {
d_om.firePropertyChange("je moeder", "je vader", "je stief");
}
}
});
listen.start();
fire.start();
// Wait for things to go wrong
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
d_running = false;
// Rethrow exception (if any)
if (d_thrown != null) {
throw d_thrown;
}
}
}