1// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"fmt"
19	"reflect"
20	"strings"
21	"testing"
22)
23
24// This file contains general purpose test assert functions.
25
26// AssertSame checks if the expected and actual values are equal and if they are not then
27// it reports an error prefixed with the supplied message and including a reason for why it failed.
28func AssertSame(t *testing.T, message string, expected interface{}, actual interface{}) {
29	t.Helper()
30	if actual != expected {
31		t.Errorf("%s: expected:\n%#v\nactual:\n%#v", message, expected, actual)
32	}
33}
34
35// AssertBoolEquals checks if the expected and actual values are equal and if they are not then it
36// reports an error prefixed with the supplied message and including a reason for why it failed.
37func AssertBoolEquals(t *testing.T, message string, expected bool, actual bool) {
38	t.Helper()
39	if actual != expected {
40		t.Errorf("%s: expected %t, actual %t", message, expected, actual)
41	}
42}
43
44// AssertIntEquals checks if the expected and actual values are equal and if they are not then it
45// reports an error prefixed with the supplied message and including a reason for why it failed.
46func AssertIntEquals(t *testing.T, message string, expected int, actual int) {
47	t.Helper()
48	if actual != expected {
49		t.Errorf("%s: expected %d, actual %d", message, expected, actual)
50	}
51}
52
53// AssertStringEquals checks if the expected and actual values are equal and if they are not then
54// it reports an error prefixed with the supplied message and including a reason for why it failed.
55func AssertStringEquals(t *testing.T, message string, expected string, actual string) {
56	t.Helper()
57	if actual != expected {
58		t.Errorf("%s: expected %s, actual %s", message, expected, actual)
59	}
60}
61
62// AssertPathRelativeToTopEquals checks if the expected value is equal to the result of calling
63// PathRelativeToTop on the actual Path.
64func AssertPathRelativeToTopEquals(t *testing.T, message string, expected string, actual Path) {
65	t.Helper()
66	AssertStringEquals(t, message, expected, PathRelativeToTop(actual))
67}
68
69// AssertPathsRelativeToTopEquals checks if the expected value is equal to the result of calling
70// PathsRelativeToTop on the actual Paths.
71func AssertPathsRelativeToTopEquals(t *testing.T, message string, expected []string, actual Paths) {
72	t.Helper()
73	AssertDeepEquals(t, message, expected, PathsRelativeToTop(actual))
74}
75
76// AssertStringPathRelativeToTopEquals checks if the expected value is equal to the result of calling
77// StringPathRelativeToTop on the actual string path.
78func AssertStringPathRelativeToTopEquals(t *testing.T, message string, config Config, expected string, actual string) {
79	t.Helper()
80	AssertStringEquals(t, message, expected, StringPathRelativeToTop(config.buildDir, actual))
81}
82
83// AssertStringPathsRelativeToTopEquals checks if the expected value is equal to the result of
84// calling StringPathsRelativeToTop on the actual string paths.
85func AssertStringPathsRelativeToTopEquals(t *testing.T, message string, config Config, expected []string, actual []string) {
86	t.Helper()
87	AssertDeepEquals(t, message, expected, StringPathsRelativeToTop(config.buildDir, actual))
88}
89
90// AssertErrorMessageEquals checks if the error is not nil and has the expected message. If it does
91// not then this reports an error prefixed with the supplied message and including a reason for why
92// it failed.
93func AssertErrorMessageEquals(t *testing.T, message string, expected string, actual error) {
94	t.Helper()
95	if actual == nil {
96		t.Errorf("Expected error but was nil")
97	} else if actual.Error() != expected {
98		t.Errorf("%s: expected %s, actual %s", message, expected, actual.Error())
99	}
100}
101
102// AssertTrimmedStringEquals checks if the expected and actual values are the same after trimming
103// leading and trailing spaces from them both. If they are not then it reports an error prefixed
104// with the supplied message and including a reason for why it failed.
105func AssertTrimmedStringEquals(t *testing.T, message string, expected string, actual string) {
106	t.Helper()
107	AssertStringEquals(t, message, strings.TrimSpace(expected), strings.TrimSpace(actual))
108}
109
110// AssertStringDoesContain checks if the string contains the expected substring. If it does not
111// then it reports an error prefixed with the supplied message and including a reason for why it
112// failed.
113func AssertStringDoesContain(t *testing.T, message string, s string, expectedSubstring string) {
114	t.Helper()
115	if !strings.Contains(s, expectedSubstring) {
116		t.Errorf("%s: could not find %q within %q", message, expectedSubstring, s)
117	}
118}
119
120// AssertStringDoesNotContain checks if the string contains the expected substring. If it does then
121// it reports an error prefixed with the supplied message and including a reason for why it failed.
122func AssertStringDoesNotContain(t *testing.T, message string, s string, unexpectedSubstring string) {
123	t.Helper()
124	if strings.Contains(s, unexpectedSubstring) {
125		t.Errorf("%s: unexpectedly found %q within %q", message, unexpectedSubstring, s)
126	}
127}
128
129// AssertStringContainsEquals checks if the string contains or does not contain the substring, given
130// the value of the expected bool. If the expectation does not hold it reports an error prefixed with
131// the supplied message and including a reason for why it failed.
132func AssertStringContainsEquals(t *testing.T, message string, s string, substring string, expected bool) {
133	if expected {
134		AssertStringDoesContain(t, message, s, substring)
135	} else {
136		AssertStringDoesNotContain(t, message, s, substring)
137	}
138}
139
140// AssertStringListContains checks if the list of strings contains the expected string. If it does
141// not then it reports an error prefixed with the supplied message and including a reason for why it
142// failed.
143func AssertStringListContains(t *testing.T, message string, list []string, s string) {
144	t.Helper()
145	if !InList(s, list) {
146		t.Errorf("%s: could not find %q within %q", message, s, list)
147	}
148}
149
150// AssertStringListDoesNotContain checks if the list of strings contains the expected string. If it does
151// then it reports an error prefixed with the supplied message and including a reason for why it failed.
152func AssertStringListDoesNotContain(t *testing.T, message string, list []string, s string) {
153	t.Helper()
154	if InList(s, list) {
155		t.Errorf("%s: unexpectedly found %q within %q", message, s, list)
156	}
157}
158
159// AssertStringContainsEquals checks if the string contains or does not contain the substring, given
160// the value of the expected bool. If the expectation does not hold it reports an error prefixed with
161// the supplied message and including a reason for why it failed.
162func AssertStringListContainsEquals(t *testing.T, message string, list []string, s string, expected bool) {
163	if expected {
164		AssertStringListContains(t, message, list, s)
165	} else {
166		AssertStringListDoesNotContain(t, message, list, s)
167	}
168}
169
170// AssertArrayString checks if the expected and actual values are equal and if they are not then it
171// reports an error prefixed with the supplied message and including a reason for why it failed.
172func AssertArrayString(t *testing.T, message string, expected, actual []string) {
173	t.Helper()
174	if len(actual) != len(expected) {
175		t.Errorf("%s: expected %d (%q), actual (%d) %q", message, len(expected), expected, len(actual), actual)
176		return
177	}
178	for i := range actual {
179		if actual[i] != expected[i] {
180			t.Errorf("%s: expected %d-th, %q (%q), actual %q (%q)",
181				message, i, expected[i], expected, actual[i], actual)
182			return
183		}
184	}
185}
186
187// AssertDeepEquals checks if the expected and actual values are equal using reflect.DeepEqual and
188// if they are not then it reports an error prefixed with the supplied message and including a
189// reason for why it failed.
190func AssertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
191	t.Helper()
192	if !reflect.DeepEqual(actual, expected) {
193		t.Errorf("%s: expected:\n  %#v\n got:\n  %#v", message, expected, actual)
194	}
195}
196
197// AssertPanicMessageContains checks that the supplied function panics as expected and the message
198// obtained by formatting the recovered value as a string contains the expected contents.
199func AssertPanicMessageContains(t *testing.T, message, expectedMessageContents string, funcThatShouldPanic func()) {
200	t.Helper()
201	panicked := false
202	var recovered interface{}
203	func() {
204		defer func() {
205			if recovered = recover(); recovered != nil {
206				panicked = true
207			}
208		}()
209		funcThatShouldPanic()
210	}()
211	if !panicked {
212		t.Errorf("%s: did not panic", message)
213	}
214
215	panicMessage := fmt.Sprintf("%s", recovered)
216	AssertStringDoesContain(t, fmt.Sprintf("%s: panic message", message), panicMessage, expectedMessageContents)
217}
218