• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 
17 package android.util
18 
19 import androidx.test.filters.LargeTest
20 import androidx.test.filters.SmallTest
21 import androidx.test.runner.AndroidJUnit4
22 import org.junit.Assert.assertEquals
23 import org.junit.Test
24 import org.junit.runner.RunWith
25 import org.mockito.Mockito.mock
26 import kotlin.math.abs
27 import kotlin.math.min
28 import kotlin.math.roundToInt
29 
30 @RunWith(AndroidJUnit4::class)
31 class TypedValueTest {
32     @LargeTest
33     @Test
testFloatToComplexnull34     fun testFloatToComplex() {
35         fun assertRoundTripEquals(value: Float, expectedRadix: Int? = null) {
36             val complex = TypedValue.floatToComplex(value)
37             // Ensure values are accurate within .5% of the original value and within .5
38             val delta = min(abs(value) / 512f, .5f)
39             assertEquals(value, TypedValue.complexToFloat(complex), delta)
40             // If expectedRadix is provided, validate it
41             if (expectedRadix != null) {
42                 val actualRadix = ((complex shr TypedValue.COMPLEX_RADIX_SHIFT)
43                         and TypedValue.COMPLEX_RADIX_MASK)
44                 assertEquals("Incorrect radix for $value:", expectedRadix, actualRadix)
45             }
46         }
47 
48         assertRoundTripEquals(0f, TypedValue.COMPLEX_RADIX_23p0)
49 
50         assertRoundTripEquals(0.5f, TypedValue.COMPLEX_RADIX_0p23)
51         assertRoundTripEquals(0.05f, TypedValue.COMPLEX_RADIX_0p23)
52         assertRoundTripEquals(0.005f, TypedValue.COMPLEX_RADIX_0p23)
53         assertRoundTripEquals(0.0005f, TypedValue.COMPLEX_RADIX_0p23)
54         assertRoundTripEquals(0.00005f, TypedValue.COMPLEX_RADIX_0p23)
55 
56         assertRoundTripEquals(1.5f, TypedValue.COMPLEX_RADIX_8p15)
57         assertRoundTripEquals(10.5f, TypedValue.COMPLEX_RADIX_8p15)
58         assertRoundTripEquals(100.5f, TypedValue.COMPLEX_RADIX_8p15)
59         assertRoundTripEquals(255.5f, TypedValue.COMPLEX_RADIX_8p15) // 2^8 - .5
60 
61         assertRoundTripEquals(256.5f, TypedValue.COMPLEX_RADIX_16p7) // 2^8 + .5
62         assertRoundTripEquals(1000.5f, TypedValue.COMPLEX_RADIX_16p7)
63         assertRoundTripEquals(10000.5f, TypedValue.COMPLEX_RADIX_16p7)
64         assertRoundTripEquals(65535.5f, TypedValue.COMPLEX_RADIX_16p7) // 2^16 - .5
65 
66         assertRoundTripEquals(65536.5f, TypedValue.COMPLEX_RADIX_23p0) // 2^16 + .5
67         assertRoundTripEquals(100000.5f, TypedValue.COMPLEX_RADIX_23p0)
68         assertRoundTripEquals(1000000.5f, TypedValue.COMPLEX_RADIX_23p0)
69         assertRoundTripEquals(8388607.2f, TypedValue.COMPLEX_RADIX_23p0) // 2^23 -.8
70 
71         assertRoundTripEquals(-0.5f, TypedValue.COMPLEX_RADIX_0p23)
72         assertRoundTripEquals(-0.05f, TypedValue.COMPLEX_RADIX_0p23)
73         assertRoundTripEquals(-0.005f, TypedValue.COMPLEX_RADIX_0p23)
74         assertRoundTripEquals(-0.0005f, TypedValue.COMPLEX_RADIX_0p23)
75         assertRoundTripEquals(-0.00005f, TypedValue.COMPLEX_RADIX_0p23)
76 
77         assertRoundTripEquals(-1.5f, TypedValue.COMPLEX_RADIX_8p15)
78         assertRoundTripEquals(-10.5f, TypedValue.COMPLEX_RADIX_8p15)
79         assertRoundTripEquals(-100.5f, TypedValue.COMPLEX_RADIX_8p15)
80         assertRoundTripEquals(-255.5f, TypedValue.COMPLEX_RADIX_8p15) // -2^8 + .5
81 
82         // NOTE: -256.5f fits in COMPLEX_RADIX_8p15 but is stored with COMPLEX_RADIX_16p7 for
83         // simplicity of the algorithm.  However, it's better not to enforce that with a test.
84         assertRoundTripEquals(-257.5f, TypedValue.COMPLEX_RADIX_16p7) // -2^8 - 1.5
85         assertRoundTripEquals(-1000.5f, TypedValue.COMPLEX_RADIX_16p7)
86         assertRoundTripEquals(-10000.5f, TypedValue.COMPLEX_RADIX_16p7)
87         assertRoundTripEquals(-65535.5f, TypedValue.COMPLEX_RADIX_16p7) // -2^16 + .5
88 
89         // NOTE: -65536.5f fits in COMPLEX_RADIX_16p7 but is stored with COMPLEX_RADIX_23p0 for
90         // simplicity of the algorithm.  However, it's better not to enforce that with a test.
91         assertRoundTripEquals(-65537.5f, TypedValue.COMPLEX_RADIX_23p0) // -2^16 - 1.5
92         assertRoundTripEquals(-100000.5f, TypedValue.COMPLEX_RADIX_23p0)
93         assertRoundTripEquals(-1000000.5f, TypedValue.COMPLEX_RADIX_23p0)
94         assertRoundTripEquals(-8388607.5f, TypedValue.COMPLEX_RADIX_23p0) // 2^23 -.5
95 
96         // Test for every integer value in the range...
97         for (i: Int in -(1 shl 23) until (1 shl 23)) {
98             // ... that true integers are stored as the precise integer
99             assertRoundTripEquals(i.toFloat(), TypedValue.COMPLEX_RADIX_23p0)
100             // ... that values round up when just below an integer
101             assertRoundTripEquals(i - .1f)
102             // ... that values round down when just above an integer
103             assertRoundTripEquals(i + .1f)
104         }
105     }
106 
107     @SmallTest
108     @Test(expected = IllegalArgumentException::class)
testFloatToComplex_failsIfValueTooLargenull109     fun testFloatToComplex_failsIfValueTooLarge() {
110         TypedValue.floatToComplex(8388607.5f) // 2^23 - .5
111     }
112 
113     @SmallTest
114     @Test(expected = IllegalArgumentException::class)
testFloatToComplex_failsIfValueTooSmallnull115     fun testFloatToComplex_failsIfValueTooSmall() {
116         TypedValue.floatToComplex(8388608.5f) // -2^23 - .5
117     }
118 
119     @LargeTest
120     @Test
testIntToComplexnull121     fun testIntToComplex() {
122         // Validates every single valid value
123         for (value: Int in -(1 shl 23) until (1 shl 23)) {
124             assertEquals(value.toFloat(), TypedValue.complexToFloat(TypedValue.intToComplex(value)))
125         }
126     }
127 
128     @SmallTest
129     @Test(expected = IllegalArgumentException::class)
testIntToComplex_failsIfValueTooLargenull130     fun testIntToComplex_failsIfValueTooLarge() {
131         TypedValue.intToComplex(0x800000)
132     }
133 
134     @SmallTest
135     @Test(expected = IllegalArgumentException::class)
testIntToComplex_failsIfValueTooSmallnull136     fun testIntToComplex_failsIfValueTooSmall() {
137         TypedValue.intToComplex(-0x800001)
138     }
139 
140     @SmallTest
141     @Test
testCreateComplexDimension_appliesUnitsnull142     fun testCreateComplexDimension_appliesUnits() {
143         val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
144         metrics.density = 3.25f
145 
146         val height = 52 * metrics.density
147         val widthFloat = height * 16 / 9
148         val widthDimen = TypedValue.createComplexDimension(
149                 widthFloat / metrics.density,
150                 TypedValue.COMPLEX_UNIT_DIP
151         )
152         val widthPx = TypedValue.complexToDimensionPixelSize(widthDimen, metrics)
153         assertEquals(widthFloat.roundToInt(), widthPx)
154     }
155 }