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.exceptions 18 19 import android.tools.Timestamp 20 import android.tools.Timestamps 21 import android.tools.flicker.assertions.Fact 22 import android.tools.flicker.subject.FlickerSubject 23 import android.tools.io.Reader 24 25 /** Class to build flicker exception messages */ 26 class ExceptionMessageBuilder { 27 private var timestamp = Timestamps.empty() 28 private var expected = "" 29 private var actual = mutableListOf<String>() 30 private var headerDescription = "" 31 private var extraDescription = mutableListOf<Fact>() 32 <lambda>null33 fun forSubject(value: FlickerSubject) = apply { 34 setTimestamp(value.timestamp) 35 addExtraDescription(value.selfFacts) 36 val reader = value.reader 37 if (reader != null) { 38 setReader(reader) 39 } 40 } 41 forInvalidElementnull42 fun forInvalidElement(elementName: String, expectElementExists: Boolean) = 43 setMessage("$elementName should ${if (expectElementExists) "" else "not "}exist") 44 .setExpected(elementName) 45 46 fun forIncorrectVisibility(elementName: String, expectElementVisible: Boolean) = 47 setMessage("$elementName should ${if (expectElementVisible) "" else "not "}be visible") 48 .setExpected(elementName) 49 50 fun forInvalidProperty(propertyName: String) = setMessage("Incorrect value for $propertyName") 51 52 fun forIncorrectRegion(propertyName: String) = setMessage("Incorrect $propertyName") 53 54 fun setTimestamp(value: Timestamp) = apply { timestamp = value } 55 <lambda>null56 fun setMessage(value: String) = apply { headerDescription = value } 57 <lambda>null58 fun setExpected(value: Any?) = apply { expected = value?.toString() ?: "null" } 59 <lambda>null60 fun setActual(value: Collection<String>) = apply { actual.addAll(value) } 61 setActualnull62 fun setActual(value: Any?) = setActual(listOf(value?.toString() ?: "null")) 63 64 fun setReader(value: Reader) = addExtraDescription("Artifact", value.artifact) 65 66 fun addExtraDescription(key: String, value: Any?) = addExtraDescription(Fact(key, value)) 67 68 fun addExtraDescription(vararg value: Fact) = addExtraDescription(value.toList()) 69 70 fun addExtraDescription(value: Collection<Fact>) = apply { extraDescription.addAll(value) } 71 <lambda>null72 fun build(): String = buildString { 73 if (headerDescription.isNotEmpty()) { 74 appendLine(headerDescription) 75 appendLine() 76 } 77 78 if (!timestamp.isEmpty) { 79 appendLine("Where?") 80 appendLine(timestamp.toString().prependIndent("\t")) 81 } 82 83 if (expected.isNotEmpty() || actual.isNotEmpty()) { 84 appendLine() 85 appendLine("What?") 86 } 87 88 if (expected.isNotEmpty()) { 89 append("Expected: ".prependIndent("\t")) 90 appendLine(expected) 91 } 92 93 actual 94 .filter { it.isNotEmpty() } 95 .forEach { 96 append("Actual: ".prependIndent("\t")) 97 appendLine(it) 98 } 99 100 if (extraDescription.isNotEmpty()) { 101 appendLine() 102 appendLine("Other information") 103 extraDescription.forEach { appendLine(it.toString().prependIndent("\t")) } 104 } 105 106 appendLine() 107 appendLine("Check the test run artifacts for trace files") 108 } 109 } 110