Skip to content

Commit

Permalink
Document and expose the new failure API, including performing the ren…
Browse files Browse the repository at this point in the history
…ames decided upon in API Review.

RELNOTES=Introduced the new API for building failure messages in a "key: value" format. See `Subject.failWithActual` and `failWithoutActual`, which use the new `Fact` class.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=195446678
  • Loading branch information
cpovirk authored and ronshapiro committed May 8, 2018
1 parent 13dfbd3 commit e06ca85
Show file tree
Hide file tree
Showing 27 changed files with 251 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.google.common.truth;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;

import java.lang.reflect.Array;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
Expand All @@ -35,14 +35,14 @@ abstract class AbstractArraySubject<S extends AbstractArraySubject<S, T>, T> ext
/** Fails if the array is not empty (i.e. {@code array.length != 0}). */
public final void isEmpty() {
if (length() > 0) {
fail(factWithoutValue("expected to be empty"));
failWithActual(simpleFact("expected to be empty"));
}
}

/** Fails if the array is empty (i.e. {@code array.length == 0}). */
public final void isNotEmpty() {
if (length() == 0) {
failWithoutActual(factWithoutValue("expected not to be empty"));
failWithoutActual(simpleFact("expected not to be empty"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Maps.immutableEntry;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;

import com.google.common.util.concurrent.AtomicLongMap;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
Expand Down Expand Up @@ -58,14 +58,14 @@ public void isNotEqualTo(@NullableDecl Object other) {
/** Fails if the {@link AtomicLongMap} is not empty. */
public void isEmpty() {
if (!actual().isEmpty()) {
fail(factWithoutValue("expected to be empty"));
failWithActual(simpleFact("expected to be empty"));
}
}

/** Fails if the {@link AtomicLongMap} is empty. */
public void isNotEmpty() {
if (actual().isEmpty()) {
failWithoutActual(factWithoutValue("expected not to be empty"));
failWithoutActual(simpleFact("expected not to be empty"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.google.common.truth;

import static com.google.common.truth.Fact.fact;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;

import java.math.BigDecimal;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
Expand Down Expand Up @@ -91,8 +91,7 @@ public void isEquivalentAccordingToCompareTo(BigDecimal expected) {

private void compareValues(BigDecimal expected) {
if (actual().compareTo(expected) != 0) {
failWithoutActual(
fact("expected", expected), butWas(), factWithoutValue("(scale is ignored)"));
failWithoutActual(fact("expected", expected), butWas(), simpleFact("(scale is ignored)"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package com.google.common.truth;

import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;

import org.checkerframework.checker.nullness.compatqual.NullableDecl;

Expand All @@ -34,7 +34,7 @@ public void isTrue() {
if (actual() == null) {
isEqualTo(true); // fails
} else if (!actual()) {
failWithoutActual(factWithoutValue("expected to be true"));
failWithoutActual(simpleFact("expected to be true"));
}
}

Expand All @@ -43,7 +43,7 @@ public void isFalse() {
if (actual() == null) {
isEqualTo(false); // fails
} else if (actual()) {
failWithoutActual(factWithoutValue("expected to be false"));
failWithoutActual(simpleFact("expected to be false"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public final class ClassSubject extends Subject<ClassSubject, Class<?>> {
*/
public void isAssignableTo(Class<?> clazz) {
if (!clazz.isAssignableFrom(actual())) {
failWithFact("expected to be assignable to", clazz.getName());
failWithActual("expected to be assignable to", clazz.getName());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ protected ComparableSubject(FailureMetadata metadata, @NullableDecl T actual) {
/** Checks that the subject is in {@code range}. */
public final void isIn(Range<T> range) {
if (!range.contains(actual())) {
failWithFact("expected to be in range", range);
failWithActual("expected to be in range", range);
}
}

/** Checks that the subject is <i>not</i> in {@code range}. */
public final void isNotIn(Range<T> range) {
if (range.contains(actual())) {
failWithFact("expected not to be in range", range);
failWithActual("expected not to be in range", range);
}
}

Expand All @@ -56,7 +56,7 @@ public final void isNotIn(Range<T> range) {
*/
public void isEquivalentAccordingToCompareTo(T expected) {
if (actual().compareTo(expected) != 0) {
failWithFact("expected value that sorts equal to", expected);
failWithActual("expected value that sorts equal to", expected);
}
}

Expand All @@ -82,7 +82,7 @@ public void comparesEqualTo(T other) {
*/
public final void isGreaterThan(T other) {
if (actual().compareTo(other) <= 0) {
failWithFact("expected to be greater than", other);
failWithActual("expected to be greater than", other);
}
}

Expand All @@ -94,7 +94,7 @@ public final void isGreaterThan(T other) {
*/
public final void isLessThan(T other) {
if (actual().compareTo(other) >= 0) {
failWithFact("expected to be less than", other);
failWithActual("expected to be less than", other);
}
}

Expand All @@ -105,7 +105,7 @@ public final void isLessThan(T other) {
*/
public final void isAtMost(T other) {
if (actual().compareTo(other) > 0) {
failWithFact("expected to be at most", other);
failWithActual("expected to be at most", other);
}
}

Expand All @@ -116,7 +116,7 @@ public final void isAtMost(T other) {
*/
public final void isAtLeast(T other) {
if (actual().compareTo(other) < 0) {
failWithFact("expected to be at least", other);
failWithActual("expected to be at least", other);
}
}
}
12 changes: 6 additions & 6 deletions core/src/main/java/com/google/common/truth/DoubleSubject.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Fact.fact;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;
import static com.google.common.truth.MathUtil.equalWithinTolerance;
import static com.google.common.truth.MathUtil.notEqualWithinTolerance;
import static com.google.common.truth.Platform.doubleToString;
Expand Down Expand Up @@ -217,7 +217,7 @@ static void checkTolerance(double tolerance) {
/** Asserts that the subject is zero (i.e. it is either {@code 0.0} or {@code -0.0}). */
public final void isZero() {
if (actual() == null || actual().doubleValue() != 0.0) {
fail(factWithoutValue("expected zero"));
failWithActual(simpleFact("expected zero"));
}
}

Expand All @@ -227,9 +227,9 @@ public final void isZero() {
*/
public final void isNonZero() {
if (actual() == null) {
fail(factWithoutValue("expected a double other than zero"));
failWithActual(simpleFact("expected a double other than zero"));
} else if (actual().doubleValue() == 0.0) {
fail(factWithoutValue("expected not to be zero"));
failWithActual(simpleFact("expected not to be zero"));
}
}

Expand All @@ -254,7 +254,7 @@ public final void isNaN() {
*/
public final void isFinite() {
if (actual() == null || actual().isNaN() || actual().isInfinite()) {
fail(factWithoutValue("expected to be finite"));
failWithActual(simpleFact("expected to be finite"));
}
}

Expand All @@ -264,7 +264,7 @@ public final void isFinite() {
*/
public final void isNotNaN() {
if (actual() == null) {
fail(factWithoutValue("expected a double other than NaN"));
failWithActual(simpleFact("expected a double other than NaN"));
} else {
isNotEqualTo(NaN);
}
Expand Down
25 changes: 21 additions & 4 deletions core/src/main/java/com/google/common/truth/Fact.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,38 @@
import java.io.Serializable;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;

/** A string key-value pair in a failure message, such as "expected: abc" or "but was: xyz." */
final class Fact implements Serializable {
/**
* A string key-value pair in a failure message, such as "expected: abc" or "but was: xyz."
*
* <p>Most Truth users will never interact with this type. It appears in the Truth API only as a
* parameter to methods like {@link Subject#failWithActual(Fact, Fact...)}, which are used only by
* custom {@code Subject} implementations.
*/
public final class Fact implements Serializable {
/**
* Creates a fact with the given key and value, which will be printed in a format like "key:
* value." The value is converted to a string by calling {@code String.valueOf} on it.
*/
static Fact fact(String key, Object value) {
public static Fact fact(String key, @NullableDecl Object value) {
return new Fact(key, String.valueOf(value));
}

/**
* Creates a fact with no value, which will be printed in the format "key" (with no colon or
* value).
*
* <p>In most cases, prefer {@linkplain #fact key-value facts}, which give Truth more flexibility
* in how to format the fact for display. {@code simpleFact} is useful primarily for:
*
* <ul>
* <li>messages from no-arg assertions. For example, {@code isNotEmpty()} would generate the
* fact "expected not to be empty"
* <li>prose that is part of a larger message. For example, {@code contains()} sometimes
* displays facts like "expected to contain: ..." <i>"but did not"</i> "though it did
* contain: ..."
* </ul>
*/
static Fact factWithoutValue(String key) {
public static Fact simpleFact(String key) {
return new Fact(key, null);
}

Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/com/google/common/truth/FloatSubject.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Fact.fact;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;
import static com.google.common.truth.MathUtil.equalWithinTolerance;
import static com.google.common.truth.MathUtil.notEqualWithinTolerance;
import static com.google.common.truth.Platform.floatToString;
Expand Down Expand Up @@ -215,7 +215,7 @@ static void checkTolerance(float tolerance) {
/** Asserts that the subject is zero (i.e. it is either {@code 0.0f} or {@code -0.0f}). */
public final void isZero() {
if (actual() == null || actual().floatValue() != 0.0f) {
fail(factWithoutValue("expected zero"));
failWithActual(simpleFact("expected zero"));
}
}

Expand All @@ -225,9 +225,9 @@ public final void isZero() {
*/
public final void isNonZero() {
if (actual() == null) {
fail(factWithoutValue("expected a float other than zero"));
failWithActual(simpleFact("expected a float other than zero"));
} else if (actual().floatValue() == 0.0f) {
fail(factWithoutValue("expected not to be zero"));
failWithActual(simpleFact("expected not to be zero"));
}
}

Expand All @@ -252,7 +252,7 @@ public final void isNaN() {
*/
public final void isFinite() {
if (actual() == null || actual().isNaN() || actual().isInfinite()) {
fail(factWithoutValue("expected to be finite"));
failWithActual(simpleFact("expected to be finite"));
}
}

Expand All @@ -262,7 +262,7 @@ public final void isFinite() {
*/
public final void isNotNaN() {
if (actual() == null) {
fail(factWithoutValue("expected a float other than NaN"));
failWithActual(simpleFact("expected a float other than NaN"));
} else {
isNotEqualTo(NaN);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.google.common.truth;

import static com.google.common.truth.Fact.fact;
import static com.google.common.truth.Fact.factWithoutValue;
import static com.google.common.truth.Fact.simpleFact;

import com.google.common.base.Optional;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
Expand All @@ -40,20 +40,19 @@ public final class GuavaOptionalSubject extends Subject<GuavaOptionalSubject, Op
/** Fails if the {@link Optional}{@code <T>} is absent or the subject is null. */
public void isPresent() {
if (actual() == null) {
fail(factWithoutValue("expected present optional"));
failWithActual(simpleFact("expected present optional"));
} else if (!actual().isPresent()) {
failWithoutActual(factWithoutValue("expected to be present"));
failWithoutActual(simpleFact("expected to be present"));
}
}

/** Fails if the {@link Optional}{@code <T>} is present or the subject is null. */
public void isAbsent() {
if (actual() == null) {
fail(factWithoutValue("expected absent optional"));
failWithActual(simpleFact("expected absent optional"));
} else if (actual().isPresent()) {
failWithoutActual(
factWithoutValue("expected to be absent"),
fact("but was present with value", actual().get()));
simpleFact("expected to be absent"), fact("but was present with value", actual().get()));
}
}

Expand All @@ -72,10 +71,9 @@ public void hasValue(Object expected) {
throw new NullPointerException("Optional cannot have a null value.");
}
if (actual() == null) {
failWithFact("expected an optional with value", expected);
failWithActual("expected an optional with value", expected);
} else if (!actual().isPresent()) {
failWithoutActual(
fact("expected to have value", expected), factWithoutValue("but was absent"));
failWithoutActual(fact("expected to have value", expected), simpleFact("but was absent"));
} else {
checkNoNeedToDisplayBothValues("get()").that(actual().get()).isEqualTo(expected);
}
Expand Down
Loading

0 comments on commit e06ca85

Please sign in to comment.