1 /*
2  * Copyright (C) 2023 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.tools.flicker.subject.region
18 
19 import android.graphics.Rect
20 import android.graphics.Region
21 import android.tools.Timestamps
22 import android.tools.testutils.CleanFlickerEnvironmentRule
23 import android.tools.testutils.assertFail
24 import org.junit.ClassRule
25 import org.junit.FixMethodOrder
26 import org.junit.Test
27 import org.junit.runners.MethodSorters
28 
29 /** Contains [RegionSubject] tests. To run this test: `atest FlickerLibTest:RegionSubjectTest` */
30 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
31 class RegionSubjectTest {
expectAllFailPositionChangenull32     private fun expectAllFailPositionChange(expectedMessage: String, rectA: Rect, rectB: Rect) {
33         assertFail(expectedMessage) {
34             RegionSubject(rectA, timestamp = Timestamps.empty()).isHigher(rectB)
35         }
36         assertFail(expectedMessage) {
37             RegionSubject(rectA, timestamp = Timestamps.empty()).isHigherOrEqual(rectB)
38         }
39         assertFail(expectedMessage) {
40             RegionSubject(rectA, timestamp = Timestamps.empty()).isLower(rectB)
41         }
42         assertFail(expectedMessage) {
43             RegionSubject(rectA, timestamp = Timestamps.empty()).isLowerOrEqual(rectB)
44         }
45     }
46 
47     @Test
detectPositionChangeHighernull48     fun detectPositionChangeHigher() {
49         val rectA = Rect(/* left */ 0, /* top */ 0, /* right */ 1, /* bottom */ 1)
50         val rectB = Rect(/* left */ 0, /* top */ 1, /* right */ 1, /* bottom */ 2)
51         RegionSubject(rectA, timestamp = Timestamps.empty()).isHigher(rectB)
52         RegionSubject(rectA, timestamp = Timestamps.empty()).isHigherOrEqual(rectB)
53         assertFail(MSG_ERROR_TOP_POSITION) {
54             RegionSubject(rectA, timestamp = Timestamps.empty()).isLower(rectB)
55         }
56         assertFail(MSG_ERROR_TOP_POSITION) {
57             RegionSubject(rectA, timestamp = Timestamps.empty()).isLowerOrEqual(rectB)
58         }
59     }
60 
61     @Test
detectPositionChangeLowernull62     fun detectPositionChangeLower() {
63         val rectA = Rect(/* left */ 0, /* top */ 2, /* right */ 1, /* bottom */ 3)
64         val rectB = Rect(/* left */ 0, /* top */ 0, /* right */ 1, /* bottom */ 1)
65         RegionSubject(rectA, timestamp = Timestamps.empty()).isLower(rectB)
66         RegionSubject(rectA, timestamp = Timestamps.empty()).isLowerOrEqual(rectB)
67         assertFail(MSG_ERROR_TOP_POSITION) {
68             RegionSubject(rectA, timestamp = Timestamps.empty()).isHigher(rectB)
69         }
70         assertFail(MSG_ERROR_TOP_POSITION) {
71             RegionSubject(rectA, timestamp = Timestamps.empty()).isHigherOrEqual(rectB)
72         }
73     }
74 
75     @Test
detectPositionChangeEqualHigherLowernull76     fun detectPositionChangeEqualHigherLower() {
77         val rectA = Rect(/* left */ 0, /* top */ 1, /* right */ 1, /* bottom */ 0)
78         val rectB = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 0)
79         RegionSubject(rectA, timestamp = Timestamps.empty()).isHigherOrEqual(rectB)
80         RegionSubject(rectA, timestamp = Timestamps.empty()).isLowerOrEqual(rectB)
81         assertFail(MSG_ERROR_TOP_POSITION) {
82             RegionSubject(rectA, timestamp = Timestamps.empty()).isHigher(rectB)
83         }
84         assertFail(MSG_ERROR_TOP_POSITION) {
85             RegionSubject(rectA, timestamp = Timestamps.empty()).isLower(rectB)
86         }
87     }
88 
89     @Test
detectPositionChangeInvalidnull90     fun detectPositionChangeInvalid() {
91         val rectA = Rect(/* left */ 0, /* top */ 1, /* right */ 2, /* bottom */ 2)
92         val rectB = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
93         val rectC = Rect(/* left */ 0, /* top */ 1, /* right */ 3, /* bottom */ 1)
94         expectAllFailPositionChange(MSG_ERROR_LEFT_POSITION, rectA, rectB)
95         expectAllFailPositionChange(MSG_ERROR_RIGHT_POSITION, rectA, rectC)
96     }
97 
98     @Test
detectCoversAtLeastnull99     fun detectCoversAtLeast() {
100         val rectA = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
101         val rectB = Rect(/* left */ 0, /* top */ 0, /* right */ 2, /* bottom */ 2)
102         RegionSubject(rectA, timestamp = Timestamps.empty()).coversAtLeast(rectA)
103         RegionSubject(rectB, timestamp = Timestamps.empty()).coversAtLeast(rectA)
104         assertFail("SkRegion((0,0,2,1)(0,1,1,2))") {
105             RegionSubject(rectA, timestamp = Timestamps.empty()).coversAtLeast(rectB)
106         }
107     }
108 
109     @Test
detectCoversAtMostnull110     fun detectCoversAtMost() {
111         val rectA = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
112         val rectB = Rect(/* left */ 0, /* top */ 0, /* right */ 2, /* bottom */ 2)
113         RegionSubject(rectA, timestamp = Timestamps.empty()).coversAtMost(rectA)
114         RegionSubject(rectA, timestamp = Timestamps.empty()).coversAtMost(rectB)
115         assertFail("SkRegion((0,0,2,1)(0,1,1,2))") {
116             RegionSubject(rectB, timestamp = Timestamps.empty()).coversAtMost(rectA)
117         }
118     }
119 
120     @Test
detectCoversExactlynull121     fun detectCoversExactly() {
122         val rectA = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
123         val rectB = Rect(/* left */ 0, /* top */ 0, /* right */ 2, /* bottom */ 2)
124         RegionSubject(rectA, timestamp = Timestamps.empty()).coversExactly(rectA)
125         assertFail("SkRegion((0,0,2,1)(0,1,1,2))") {
126             RegionSubject(rectA, timestamp = Timestamps.empty()).coversExactly(rectB)
127         }
128     }
129 
130     @Test
detectOverlapsnull131     fun detectOverlaps() {
132         val rectA = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
133         val rectB = Rect(/* left */ 0, /* top */ 0, /* right */ 2, /* bottom */ 2)
134         val rectC = Rect(/* left */ 2, /* top */ 2, /* right */ 3, /* bottom */ 3)
135         RegionSubject(rectA, timestamp = Timestamps.empty()).overlaps(rectB)
136         RegionSubject(rectB, timestamp = Timestamps.empty()).overlaps(rectA)
137         assertFail("should overlap with ${Region(rectC)}") {
138             RegionSubject(rectA, timestamp = Timestamps.empty()).overlaps(rectC)
139         }
140     }
141 
142     @Test
detectsNotOverlapsnull143     fun detectsNotOverlaps() {
144         val rectA = Rect(/* left */ 1, /* top */ 1, /* right */ 2, /* bottom */ 2)
145         val rectB = Rect(/* left */ 2, /* top */ 2, /* right */ 3, /* bottom */ 3)
146         val rectC = Rect(/* left */ 0, /* top */ 0, /* right */ 2, /* bottom */ 2)
147         RegionSubject(rectA, timestamp = Timestamps.empty()).notOverlaps(rectB)
148         RegionSubject(rectB, timestamp = Timestamps.empty()).notOverlaps(rectA)
149         assertFail("SkRegion((1,1,2,2))") {
150             RegionSubject(rectA, timestamp = Timestamps.empty()).notOverlaps(rectC)
151         }
152     }
153 
154     companion object {
155         @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
156         private const val MSG_ERROR_TOP_POSITION = "top"
157         private const val MSG_ERROR_LEFT_POSITION = "left"
158         private const val MSG_ERROR_RIGHT_POSITION = "right"
159     }
160 }
161