| /* | 
 |  * Copyright (C) 2017 The Android Open Source Project | 
 |  * | 
 |  * 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 android.arch.lifecycle; | 
 |  | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_ANY; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_START; | 
 | import static android.arch.lifecycle.Lifecycle.Event.ON_STOP; | 
 | import static android.arch.lifecycle.Lifecycle.State.CREATED; | 
 | import static android.arch.lifecycle.Lifecycle.State.INITIALIZED; | 
 | import static android.arch.lifecycle.Lifecycle.State.RESUMED; | 
 | import static android.arch.lifecycle.Lifecycle.State.STARTED; | 
 |  | 
 | import static org.hamcrest.MatcherAssert.assertThat; | 
 | import static org.hamcrest.core.Is.is; | 
 | import static org.mockito.Mockito.mock; | 
 | import static org.mockito.Mockito.never; | 
 | import static org.mockito.Mockito.reset; | 
 | import static org.mockito.Mockito.verify; | 
 | import static org.mockito.Mockito.when; | 
 |  | 
 | import org.junit.Before; | 
 | import org.junit.Test; | 
 | import org.junit.runner.RunWith; | 
 | import org.junit.runners.JUnit4; | 
 | import org.mockito.Matchers; | 
 |  | 
 | @RunWith(JUnit4.class) | 
 | public class ReflectiveGenericLifecycleObserverTest { | 
 |     private LifecycleOwner mOwner; | 
 |     private Lifecycle mLifecycle; | 
 |  | 
 |     @Before | 
 |     public void initMocks() { | 
 |         mOwner = mock(LifecycleOwner.class); | 
 |         mLifecycle = mock(Lifecycle.class); | 
 |         when(mOwner.getLifecycle()).thenReturn(mLifecycle); | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void anyState() { | 
 |         AnyStateListener obj = mock(AnyStateListener.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         when(mLifecycle.getCurrentState()).thenReturn(STARTED); | 
 |         observer.onStateChanged(mOwner, ON_CREATE); | 
 |         verify(obj).onAnyState(mOwner, ON_CREATE); | 
 |         reset(obj); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_START); | 
 |         verify(obj).onAnyState(mOwner, ON_START); | 
 |         reset(obj); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_RESUME); | 
 |         verify(obj).onAnyState(mOwner, ON_RESUME); | 
 |         reset(obj); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_PAUSE); | 
 |         verify(obj).onAnyState(mOwner, ON_PAUSE); | 
 |         reset(obj); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_STOP); | 
 |         verify(obj).onAnyState(mOwner, ON_STOP); | 
 |         reset(obj); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_DESTROY); | 
 |         verify(obj).onAnyState(mOwner, ON_DESTROY); | 
 |         reset(obj); | 
 |     } | 
 |  | 
 |     private static class AnyStateListener implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_ANY) | 
 |         void onAnyState(LifecycleOwner owner, Lifecycle.Event event) { | 
 |  | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void singleMethod() { | 
 |         CreatedStateListener obj = mock(CreatedStateListener.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         when(mLifecycle.getCurrentState()).thenReturn(CREATED); | 
 |         observer.onStateChanged(mOwner, ON_CREATE); | 
 |         verify(obj).onCreated(); | 
 |         verify(obj).onCreated(mOwner); | 
 |     } | 
 |  | 
 |     private static class CreatedStateListener implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_CREATE) | 
 |         void onCreated() { | 
 |  | 
 |         } | 
 |         @SuppressWarnings("UnusedParameters") | 
 |         @OnLifecycleEvent(ON_CREATE) | 
 |         void onCreated(LifecycleOwner provider) { | 
 |  | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void eachEvent() { | 
 |         AllMethodsListener obj = mock(AllMethodsListener.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         when(mLifecycle.getCurrentState()).thenReturn(CREATED); | 
 |  | 
 |         observer.onStateChanged(mOwner, ON_CREATE); | 
 |         verify(obj).created(); | 
 |         reset(obj); | 
 |  | 
 |         when(mLifecycle.getCurrentState()).thenReturn(STARTED); | 
 |         observer.onStateChanged(mOwner, ON_START); | 
 |         verify(obj).started(); | 
 |         reset(obj); | 
 |  | 
 |         when(mLifecycle.getCurrentState()).thenReturn(RESUMED); | 
 |         observer.onStateChanged(mOwner, ON_RESUME); | 
 |         verify(obj).resumed(); | 
 |         reset(obj); | 
 |  | 
 |         when(mLifecycle.getCurrentState()).thenReturn(STARTED); | 
 |         observer.onStateChanged(mOwner, ON_PAUSE); | 
 |         verify(obj).paused(); | 
 |         reset(obj); | 
 |  | 
 |         when(mLifecycle.getCurrentState()).thenReturn(CREATED); | 
 |         observer.onStateChanged(mOwner, ON_STOP); | 
 |         verify(obj).stopped(); | 
 |         reset(obj); | 
 |  | 
 |         when(mLifecycle.getCurrentState()).thenReturn(INITIALIZED); | 
 |         observer.onStateChanged(mOwner, ON_DESTROY); | 
 |         verify(obj).destroyed(); | 
 |         reset(obj); | 
 |     } | 
 |  | 
 |  | 
 |     private static class AllMethodsListener implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_CREATE) | 
 |         void created() {} | 
 |  | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void started() {} | 
 |  | 
 |         @OnLifecycleEvent(ON_RESUME) | 
 |         void resumed() {} | 
 |  | 
 |         @OnLifecycleEvent(ON_PAUSE) | 
 |         void paused() {} | 
 |  | 
 |         @OnLifecycleEvent(ON_STOP) | 
 |         void stopped() {} | 
 |  | 
 |         @OnLifecycleEvent(ON_DESTROY) | 
 |         void destroyed() { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void testFailingObserver() { | 
 |         class UnprecedentedError extends Error { | 
 |         } | 
 |  | 
 |         LifecycleObserver obj = new LifecycleObserver() { | 
 |             @OnLifecycleEvent(ON_START) | 
 |             void started() { | 
 |                 throw new UnprecedentedError(); | 
 |             } | 
 |         }; | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         try { | 
 |             observer.onStateChanged(mOwner, ON_START); | 
 |         } catch (Exception e) { | 
 |             assertThat("exception cause is wrong", | 
 |                     e.getCause() instanceof UnprecedentedError); | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void testPrivateObserverMethods() { | 
 |         class ObserverWithPrivateMethod implements LifecycleObserver { | 
 |             boolean mCalled = false; | 
 |             @OnLifecycleEvent(ON_START) | 
 |             private void started() { | 
 |                 mCalled = true; | 
 |             } | 
 |         } | 
 |  | 
 |         ObserverWithPrivateMethod obj = mock(ObserverWithPrivateMethod.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         observer.onStateChanged(mOwner, ON_START); | 
 |         assertThat(obj.mCalled, is(true)); | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testWrongFirstParam1() { | 
 |         LifecycleObserver observer = new LifecycleObserver() { | 
 |             @OnLifecycleEvent(ON_START) | 
 |             private void started(Lifecycle.Event e) { | 
 |             } | 
 |         }; | 
 |         new ReflectiveGenericLifecycleObserver(observer); | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testWrongFirstParam2() { | 
 |         LifecycleObserver observer = new LifecycleObserver() { | 
 |             @OnLifecycleEvent(ON_ANY) | 
 |             private void started(Lifecycle l, Lifecycle.Event e) { | 
 |             } | 
 |         }; | 
 |         new ReflectiveGenericLifecycleObserver(observer); | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testWrongSecondParam() { | 
 |         LifecycleObserver observer = new LifecycleObserver() { | 
 |             @OnLifecycleEvent(ON_START) | 
 |             private void started(LifecycleOwner owner, Lifecycle l) { | 
 |             } | 
 |         }; | 
 |         new ReflectiveGenericLifecycleObserver(observer); | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testThreeParams() { | 
 |         LifecycleObserver observer = new LifecycleObserver() { | 
 |             @OnLifecycleEvent(ON_ANY) | 
 |             private void started(LifecycleOwner owner, Lifecycle.Event e, int i) { | 
 |             } | 
 |         }; | 
 |         new ReflectiveGenericLifecycleObserver(observer); | 
 |     } | 
 |  | 
 |     class BaseClass1 implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     class DerivedClass1 extends BaseClass1 { | 
 |         @OnLifecycleEvent(ON_STOP) | 
 |         void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testInvalidSuper1() { | 
 |         new ReflectiveGenericLifecycleObserver(new DerivedClass1()); | 
 |     } | 
 |  | 
 |     class BaseClass2 implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     class DerivedClass2 extends BaseClass1 { | 
 |         @OnLifecycleEvent(ON_STOP) | 
 |         void foo() { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void testValidSuper1() { | 
 |         DerivedClass2 obj = mock(DerivedClass2.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         observer.onStateChanged(mock(LifecycleOwner.class), ON_START); | 
 |         verify(obj).foo(Matchers.<LifecycleOwner>any()); | 
 |         verify(obj, never()).foo(); | 
 |         reset(obj); | 
 |         observer.onStateChanged(mock(LifecycleOwner.class), ON_STOP); | 
 |         verify(obj).foo(); | 
 |         verify(obj, never()).foo(Matchers.<LifecycleOwner>any()); | 
 |     } | 
 |  | 
 |     class BaseClass3 implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     interface Interface3 extends LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_STOP) | 
 |         void foo(LifecycleOwner owner); | 
 |     } | 
 |  | 
 |     class DerivedClass3 extends BaseClass3 implements Interface3 { | 
 |         @Override | 
 |         public void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testInvalidSuper2() { | 
 |         new ReflectiveGenericLifecycleObserver(new DerivedClass3()); | 
 |     } | 
 |  | 
 |     class BaseClass4 implements LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     interface Interface4 extends LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner); | 
 |     } | 
 |  | 
 |     class DerivedClass4 extends BaseClass4 implements Interface4 { | 
 |         @Override | 
 |         @OnLifecycleEvent(ON_START) | 
 |         public void foo(LifecycleOwner owner) { | 
 |         } | 
 |  | 
 |         @OnLifecycleEvent(ON_START) | 
 |         public void foo() { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test | 
 |     public void testValidSuper2() { | 
 |         DerivedClass4 obj = mock(DerivedClass4.class); | 
 |         ReflectiveGenericLifecycleObserver observer = new ReflectiveGenericLifecycleObserver(obj); | 
 |         observer.onStateChanged(mock(LifecycleOwner.class), ON_START); | 
 |         verify(obj).foo(Matchers.<LifecycleOwner>any()); | 
 |         verify(obj).foo(); | 
 |     } | 
 |  | 
 |     interface InterfaceStart extends LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_START) | 
 |         void foo(LifecycleOwner owner); | 
 |     } | 
 |  | 
 |     interface InterfaceStop extends LifecycleObserver { | 
 |         @OnLifecycleEvent(ON_STOP) | 
 |         void foo(LifecycleOwner owner); | 
 |     } | 
 |  | 
 |     class DerivedClass5 implements InterfaceStart, InterfaceStop { | 
 |         @Override | 
 |         public void foo(LifecycleOwner owner) { | 
 |         } | 
 |     } | 
 |  | 
 |     @Test(expected = IllegalArgumentException.class) | 
 |     public void testInvalidSuper3() { | 
 |         new ReflectiveGenericLifecycleObserver(new DerivedClass5()); | 
 |     } | 
 | } |