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} */ isHighernull71 override fun isHigher(other: Rect): RegionTraceSubject = isHigher(Region(other)) 72 73 /** {@inheritDoc} */ 74 override fun isHigher(other: Region): RegionTraceSubject = apply { 75 addAssertion("isHigher($other, $componentsAsString)") { it.isHigher(other) } 76 } 77 78 /** {@inheritDoc} */ isLowernull79 override fun isLower(other: Rect): RegionTraceSubject = isLower(Region(other)) 80 81 /** {@inheritDoc} */ 82 override fun isLower(other: Region): RegionTraceSubject = apply { 83 addAssertion("isLower($other, $componentsAsString)") { it.isLower(other) } 84 } 85 86 /** {@inheritDoc} */ <lambda>null87 override fun coversAtMost(other: Region): RegionTraceSubject = apply { 88 addAssertion("coversAtMost($other, $componentsAsString)") { it.coversAtMost(other) } 89 } 90 91 /** {@inheritDoc} */ coversAtMostnull92 override fun coversAtMost(other: Rect): RegionTraceSubject = this.coversAtMost(Region(other)) 93 94 /** {@inheritDoc} */ 95 override fun notBiggerThan(other: Region): RegionTraceSubject = apply { 96 addAssertion("notBiggerThan($other, $componentsAsString)") { it.notBiggerThan(other) } 97 } 98 99 /** {@inheritDoc} */ <lambda>null100 override fun notSmallerThan(other: Region): RegionTraceSubject = apply { 101 addAssertion("notSmallerThan($other, $componentsAsString)") { it.notSmallerThan(other) } 102 } 103 104 /** {@inheritDoc} */ <lambda>null105 override fun isToTheRightBottom(other: Region, threshold: Int): RegionTraceSubject = apply { 106 addAssertion("isToTheRightBottom($other, $componentsAsString)") { 107 it.isToTheRightBottom(other, threshold) 108 } 109 } 110 111 /** {@inheritDoc} */ <lambda>null112 override fun regionsCenterPointInside(other: Rect): RegionTraceSubject = apply { 113 addAssertion("regionsCenterPointInside($other, $componentsAsString)") { 114 it.regionsCenterPointInside(other) 115 } 116 } 117 118 /** {@inheritDoc} */ <lambda>null119 override fun coversAtLeast(other: Region): RegionTraceSubject = apply { 120 addAssertion("coversAtLeast($other, $componentsAsString)") { it.coversAtLeast(other) } 121 } 122 123 /** {@inheritDoc} */ coversAtLeastnull124 override fun coversAtLeast(other: Rect): RegionTraceSubject = this.coversAtLeast(Region(other)) 125 126 /** {@inheritDoc} */ 127 override fun coversExactly(other: Region): RegionTraceSubject = apply { 128 addAssertion("coversExactly($other, $componentsAsString)") { it.coversExactly(other) } 129 } 130 131 /** {@inheritDoc} */ coversExactlynull132 override fun coversExactly(other: Rect): RegionTraceSubject = apply { 133 addAssertion("coversExactly($other, $componentsAsString)") { it.coversExactly(other) } 134 } 135 136 /** {@inheritDoc} */ <lambda>null137 override fun overlaps(other: Region): RegionTraceSubject = apply { 138 addAssertion("overlaps($other, $componentsAsString)") { it.overlaps(other) } 139 } 140 141 /** {@inheritDoc} */ overlapsnull142 override fun overlaps(other: Rect): RegionTraceSubject = overlaps(Region(other)) 143 144 /** {@inheritDoc} */ 145 override fun notOverlaps(other: Region): RegionTraceSubject = apply { 146 addAssertion("notOverlaps($other, $componentsAsString)") { it.notOverlaps(other) } 147 } 148 149 /** {@inheritDoc} */ notOverlapsnull150 override fun notOverlaps(other: Rect): RegionTraceSubject = notOverlaps(Region(other)) 151 152 fun isSameAspectRatio(other: Region): RegionTraceSubject = 153 isSameAspectRatio(other, threshold = 0.1) 154 155 /** {@inheritDoc} */ 156 override fun isSameAspectRatio(other: Region, threshold: Double): RegionTraceSubject = apply { 157 addAssertion("isSameAspectRatio($other, $componentsAsString)") { 158 it.isSameAspectRatio(other, threshold) 159 } 160 } 161 <lambda>null162 override fun hasSameLeftPosition(displayRect: Rect): RegionTraceSubject = apply { 163 addAssertion("hasSameLeftPosition($displayRect)") { it.hasSameLeftPosition(displayRect) } 164 } 165 <lambda>null166 override fun hasSameBottomPosition(displayRect: Rect): RegionTraceSubject = apply { 167 addAssertion("hasSameBottomPosition($displayRect)") { 168 it.hasSameBottomPosition(displayRect) 169 } 170 } 171 <lambda>null172 override fun hasSameRightPosition(displayRect: Rect): RegionTraceSubject = apply { 173 addAssertion("hasSameRightPosition($displayRect)") { it.hasSameRightPosition(displayRect) } 174 } 175 <lambda>null176 override fun hasSameTopPosition(displayRect: Rect): RegionTraceSubject = apply { 177 addAssertion("hasSameTopPosition($displayRect)") { it.hasSameTopPosition(displayRect) } 178 } 179 180 @JvmOverloads invokenull181 operator fun invoke( 182 name: String, 183 isOptional: Boolean = false, 184 assertion: AssertionPredicate<RegionSubject>, 185 ): RegionTraceSubject = apply { addAssertion(name, isOptional, assertion) } 186 } 187