1 /*
<lambda>null2  * Copyright 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 androidx.glance.testing
18 
19 import java.lang.StringBuilder
20 
21 /**
22  * Builds error message with reason appended.
23  *
24  * @param errorMessageOnFail message explaining which operation you were about to perform. This
25  *   makes it easier for developer to find where the failure happened.
26  * @param reason the reason for failure
27  */
28 internal fun buildErrorMessageWithReason(errorMessageOnFail: String, reason: String): String {
29     return "${errorMessageOnFail}\nReason: $reason"
30 }
31 
32 /**
33  * Builds error reason for case where amount of matching nodes are less than needed to query given
34  * index and perform assertions on (e.g. if getting a node at index 2 but only 2 nodes exist in the
35  * collection).
36  */
buildErrorReasonForIndexOutOfMatchedNodeBoundsnull37 internal fun buildErrorReasonForIndexOutOfMatchedNodeBounds(
38     matcherDescription: String,
39     requestedIndex: Int,
40     actualCount: Int
41 ): String {
42     return "Not enough node(s) matching condition: ($matcherDescription) " +
43         "to get node at index '$requestedIndex'. Found '$actualCount' matching node(s)"
44 }
45 
46 /** Builds error reason for case where expected amount of matching nodes does not match reality. */
buildErrorReasonForCountMismatchnull47 internal fun buildErrorReasonForCountMismatch(
48     matcherDescription: String,
49     expectedCount: Int,
50     actualCount: Int
51 ): String {
52     val sb = StringBuilder()
53 
54     when (expectedCount) {
55         0 -> {
56             sb.append("Did not expect any node matching condition: $matcherDescription")
57         }
58         else -> {
59             sb.append("Expected '$expectedCount' node(s) matching condition: $matcherDescription")
60         }
61     }
62 
63     sb.append(", but found '$actualCount'")
64 
65     return sb.toString()
66 }
67 
68 /**
69  * Builds error reason for assertions where at least one node was expected to be present to make
70  * assertions on (e.g. assertAny).
71  */
buildErrorReasonForAtLeastOneNodeExpectednull72 internal fun buildErrorReasonForAtLeastOneNodeExpected(matcherDescription: String): String {
73     return "Expected to receive at least 1 node " +
74         "but 0 nodes were found for condition: ($matcherDescription)"
75 }
76 
77 /**
78  * Builds error message for general assertion errors involving a single node.
79  *
80  * <p>Provide [errorMessage] to explain which operation you were about to perform. This makes it
81  * easier for developer to find where the failure happened.
82  */
buildGeneralErrorMessagenull83 internal fun <R> buildGeneralErrorMessage(errorMessage: String, node: GlanceNode<R>): String {
84     val sb = StringBuilder()
85     sb.append(errorMessage)
86 
87     sb.append("\n")
88     sb.append("Glance Node: ${node.toDebugString()}")
89 
90     return sb.toString()
91 }
92 
93 /**
94  * Builds error message for general assertion errors for multiple nodes.
95  *
96  * <p>Provide [errorMessage] to explain which operation you were about to perform. This makes it
97  * easier for developer to find where the failure happened.
98  */
buildGeneralErrorMessagenull99 internal fun <R> buildGeneralErrorMessage(
100     errorMessage: String,
101     nodes: List<GlanceNode<R>>
102 ): String {
103     val sb = StringBuilder()
104     sb.append(errorMessage)
105 
106     sb.append("\n")
107     sb.append("Found ${nodes.size} node(s) that don't match.")
108 
109     nodes.forEachIndexed { index, glanceNode ->
110         sb.append("\nNon-matching Glance Node #${index + 1}: ${glanceNode.toDebugString()}")
111     }
112 
113     return sb.toString()
114 }
115