LifecycleRegistry extends Lifecycle { @Override public void addObserver(LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); if (previous != null) { return; } boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent; State targetState = calculateTargetState(observer); mAddingObserverCounter++; while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); targetState = calculateTargetState(observer); } if (!isReentrance) { sync(); } mAddingObserverCounter--; } LifecycleRegistry(@NonNull LifecycleOwner provider); @SuppressWarnings("WeakerAccess") void markState(State state); void handleLifecycleEvent(Lifecycle.Event event); @Override void addObserver(LifecycleObserver observer); @Override void removeObserver(LifecycleObserver observer); @SuppressWarnings("WeakerAccess") int getObserverCount(); @Override State getCurrentState();  }
@Test public void addGenericAndObserve() { GenericLifecycleObserver generic = mock(GenericLifecycleObserver.class); mRegistry.addObserver(generic); dispatchEvent(ON_CREATE); verify(generic).onStateChanged(mLifecycleOwner, ON_CREATE); reset(generic); dispatchEvent(ON_CREATE); verify(generic, never()).onStateChanged(mLifecycleOwner, ON_CREATE); }
@Test public void addRegularClass() { TestObserver testObserver = mock(TestObserver.class); mRegistry.addObserver(testObserver); dispatchEvent(ON_START); verify(testObserver, never()).onStop(); dispatchEvent(ON_STOP); verify(testObserver).onStop(); }
@Test public void constructionOrder() { fullyInitializeRegistry(); final TestObserver observer = mock(TestObserver.class); mRegistry.addObserver(observer); InOrder inOrder = inOrder(observer); inOrder.verify(observer).onCreate(); inOrder.verify(observer).onStart(); inOrder.verify(observer).onResume(); }
@Test public void constructionDestruction1() { fullyInitializeRegistry(); final TestObserver observer = spy(new TestObserver() { @Override void onStart() { dispatchEvent(ON_PAUSE); } }); mRegistry.addObserver(observer); InOrder constructionOrder = inOrder(observer); constructionOrder.verify(observer).onCreate(); constructionOrder.verify(observer).onStart(); constructionOrder.verify(observer, never()).onResume(); }
@Test public void constructionDestruction2() { fullyInitializeRegistry(); final TestObserver observer = spy(new TestObserver() { @Override void onStart() { dispatchEvent(ON_PAUSE); dispatchEvent(ON_STOP); dispatchEvent(ON_DESTROY); } }); mRegistry.addObserver(observer); InOrder orderVerifier = inOrder(observer); orderVerifier.verify(observer).onCreate(); orderVerifier.verify(observer).onStart(); orderVerifier.verify(observer).onStop(); orderVerifier.verify(observer).onDestroy(); orderVerifier.verify(observer, never()).onResume(); }
@Test public void twoObserversChangingState() { final TestObserver observer1 = spy(new TestObserver() { @Override void onCreate() { dispatchEvent(ON_START); } }); final TestObserver observer2 = mock(TestObserver.class); mRegistry.addObserver(observer1); mRegistry.addObserver(observer2); dispatchEvent(ON_CREATE); verify(observer1, times(1)).onCreate(); verify(observer2, times(1)).onCreate(); verify(observer1, times(1)).onStart(); verify(observer2, times(1)).onStart(); }
@Test public void addDuringTraversing() { final TestObserver observer3 = mock(TestObserver.class); final TestObserver observer1 = spy(new TestObserver() { @Override public void onStart() { mRegistry.addObserver(observer3); } }); final TestObserver observer2 = mock(TestObserver.class); mRegistry.addObserver(observer1); mRegistry.addObserver(observer2); dispatchEvent(ON_CREATE); dispatchEvent(ON_START); InOrder inOrder = inOrder(observer1, observer2, observer3); inOrder.verify(observer1).onCreate(); inOrder.verify(observer2).onCreate(); inOrder.verify(observer1).onStart(); inOrder.verify(observer3).onCreate(); inOrder.verify(observer2).onStart(); inOrder.verify(observer3).onStart(); }
@Test public void addDuringAddition() { final TestObserver observer3 = mock(TestObserver.class); final TestObserver observer2 = spy(new TestObserver() { @Override public void onCreate() { mRegistry.addObserver(observer3); } }); final TestObserver observer1 = spy(new TestObserver() { @Override public void onResume() { mRegistry.addObserver(observer2); } }); mRegistry.addObserver(observer1); dispatchEvent(ON_CREATE); dispatchEvent(ON_START); dispatchEvent(ON_RESUME); InOrder inOrder = inOrder(observer1, observer2, observer3); inOrder.verify(observer1).onCreate(); inOrder.verify(observer1).onStart(); inOrder.verify(observer1).onResume(); inOrder.verify(observer2).onCreate(); inOrder.verify(observer2).onStart(); inOrder.verify(observer2).onResume(); inOrder.verify(observer3).onCreate(); inOrder.verify(observer3).onStart(); inOrder.verify(observer3).onResume(); }
@Test public void subscribeToDead() { dispatchEvent(ON_CREATE); final TestObserver observer1 = mock(TestObserver.class); mRegistry.addObserver(observer1); verify(observer1).onCreate(); dispatchEvent(ON_DESTROY); verify(observer1).onDestroy(); final TestObserver observer2 = mock(TestObserver.class); mRegistry.addObserver(observer2); verify(observer2, never()).onCreate(); reset(observer1); dispatchEvent(ON_CREATE); verify(observer1).onCreate(); verify(observer2).onCreate(); }
@Test public void downEvents() { fullyInitializeRegistry(); final TestObserver observer1 = mock(TestObserver.class); final TestObserver observer2 = mock(TestObserver.class); mRegistry.addObserver(observer1); mRegistry.addObserver(observer2); InOrder orderVerifier = inOrder(observer1, observer2); dispatchEvent(ON_PAUSE); orderVerifier.verify(observer2).onPause(); orderVerifier.verify(observer1).onPause(); dispatchEvent(ON_STOP); orderVerifier.verify(observer2).onStop(); orderVerifier.verify(observer1).onStop(); dispatchEvent(ON_DESTROY); orderVerifier.verify(observer2).onDestroy(); orderVerifier.verify(observer1).onDestroy(); }
@Test public void downEventsAddition() { dispatchEvent(ON_CREATE); dispatchEvent(ON_START); final TestObserver observer1 = mock(TestObserver.class); final TestObserver observer3 = mock(TestObserver.class); final TestObserver observer2 = spy(new TestObserver() { @Override void onStop() { mRegistry.addObserver(observer3); } }); mRegistry.addObserver(observer1); mRegistry.addObserver(observer2); InOrder orderVerifier = inOrder(observer1, observer2, observer3); dispatchEvent(ON_STOP); orderVerifier.verify(observer2).onStop(); orderVerifier.verify(observer3).onCreate(); orderVerifier.verify(observer1).onStop(); dispatchEvent(ON_DESTROY); orderVerifier.verify(observer3).onDestroy(); orderVerifier.verify(observer2).onDestroy(); orderVerifier.verify(observer1).onDestroy(); }
@Test public void siblingLimitationCheck() { fullyInitializeRegistry(); final TestObserver observer2 = mock(TestObserver.class); final TestObserver observer3 = mock(TestObserver.class); final TestObserver observer1 = spy(new TestObserver() { @Override void onStart() { mRegistry.addObserver(observer2); } @Override void onResume() { mRegistry.addObserver(observer3); } }); mRegistry.addObserver(observer1); InOrder inOrder = inOrder(observer1, observer2, observer3); inOrder.verify(observer1).onCreate(); inOrder.verify(observer1).onStart(); inOrder.verify(observer2).onCreate(); inOrder.verify(observer1).onResume(); inOrder.verify(observer3).onCreate(); inOrder.verify(observer2).onStart(); inOrder.verify(observer2).onResume(); inOrder.verify(observer3).onStart(); inOrder.verify(observer3).onResume(); }