1/*
2 * Copyright (C) 2017 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.junit.Assert.assertEquals;
20import static org.junit.Assert.assertTrue;
21import static org.mockito.Matchers.any;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.timeout;
25import static org.mockito.Mockito.verify;
26
27import android.support.test.InstrumentationRegistry;
28import android.support.test.filters.LargeTest;
29import android.support.test.filters.MediumTest;
30import android.support.transition.test.R;
31import android.view.Gravity;
32import android.view.View;
33import android.view.ViewGroup;
34
35import org.junit.Test;
36
37@MediumTest
38public class SlideEdgeTest extends BaseTransitionTest {
39
40    private static final Object[][] sSlideEdgeArray = {
41            {Gravity.START, "START"},
42            {Gravity.END, "END"},
43            {Gravity.LEFT, "LEFT"},
44            {Gravity.TOP, "TOP"},
45            {Gravity.RIGHT, "RIGHT"},
46            {Gravity.BOTTOM, "BOTTOM"},
47    };
48
49    @Test
50    public void testSetSide() throws Throwable {
51        for (int i = 0; i < sSlideEdgeArray.length; i++) {
52            int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
53            String edgeName = (String) (sSlideEdgeArray[i][1]);
54            Slide slide = new Slide(slideEdge);
55            assertEquals("Edge not set properly in constructor " + edgeName,
56                    slideEdge, slide.getSlideEdge());
57
58            slide = new Slide();
59            slide.setSlideEdge(slideEdge);
60            assertEquals("Edge not set properly with setter " + edgeName,
61                    slideEdge, slide.getSlideEdge());
62        }
63    }
64
65    @LargeTest
66    @Test
67    public void testSlideOut() throws Throwable {
68        for (int i = 0; i < sSlideEdgeArray.length; i++) {
69            final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
70            final Slide slide = new Slide(slideEdge);
71            final Transition.TransitionListener listener =
72                    mock(Transition.TransitionListener.class);
73            slide.addListener(listener);
74
75            rule.runOnUiThread(new Runnable() {
76                @Override
77                public void run() {
78                    rule.getActivity().setContentView(R.layout.scene1);
79                }
80            });
81            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
82
83            final View redSquare = rule.getActivity().findViewById(R.id.redSquare);
84            final View greenSquare = rule.getActivity().findViewById(R.id.greenSquare);
85            final View hello = rule.getActivity().findViewById(R.id.hello);
86            final ViewGroup sceneRoot = (ViewGroup) rule.getActivity().findViewById(R.id.holder);
87
88            rule.runOnUiThread(new Runnable() {
89                @Override
90                public void run() {
91                    TransitionManager.beginDelayedTransition(sceneRoot, slide);
92                    redSquare.setVisibility(View.INVISIBLE);
93                    greenSquare.setVisibility(View.INVISIBLE);
94                    hello.setVisibility(View.INVISIBLE);
95                }
96            });
97            verify(listener, timeout(1000)).onTransitionStart(any(Transition.class));
98            verify(listener, never()).onTransitionEnd(any(Transition.class));
99            assertEquals(View.VISIBLE, redSquare.getVisibility());
100            assertEquals(View.VISIBLE, greenSquare.getVisibility());
101            assertEquals(View.VISIBLE, hello.getVisibility());
102
103            float redStartX = redSquare.getTranslationX();
104            float redStartY = redSquare.getTranslationY();
105
106            Thread.sleep(200);
107            verifyTranslation(slideEdge, redSquare);
108            verifyTranslation(slideEdge, greenSquare);
109            verifyTranslation(slideEdge, hello);
110
111            final float redMidX = redSquare.getTranslationX();
112            final float redMidY = redSquare.getTranslationY();
113
114            switch (slideEdge) {
115                case Gravity.LEFT:
116                case Gravity.START:
117                    assertTrue(
118                            "isn't sliding out to left. Expecting " + redStartX + " > " + redMidX,
119                            redStartX > redMidX);
120                    break;
121                case Gravity.RIGHT:
122                case Gravity.END:
123                    assertTrue(
124                            "isn't sliding out to right. Expecting " + redStartX + " < " + redMidX,
125                            redStartX < redMidX);
126                    break;
127                case Gravity.TOP:
128                    assertTrue("isn't sliding out to top. Expecting " + redStartY + " > " + redMidY,
129                            redStartY > redSquare.getTranslationY());
130                    break;
131                case Gravity.BOTTOM:
132                    assertTrue(
133                            "isn't sliding out to bottom. Expecting " + redStartY + " < " + redMidY,
134                            redStartY < redSquare.getTranslationY());
135                    break;
136            }
137            verify(listener, timeout(1000)).onTransitionEnd(any(Transition.class));
138            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
139
140            verifyNoTranslation(redSquare);
141            verifyNoTranslation(greenSquare);
142            verifyNoTranslation(hello);
143            assertEquals(View.INVISIBLE, redSquare.getVisibility());
144            assertEquals(View.INVISIBLE, greenSquare.getVisibility());
145            assertEquals(View.INVISIBLE, hello.getVisibility());
146        }
147    }
148
149    @LargeTest
150    @Test
151    public void testSlideIn() throws Throwable {
152        for (int i = 0; i < sSlideEdgeArray.length; i++) {
153            final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
154            final Slide slide = new Slide(slideEdge);
155            final Transition.TransitionListener listener =
156                    mock(Transition.TransitionListener.class);
157            slide.addListener(listener);
158
159            rule.runOnUiThread(new Runnable() {
160                @Override
161                public void run() {
162                    rule.getActivity().setContentView(R.layout.scene1);
163                }
164            });
165            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
166
167            final View redSquare = rule.getActivity().findViewById(R.id.redSquare);
168            final View greenSquare = rule.getActivity().findViewById(R.id.greenSquare);
169            final View hello = rule.getActivity().findViewById(R.id.hello);
170            final ViewGroup sceneRoot = (ViewGroup) rule.getActivity().findViewById(R.id.holder);
171
172            rule.runOnUiThread(new Runnable() {
173                @Override
174                public void run() {
175                    redSquare.setVisibility(View.INVISIBLE);
176                    greenSquare.setVisibility(View.INVISIBLE);
177                    hello.setVisibility(View.INVISIBLE);
178                }
179            });
180            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
181
182            // now slide in
183            rule.runOnUiThread(new Runnable() {
184                @Override
185                public void run() {
186                    TransitionManager.beginDelayedTransition(sceneRoot, slide);
187                    redSquare.setVisibility(View.VISIBLE);
188                    greenSquare.setVisibility(View.VISIBLE);
189                    hello.setVisibility(View.VISIBLE);
190                }
191            });
192            verify(listener, timeout(1000)).onTransitionStart(any(Transition.class));
193
194            verify(listener, never()).onTransitionEnd(any(Transition.class));
195            assertEquals(View.VISIBLE, redSquare.getVisibility());
196            assertEquals(View.VISIBLE, greenSquare.getVisibility());
197            assertEquals(View.VISIBLE, hello.getVisibility());
198
199            final float redStartX = redSquare.getTranslationX();
200            final float redStartY = redSquare.getTranslationY();
201
202            Thread.sleep(200);
203            verifyTranslation(slideEdge, redSquare);
204            verifyTranslation(slideEdge, greenSquare);
205            verifyTranslation(slideEdge, hello);
206            final float redMidX = redSquare.getTranslationX();
207            final float redMidY = redSquare.getTranslationY();
208
209            switch (slideEdge) {
210                case Gravity.LEFT:
211                case Gravity.START:
212                    assertTrue(
213                            "isn't sliding in from left. Expecting " + redStartX + " < " + redMidX,
214                            redStartX < redMidX);
215                    break;
216                case Gravity.RIGHT:
217                case Gravity.END:
218                    assertTrue(
219                            "isn't sliding in from right. Expecting " + redStartX + " > " + redMidX,
220                            redStartX > redMidX);
221                    break;
222                case Gravity.TOP:
223                    assertTrue(
224                            "isn't sliding in from top. Expecting " + redStartY + " < " + redMidY,
225                            redStartY < redSquare.getTranslationY());
226                    break;
227                case Gravity.BOTTOM:
228                    assertTrue("isn't sliding in from bottom. Expecting " + redStartY + " > "
229                                    + redMidY,
230                            redStartY > redSquare.getTranslationY());
231                    break;
232            }
233            verify(listener, timeout(1000)).onTransitionEnd(any(Transition.class));
234            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
235
236            verifyNoTranslation(redSquare);
237            verifyNoTranslation(greenSquare);
238            verifyNoTranslation(hello);
239            assertEquals(View.VISIBLE, redSquare.getVisibility());
240            assertEquals(View.VISIBLE, greenSquare.getVisibility());
241            assertEquals(View.VISIBLE, hello.getVisibility());
242        }
243    }
244
245    private void verifyTranslation(int slideEdge, View view) {
246        switch (slideEdge) {
247            case Gravity.LEFT:
248            case Gravity.START:
249                assertTrue(view.getTranslationX() < 0);
250                assertEquals(0f, view.getTranslationY(), 0.01f);
251                break;
252            case Gravity.RIGHT:
253            case Gravity.END:
254                assertTrue(view.getTranslationX() > 0);
255                assertEquals(0f, view.getTranslationY(), 0.01f);
256                break;
257            case Gravity.TOP:
258                assertTrue(view.getTranslationY() < 0);
259                assertEquals(0f, view.getTranslationX(), 0.01f);
260                break;
261            case Gravity.BOTTOM:
262                assertTrue(view.getTranslationY() > 0);
263                assertEquals(0f, view.getTranslationX(), 0.01f);
264                break;
265        }
266    }
267
268    private void verifyNoTranslation(View view) {
269        assertEquals(0f, view.getTranslationX(), 0.01f);
270        assertEquals(0f, view.getTranslationY(), 0.01f);
271    }
272
273}
274