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 */
16
17package android.support.transition;
18
19import static org.hamcrest.CoreMatchers.is;
20import static org.hamcrest.CoreMatchers.notNullValue;
21import static org.hamcrest.MatcherAssert.assertThat;
22import static org.hamcrest.Matchers.sameInstance;
23import static org.mockito.Matchers.any;
24import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.never;
26import static org.mockito.Mockito.timeout;
27import static org.mockito.Mockito.verify;
28
29import android.support.test.annotation.UiThreadTest;
30import android.support.test.filters.MediumTest;
31import android.support.transition.test.R;
32import android.view.ViewGroup;
33
34import org.junit.Before;
35import org.junit.Test;
36
37@MediumTest
38public class TransitionManagerTest extends BaseTest {
39
40    private Scene[] mScenes = new Scene[2];
41
42    @Before
43    public void prepareScenes() {
44        TransitionActivity activity = rule.getActivity();
45        ViewGroup root = activity.getRoot();
46        mScenes[0] = Scene.getSceneForLayout(root, R.layout.support_scene0, activity);
47        mScenes[1] = Scene.getSceneForLayout(root, R.layout.support_scene1, activity);
48    }
49
50    @Test
51    public void testSetup() {
52        assertThat(mScenes[0], is(notNullValue()));
53        assertThat(mScenes[1], is(notNullValue()));
54    }
55
56    @Test
57    @UiThreadTest
58    public void testGo_enterAction() {
59        CheckCalledRunnable runnable = new CheckCalledRunnable();
60        mScenes[0].setEnterAction(runnable);
61        assertThat(runnable.wasCalled(), is(false));
62        TransitionManager.go(mScenes[0]);
63        assertThat(runnable.wasCalled(), is(true));
64    }
65
66    @Test
67    public void testGo_exitAction() throws Throwable {
68        final CheckCalledRunnable enter = new CheckCalledRunnable();
69        final CheckCalledRunnable exit = new CheckCalledRunnable();
70        mScenes[0].setEnterAction(enter);
71        mScenes[0].setExitAction(exit);
72        rule.runOnUiThread(new Runnable() {
73            @Override
74            public void run() {
75                assertThat(enter.wasCalled(), is(false));
76                assertThat(exit.wasCalled(), is(false));
77                TransitionManager.go(mScenes[0]);
78                assertThat(enter.wasCalled(), is(true));
79                assertThat(exit.wasCalled(), is(false));
80            }
81        });
82        // Let the main thread catch up with the scene change
83        rule.runOnUiThread(new Runnable() {
84            @Override
85            public void run() {
86                TransitionManager.go(mScenes[1]);
87                assertThat(exit.wasCalled(), is(true));
88            }
89        });
90    }
91
92    @Test
93    public void testGo_transitionListenerStart() throws Throwable {
94        final SyncTransitionListener listener =
95                new SyncTransitionListener(SyncTransitionListener.EVENT_START);
96        rule.runOnUiThread(new Runnable() {
97            @Override
98            public void run() {
99                Transition transition = new AutoTransition();
100                transition.setDuration(0);
101                assertThat(transition.addListener(listener), is(sameInstance(transition)));
102                TransitionManager.go(mScenes[0], transition);
103            }
104        });
105        assertThat("Timed out waiting for the TransitionListener",
106                listener.await(), is(true));
107    }
108
109    @Test
110    public void testGo_transitionListenerEnd() throws Throwable {
111        final SyncTransitionListener listener =
112                new SyncTransitionListener(SyncTransitionListener.EVENT_END);
113        rule.runOnUiThread(new Runnable() {
114            @Override
115            public void run() {
116                Transition transition = new AutoTransition();
117                transition.setDuration(0);
118                assertThat(transition.addListener(listener), is(sameInstance(transition)));
119                TransitionManager.go(mScenes[0], transition);
120            }
121        });
122        assertThat("Timed out waiting for the TransitionListener",
123                listener.await(), is(true));
124    }
125
126    @Test
127    public void testGo_nullParameter() throws Throwable {
128        final ViewGroup root = rule.getActivity().getRoot();
129        rule.runOnUiThread(new Runnable() {
130            @Override
131            public void run() {
132                TransitionManager.go(mScenes[0], null);
133                assertThat(Scene.getCurrentScene(root), is(mScenes[0]));
134                TransitionManager.go(mScenes[1], null);
135                assertThat(Scene.getCurrentScene(root), is(mScenes[1]));
136            }
137        });
138    }
139
140    @Test
141    public void testEndTransitions() throws Throwable {
142        final ViewGroup root = rule.getActivity().getRoot();
143        final Transition transition = new AutoTransition();
144        // This transition is very long, but will be forced to end as soon as it starts
145        transition.setDuration(30000);
146        final Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
147        transition.addListener(listener);
148        rule.runOnUiThread(new Runnable() {
149            @Override
150            public void run() {
151                TransitionManager.go(mScenes[0], transition);
152            }
153        });
154        verify(listener, timeout(3000)).onTransitionStart(any(Transition.class));
155        rule.runOnUiThread(new Runnable() {
156            @Override
157            public void run() {
158                TransitionManager.endTransitions(root);
159            }
160        });
161        verify(listener, timeout(3000)).onTransitionEnd(any(Transition.class));
162    }
163
164    @Test
165    public void testEndTransitionsBeforeStarted() throws Throwable {
166        final ViewGroup root = rule.getActivity().getRoot();
167        final Transition transition = new AutoTransition();
168        transition.setDuration(0);
169        final Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
170        transition.addListener(listener);
171        rule.runOnUiThread(new Runnable() {
172            @Override
173            public void run() {
174                TransitionManager.go(mScenes[0], transition);
175                // This terminates the transition before it starts
176                TransitionManager.endTransitions(root);
177            }
178        });
179        verify(listener, never()).onTransitionStart(any(Transition.class));
180        verify(listener, never()).onTransitionEnd(any(Transition.class));
181    }
182
183}
184