LifecycleTest.java revision ece840b115d531454d8f59533c7340ea05a4ba54
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settingslib.core.lifecycle;
17
18import static android.arch.lifecycle.Lifecycle.Event.ON_START;
19
20import static com.google.common.truth.Truth.assertThat;
21
22import android.content.Context;
23import android.view.Menu;
24import android.view.MenuInflater;
25import android.view.MenuItem;
26
27import com.android.settingslib.SettingsLibRobolectricTestRunner;
28import com.android.settingslib.TestConfig;
29import com.android.settingslib.core.lifecycle.events.OnAttach;
30import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
31import com.android.settingslib.core.lifecycle.events.OnDestroy;
32import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
33import com.android.settingslib.core.lifecycle.events.OnPause;
34import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
35import com.android.settingslib.core.lifecycle.events.OnResume;
36import com.android.settingslib.core.lifecycle.events.OnStart;
37import com.android.settingslib.core.lifecycle.events.OnStop;
38
39import org.junit.Before;
40import org.junit.Test;
41import org.junit.runner.RunWith;
42import org.robolectric.Robolectric;
43import org.robolectric.android.controller.ActivityController;
44import org.robolectric.android.controller.FragmentController;
45import org.robolectric.annotation.Config;
46
47@RunWith(SettingsLibRobolectricTestRunner.class)
48@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
49public class LifecycleTest {
50
51    private Lifecycle mLifecycle;
52
53    public static class TestDialogFragment extends ObservableDialogFragment {
54
55        final TestObserver mFragObserver;
56
57        public TestDialogFragment() {
58            mFragObserver = new TestObserver();
59            mLifecycle.addObserver(mFragObserver);
60        }
61    }
62
63    public static class TestFragment extends ObservableFragment {
64
65        final TestObserver mFragObserver;
66
67        public TestFragment() {
68            mFragObserver = new TestObserver();
69            getLifecycle().addObserver(mFragObserver);
70        }
71    }
72
73    public static class TestActivity extends ObservableActivity {
74
75        final TestObserver mActObserver;
76
77        public TestActivity() {
78            mActObserver = new TestObserver();
79            getLifecycle().addObserver(mActObserver);
80        }
81
82    }
83
84    public static class TestObserver implements LifecycleObserver, OnAttach, OnStart, OnResume,
85            OnPause, OnStop, OnDestroy, OnCreateOptionsMenu, OnPrepareOptionsMenu,
86            OnOptionsItemSelected {
87
88        boolean mOnAttachObserved;
89        boolean mOnAttachHasContext;
90        boolean mOnStartObserved;
91        boolean mOnResumeObserved;
92        boolean mOnPauseObserved;
93        boolean mOnStopObserved;
94        boolean mOnDestroyObserved;
95        boolean mOnCreateOptionsMenuObserved;
96        boolean mOnPrepareOptionsMenuObserved;
97        boolean mOnOptionsItemSelectedObserved;
98
99        @Override
100        public void onAttach(Context context) {
101            mOnAttachObserved = true;
102            mOnAttachHasContext = context != null;
103        }
104
105        @Override
106        public void onStart() {
107            mOnStartObserved = true;
108        }
109
110        @Override
111        public void onPause() {
112            mOnPauseObserved = true;
113        }
114
115        @Override
116        public void onResume() {
117            mOnResumeObserved = true;
118        }
119
120        @Override
121        public void onStop() {
122            mOnStopObserved = true;
123        }
124
125        @Override
126        public void onDestroy() {
127            mOnDestroyObserved = true;
128        }
129
130        @Override
131        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
132            mOnCreateOptionsMenuObserved = true;
133        }
134
135        @Override
136        public boolean onOptionsItemSelected(MenuItem menuItem) {
137            mOnOptionsItemSelectedObserved = true;
138            return true;
139        }
140
141        @Override
142        public void onPrepareOptionsMenu(Menu menu) {
143            mOnPrepareOptionsMenuObserved = true;
144        }
145    }
146
147    @Before
148    public void setUp() {
149        mLifecycle = new Lifecycle(() -> mLifecycle);
150    }
151
152    @Test
153    public void runThroughActivityLifecycles_shouldObserveEverything() {
154        ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
155        TestActivity activity = ac.get();
156
157        ac.start();
158        assertThat(activity.mActObserver.mOnStartObserved).isTrue();
159        ac.resume();
160        assertThat(activity.mActObserver.mOnResumeObserved).isTrue();
161        activity.onCreateOptionsMenu(null);
162        assertThat(activity.mActObserver.mOnCreateOptionsMenuObserved).isTrue();
163        activity.onPrepareOptionsMenu(null);
164        assertThat(activity.mActObserver.mOnPrepareOptionsMenuObserved).isTrue();
165        activity.onOptionsItemSelected(null);
166        assertThat(activity.mActObserver.mOnOptionsItemSelectedObserved).isTrue();
167        ac.pause();
168        assertThat(activity.mActObserver.mOnPauseObserved).isTrue();
169        ac.stop();
170        assertThat(activity.mActObserver.mOnStopObserved).isTrue();
171        ac.destroy();
172        assertThat(activity.mActObserver.mOnDestroyObserved).isTrue();
173    }
174
175    @Test
176    public void runThroughDialogFragmentLifecycles_shouldObserveEverything() {
177        FragmentController<TestDialogFragment> fragmentController =
178                Robolectric.buildFragment(TestDialogFragment.class);
179        TestDialogFragment fragment = fragmentController.get();
180
181        fragmentController.create().start().resume();
182        fragment.onCreateOptionsMenu(null, null);
183        fragment.onPrepareOptionsMenu(null);
184        fragment.onOptionsItemSelected(null);
185        fragmentController.pause().stop().destroy();
186
187        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
188        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
189        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
190        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
191        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
192        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
193        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
194        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
195        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
196        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
197    }
198
199    @Test
200    public void runThroughFragmentLifecycles_shouldObserveEverything() {
201        FragmentController<TestFragment> fragmentController =
202                Robolectric.buildFragment(TestFragment.class);
203        TestFragment fragment = fragmentController.get();
204
205        fragmentController.create().start().resume();
206        fragment.onCreateOptionsMenu(null, null);
207        fragment.onPrepareOptionsMenu(null);
208        fragment.onOptionsItemSelected(null);
209        fragmentController.pause().stop().destroy();
210
211        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
212        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
213        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
214        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
215        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
216        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
217        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
218        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
219        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
220        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
221    }
222
223    @Test
224    public void addObserverDuringObserve_shoudNotCrash() {
225        mLifecycle.addObserver(new OnStartObserver(mLifecycle));
226        mLifecycle.handleLifecycleEvent(ON_START);
227    }
228
229    private static class OptionItemAccepter implements LifecycleObserver, OnOptionsItemSelected {
230        public boolean wasCalled = false;
231
232        @Override
233        public boolean onOptionsItemSelected(MenuItem menuItem) {
234            wasCalled = true;
235            return false;
236        }
237    }
238
239    @Test
240    public void onOptionItemSelectedShortCircuitsIfAnObserverHandlesTheMenuItem() {
241        FragmentController<TestFragment> fragmentController =
242                Robolectric.buildFragment(TestFragment.class);
243        TestFragment fragment = fragmentController.get();
244        OptionItemAccepter accepter = new OptionItemAccepter();
245        fragment.getLifecycle().addObserver(accepter);
246
247        fragmentController.create().start().resume();
248        fragment.onCreateOptionsMenu(null, null);
249        fragment.onPrepareOptionsMenu(null);
250        fragment.onOptionsItemSelected(null);
251        fragmentController.pause().stop().destroy();
252
253        assertThat(accepter.wasCalled).isFalse();
254    }
255
256    private class OnStartObserver implements LifecycleObserver, OnStart {
257
258        private final Lifecycle mLifecycle;
259
260        public OnStartObserver(Lifecycle lifecycle) {
261            mLifecycle = lifecycle;
262        }
263
264        @Override
265        public void onStart() {
266            mLifecycle.addObserver(new LifecycleObserver() {
267            });
268        }
269    }
270}
271