Home | History | Annotate | Download | only in view
      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 
     17 package androidx.core.view
     18 
     19 import android.support.test.InstrumentationRegistry
     20 import android.support.test.filters.SdkSuppress
     21 import android.view.View
     22 import android.view.ViewGroup
     23 import android.widget.LinearLayout
     24 import androidx.testutils.assertThrows
     25 import androidx.testutils.fail
     26 import com.google.common.truth.Truth.assertThat
     27 import org.junit.Assert.assertEquals
     28 import org.junit.Assert.assertFalse
     29 import org.junit.Assert.assertSame
     30 import org.junit.Assert.assertTrue
     31 import org.junit.Test
     32 
     33 class ViewGroupTest {
     34     private val context = InstrumentationRegistry.getContext()
     35     private val viewGroup = LinearLayout(context)
     36 
     37     @Test fun get() {
     38         val view1 = View(context)
     39         viewGroup.addView(view1)
     40         val view2 = View(context)
     41         viewGroup.addView(view2)
     42 
     43         assertSame(view1, viewGroup[0])
     44         assertSame(view2, viewGroup[1])
     45 
     46         assertThrows<IndexOutOfBoundsException> {
     47             viewGroup[-1]
     48         }.hasMessageThat().isEqualTo("Index: -1, Size: 2")
     49 
     50         assertThrows<IndexOutOfBoundsException> {
     51             viewGroup[2]
     52         }.hasMessageThat().isEqualTo("Index: 2, Size: 2")
     53     }
     54 
     55     @Test fun contains() {
     56         val view1 = View(context)
     57         viewGroup.addView(view1)
     58         assertTrue(view1 in viewGroup)
     59         assertFalse(view1 !in viewGroup)
     60 
     61         val view2 = View(context)
     62         assertFalse(view2 in viewGroup)
     63         assertTrue(view2 !in viewGroup)
     64     }
     65 
     66     @Test fun plusAssign() {
     67         assertEquals(0, viewGroup.childCount)
     68 
     69         val view1 = View(context)
     70         viewGroup += view1
     71         assertEquals(1, viewGroup.childCount)
     72         assertSame(view1, viewGroup.getChildAt(0))
     73 
     74         val view2 = View(context)
     75         viewGroup += view2
     76         assertEquals(2, viewGroup.childCount)
     77         assertSame(view2, viewGroup.getChildAt(1))
     78     }
     79 
     80     @Test fun minusAssign() {
     81         val view1 = View(context)
     82         viewGroup.addView(view1)
     83         val view2 = View(context)
     84         viewGroup.addView(view2)
     85 
     86         assertEquals(2, viewGroup.childCount)
     87 
     88         viewGroup -= view2
     89         assertEquals(1, viewGroup.childCount)
     90         assertSame(view1, viewGroup.getChildAt(0))
     91 
     92         viewGroup -= view1
     93         assertEquals(0, viewGroup.childCount)
     94     }
     95 
     96     @Test fun size() {
     97         assertEquals(0, viewGroup.size)
     98 
     99         viewGroup.addView(View(context))
    100         assertEquals(1, viewGroup.size)
    101 
    102         viewGroup.addView(View(context))
    103         assertEquals(2, viewGroup.size)
    104 
    105         viewGroup.removeViewAt(0)
    106         assertEquals(1, viewGroup.size)
    107     }
    108 
    109     @Test fun isEmpty() {
    110         assertTrue(viewGroup.isEmpty())
    111         viewGroup.addView(View(context))
    112         assertFalse(viewGroup.isEmpty())
    113     }
    114 
    115     @Test fun isNotEmpty() {
    116         assertFalse(viewGroup.isNotEmpty())
    117         viewGroup.addView(View(context))
    118         assertTrue(viewGroup.isNotEmpty())
    119     }
    120 
    121     @Test fun forEach() {
    122         viewGroup.forEach {
    123             fail("Empty view group should not invoke lambda")
    124         }
    125 
    126         val view1 = View(context)
    127         viewGroup.addView(view1)
    128         val view2 = View(context)
    129         viewGroup.addView(view2)
    130 
    131         val views = mutableListOf<View>()
    132         viewGroup.forEach {
    133             views += it
    134         }
    135         assertThat(views).containsExactly(view1, view2)
    136     }
    137 
    138     @Test fun forEachIndexed() {
    139         viewGroup.forEachIndexed { _, _ ->
    140             fail("Empty view group should not invoke lambda")
    141         }
    142 
    143         val view1 = View(context)
    144         viewGroup.addView(view1)
    145         val view2 = View(context)
    146         viewGroup.addView(view2)
    147 
    148         val views = mutableListOf<View>()
    149         viewGroup.forEachIndexed { index, view ->
    150             assertEquals(index, views.size)
    151             views += view
    152         }
    153         assertThat(views).containsExactly(view1, view2)
    154     }
    155 
    156     @Test fun iterator() {
    157         val view1 = View(context)
    158         viewGroup.addView(view1)
    159         val view2 = View(context)
    160         viewGroup.addView(view2)
    161 
    162         val iterator = viewGroup.iterator()
    163         assertTrue(iterator.hasNext())
    164         assertSame(view1, iterator.next())
    165         assertTrue(iterator.hasNext())
    166         assertSame(view2, iterator.next())
    167         assertFalse(iterator.hasNext())
    168         assertThrows<IndexOutOfBoundsException> {
    169             iterator.next()
    170         }
    171     }
    172 
    173     @Test fun iteratorRemoving() {
    174         val view1 = View(context)
    175         viewGroup.addView(view1)
    176         val view2 = View(context)
    177         viewGroup.addView(view2)
    178 
    179         val iterator = viewGroup.iterator()
    180 
    181         assertSame(view1, iterator.next())
    182         iterator.remove()
    183         assertFalse(view1 in viewGroup)
    184         assertEquals(1, viewGroup.childCount)
    185 
    186         assertSame(view2, iterator.next())
    187         iterator.remove()
    188         assertFalse(view2 in viewGroup)
    189         assertEquals(0, viewGroup.childCount)
    190     }
    191 
    192     @Test fun iteratorForEach() {
    193         val views = listOf(View(context), View(context))
    194         views.forEach(viewGroup::addView)
    195 
    196         var index = 0
    197         for (view in viewGroup) {
    198             assertSame(views[index++], view)
    199         }
    200     }
    201 
    202     @Test fun children() {
    203         val views = listOf(View(context), View(context), View(context))
    204         views.forEach { viewGroup.addView(it) }
    205 
    206         viewGroup.children.forEachIndexed { index, child ->
    207             assertSame(views[index], child)
    208         }
    209     }
    210 
    211     @Test fun setMargins() {
    212         val layoutParams = ViewGroup.MarginLayoutParams(100, 200)
    213         layoutParams.setMargins(42)
    214         assertEquals(42, layoutParams.leftMargin)
    215         assertEquals(42, layoutParams.topMargin)
    216         assertEquals(42, layoutParams.rightMargin)
    217         assertEquals(42, layoutParams.bottomMargin)
    218     }
    219 
    220     @Test fun updateMargins() {
    221         val layoutParams = ViewGroup.MarginLayoutParams(100, 200)
    222         layoutParams.updateMargins(top = 10, right = 20)
    223         assertEquals(0, layoutParams.leftMargin)
    224         assertEquals(10, layoutParams.topMargin)
    225         assertEquals(20, layoutParams.rightMargin)
    226         assertEquals(0, layoutParams.bottomMargin)
    227     }
    228 
    229     @Test fun updateMarginsNoOp() {
    230         val layoutParams = ViewGroup.MarginLayoutParams(100, 200)
    231         layoutParams.setMargins(10, 20, 30, 40)
    232         layoutParams.updateMargins()
    233         assertEquals(10, layoutParams.leftMargin)
    234         assertEquals(20, layoutParams.topMargin)
    235         assertEquals(30, layoutParams.rightMargin)
    236         assertEquals(40, layoutParams.bottomMargin)
    237     }
    238 
    239     @SdkSuppress(minSdkVersion = 17)
    240     @Test fun updateMarginsRelative() {
    241         val layoutParams = ViewGroup.MarginLayoutParams(100, 200)
    242         layoutParams.updateMarginsRelative(start = 10, end = 20)
    243         assertEquals(0, layoutParams.leftMargin)
    244         assertEquals(0, layoutParams.topMargin)
    245         assertEquals(0, layoutParams.rightMargin)
    246         assertEquals(0, layoutParams.bottomMargin)
    247         assertEquals(10, layoutParams.marginStart)
    248         assertEquals(20, layoutParams.marginEnd)
    249         assertTrue(layoutParams.isMarginRelative)
    250     }
    251 
    252     @SdkSuppress(minSdkVersion = 17)
    253     @Test fun updateMarginsRelativeNoOp() {
    254         val layoutParams = ViewGroup.MarginLayoutParams(100, 200)
    255         layoutParams.setMargins(10, 20, 30, 40)
    256         layoutParams.updateMarginsRelative()
    257         assertEquals(10, layoutParams.leftMargin)
    258         assertEquals(20, layoutParams.topMargin)
    259         assertEquals(30, layoutParams.rightMargin)
    260         assertEquals(40, layoutParams.bottomMargin)
    261         assertEquals(10, layoutParams.marginStart)
    262         assertEquals(30, layoutParams.marginEnd)
    263     }
    264 }
    265