[go: nahoru, domu]

blob: 77fec16e92b1c6b9804eee460a63d4ff57410ac2 [file] [log] [blame]
Andrey Kulikovb87ddf62020-03-31 17:27:27 +01001/*
2 * Copyright 2020 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 androidx.ui.core.test
18
Adam Powell5f07ae82020-03-30 14:36:42 -070019import androidx.compose.getValue
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010020import androidx.compose.mutableStateOf
Adam Powell5f07ae82020-03-30 14:36:42 -070021import androidx.compose.setValue
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010022import androidx.test.filters.SmallTest
23import androidx.test.rule.ActivityTestRule
24import androidx.ui.core.Layout
George Mount1cc5db92020-03-31 10:12:56 -070025import androidx.ui.core.LayoutCoordinates
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010026import androidx.ui.core.Modifier
George Mount1cc5db92020-03-31 10:12:56 -070027import androidx.ui.core.boundsInParent
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010028import androidx.ui.core.globalPosition
29import androidx.ui.core.onChildPositioned
30import androidx.ui.core.onPositioned
George Mount1cc5db92020-03-31 10:12:56 -070031import androidx.ui.core.positionInParent
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010032import androidx.ui.core.setContent
33import androidx.ui.framework.test.TestActivity
George Mount1cc5db92020-03-31 10:12:56 -070034import androidx.ui.unit.PxBounds
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010035import androidx.ui.unit.PxPosition
36import androidx.ui.unit.ipx
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010037import androidx.ui.unit.toPx
38import org.junit.Assert.assertEquals
39import org.junit.Assert.assertFalse
40import org.junit.Assert.assertTrue
41import org.junit.Before
42import org.junit.Rule
43import org.junit.Test
44import org.junit.runner.RunWith
45import org.junit.runners.JUnit4
46import java.util.concurrent.CountDownLatch
47import java.util.concurrent.TimeUnit
48
49@SmallTest
50@RunWith(JUnit4::class)
51class OnPositionedTest {
52
53 @get:Rule
54 val rule = ActivityTestRule<TestActivity>(TestActivity::class.java)
55 private lateinit var activity: TestActivity
56
57 @Before
58 fun setup() {
59 activity = rule.activity
60 activity.hasFocusLatch.await(5, TimeUnit.SECONDS)
61 }
62
63 @Test
64 fun handlesChildrenNodeMoveCorrectly() {
65 val size = 50.ipx
66 var index by mutableStateOf(0)
67 var latch = CountDownLatch(2)
Nader Jawad63153c12020-05-21 14:17:08 -070068 var wrap1Position = 0f
69 var wrap2Position = 0f
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010070 rule.runOnUiThread {
Andrey Kulikov1526ea52020-04-07 18:43:27 +010071 activity.setContent {
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010072 SimpleRow {
73 for (i in 0 until 2) {
74 if (index == i) {
75 Wrap(
76 minWidth = size,
77 minHeight = size,
78 modifier = Modifier.onPositioned { coordinates ->
Nader Jawad63153c12020-05-21 14:17:08 -070079 wrap1Position = coordinates.globalPosition.x
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010080 latch.countDown()
81 }
82 )
83 } else {
84 Wrap(
85 minWidth = size,
86 minHeight = size,
87 modifier = Modifier.onPositioned { coordinates ->
Nader Jawad63153c12020-05-21 14:17:08 -070088 wrap2Position = coordinates.globalPosition.x
Andrey Kulikovb87ddf62020-03-31 17:27:27 +010089 latch.countDown()
90 }
91 )
92 }
93 }
94 }
95 }
96 }
97 assertTrue(latch.await(1, TimeUnit.SECONDS))
Nader Jawad63153c12020-05-21 14:17:08 -070098 assertEquals(0f, wrap1Position)
99 assertEquals(size.toPx().value, wrap2Position)
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100100 latch = CountDownLatch(2)
101 rule.runOnUiThread {
102 index = 1
103 }
104 assertTrue(latch.await(1, TimeUnit.SECONDS))
Nader Jawad63153c12020-05-21 14:17:08 -0700105 assertEquals(size.toPx().value, wrap1Position)
106 assertEquals(0f, wrap2Position)
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100107 }
108
109 @Test
110 fun callbacksAreCalledWhenChildResized() {
111 var size by mutableStateOf(10.ipx)
112 var realSize = 0.ipx
113 var realChildSize = 0.ipx
114 var latch = CountDownLatch(1)
115 var childLatch = CountDownLatch(1)
116 rule.runOnUiThreadIR {
117 activity.setContent {
118 AtLeastSize(size = 20.ipx, modifier = Modifier.onChildPositioned {
119 realSize = it.size.width
120 latch.countDown()
121 }) {
122 Wrap(minWidth = size, minHeight = size, modifier = Modifier.onPositioned {
123 realChildSize = it.size.width
124 childLatch.countDown()
125 })
126 }
127 }
128 }
129
130 assertTrue(latch.await(1, TimeUnit.SECONDS))
131 assertTrue(childLatch.await(1, TimeUnit.SECONDS))
132 assertEquals(10.ipx, realSize)
133 assertEquals(10.ipx, realChildSize)
134
135 latch = CountDownLatch(1)
136 childLatch = CountDownLatch(1)
137 rule.runOnUiThread {
138 size = 15.ipx
139 }
140
141 assertTrue(latch.await(1, TimeUnit.SECONDS))
142 assertTrue(childLatch.await(1, TimeUnit.SECONDS))
143 assertEquals(15.ipx, realSize)
144 assertEquals(15.ipx, realChildSize)
145 }
146
147 @Test
148 fun callbackCalledForChildWhenParentMoved() {
149 var position by mutableStateOf(0.ipx)
Nader Jawade6a9b332020-05-21 13:49:20 -0700150 var childGlobalPosition = PxPosition(0f, 0f)
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100151 var latch = CountDownLatch(1)
152 rule.runOnUiThreadIR {
Andrey Kulikov1526ea52020-04-07 18:43:27 +0100153 activity.setContent {
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100154 Layout(
155 measureBlock = { measurables, constraints, _ ->
156 layout(10.ipx, 10.ipx) {
157 measurables[0].measure(constraints).place(position, 0.ipx)
158 }
159 },
160 children = {
161 Wrap(
162 minWidth = 10.ipx,
163 minHeight = 10.ipx
164 ) {
165 Wrap(
166 minWidth = 10.ipx,
167 minHeight = 10.ipx,
168 modifier = Modifier.onPositioned { coordinates ->
169 childGlobalPosition = coordinates.globalPosition
170 latch.countDown()
171 }
172 )
173 }
174 }
175 )
176 }
177 }
178
179 assertTrue(latch.await(1, TimeUnit.SECONDS))
180
181 latch = CountDownLatch(1)
182 rule.runOnUiThread {
183 position = 10.ipx
184 }
185
186 assertTrue(latch.await(1, TimeUnit.SECONDS))
Nader Jawade6a9b332020-05-21 13:49:20 -0700187 assertEquals(PxPosition(10f, 0f), childGlobalPosition)
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100188 }
189
190 @Test
191 fun callbacksAreCalledOnlyForPositionedChildren() {
192 val latch = CountDownLatch(1)
193 var wrap1OnPositionedCalled = false
194 var wrap2OnPositionedCalled = false
195 var onChildPositionedCalledTimes = 0
196 rule.runOnUiThread {
Andrey Kulikov1526ea52020-04-07 18:43:27 +0100197 activity.setContent {
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100198 Layout(
199 modifier = Modifier.onChildPositioned {
200 onChildPositionedCalledTimes++
201 },
202 measureBlock = { measurables, constraints, _ ->
203 layout(10.ipx, 10.ipx) {
204 measurables[1].measure(constraints).place(0.ipx, 0.ipx)
205 }
206 },
207 children = {
208 Wrap(
209 minWidth = 10.ipx,
210 minHeight = 10.ipx,
211 modifier = Modifier.onPositioned {
212 wrap1OnPositionedCalled = true
213 }
214 )
215 Wrap(
216 minWidth = 10.ipx,
217 minHeight = 10.ipx,
218 modifier = Modifier.onPositioned {
219 wrap2OnPositionedCalled = true
220 }
221 ) {
222 Wrap(
223 minWidth = 10.ipx,
224 minHeight = 10.ipx,
225 modifier = Modifier.onPositioned {
226 latch.countDown()
227 }
228 )
229 }
230 }
231 )
232 }
233 }
234
235 assertTrue(latch.await(1, TimeUnit.SECONDS))
236 assertFalse(wrap1OnPositionedCalled)
237 assertTrue(wrap2OnPositionedCalled)
238 assertEquals(1, onChildPositionedCalledTimes)
239 }
George Mount1cc5db92020-03-31 10:12:56 -0700240
241 @Test
242 fun testPositionInParent() {
243 val positionedLatch = CountDownLatch(1)
244 var coordinates: LayoutCoordinates? = null
245
246 rule.runOnUiThread {
Andrey Kulikov1526ea52020-04-07 18:43:27 +0100247 activity.setContent {
George Mount1cc5db92020-03-31 10:12:56 -0700248 FixedSize(10.ipx,
249 PaddingModifier(5.ipx) +
250 Modifier.onPositioned {
251 coordinates = it
252 positionedLatch.countDown()
253 }
254 ) {
255 }
256 }
257 }
258 assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
259
260 rule.runOnUiThread {
Nader Jawade6a9b332020-05-21 13:49:20 -0700261 assertEquals(PxPosition(5f, 5f), coordinates!!.positionInParent)
George Mount1cc5db92020-03-31 10:12:56 -0700262
263 var root = coordinates!!
264 while (root.parentCoordinates != null) {
265 root = root.parentCoordinates!!
266 }
267
268 assertEquals(PxPosition.Origin, root.positionInParent)
269 }
270 }
271
272 @Test
273 fun testBoundsInParent() {
274 val positionedLatch = CountDownLatch(1)
275 var coordinates: LayoutCoordinates? = null
276
277 rule.runOnUiThread {
Andrey Kulikov1526ea52020-04-07 18:43:27 +0100278 activity.setContent {
George Mount1cc5db92020-03-31 10:12:56 -0700279 FixedSize(10.ipx,
280 PaddingModifier(5.ipx) +
281 Modifier.onPositioned {
282 coordinates = it
283 positionedLatch.countDown()
284 }
285 ) {
286 }
287 }
288 }
289 assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
290
291 rule.runOnUiThread {
Nader Jawad63153c12020-05-21 14:17:08 -0700292 assertEquals(PxBounds(5f, 5f, 15f, 15f), coordinates!!.boundsInParent)
George Mount1cc5db92020-03-31 10:12:56 -0700293
294 var root = coordinates!!
295 while (root.parentCoordinates != null) {
296 root = root.parentCoordinates!!
297 }
298
Nader Jawad63153c12020-05-21 14:17:08 -0700299 assertEquals(PxBounds(0f, 0f, 20f, 20f), root.boundsInParent)
George Mount1cc5db92020-03-31 10:12:56 -0700300 }
301 }
Andrey Kulikovb87ddf62020-03-31 17:27:27 +0100302}