// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.testutil;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.util.BlazeClock;
import com.google.devtools.build.lib.util.ExitCode;
import junit.framework.TestCase;
import java.util.Objects;
import java.util.Set;
/**
* Most of this stuff is copied from junit's {@link junit.framework.Assert}
* class, and then customized to make the error messages a bit more informative.
*/
public abstract class ChattyAssertsTestCase extends TestCase {
private long currentTestStartTime = -1;
@Override
protected void setUp() throws Exception {
super.setUp();
currentTestStartTime = BlazeClock.instance().currentTimeMillis();
}
@Override
protected void tearDown() throws Exception {
JunitTestUtils.nullifyInstanceFields(this);
assertFalse("tearDown without setUp!", currentTestStartTime == -1);
super.tearDown();
}
/**
* Asserts that two objects are equal. If they are not
* an AssertionFailedError is thrown with the given message.
*/
public static void assertEquals(String message, Object expected,
Object actual) {
if (Objects.equals(expected, actual)) {
return;
}
chattyFailNotEquals(message, expected, actual);
}
/**
* Asserts that two objects are equal. If they are not
* an AssertionFailedError is thrown.
*/
public static void assertEquals(Object expected, Object actual) {
assertEquals(null, expected, actual);
}
/**
* Asserts that two Strings are equal.
*/
public static void assertEquals(String message, String expected, String actual) {
assertWithMessage(message).that(actual).isEqualTo(expected);
}
/**
* Asserts that two Strings are equal.
*/
public static void assertEquals(String expected, String actual) {
assertEquals(null, expected, actual);
}
/**
* Asserts that two Strings are equal considering the line separator to be \n
* independently of the operating system.
*/
public static void assertEqualsUnifyingLineEnds(String expected, String actual) {
MoreAsserts.assertEqualsUnifyingLineEnds(expected, actual);
}
private static void chattyFailNotEquals(String message, Object expected,
Object actual) {
fail(MoreAsserts.chattyFormat(message, expected, actual));
}
/**
* Asserts that {@code e}'s exception message contains each of {@code strings}
* surrounded by single quotation marks.
*/
public static void assertMessageContainsWordsWithQuotes(Exception e,
String... strings) {
assertContainsWordsWithQuotes(e.getMessage(), strings);
}
/**
* Asserts that {@code message} contains each of {@code strings}
* surrounded by single quotation marks.
*/
public static void assertContainsWordsWithQuotes(String message,
String... strings) {
MoreAsserts.assertContainsWordsWithQuotes(message, strings);
}
public static void assertNonZeroExitCode(int exitCode, String stdout, String stderr) {
MoreAsserts.assertNonZeroExitCode(exitCode, stdout, stderr);
}
public static void assertZeroExitCode(int exitCode, String stdout, String stderr) {
assertExitCode(0, exitCode, stdout, stderr);
}
public static void assertExitCode(ExitCode expectedExitCode,
int exitCode, String stdout, String stderr) {
int expectedExitCodeValue = expectedExitCode.getNumericExitCode();
if (exitCode != expectedExitCodeValue) {
fail(String.format("expected exit code '%s' <%d> but exit code was <%d> and stdout was <%s> "
+ "and stderr was <%s>",
expectedExitCode.name(), expectedExitCodeValue, exitCode, stdout, stderr));
}
}
public static void assertExitCode(int expectedExitCode,
int exitCode, String stdout, String stderr) {
MoreAsserts.assertExitCode(expectedExitCode, exitCode, stdout, stderr);
}
public static void assertStdoutContainsString(String expected, String stdout, String stderr) {
MoreAsserts.assertStdoutContainsString(expected, stdout, stderr);
}
public static void assertStderrContainsString(String expected, String stdout, String stderr) {
MoreAsserts.assertStderrContainsString(expected, stdout, stderr);
}
public static void assertStdoutContainsRegex(String expectedRegex,
String stdout, String stderr) {
MoreAsserts.assertStdoutContainsRegex(expectedRegex, stdout, stderr);
}
public static void assertStderrContainsRegex(String expectedRegex,
String stdout, String stderr) {
MoreAsserts.assertStderrContainsRegex(expectedRegex, stdout, stderr);
}
/********************************************************************
* *
* Other testing utilities (unrelated to "chattiness") *
* *
********************************************************************/
/**
* Returns the elements from the given collection in a set.
*/
protected static Set asSet(Iterable collection) {
return Sets.newHashSet(collection);
}
/**
* Returns the arguments given as varargs as a set.
*/
@SuppressWarnings({"unchecked", "varargs"})
protected static Set asSet(T... elements) {
return Sets.newHashSet(elements);
}
/**
* Returns the arguments given as varargs as a set of sorted Strings.
*/
protected static Set asStringSet(Iterable> collection) {
return MoreAsserts.asStringSet(collection);
}
/**
* An equivalence relation for Collection, based on mapping to Set.
*
* Oft-forgotten fact: for all x in Set, y in List, !x.equals(y) even if
* their elements are the same.
*/
protected static void
assertSameContents(Iterable extends T> expected, Iterable extends T> actual) {
MoreAsserts.assertSameContents(expected, actual);
}
/**
* Asserts the presence or absence of values in the collection.
*/
protected void assertPresence(Iterable actual, Iterable> expectedPresences) {
for (Presence expected : expectedPresences) {
if (expected.presence) {
assertThat(actual).contains(expected.value);
} else {
assertThat(actual).doesNotContain(expected.value);
}
}
}
/** Creates a presence information with expected value. */
protected static Presence present(T expected) {
return new Presence<>(expected, true);
}
/** Creates an absence information with expected value. */
protected static Presence absent(T expected) {
return new Presence<>(expected, false);
}
/**
* Combines value with the boolean presence flag.
*
* @param value type
*/
protected final static class Presence {
/** wrapped value */
public final T value;
/** boolean presence flag */
public final boolean presence;
/** Creates a tuple of value and a boolean presence flag. */
Presence(T value, boolean presence) {
this.value = value;
this.presence = presence;
}
}
}