Skip to content

Commit 6464cb5

Browse files
cpovirkGoogle Java Core Libraries
authored and
Google Java Core Libraries
committedDec 11, 2023
Add isWithin().of() support to IntegerSubject.
To make `IntegerSubjectTest` match `LongSubjectTest` more closely, I moved some of the existing `IntegerSubjectTest` tests into a new `NumericComparisonTest` class. This is arguably how they should always have been: The tests there don't exercise logic implemented in `IntegerSubject` but rather logic in `Subject` itself. (So yes, the tests could also go into `SubjectTest`. But that class is already quite long.) This CL is otherwise a mechanical copy-paste of cl/586097910. RELNOTES=Added `isWithin().of()` support to `IntegerSubject`. PiperOrigin-RevId: 589914997
1 parent 91f4bdc commit 6464cb5

File tree

5 files changed

+435
-150
lines changed

5 files changed

+435
-150
lines changed
 

‎core/src/main/java/com/google/common/truth/IntegerSubject.java

+110-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
*/
1616
package com.google.common.truth;
1717

18+
import static com.google.common.base.Preconditions.checkArgument;
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
import static com.google.common.truth.Fact.fact;
21+
import static com.google.common.truth.MathUtil.equalWithinTolerance;
22+
1823
import org.checkerframework.checker.nullness.qual.Nullable;
1924

2025
/**
@@ -25,12 +30,110 @@
2530
* @author Kurt Alfred Kluever
2631
*/
2732
public class IntegerSubject extends ComparableSubject<Integer> {
33+
private final @Nullable Integer actual;
34+
2835
/**
2936
* Constructor for use by subclasses. If you want to create an instance of this class itself, call
3037
* {@link Subject#check(String, Object...) check(...)}{@code .that(actual)}.
3138
*/
32-
protected IntegerSubject(FailureMetadata metadata, @Nullable Integer integer) {
33-
super(metadata, integer);
39+
protected IntegerSubject(FailureMetadata metadata, @Nullable Integer actual) {
40+
super(metadata, actual);
41+
this.actual = actual;
42+
}
43+
44+
/**
45+
* A partially specified check about an approximate relationship to a {@code int} subject using a
46+
* tolerance.
47+
*
48+
* @since 1.2
49+
*/
50+
public abstract static class TolerantIntegerComparison {
51+
52+
// Prevent subclassing outside of this class
53+
private TolerantIntegerComparison() {}
54+
55+
/**
56+
* Fails if the subject was expected to be within the tolerance of the given value but was not
57+
* <i>or</i> if it was expected <i>not</i> to be within the tolerance but was. The subject and
58+
* tolerance are specified earlier in the fluent call chain.
59+
*/
60+
public abstract void of(int expectedInteger);
61+
62+
/**
63+
* @throws UnsupportedOperationException always
64+
* @deprecated {@link Object#equals(Object)} is not supported on TolerantIntegerComparison. If
65+
* you meant to compare ints, use {@link #of(int)} instead.
66+
*/
67+
@Deprecated
68+
@Override
69+
public boolean equals(@Nullable Object o) {
70+
throw new UnsupportedOperationException(
71+
"If you meant to compare ints, use .of(int) instead.");
72+
}
73+
74+
/**
75+
* @throws UnsupportedOperationException always
76+
* @deprecated {@link Object#hashCode()} is not supported on TolerantIntegerComparison
77+
*/
78+
@Deprecated
79+
@Override
80+
public int hashCode() {
81+
throw new UnsupportedOperationException("Subject.hashCode() is not supported.");
82+
}
83+
}
84+
85+
/**
86+
* Prepares for a check that the subject is a number within the given tolerance of an expected
87+
* value that will be provided in the next call in the fluent chain.
88+
*
89+
* @param tolerance an inclusive upper bound on the difference between the subject and object
90+
* allowed by the check, which must be a non-negative value.
91+
* @since 1.2
92+
*/
93+
public TolerantIntegerComparison isWithin(int tolerance) {
94+
return new TolerantIntegerComparison() {
95+
@Override
96+
public void of(int expected) {
97+
Integer actual = IntegerSubject.this.actual;
98+
checkNotNull(
99+
actual, "actual value cannot be null. tolerance=%s expected=%s", tolerance, expected);
100+
checkTolerance(tolerance);
101+
102+
if (!equalWithinTolerance(actual, expected, tolerance)) {
103+
failWithoutActual(
104+
fact("expected", Integer.toString(expected)),
105+
butWas(),
106+
fact("outside tolerance", Integer.toString(tolerance)));
107+
}
108+
}
109+
};
110+
}
111+
112+
/**
113+
* Prepares for a check that the subject is a number not within the given tolerance of an expected
114+
* value that will be provided in the next call in the fluent chain.
115+
*
116+
* @param tolerance an exclusive lower bound on the difference between the subject and object
117+
* allowed by the check, which must be a non-negative value.
118+
* @since 1.2
119+
*/
120+
public TolerantIntegerComparison isNotWithin(int tolerance) {
121+
return new TolerantIntegerComparison() {
122+
@Override
123+
public void of(int expected) {
124+
Integer actual = IntegerSubject.this.actual;
125+
checkNotNull(
126+
actual, "actual value cannot be null. tolerance=%s expected=%s", tolerance, expected);
127+
checkTolerance(tolerance);
128+
129+
if (equalWithinTolerance(actual, expected, tolerance)) {
130+
failWithoutActual(
131+
fact("expected not to be", Integer.toString(expected)),
132+
butWas(),
133+
fact("within tolerance", Integer.toString(tolerance)));
134+
}
135+
}
136+
};
34137
}
35138

36139
/**
@@ -41,4 +144,9 @@ protected IntegerSubject(FailureMetadata metadata, @Nullable Integer integer) {
41144
public final void isEquivalentAccordingToCompareTo(@Nullable Integer other) {
42145
super.isEquivalentAccordingToCompareTo(other);
43146
}
147+
148+
/** Ensures that the given tolerance is a non-negative value. */
149+
private static void checkTolerance(int tolerance) {
150+
checkArgument(tolerance >= 0, "tolerance (%s) cannot be negative", tolerance);
151+
}
44152
}

‎core/src/main/java/com/google/common/truth/LongSubject.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
import static com.google.common.base.Preconditions.checkArgument;
1919
import static com.google.common.base.Preconditions.checkNotNull;
20-
import static com.google.common.truth.MathUtil.equalWithinTolerance;
2120
import static com.google.common.truth.Fact.fact;
21+
import static com.google.common.truth.MathUtil.equalWithinTolerance;
2222

2323
import org.checkerframework.checker.nullness.qual.Nullable;
2424

@@ -147,7 +147,7 @@ public final void isEquivalentAccordingToCompareTo(@Nullable Long other) {
147147
}
148148

149149
/** Ensures that the given tolerance is a non-negative value. */
150-
static void checkTolerance(long tolerance) {
150+
private static void checkTolerance(long tolerance) {
151151
checkArgument(tolerance >= 0, "tolerance (%s) cannot be negative", tolerance);
152152
}
153153

‎core/src/main/java/com/google/common/truth/MathUtil.java

+16
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ private MathUtil() {}
4040
}
4141
}
4242

43+
/**
44+
* Returns true iff {@code left} and {@code right} are values within {@code tolerance} of each
45+
* other.
46+
*/
47+
/* package */ static boolean equalWithinTolerance(int left, int right, int tolerance) {
48+
try {
49+
// subtractExact is always desugared.
50+
@SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
51+
int absDiff = Math.abs(subtractExact(left, right));
52+
return 0 <= absDiff && absDiff <= Math.abs(tolerance);
53+
} catch (ArithmeticException e) {
54+
// The numbers are so far apart their difference isn't even a int.
55+
return false;
56+
}
57+
}
58+
4359
/**
4460
* Returns true iff {@code left} and {@code right} are finite values within {@code tolerance} of
4561
* each other. Note that both this method and {@link #notEqualWithinTolerance} returns false if

‎core/src/test/java/com/google/common/truth/IntegerSubjectTest.java

+113-146
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
*/
1616
package com.google.common.truth;
1717

18+
import static com.google.common.truth.ExpectFailure.assertThat;
1819
import static com.google.common.truth.Truth.assertThat;
20+
import static org.junit.Assert.fail;
1921

20-
import com.google.common.collect.ImmutableSet;
22+
import com.google.common.truth.ExpectFailure.SimpleSubjectBuilderCallback;
23+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
2124
import org.junit.Test;
2225
import org.junit.runner.RunWith;
2326
import org.junit.runners.JUnit4;
@@ -116,160 +119,124 @@ public void overflowBetweenIntegerAndLong_shouldBeDifferent_max() {
116119
expectFailureWhenTestingThat(Integer.MAX_VALUE).isEqualTo(Long.MAX_VALUE);
117120
}
118121

119-
@SuppressWarnings("TruthSelfEquals")
120122
@Test
121-
public void testPrimitivesVsBoxedPrimitivesVsObject_int() {
122-
int int42 = 42;
123-
Integer integer42 = new Integer(42);
124-
Object object42 = (Object) 42;
125-
126-
assertThat(int42).isEqualTo(int42);
127-
assertThat(integer42).isEqualTo(int42);
128-
assertThat(object42).isEqualTo(int42);
129-
130-
assertThat(int42).isEqualTo(integer42);
131-
assertThat(integer42).isEqualTo(integer42);
132-
assertThat(object42).isEqualTo(integer42);
133-
134-
assertThat(int42).isEqualTo(object42);
135-
assertThat(integer42).isEqualTo(object42);
136-
assertThat(object42).isEqualTo(object42);
137-
}
138-
139-
@SuppressWarnings("TruthSelfEquals")
140-
@Test
141-
public void testPrimitivesVsBoxedPrimitivesVsObject_long() {
142-
long longPrim42 = 42;
143-
Long long42 = new Long(42);
144-
Object object42 = (Object) 42L;
145-
146-
assertThat(longPrim42).isEqualTo(longPrim42);
147-
assertThat(long42).isEqualTo(longPrim42);
148-
assertThat(object42).isEqualTo(longPrim42);
149-
150-
assertThat(longPrim42).isEqualTo(long42);
151-
assertThat(long42).isEqualTo(long42);
152-
assertThat(object42).isEqualTo(long42);
153-
154-
assertThat(longPrim42).isEqualTo(object42);
155-
assertThat(long42).isEqualTo(object42);
156-
assertThat(object42).isEqualTo(object42);
157-
}
158-
159-
@Test
160-
public void testAllCombinations_pass() {
161-
assertThat(42).isEqualTo(42L);
162-
assertThat(42).isEqualTo(new Long(42L));
163-
assertThat(new Integer(42)).isEqualTo(42L);
164-
assertThat(new Integer(42)).isEqualTo(new Long(42L));
165-
assertThat(42L).isEqualTo(42);
166-
assertThat(42L).isEqualTo(new Integer(42));
167-
assertThat(new Long(42L)).isEqualTo(42);
168-
assertThat(new Long(42L)).isEqualTo(new Integer(42));
169-
170-
assertThat(42).isEqualTo(42);
171-
assertThat(42).isEqualTo(new Integer(42));
172-
assertThat(new Integer(42)).isEqualTo(42);
173-
assertThat(new Integer(42)).isEqualTo(new Integer(42));
174-
assertThat(42L).isEqualTo(42L);
175-
assertThat(42L).isEqualTo(new Long(42L));
176-
assertThat(new Long(42L)).isEqualTo(42L);
177-
assertThat(new Long(42L)).isEqualTo(new Long(42L));
178-
}
179-
180-
@Test
181-
public void testNumericTypeWithSameValue_shouldBeEqual_int_long() {
182-
expectFailureWhenTestingThat(42).isNotEqualTo(42L);
183-
}
184-
185-
@Test
186-
public void testNumericTypeWithSameValue_shouldBeEqual_int_int() {
187-
expectFailureWhenTestingThat(42).isNotEqualTo(42);
188-
}
189-
190-
@Test
191-
public void testNumericPrimitiveTypes_isNotEqual_shouldFail_intToChar() {
192-
expectFailureWhenTestingThat(42).isNotEqualTo((char) 42);
193-
// 42 in ASCII is '*'
194-
assertFailureValue("expected not to be", "*");
195-
assertFailureValue("but was; string representation of actual value", "42");
123+
public void isWithinOf() {
124+
assertThat(20000).isWithin(0).of(20000);
125+
assertThat(20000).isWithin(1).of(20000);
126+
assertThat(20000).isWithin(10000).of(20000);
127+
assertThat(20000).isWithin(10000).of(30000);
128+
assertThat(Integer.MIN_VALUE).isWithin(1).of(Integer.MIN_VALUE + 1);
129+
assertThat(Integer.MAX_VALUE).isWithin(1).of(Integer.MAX_VALUE - 1);
130+
assertThat(Integer.MAX_VALUE / 2).isWithin(Integer.MAX_VALUE).of(-Integer.MAX_VALUE / 2);
131+
assertThat(-Integer.MAX_VALUE / 2).isWithin(Integer.MAX_VALUE).of(Integer.MAX_VALUE / 2);
132+
133+
assertThatIsWithinFails(20000, 9999, 30000);
134+
assertThatIsWithinFails(20000, 10000, 30001);
135+
assertThatIsWithinFails(Integer.MIN_VALUE, 0, Integer.MAX_VALUE);
136+
assertThatIsWithinFails(Integer.MAX_VALUE, 0, Integer.MIN_VALUE);
137+
assertThatIsWithinFails(Integer.MIN_VALUE, 1, Integer.MIN_VALUE + 2);
138+
assertThatIsWithinFails(Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 2);
139+
// Don't fall for rollover
140+
assertThatIsWithinFails(Integer.MIN_VALUE, 1, Integer.MAX_VALUE);
141+
assertThatIsWithinFails(Integer.MAX_VALUE, 1, Integer.MIN_VALUE);
142+
}
143+
144+
private static void assertThatIsWithinFails(int actual, int tolerance, int expected) {
145+
ExpectFailure.SimpleSubjectBuilderCallback<IntegerSubject, Integer> callback =
146+
new ExpectFailure.SimpleSubjectBuilderCallback<IntegerSubject, Integer>() {
147+
@Override
148+
public void invokeAssertion(SimpleSubjectBuilder<IntegerSubject, Integer> expect) {
149+
expect.that(actual).isWithin(tolerance).of(expected);
150+
}
151+
};
152+
AssertionError failure = expectFailure(callback);
153+
assertThat(failure)
154+
.factKeys()
155+
.containsExactly("expected", "but was", "outside tolerance")
156+
.inOrder();
157+
assertThat(failure).factValue("expected").isEqualTo(Integer.toString(expected));
158+
assertThat(failure).factValue("but was").isEqualTo(Integer.toString(actual));
159+
assertThat(failure).factValue("outside tolerance").isEqualTo(Integer.toString(tolerance));
160+
}
161+
162+
@Test
163+
public void isNotWithinOf() {
164+
assertThatIsNotWithinFails(20000, 0, 20000);
165+
assertThatIsNotWithinFails(20000, 1, 20000);
166+
assertThatIsNotWithinFails(20000, 10000, 20000);
167+
assertThatIsNotWithinFails(20000, 10000, 30000);
168+
assertThatIsNotWithinFails(Integer.MIN_VALUE, 1, Integer.MIN_VALUE + 1);
169+
assertThatIsNotWithinFails(Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 1);
170+
assertThatIsNotWithinFails(Integer.MAX_VALUE / 2, Integer.MAX_VALUE, -Integer.MAX_VALUE / 2);
171+
assertThatIsNotWithinFails(-Integer.MAX_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE / 2);
172+
173+
assertThat(20000).isNotWithin(9999).of(30000);
174+
assertThat(20000).isNotWithin(10000).of(30001);
175+
assertThat(Integer.MIN_VALUE).isNotWithin(0).of(Integer.MAX_VALUE);
176+
assertThat(Integer.MAX_VALUE).isNotWithin(0).of(Integer.MIN_VALUE);
177+
assertThat(Integer.MIN_VALUE).isNotWithin(1).of(Integer.MIN_VALUE + 2);
178+
assertThat(Integer.MAX_VALUE).isNotWithin(1).of(Integer.MAX_VALUE - 2);
179+
// Don't fall for rollover
180+
assertThat(Integer.MIN_VALUE).isNotWithin(1).of(Integer.MAX_VALUE);
181+
assertThat(Integer.MAX_VALUE).isNotWithin(1).of(Integer.MIN_VALUE);
182+
}
183+
184+
private static void assertThatIsNotWithinFails(int actual, int tolerance, int expected) {
185+
ExpectFailure.SimpleSubjectBuilderCallback<IntegerSubject, Integer> callback =
186+
new ExpectFailure.SimpleSubjectBuilderCallback<IntegerSubject, Integer>() {
187+
@Override
188+
public void invokeAssertion(SimpleSubjectBuilder<IntegerSubject, Integer> expect) {
189+
expect.that(actual).isNotWithin(tolerance).of(expected);
190+
}
191+
};
192+
AssertionError failure = expectFailure(callback);
193+
assertThat(failure).factValue("expected not to be").isEqualTo(Integer.toString(expected));
194+
assertThat(failure).factValue("within tolerance").isEqualTo(Integer.toString(tolerance));
195+
}
196+
197+
@Test
198+
public void isWithinNegativeTolerance() {
199+
isWithinNegativeToleranceThrowsIAE(0, -10, 5);
200+
isWithinNegativeToleranceThrowsIAE(0, -10, 20);
201+
isNotWithinNegativeToleranceThrowsIAE(0, -10, 5);
202+
isNotWithinNegativeToleranceThrowsIAE(0, -10, 20);
203+
}
204+
205+
private static void isWithinNegativeToleranceThrowsIAE(int actual, int tolerance, int expected) {
206+
try {
207+
assertThat(actual).isWithin(tolerance).of(expected);
208+
fail("Expected IllegalArgumentException to be thrown but wasn't");
209+
} catch (IllegalArgumentException iae) {
210+
assertThat(iae)
211+
.hasMessageThat()
212+
.isEqualTo("tolerance (" + tolerance + ") cannot be negative");
213+
}
196214
}
197215

198-
@Test
199-
public void testNumericPrimitiveTypes_isNotEqual_shouldFail_charToInt() {
200-
// Uses Object overload rather than Integer.
201-
expectFailure.whenTesting().that((char) 42).isNotEqualTo(42);
202-
// 42 in ASCII is '*'
203-
assertFailureValue("expected not to be", "42");
204-
assertFailureValue("but was; string representation of actual value", "*");
216+
private static void isNotWithinNegativeToleranceThrowsIAE(
217+
int actual, int tolerance, int expected) {
218+
try {
219+
assertThat(actual).isNotWithin(tolerance).of(expected);
220+
fail("Expected IllegalArgumentException to be thrown but wasn't");
221+
} catch (IllegalArgumentException iae) {
222+
assertThat(iae)
223+
.hasMessageThat()
224+
.isEqualTo("tolerance (" + tolerance + ") cannot be negative");
225+
}
205226
}
206227

207-
private static final Subject.Factory<Subject, Object> DEFAULT_SUBJECT_FACTORY =
208-
new Subject.Factory<Subject, Object>() {
228+
private static final Subject.Factory<IntegerSubject, Integer> INTEGER_SUBJECT_FACTORY =
229+
new Subject.Factory<IntegerSubject, Integer>() {
209230
@Override
210-
public Subject createSubject(FailureMetadata metadata, Object that) {
211-
return new Subject(metadata, that);
231+
public IntegerSubject createSubject(FailureMetadata metadata, Integer that) {
232+
return new IntegerSubject(metadata, that);
212233
}
213234
};
214235

215-
private static void expectFailure(
216-
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> callback) {
217-
AssertionError unused = ExpectFailure.expectFailureAbout(DEFAULT_SUBJECT_FACTORY, callback);
218-
}
219-
220-
@Test
221-
public void testNumericPrimitiveTypes() {
222-
byte byte42 = (byte) 42;
223-
short short42 = (short) 42;
224-
char char42 = (char) 42;
225-
int int42 = 42;
226-
long long42 = (long) 42;
227-
228-
ImmutableSet<Object> fortyTwos =
229-
ImmutableSet.<Object>of(byte42, short42, char42, int42, long42);
230-
for (Object actual : fortyTwos) {
231-
for (Object expected : fortyTwos) {
232-
assertThat(actual).isEqualTo(expected);
233-
}
234-
}
235-
236-
ImmutableSet<Object> fortyTwosNoChar = ImmutableSet.<Object>of(byte42, short42, int42, long42);
237-
for (Object actual : fortyTwosNoChar) {
238-
for (Object expected : fortyTwosNoChar) {
239-
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> actualFirst =
240-
new ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object>() {
241-
@Override
242-
public void invokeAssertion(SimpleSubjectBuilder<Subject, Object> expect) {
243-
expect.that(actual).isNotEqualTo(expected);
244-
}
245-
};
246-
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> expectedFirst =
247-
new ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object>() {
248-
@Override
249-
public void invokeAssertion(SimpleSubjectBuilder<Subject, Object> expect) {
250-
expect.that(expected).isNotEqualTo(actual);
251-
}
252-
};
253-
expectFailure(actualFirst);
254-
expectFailure(expectedFirst);
255-
}
256-
}
257-
258-
byte byte41 = (byte) 41;
259-
short short41 = (short) 41;
260-
char char41 = (char) 41;
261-
int int41 = 41;
262-
long long41 = (long) 41;
263-
264-
ImmutableSet<Object> fortyOnes =
265-
ImmutableSet.<Object>of(byte41, short41, char41, int41, long41);
266-
267-
for (Object first : fortyTwos) {
268-
for (Object second : fortyOnes) {
269-
assertThat(first).isNotEqualTo(second);
270-
assertThat(second).isNotEqualTo(first);
271-
}
272-
}
236+
@CanIgnoreReturnValue
237+
private static AssertionError expectFailure(
238+
SimpleSubjectBuilderCallback<IntegerSubject, Integer> callback) {
239+
return ExpectFailure.expectFailureAbout(INTEGER_SUBJECT_FACTORY, callback);
273240
}
274241

275242
private IntegerSubject expectFailureWhenTestingThat(Integer actual) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* Copyright (c) 2011 Google, Inc.
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+
package com.google.common.truth;
17+
18+
import static com.google.common.truth.Truth.assertThat;
19+
20+
import com.google.common.collect.ImmutableSet;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.junit.runners.JUnit4;
24+
25+
/**
26+
* Tests for comparisons between various integral types.
27+
*
28+
* @author David Saff
29+
* @author Christian Gruber
30+
* @author Kurt Alfred Kluever
31+
*/
32+
@RunWith(JUnit4.class)
33+
public class NumericComparisonTest extends BaseSubjectTestCase {
34+
35+
@SuppressWarnings("TruthSelfEquals")
36+
@Test
37+
public void testPrimitivesVsBoxedPrimitivesVsObject_int() {
38+
int int42 = 42;
39+
Integer integer42 = new Integer(42);
40+
Object object42 = (Object) 42;
41+
42+
assertThat(int42).isEqualTo(int42);
43+
assertThat(integer42).isEqualTo(int42);
44+
assertThat(object42).isEqualTo(int42);
45+
46+
assertThat(int42).isEqualTo(integer42);
47+
assertThat(integer42).isEqualTo(integer42);
48+
assertThat(object42).isEqualTo(integer42);
49+
50+
assertThat(int42).isEqualTo(object42);
51+
assertThat(integer42).isEqualTo(object42);
52+
assertThat(object42).isEqualTo(object42);
53+
}
54+
55+
@SuppressWarnings("TruthSelfEquals")
56+
@Test
57+
public void testPrimitivesVsBoxedPrimitivesVsObject_long() {
58+
long longPrim42 = 42;
59+
Long long42 = new Long(42);
60+
Object object42 = (Object) 42L;
61+
62+
assertThat(longPrim42).isEqualTo(longPrim42);
63+
assertThat(long42).isEqualTo(longPrim42);
64+
assertThat(object42).isEqualTo(longPrim42);
65+
66+
assertThat(longPrim42).isEqualTo(long42);
67+
assertThat(long42).isEqualTo(long42);
68+
assertThat(object42).isEqualTo(long42);
69+
70+
assertThat(longPrim42).isEqualTo(object42);
71+
assertThat(long42).isEqualTo(object42);
72+
assertThat(object42).isEqualTo(object42);
73+
}
74+
75+
@Test
76+
public void testAllCombinations_pass() {
77+
assertThat(42).isEqualTo(42L);
78+
assertThat(42).isEqualTo(new Long(42L));
79+
assertThat(new Integer(42)).isEqualTo(42L);
80+
assertThat(new Integer(42)).isEqualTo(new Long(42L));
81+
assertThat(42L).isEqualTo(42);
82+
assertThat(42L).isEqualTo(new Integer(42));
83+
assertThat(new Long(42L)).isEqualTo(42);
84+
assertThat(new Long(42L)).isEqualTo(new Integer(42));
85+
86+
assertThat(42).isEqualTo(42);
87+
assertThat(42).isEqualTo(new Integer(42));
88+
assertThat(new Integer(42)).isEqualTo(42);
89+
assertThat(new Integer(42)).isEqualTo(new Integer(42));
90+
assertThat(42L).isEqualTo(42L);
91+
assertThat(42L).isEqualTo(new Long(42L));
92+
assertThat(new Long(42L)).isEqualTo(42L);
93+
assertThat(new Long(42L)).isEqualTo(new Long(42L));
94+
}
95+
96+
@Test
97+
public void testNumericTypeWithSameValue_shouldBeEqual_int_long() {
98+
expectFailureWhenTestingThat(42).isNotEqualTo(42L);
99+
}
100+
101+
@Test
102+
public void testNumericTypeWithSameValue_shouldBeEqual_int_int() {
103+
expectFailureWhenTestingThat(42).isNotEqualTo(42);
104+
}
105+
106+
@Test
107+
public void testNumericPrimitiveTypes_isNotEqual_shouldFail_intToChar() {
108+
expectFailureWhenTestingThat(42).isNotEqualTo((char) 42);
109+
// 42 in ASCII is '*'
110+
assertFailureValue("expected not to be", "*");
111+
assertFailureValue("but was; string representation of actual value", "42");
112+
}
113+
114+
@Test
115+
public void testNumericPrimitiveTypes_isNotEqual_shouldFail_charToInt() {
116+
// Uses Object overload rather than Integer.
117+
expectFailure.whenTesting().that((char) 42).isNotEqualTo(42);
118+
// 42 in ASCII is '*'
119+
assertFailureValue("expected not to be", "42");
120+
assertFailureValue("but was; string representation of actual value", "*");
121+
}
122+
123+
private static final Subject.Factory<Subject, Object> DEFAULT_SUBJECT_FACTORY =
124+
new Subject.Factory<Subject, Object>() {
125+
@Override
126+
public Subject createSubject(FailureMetadata metadata, Object that) {
127+
return new Subject(metadata, that);
128+
}
129+
};
130+
131+
private static void expectFailure(
132+
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> callback) {
133+
AssertionError unused = ExpectFailure.expectFailureAbout(DEFAULT_SUBJECT_FACTORY, callback);
134+
}
135+
136+
@Test
137+
public void testNumericPrimitiveTypes() {
138+
byte byte42 = (byte) 42;
139+
short short42 = (short) 42;
140+
char char42 = (char) 42;
141+
int int42 = 42;
142+
long long42 = (long) 42;
143+
144+
ImmutableSet<Object> fortyTwos =
145+
ImmutableSet.<Object>of(byte42, short42, char42, int42, long42);
146+
for (Object actual : fortyTwos) {
147+
for (Object expected : fortyTwos) {
148+
assertThat(actual).isEqualTo(expected);
149+
}
150+
}
151+
152+
ImmutableSet<Object> fortyTwosNoChar = ImmutableSet.<Object>of(byte42, short42, int42, long42);
153+
for (Object actual : fortyTwosNoChar) {
154+
for (Object expected : fortyTwosNoChar) {
155+
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> actualFirst =
156+
new ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object>() {
157+
@Override
158+
public void invokeAssertion(SimpleSubjectBuilder<Subject, Object> expect) {
159+
expect.that(actual).isNotEqualTo(expected);
160+
}
161+
};
162+
ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object> expectedFirst =
163+
new ExpectFailure.SimpleSubjectBuilderCallback<Subject, Object>() {
164+
@Override
165+
public void invokeAssertion(SimpleSubjectBuilder<Subject, Object> expect) {
166+
expect.that(expected).isNotEqualTo(actual);
167+
}
168+
};
169+
expectFailure(actualFirst);
170+
expectFailure(expectedFirst);
171+
}
172+
}
173+
174+
byte byte41 = (byte) 41;
175+
short short41 = (short) 41;
176+
char char41 = (char) 41;
177+
int int41 = 41;
178+
long long41 = (long) 41;
179+
180+
ImmutableSet<Object> fortyOnes =
181+
ImmutableSet.<Object>of(byte41, short41, char41, int41, long41);
182+
183+
for (Object first : fortyTwos) {
184+
for (Object second : fortyOnes) {
185+
assertThat(first).isNotEqualTo(second);
186+
assertThat(second).isNotEqualTo(first);
187+
}
188+
}
189+
}
190+
191+
private IntegerSubject expectFailureWhenTestingThat(Integer actual) {
192+
return expectFailure.whenTesting().that(actual);
193+
}
194+
}

0 commit comments

Comments
 (0)
Please sign in to comment.