Home | History | Annotate | Download | only in widget
      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 
     17 package androidx.leanback.widget;
     18 
     19 import static androidx.leanback.widget.BaseCardView.LayoutParams.MATCH_PARENT;
     20 import static androidx.leanback.widget.BaseCardView.LayoutParams.VIEW_TYPE_INFO;
     21 import static androidx.leanback.widget.BaseCardView.LayoutParams.VIEW_TYPE_MAIN;
     22 
     23 import static org.junit.Assert.assertEquals;
     24 import static org.junit.Assert.assertFalse;
     25 import static org.junit.Assert.assertNull;
     26 import static org.junit.Assert.assertTrue;
     27 import static org.mockito.Matchers.any;
     28 import static org.mockito.Mockito.times;
     29 import static org.mockito.Mockito.verify;
     30 
     31 import android.support.test.InstrumentationRegistry;
     32 import android.support.test.filters.SmallTest;
     33 import android.view.View;
     34 
     35 import org.junit.Test;
     36 import org.junit.runner.RunWith;
     37 import org.junit.runners.JUnit4;
     38 import org.mockito.Mockito;
     39 
     40 @SmallTest
     41 @RunWith(JUnit4.class)
     42 public class BaseCardViewTest {
     43 
     44     BaseCardView.LayoutParams createLayoutParams(int viewType, int width, int height) {
     45         BaseCardView.LayoutParams lp = new BaseCardView.LayoutParams(width, height);
     46         lp.viewType = viewType;
     47         return lp;
     48     }
     49 
     50     void mockInfoHeightAnimation(BaseCardView view, int width, int startHeight, int endHeight) {
     51         ((BaseCardView.InfoHeightAnimation) view.getAnimation()).mockStart();
     52         measureAndLayout(view, width, startHeight);
     53         ((BaseCardView.InfoHeightAnimation) view.getAnimation()).mockEnd();
     54         assertNull(view.getAnimation());
     55         measureAndLayout(view, width, endHeight);
     56     }
     57 
     58     void mockInfoAlphaAnimation(BaseCardView view, View infoView,
     59             float startAlpha, float endAlpha) {
     60         ((BaseCardView.InfoAlphaAnimation) view.getAnimation()).mockStart();
     61         assertEquals(startAlpha, infoView.getAlpha(), 0.01f);
     62         assertEquals(View.VISIBLE, infoView.getVisibility());
     63         ((BaseCardView.InfoAlphaAnimation) view.getAnimation()).mockEnd();
     64         assertNull(view.getAnimation());
     65         assertEquals(endAlpha, infoView.getAlpha(), 0.01f);
     66         assertEquals(endAlpha == 0f? View.GONE: View.VISIBLE, infoView.getVisibility());
     67     }
     68 
     69     void measureAndLayout(View view, int expectedWidth, int expectedHeight) {
     70         view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
     71         assertEquals(expectedWidth, view.getMeasuredWidth());
     72         assertEquals(expectedHeight, view.getMeasuredHeight());
     73         view.layout(0, 0, expectedWidth, expectedHeight);
     74     }
     75 
     76     void verifyLayoutTimes(View.OnLayoutChangeListener listener, int timesCalled) {
     77         verify(listener, times(timesCalled)).onLayoutChange(any(View.class),
     78                 any(Integer.class), any(Integer.class), any(Integer.class), any(Integer.class),
     79                 any(Integer.class), any(Integer.class), any(Integer.class), any(Integer.class));
     80     }
     81 
     82     @Test
     83     public void infoOver_InfoVisibleAlways() {
     84         BaseCardView cardView = new BaseCardView(InstrumentationRegistry.getContext());
     85         View main = new View(cardView.getContext());
     86         main.setLayoutParams(createLayoutParams(VIEW_TYPE_MAIN, 500, 500));
     87         cardView.addView(main);
     88         View info = new View(cardView.getContext());
     89         View.OnLayoutChangeListener onLayout = Mockito.mock(View.OnLayoutChangeListener.class);
     90         info.addOnLayoutChangeListener(onLayout);
     91         info.setLayoutParams(createLayoutParams(VIEW_TYPE_INFO, MATCH_PARENT, 200));
     92         cardView.addView(info);
     93         cardView.setCardType(BaseCardView.CARD_TYPE_INFO_OVER);
     94         cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_ALWAYS);
     95 
     96         measureAndLayout(cardView, 500, 500);
     97         verifyLayoutTimes(onLayout, 1);
     98         assertEquals(1f, info.getAlpha(), 0.01f);
     99 
    100         cardView.setActivated(true);
    101         assertFalse(cardView.isLayoutRequested());
    102         assertNull(cardView.getAnimation());
    103         measureAndLayout(cardView, 500, 500);
    104         verifyLayoutTimes(onLayout, 1);
    105         assertEquals(1f, info.getAlpha(), 0.01f);
    106 
    107         cardView.setActivated(false);
    108         assertFalse(cardView.isLayoutRequested());
    109         assertNull(cardView.getAnimation());
    110         measureAndLayout(cardView, 500, 500);
    111         verifyLayoutTimes(onLayout, 1);
    112         assertEquals(1f, info.getAlpha(), 0.01f);
    113 
    114         cardView.setSelected(true);
    115         assertFalse(cardView.isLayoutRequested());
    116         assertNull(cardView.getAnimation());
    117         measureAndLayout(cardView, 500, 500);
    118         verifyLayoutTimes(onLayout, 1);
    119         assertEquals(1f, info.getAlpha(), 0.01f);
    120 
    121         cardView.setSelected(false);
    122         assertFalse(cardView.isLayoutRequested());
    123         assertNull(cardView.getAnimation());
    124         measureAndLayout(cardView, 500, 500);
    125         verifyLayoutTimes(onLayout, 1);
    126         assertEquals(1f, info.getAlpha(), 0.01f);
    127     }
    128 
    129     @Test
    130     public void infoUnder_InfoVisibleAlways() {
    131         BaseCardView cardView = new BaseCardView(InstrumentationRegistry.getContext());
    132         View main = new View(cardView.getContext());
    133         main.setLayoutParams(createLayoutParams(VIEW_TYPE_MAIN, 500, 500));
    134         cardView.addView(main);
    135         View info = new View(cardView.getContext());
    136         View.OnLayoutChangeListener onLayout = Mockito.mock(View.OnLayoutChangeListener.class);
    137         info.addOnLayoutChangeListener(onLayout);
    138         info.setLayoutParams(createLayoutParams(VIEW_TYPE_INFO, MATCH_PARENT, 200));
    139         cardView.addView(info);
    140         cardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);
    141         cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_ALWAYS);
    142 
    143         measureAndLayout(cardView, 500, 700);
    144         verifyLayoutTimes(onLayout, 1);
    145         assertEquals(1f, info.getAlpha(), 0.01f);
    146 
    147         cardView.setActivated(true);
    148         assertFalse(cardView.isLayoutRequested());
    149         assertNull(cardView.getAnimation());
    150         measureAndLayout(cardView, 500, 700);
    151         verifyLayoutTimes(onLayout, 1);
    152         assertEquals(1f, info.getAlpha(), 0.01f);
    153 
    154         cardView.setActivated(false);
    155         assertFalse(cardView.isLayoutRequested());
    156         assertNull(cardView.getAnimation());
    157         measureAndLayout(cardView, 500, 700);
    158         verifyLayoutTimes(onLayout, 1);
    159         assertEquals(1f, info.getAlpha(), 0.01f);
    160 
    161         cardView.setSelected(true);
    162         assertFalse(cardView.isLayoutRequested());
    163         assertNull(cardView.getAnimation());
    164         measureAndLayout(cardView, 500, 700);
    165         verifyLayoutTimes(onLayout, 1);
    166         assertEquals(1f, info.getAlpha(), 0.01f);
    167 
    168         cardView.setSelected(false);
    169         assertFalse(cardView.isLayoutRequested());
    170         assertNull(cardView.getAnimation());
    171         measureAndLayout(cardView, 500, 700);
    172         verifyLayoutTimes(onLayout, 1);
    173         assertEquals(1f, info.getAlpha(), 0.01f);
    174     }
    175 
    176     @Test
    177     public void infoUnder_InfoVisibleActivated() {
    178         BaseCardView cardView = new BaseCardView(InstrumentationRegistry.getContext());
    179         View main = new View(cardView.getContext());
    180         main.setLayoutParams(createLayoutParams(VIEW_TYPE_MAIN, 500, 500));
    181         cardView.addView(main);
    182         View info = new View(cardView.getContext());
    183         View.OnLayoutChangeListener onLayout = Mockito.mock(View.OnLayoutChangeListener.class);
    184         info.addOnLayoutChangeListener(onLayout);
    185         info.setLayoutParams(createLayoutParams(VIEW_TYPE_INFO, MATCH_PARENT, 200));
    186         cardView.addView(info);
    187         cardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);
    188         cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_ACTIVATED);
    189 
    190         measureAndLayout(cardView, 500, 500);
    191         verifyLayoutTimes(onLayout, 0);
    192         assertEquals(1f, info.getAlpha(), 0.01f);
    193 
    194         cardView.setActivated(true);
    195         assertTrue(cardView.isLayoutRequested());
    196         measureAndLayout(cardView, 500, 700);
    197         verifyLayoutTimes(onLayout, 1);
    198         assertEquals(1f, info.getAlpha(), 0.01f);
    199 
    200         cardView.setActivated(false);
    201         assertTrue(cardView.isLayoutRequested());
    202         measureAndLayout(cardView, 500, 500);
    203         verifyLayoutTimes(onLayout, 1);
    204         assertEquals(1f, info.getAlpha(), 0.01f);
    205 
    206         // changing selected does not affect size
    207         cardView.setSelected(true);
    208         assertFalse(cardView.isLayoutRequested());
    209         measureAndLayout(cardView, 500, 500);
    210         verifyLayoutTimes(onLayout, 1);
    211         assertEquals(1f, info.getAlpha(), 0.01f);
    212 
    213         // changing selected does not affect size
    214         cardView.setSelected(false);
    215         assertFalse(cardView.isLayoutRequested());
    216         measureAndLayout(cardView, 500, 500);
    217         verifyLayoutTimes(onLayout, 1);
    218         assertEquals(1f, info.getAlpha(), 0.01f);
    219     }
    220 
    221     @Test
    222     public void infoUnder_InfoVisibleSelected() {
    223         final BaseCardView cardView = new BaseCardView(InstrumentationRegistry.getContext());
    224         View main = new View(cardView.getContext());
    225         main.setLayoutParams(createLayoutParams(VIEW_TYPE_MAIN, 500, 500));
    226         cardView.addView(main);
    227         View info = new View(cardView.getContext());
    228         View.OnLayoutChangeListener onLayout = Mockito.mock(View.OnLayoutChangeListener.class);
    229         info.addOnLayoutChangeListener(onLayout);
    230         info.setLayoutParams(createLayoutParams(VIEW_TYPE_INFO, MATCH_PARENT, 200));
    231         cardView.addView(info);
    232         cardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);
    233         cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_SELECTED);
    234 
    235         measureAndLayout(cardView, 500, 500);
    236         verifyLayoutTimes(onLayout, 0);
    237         assertEquals(1f, info.getAlpha(), 0.01f);
    238 
    239         // changing activated does not affect size
    240         cardView.setActivated(true);
    241         measureAndLayout(cardView, 500, 500);
    242         assertNull(cardView.getAnimation());
    243         assertEquals(1f, info.getAlpha(), 0.01f);
    244 
    245         // start info height animation 500 -> 700
    246         cardView.setSelected(true);
    247         assertEquals(1f, info.getAlpha(), 0.01f);
    248         mockInfoHeightAnimation(cardView, 500 /*width*/, 500 /*startHeight*/, 700 /*endHeight*/);
    249 
    250         // changing activated does not affect size
    251         cardView.setActivated(false);
    252         assertEquals(1f, info.getAlpha(), 0.01f);
    253         measureAndLayout(cardView, 500, 700);
    254         assertNull(cardView.getAnimation());
    255 
    256         // start info height animation 700 -> 500
    257         cardView.setSelected(false);
    258         assertEquals(1f, info.getAlpha(), 0.01f);
    259         mockInfoHeightAnimation(cardView, 500 /*width*/, 700 /*startHeight*/, 500 /*endHeight*/);
    260     }
    261 
    262     @Test
    263     public void infoOver_InfoVisibleSelected() {
    264         final BaseCardView cardView = new BaseCardView(InstrumentationRegistry.getContext());
    265         View main = new View(cardView.getContext());
    266         main.setLayoutParams(createLayoutParams(VIEW_TYPE_MAIN, 500, 500));
    267         cardView.addView(main);
    268         View info = new View(cardView.getContext());
    269         View.OnLayoutChangeListener onLayout = Mockito.mock(View.OnLayoutChangeListener.class);
    270         info.addOnLayoutChangeListener(onLayout);
    271         info.setLayoutParams(createLayoutParams(VIEW_TYPE_INFO, MATCH_PARENT, 200));
    272         cardView.addView(info);
    273         cardView.setCardType(BaseCardView.CARD_TYPE_INFO_OVER);
    274         cardView.setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_SELECTED);
    275 
    276         measureAndLayout(cardView, 500, 500);
    277         verifyLayoutTimes(onLayout, 0);
    278         assertFalse(cardView.isSelected());
    279         assertFalse(cardView.isActivated());
    280         assertEquals(0f, info.getAlpha(), 0.01f);
    281 
    282         cardView.setActivated(true);
    283         assertFalse(cardView.isLayoutRequested());
    284         assertNull(cardView.getAnimation());
    285 
    286         assertEquals(info.getVisibility(), View.GONE);
    287         assertEquals(0f, info.getAlpha(), 0.01f);
    288         // start info animation alpha 0f -> 1f
    289         cardView.setSelected(true);
    290         // change visibility when start animation causing layout requested
    291         assertTrue(cardView.isLayoutRequested());
    292         measureAndLayout(cardView, 500, 500);
    293         mockInfoAlphaAnimation(cardView, info, 0f, 1f);
    294         assertEquals(1f, info.getAlpha(), 0.01f);
    295 
    296         // start info animation alpha 1f -> 0f
    297         cardView.setSelected(false);
    298         assertFalse(cardView.isLayoutRequested());
    299         mockInfoAlphaAnimation(cardView, info, 1f, 0f);
    300         assertEquals(0f, info.getAlpha(), 0.01f);
    301     }
    302 
    303 }
    304