|
40 | 40 | * caller tries to access the facts of an error that wasn't produced by Truth.
|
41 | 41 | */
|
42 | 42 | final class TruthFailureSubject extends ThrowableSubject {
|
| 43 | + static final Fact HOW_TO_TEST_KEYS_WITHOUT_VALUES = |
| 44 | + factWithoutValue( |
| 45 | + "To test that a key is present without a value, " |
| 46 | + + "use factKeys().contains(...) or a similar method."); |
| 47 | + |
43 | 48 | /*
|
44 | 49 | * TODO(cpovirk): Expose this publicly once it can have the right type. That can't happen until we
|
45 | 50 | * add type parameters to ThrowableSubject, make TruthFailureSubject not extend ThrowableSubject,
|
@@ -89,12 +94,19 @@ private static ImmutableList<String> getFactKeys(ErrorWithFacts error) {
|
89 | 94 | /**
|
90 | 95 | * Returns a subject for the value with the given name.
|
91 | 96 | *
|
92 |
| - * <p>The value, if present, is always a string, the {@code String.valueOf} representation of the |
93 |
| - * value passed to {@link Fact#fact}. |
| 97 | + * <p>The value is always a string, the {@code String.valueOf} representation of the value passed |
| 98 | + * to {@link Fact#fact}. |
| 99 | + * |
| 100 | + * <p>The value is never null: |
94 | 101 | *
|
95 |
| - * <p>The value is null in the case of {@linkplain Fact#factWithoutValue facts that have no |
96 |
| - * value}. By contrast, facts that have a value that is rendered as "null" (such as those created |
97 |
| - * with {@code fact("key", null)}) are considered to have a value, the string "null." |
| 102 | + * <ul> |
| 103 | + * <li>In the case of {@linkplain Fact#factWithoutValue facts that have no value}, {@code |
| 104 | + * factValue} throws an exception. To test for such facts, use {@link #factKeys()}{@code |
| 105 | + * .contains(...)} or a similar method. |
| 106 | + * <li>In the case of facts that have a value that is rendered as "null" (such as those created |
| 107 | + * with {@code fact("key", null)}), {@code factValue} considers them have a string value, |
| 108 | + * the string "null." |
| 109 | + * </ul> |
98 | 110 | *
|
99 | 111 | * <p>If the failure under test contains more than one fact with the given key, this method will
|
100 | 112 | * fail the test. To assert about such a failure, use {@linkplain #factValue(String, int) the
|
@@ -145,9 +157,27 @@ private StringSubject doFactValue(String key, @Nullable Integer index) {
|
145 | 157 | fact("fact count was", factsWithName.size()));
|
146 | 158 | return ignoreCheck().that("");
|
147 | 159 | }
|
| 160 | + String value = factsWithName.get(firstNonNull(index, 0)).value; |
| 161 | + if (value == null) { |
| 162 | + if (index == null) { |
| 163 | + failWithoutActual( |
| 164 | + factWithoutValue("expected to have a value"), |
| 165 | + fact("for key", key), |
| 166 | + factWithoutValue("but the key was present with no value"), |
| 167 | + HOW_TO_TEST_KEYS_WITHOUT_VALUES); |
| 168 | + } else { |
| 169 | + failWithoutActual( |
| 170 | + factWithoutValue("expected to have a value"), |
| 171 | + fact("for key", key), |
| 172 | + fact("and index", index), |
| 173 | + factWithoutValue("but the key was present with no value"), |
| 174 | + HOW_TO_TEST_KEYS_WITHOUT_VALUES); |
| 175 | + } |
| 176 | + return ignoreCheck().that(""); |
| 177 | + } |
148 | 178 | StandardSubjectBuilder check =
|
149 | 179 | index == null ? check("factValue(%s)", key) : check("factValue(%s, %s)", key, index);
|
150 |
| - return check.that(factsWithName.get(firstNonNull(index, 0)).value); |
| 180 | + return check.that(value); |
151 | 181 | }
|
152 | 182 |
|
153 | 183 | private static ImmutableList<Fact> factsWithName(ErrorWithFacts error, String key) {
|
|
0 commit comments