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.flicker.subject.FlickerTraceSubject 22 import android.tools.function.AssertionPredicate 23 import android.tools.io.Reader 24 import android.tools.traces.region.RegionTrace 25 26 /** 27 * Subject for [RegionTrace] objects, used to make assertions over behaviors that occur on a 28 * sequence of regions. 29 */ 30 class RegionTraceSubject 31 @JvmOverloads 32 constructor(val trace: RegionTrace, override val reader: Reader? = null) : 33 FlickerTraceSubject<RegionSubject>(), IRegionSubject { 34 <lambda>null35 override val subjects by lazy { trace.entries.map { RegionSubject(it, it.timestamp, reader) } } 36 37 private val componentsAsString = 38 if (trace.components == null) { 39 "<any>" 40 } else { 41 "[${trace.components}]" 42 } 43 44 /** {@inheritDoc} */ thennull45 override fun then(): RegionTraceSubject { 46 return super.then() as RegionTraceSubject 47 } 48 49 /** {@inheritDoc} */ isHigherOrEqualnull50 override fun isHigherOrEqual(other: Rect): RegionTraceSubject = isHigherOrEqual(Region(other)) 51 52 /** {@inheritDoc} */ 53 override fun isHigherOrEqual(other: Region): RegionTraceSubject = apply { 54 addAssertion("isHigherOrEqual($other, $componentsAsString)") { it.isHigherOrEqual(other) } 55 } 56 57 /** {@inheritDoc} */ isLowerOrEqualnull58 override fun isLowerOrEqual(other: Rect): RegionTraceSubject = isLowerOrEqual(Region(other)) 59 60 /** {@inheritDoc} */ 61 override fun isLowerOrEqual(other: Region): RegionTraceSubject = apply { 62 addAssertion("isLowerOrEqual($other, $componentsAsString)") { it.isLowerOrEqual(other) } 63 } 64 65 /** {@inheritDoc} */ <lambda>null66 override fun isToTheRight(other: Region): RegionTraceSubject = apply { 67 addAssertion("isToTheRight($other, $componentsAsString)") { it.isToTheRight(other) } 68 } 69 70 /** {@inheritDoc} */ <lambda>null71 override fun isLeftEdgeToTheRight(other: Region): RegionTraceSubject = apply { 72 addAssertion("isLeftEdgeToTheRight($other, $componentsAsString)") { 73 it.isLeftEdgeToTheRight(other) 74 } 75 } 76 77 /** {@inheritDoc} */ isHighernull78 override fun isHigher(other: Rect): RegionTraceSubject = isHigher(Region(other)) 79 80 /** {@inheritDoc} */ 81 override fun isHigher(other: Region): RegionTraceSubject = apply { 82 addAssertion("isHigher($other, $componentsAsString)") { it.isHigher(other) } 83 } 84 85 /** {@inheritDoc} */ isLowernull86 override fun isLower(other: Rect): RegionTraceSubject = isLower(Region(other)) 87 88 /** {@inheritDoc} */ 89 override fun isLower(other: Region): RegionTraceSubject = apply { 90 addAssertion("isLower($other, $componentsAsString)") { it.isLower(other) } 91 } 92 93 /** {@inheritDoc} */ <lambda>null94 override fun coversAtMost(other: Region): RegionTraceSubject = apply { 95 addAssertion("coversAtMost($other, $componentsAsString)") { it.coversAtMost(other) } 96 } 97 98 /** {@inheritDoc} */ coversAtMostnull99 override fun coversAtMost(other: Rect): RegionTraceSubject = this.coversAtMost(Region(other)) 100 101 /** {@inheritDoc} */ 102 override fun notBiggerThan(other: Region): RegionTraceSubject = apply { 103 addAssertion("notBiggerThan($other, $componentsAsString)") { it.notBiggerThan(other) } 104 } 105 106 /** {@inheritDoc} */ <lambda>null107 override fun notSmallerThan(other: Region): RegionTraceSubject = apply { 108 addAssertion("notSmallerThan($other, $componentsAsString)") { it.notSmallerThan(other) } 109 } 110 111 /** {@inheritDoc} */ <lambda>null112 override fun isToTheRightBottom(other: Region, threshold: Int): RegionTraceSubject = apply { 113 addAssertion("isToTheRightBottom($other, $componentsAsString)") { 114 it.isToTheRightBottom(other, threshold) 115 } 116 } 117 118 /** {@inheritDoc} */ <lambda>null119 override fun regionsCenterPointInside(other: Rect): RegionTraceSubject = apply { 120 addAssertion("regionsCenterPointInside($other, $componentsAsString)") { 121 it.regionsCenterPointInside(other) 122 } 123 } 124 125 /** {@inheritDoc} */ <lambda>null126 override fun coversAtLeast(other: Region): RegionTraceSubject = apply { 127 addAssertion("coversAtLeast($other, $componentsAsString)") { it.coversAtLeast(other) } 128 } 129 130 /** {@inheritDoc} */ coversAtLeastnull131 override fun coversAtLeast(other: Rect): RegionTraceSubject = this.coversAtLeast(Region(other)) 132 133 /** {@inheritDoc} */ 134 override fun coversExactly(other: Region): RegionTraceSubject = apply { 135 addAssertion("coversExactly($other, $componentsAsString)") { it.coversExactly(other) } 136 } 137 138 /** {@inheritDoc} */ coversExactlynull139 override fun coversExactly(other: Rect): RegionTraceSubject = apply { 140 addAssertion("coversExactly($other, $componentsAsString)") { it.coversExactly(other) } 141 } 142 143 /** {@inheritDoc} */ <lambda>null144 override fun overlaps(other: Region): RegionTraceSubject = apply { 145 addAssertion("overlaps($other, $componentsAsString)") { it.overlaps(other) } 146 } 147 148 /** {@inheritDoc} */ overlapsnull149 override fun overlaps(other: Rect): RegionTraceSubject = overlaps(Region(other)) 150 151 /** {@inheritDoc} */ 152 override fun notOverlaps(other: Region): RegionTraceSubject = apply { 153 addAssertion("notOverlaps($other, $componentsAsString)") { it.notOverlaps(other) } 154 } 155 156 /** {@inheritDoc} */ notOverlapsnull157 override fun notOverlaps(other: Rect): RegionTraceSubject = notOverlaps(Region(other)) 158 159 fun isSameAspectRatio(other: Region): RegionTraceSubject = 160 isSameAspectRatio(other, threshold = 0.1) 161 162 /** {@inheritDoc} */ 163 override fun isSameAspectRatio(other: Region, threshold: Double): RegionTraceSubject = apply { 164 addAssertion("isSameAspectRatio($other, $componentsAsString)") { 165 it.isSameAspectRatio(other, threshold) 166 } 167 } 168 <lambda>null169 override fun hasSameLeftPosition(displayRect: Rect): RegionTraceSubject = apply { 170 addAssertion("hasSameLeftPosition($displayRect)") { it.hasSameLeftPosition(displayRect) } 171 } 172 <lambda>null173 override fun hasSameBottomPosition(displayRect: Rect): RegionTraceSubject = apply { 174 addAssertion("hasSameBottomPosition($displayRect)") { 175 it.hasSameBottomPosition(displayRect) 176 } 177 } 178 <lambda>null179 override fun hasSameRightPosition(displayRect: Rect): RegionTraceSubject = apply { 180 addAssertion("hasSameRightPosition($displayRect)") { it.hasSameRightPosition(displayRect) } 181 } 182 <lambda>null183 override fun hasSameTopPosition(displayRect: Rect): RegionTraceSubject = apply { 184 addAssertion("hasSameTopPosition($displayRect)") { it.hasSameTopPosition(displayRect) } 185 } 186 187 @JvmOverloads invokenull188 operator fun invoke( 189 name: String, 190 isOptional: Boolean = false, 191 assertion: AssertionPredicate<RegionSubject>, 192 ): RegionTraceSubject = apply { addAssertion(name, isOptional, assertion) } 193 } 194