|
|
@@ -0,0 +1,144 @@
|
|
|
+package org.leumasjaffe.observer;
|
|
|
+
|
|
|
+import static org.junit.jupiter.api.Assertions.*;
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
+
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.junit.jupiter.api.extension.ExtendWith;
|
|
|
+import org.mockito.Mock;
|
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
+
|
|
|
+@ExtendWith(MockitoExtension.class)
|
|
|
+class IndirectObservableListenerTest {
|
|
|
+
|
|
|
+ @Mock MockObserverUpdate update;
|
|
|
+ IndirectObservableListener<Void, Object> listener;
|
|
|
+
|
|
|
+ @BeforeEach
|
|
|
+ void setUp() {
|
|
|
+ listener = new IndirectObservableListener<>(null, update);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCannotObserveNull() {
|
|
|
+ assertThrows(NullPointerException.class,
|
|
|
+ () -> listener.setObserved(null));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCanObserveZeroObjects() {
|
|
|
+ assertDoesNotThrow(() -> listener.setObserved(new Object()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCanObserveMultipleObjects() {
|
|
|
+ final Observable.Instance[] objects = {
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ };
|
|
|
+ assertDoesNotThrow(() -> listener.setObserved(new Object(), objects));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCanObserveCollectionOfObjects() {
|
|
|
+ final List<Observable.Instance> objects = Arrays.asList(
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ );
|
|
|
+ assertDoesNotThrow(() -> listener.setObserved(new Object(), objects));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testSettingObservationTriggersUpdate() {
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj);
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testChangingObservationTriggersUpdate() {
|
|
|
+ final Object obj = new Object();
|
|
|
+ final Object next = new Object();
|
|
|
+ listener.setObserved(obj);
|
|
|
+ listener.setObserved(next);
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(next));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testReApplyingObservationDoesNotUpdate() {
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj);
|
|
|
+ listener.setObserved(obj);
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testNotifyFromObservedObjectWillTriggerUpdate() {
|
|
|
+ final Observable.Instance[] objects = {
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ };
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj, objects);
|
|
|
+
|
|
|
+ ObserverDispatch.notifySubscribers(objects[0]);
|
|
|
+ ObserverDispatch.notifySubscribers(objects[1]);
|
|
|
+ verify(update, times(3)).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testOverwritesNotifyListOnUpdate() {
|
|
|
+ final Observable.Instance[] objects = {
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ };
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj, objects);
|
|
|
+ listener.setObserved(obj);
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ ObserverDispatch.notifySubscribers(objects[0]);
|
|
|
+ ObserverDispatch.notifySubscribers(objects[1]);
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testDeployingNotifyFromListenerDoesNotUpdate() {
|
|
|
+ final Observable.Instance[] objects = {
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ };
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj, objects);
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ listener.notifySubscribers(objects[0]);
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCannotRecursivelyUpdate() {
|
|
|
+ final Observable.Instance[] objects = {
|
|
|
+ new Observable.Instance(),
|
|
|
+ new Observable.Instance()
|
|
|
+ };
|
|
|
+ final Object obj = new Object();
|
|
|
+ listener.setObserved(obj, objects);
|
|
|
+
|
|
|
+ doAnswer(inv -> {
|
|
|
+ ObserverDispatch.notifySubscribers(objects[0]);
|
|
|
+ return null;
|
|
|
+ }).when(update).accept(any(), any());
|
|
|
+
|
|
|
+ verify(update).accept(isNull(), same(obj));
|
|
|
+ ObserverDispatch.notifySubscribers(objects[0]);
|
|
|
+ verify(update, times(2)).accept(isNull(), same(obj));
|
|
|
+ }
|
|
|
+}
|