1 /*
2  * Copyright (C) 2024 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 platform.test.motion.compose
18 
19 import androidx.compose.ui.geometry.Offset
20 import androidx.compose.ui.geometry.isFinite
21 import androidx.compose.ui.geometry.isUnspecified
22 import androidx.compose.ui.unit.Dp
23 import androidx.compose.ui.unit.DpOffset
24 import androidx.compose.ui.unit.DpSize
25 import androidx.compose.ui.unit.IntSize
26 import androidx.compose.ui.unit.dp
27 import java.lang.reflect.Array.getDouble
28 import org.json.JSONObject
29 import platform.test.motion.golden.DataPointType
30 import platform.test.motion.golden.UnknownTypeException
31 
Dpnull32 fun Dp.asDataPoint() = DataPointTypes.dp.makeDataPoint(this)
33 
34 fun IntSize.asDataPoint() = DataPointTypes.intSize.makeDataPoint(this)
35 
36 fun Offset.asDataPoint() = DataPointTypes.offset.makeDataPoint(this)
37 
38 fun DpSize.asDataPoint() = DataPointTypes.dpSize.makeDataPoint(this)
39 
40 fun DpOffset.asDataPoint() = DataPointTypes.dpOffset.makeDataPoint(this)
41 
42 object DataPointTypes {
43 
44     val dp: DataPointType<Dp> =
45         DataPointType(
46             "dp",
47             jsonToValue = {
48                 when (it) {
49                     is Float -> it.dp
50                     is Number -> it.toFloat().dp
51                     is String -> it.toFloatOrNull()?.dp ?: throw UnknownTypeException()
52                     else -> throw UnknownTypeException()
53                 }
54             },
55             valueToJson = { it.value }
56         )
57 
58     val intSize: DataPointType<IntSize> =
59         DataPointType(
60             "intSize",
61             jsonToValue = {
62                 with(it as? JSONObject ?: throw UnknownTypeException()) {
63                     IntSize(getInt("width"), getInt("height"))
64                 }
65             },
66             valueToJson = {
67                 JSONObject().apply {
68                     put("width", it.width)
69                     put("height", it.height)
70                 }
71             }
72         )
73 
74     val dpSize: DataPointType<DpSize> =
75         DataPointType(
76             "dpSize",
77             jsonToValue = {
78                 with(it as? JSONObject ?: throw UnknownTypeException()) {
79                     DpSize(getDouble("width").dp, getDouble("height").dp)
80                 }
81             },
82             valueToJson = {
83                 JSONObject().apply {
84                     put("width", it.width.value)
85                     put("height", it.height.value)
86                 }
87             }
88         )
89 
90     val dpOffset: DataPointType<DpOffset> =
91         DataPointType(
92             "dpOffset",
93             jsonToValue = {
94                 with(it as? JSONObject ?: throw UnknownTypeException()) {
95                     DpOffset(getDouble("x").dp, getDouble("y").dp)
96                 }
97             },
98             valueToJson = {
99                 JSONObject().apply {
100                     put("x", it.x.value)
101                     put("y", it.y.value)
102                 }
103             }
104         )
105 
106     val offset: DataPointType<Offset> =
107         DataPointType(
108             "offset",
109             jsonToValue = {
110                 when (it) {
111                     "unspecified" -> Offset.Unspecified
112                     "infinite" -> Offset.Infinite
113                     is JSONObject ->
114                         Offset(it.getDouble("x").toFloat(), it.getDouble("y").toFloat())
115                     else -> throw UnknownTypeException()
116                 }
117             },
118             valueToJson = {
119                 when {
120                     it.isUnspecified -> "unspecified"
121                     !it.isFinite -> "infinite"
122                     else ->
123                         JSONObject().apply {
124                             put("x", it.x)
125                             put("y", it.y)
126                         }
127                 }
128             }
129         )
130 }
131