LifecycleTest.java revision f6631bf618477372bca3d4accae96553af2ae1d3
147d431f63a66505a645f282416659a9758a91f1cBrett Chabot/*
247d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Copyright (C) 2016 The Android Open Source Project
347d431f63a66505a645f282416659a9758a91f1cBrett Chabot *
447d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Licensed under the Apache License, Version 2.0 (the "License");
547d431f63a66505a645f282416659a9758a91f1cBrett Chabot * you may not use this file except in compliance with the License.
647d431f63a66505a645f282416659a9758a91f1cBrett Chabot * You may obtain a copy of the License at
747d431f63a66505a645f282416659a9758a91f1cBrett Chabot *
847d431f63a66505a645f282416659a9758a91f1cBrett Chabot *      http://www.apache.org/licenses/LICENSE-2.0
947d431f63a66505a645f282416659a9758a91f1cBrett Chabot *
1047d431f63a66505a645f282416659a9758a91f1cBrett Chabot * Unless required by applicable law or agreed to in writing, software
1147d431f63a66505a645f282416659a9758a91f1cBrett Chabot * distributed under the License is distributed on an "AS IS" BASIS,
1247d431f63a66505a645f282416659a9758a91f1cBrett Chabot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1347d431f63a66505a645f282416659a9758a91f1cBrett Chabot * See the License for the specific language governing permissions and
1447d431f63a66505a645f282416659a9758a91f1cBrett Chabot * limitations under the License.
1547d431f63a66505a645f282416659a9758a91f1cBrett Chabot */
1647d431f63a66505a645f282416659a9758a91f1cBrett Chabotpackage com.android.settingslib.core.lifecycle;
1747d431f63a66505a645f282416659a9758a91f1cBrett Chabot
1847d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport android.content.Context;
1947d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport android.view.Menu;
2047d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport android.view.MenuInflater;
2147d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport android.view.MenuItem;
2247d431f63a66505a645f282416659a9758a91f1cBrett Chabot
2347d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.SettingsLibRobolectricTestRunner;
2447d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.TestConfig;
2547d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnAttach;
2647d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
2747d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnDestroy;
2847d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
2947d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnPause;
3047d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
3147d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnResume;
3247d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnStart;
3347d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport com.android.settingslib.core.lifecycle.events.OnStop;
3447d431f63a66505a645f282416659a9758a91f1cBrett Chabot
3547d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.junit.Test;
3647d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.junit.runner.RunWith;
3747d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.robolectric.Robolectric;
3847d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.robolectric.android.controller.ActivityController;
3947d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.robolectric.android.controller.FragmentController;
4047d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport org.robolectric.annotation.Config;
4147d431f63a66505a645f282416659a9758a91f1cBrett Chabot
4247d431f63a66505a645f282416659a9758a91f1cBrett Chabotimport static com.google.common.truth.Truth.assertThat;
4347d431f63a66505a645f282416659a9758a91f1cBrett Chabot
4447d431f63a66505a645f282416659a9758a91f1cBrett Chabot@RunWith(SettingsLibRobolectricTestRunner.class)
4547d431f63a66505a645f282416659a9758a91f1cBrett Chabot@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
4647d431f63a66505a645f282416659a9758a91f1cBrett Chabotpublic class LifecycleTest {
4747d431f63a66505a645f282416659a9758a91f1cBrett Chabot
4847d431f63a66505a645f282416659a9758a91f1cBrett Chabot    public static class TestDialogFragment extends ObservableDialogFragment {
4947d431f63a66505a645f282416659a9758a91f1cBrett Chabot
5047d431f63a66505a645f282416659a9758a91f1cBrett Chabot        final TestObserver mFragObserver;
5147d431f63a66505a645f282416659a9758a91f1cBrett Chabot
5247d431f63a66505a645f282416659a9758a91f1cBrett Chabot        public TestDialogFragment() {
5347d431f63a66505a645f282416659a9758a91f1cBrett Chabot            mFragObserver = new TestObserver();
5447d431f63a66505a645f282416659a9758a91f1cBrett Chabot            mLifecycle.addObserver(mFragObserver);
5547d431f63a66505a645f282416659a9758a91f1cBrett Chabot        }
5647d431f63a66505a645f282416659a9758a91f1cBrett Chabot    }
5747d431f63a66505a645f282416659a9758a91f1cBrett Chabot
5847d431f63a66505a645f282416659a9758a91f1cBrett Chabot    public static class TestFragment extends ObservableFragment {
5947d431f63a66505a645f282416659a9758a91f1cBrett Chabot
6047d431f63a66505a645f282416659a9758a91f1cBrett Chabot        final TestObserver mFragObserver;
6147d431f63a66505a645f282416659a9758a91f1cBrett Chabot
6247d431f63a66505a645f282416659a9758a91f1cBrett Chabot        public TestFragment() {
6347d431f63a66505a645f282416659a9758a91f1cBrett Chabot            mFragObserver = new TestObserver();
64            getLifecycle().addObserver(mFragObserver);
65        }
66    }
67
68    public static class TestActivity extends ObservableActivity {
69
70        final TestObserver mActObserver;
71
72        public TestActivity() {
73            mActObserver = new TestObserver();
74            getLifecycle().addObserver(mActObserver);
75        }
76
77    }
78
79    public static class TestObserver implements LifecycleObserver, OnAttach, OnStart, OnResume,
80            OnPause, OnStop, OnDestroy, OnCreateOptionsMenu, OnPrepareOptionsMenu,
81            OnOptionsItemSelected {
82
83        boolean mOnAttachObserved;
84        boolean mOnAttachHasContext;
85        boolean mOnStartObserved;
86        boolean mOnResumeObserved;
87        boolean mOnPauseObserved;
88        boolean mOnStopObserved;
89        boolean mOnDestroyObserved;
90        boolean mOnCreateOptionsMenuObserved;
91        boolean mOnPrepareOptionsMenuObserved;
92        boolean mOnOptionsItemSelectedObserved;
93
94        @Override
95        public void onAttach(Context context) {
96            mOnAttachObserved = true;
97            mOnAttachHasContext = context != null;
98        }
99
100        @Override
101        public void onStart() {
102            mOnStartObserved = true;
103        }
104
105        @Override
106        public void onPause() {
107            mOnPauseObserved = true;
108        }
109
110        @Override
111        public void onResume() {
112            mOnResumeObserved = true;
113        }
114
115        @Override
116        public void onStop() {
117            mOnStopObserved = true;
118        }
119
120        @Override
121        public void onDestroy() {
122            mOnDestroyObserved = true;
123        }
124
125        @Override
126        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
127            mOnCreateOptionsMenuObserved = true;
128        }
129
130        @Override
131        public boolean onOptionsItemSelected(MenuItem menuItem) {
132            mOnOptionsItemSelectedObserved = true;
133            return true;
134        }
135
136        @Override
137        public void onPrepareOptionsMenu(Menu menu) {
138            mOnPrepareOptionsMenuObserved = true;
139        }
140    }
141
142    @Test
143    public void runThroughActivityLifecycles_shouldObserveEverything() {
144        ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
145        TestActivity activity = ac.get();
146
147        ac.start();
148        assertThat(activity.mActObserver.mOnStartObserved).isTrue();
149        ac.resume();
150        assertThat(activity.mActObserver.mOnResumeObserved).isTrue();
151        activity.onCreateOptionsMenu(null);
152        assertThat(activity.mActObserver.mOnCreateOptionsMenuObserved).isTrue();
153        activity.onPrepareOptionsMenu(null);
154        assertThat(activity.mActObserver.mOnPrepareOptionsMenuObserved).isTrue();
155        activity.onOptionsItemSelected(null);
156        assertThat(activity.mActObserver.mOnOptionsItemSelectedObserved).isTrue();
157        ac.pause();
158        assertThat(activity.mActObserver.mOnPauseObserved).isTrue();
159        ac.stop();
160        assertThat(activity.mActObserver.mOnStopObserved).isTrue();
161        ac.destroy();
162        assertThat(activity.mActObserver.mOnDestroyObserved).isTrue();
163    }
164
165    @Test
166    public void runThroughDialogFragmentLifecycles_shouldObserveEverything() {
167        FragmentController<TestDialogFragment> fragmentController =
168                Robolectric.buildFragment(TestDialogFragment.class);
169        TestDialogFragment fragment = fragmentController.get();
170
171        fragmentController.create().start().resume();
172        fragment.onCreateOptionsMenu(null, null);
173        fragment.onPrepareOptionsMenu(null);
174        fragment.onOptionsItemSelected(null);
175        fragmentController.pause().stop().destroy();
176
177        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
178        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
179        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
180        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
181        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
182        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
183        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
184        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
185        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
186        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
187    }
188
189    @Test
190    public void runThroughFragmentLifecycles_shouldObserveEverything() {
191        FragmentController<TestFragment> fragmentController =
192                Robolectric.buildFragment(TestFragment.class);
193        TestFragment fragment = fragmentController.get();
194
195        fragmentController.create().start().resume();
196        fragment.onCreateOptionsMenu(null, null);
197        fragment.onPrepareOptionsMenu(null);
198        fragment.onOptionsItemSelected(null);
199        fragmentController.pause().stop().destroy();
200
201        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
202        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
203        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
204        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
205        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
206        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
207        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
208        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
209        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
210        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
211    }
212
213    @Test
214    public void addObserverDuringObserve_shoudNotCrash() {
215        Lifecycle lifecycle = new Lifecycle();
216        lifecycle.addObserver(new OnStartObserver(lifecycle));
217        lifecycle.onStart();
218    }
219
220    private static class OptionItemAccepter implements LifecycleObserver, OnOptionsItemSelected {
221        public boolean wasCalled = false;
222
223        @Override
224        public boolean onOptionsItemSelected(MenuItem menuItem) {
225            wasCalled = true;
226            return false;
227        }
228    }
229
230    @Test
231    public void onOptionItemSelectedShortCircuitsIfAnObserverHandlesTheMenuItem() {
232        FragmentController<TestFragment> fragmentController =
233                Robolectric.buildFragment(TestFragment.class);
234        TestFragment fragment = fragmentController.get();
235        OptionItemAccepter accepter = new OptionItemAccepter();
236        fragment.getLifecycle().addObserver(accepter);
237
238        fragmentController.create().start().resume();
239        fragment.onCreateOptionsMenu(null, null);
240        fragment.onPrepareOptionsMenu(null);
241        fragment.onOptionsItemSelected(null);
242        fragmentController.pause().stop().destroy();
243
244        assertThat(accepter.wasCalled).isFalse();
245    }
246
247    private class OnStartObserver implements LifecycleObserver, OnStart {
248
249        private final Lifecycle mLifecycle;
250
251        public OnStartObserver(Lifecycle lifecycle) {
252            mLifecycle = lifecycle;
253        }
254
255        @Override
256        public void onStart() {
257            mLifecycle.addObserver(new LifecycleObserver() {
258            });
259        }
260    }
261}
262