Skip to content

Commit 21e1168

Browse files
committed
Add EqualsBuilderReflectJreImplementationTest
See work in progress #1328
1 parent 68714b2 commit 21e1168

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.lang3.builder;
19+
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
23+
import java.time.Duration;
24+
import java.time.Instant;
25+
import java.time.temporal.TemporalAccessor;
26+
import java.time.temporal.TemporalField;
27+
import java.util.Arrays;
28+
29+
import org.apache.commons.lang3.AbstractLangTest;
30+
import org.junit.jupiter.api.Test;
31+
32+
/**
33+
* Tests that {@link EqualsBuilder} works using reflection when types that implement JRE interfaces like TemporalAccessor, TemporalAmout, and CharSequence work.
34+
*/
35+
public class EqualsBuilderReflectJreImplementationTest extends AbstractLangTest {
36+
37+
static class MyCharSequence implements CharSequence {
38+
39+
private final char[] chars;
40+
41+
MyCharSequence(final char[] chars) {
42+
this.chars = Arrays.copyOf(chars, chars.length);
43+
}
44+
45+
MyCharSequence(final char[] chars, final int start, final int end) {
46+
this.chars = Arrays.copyOfRange(chars, start, end);
47+
}
48+
49+
MyCharSequence(final String string) {
50+
this.chars = string.toCharArray();
51+
}
52+
53+
@Override
54+
public char charAt(final int index) {
55+
return chars[index];
56+
}
57+
58+
@Override
59+
public int length() {
60+
return chars.length;
61+
}
62+
63+
@Override
64+
public CharSequence subSequence(final int start, final int end) {
65+
return new MyCharSequence(chars, start, end);
66+
}
67+
68+
@Override
69+
public String toString() {
70+
return new String(chars);
71+
}
72+
}
73+
74+
static class MyClass {
75+
76+
private final MyTemporalAccessor time;
77+
private final MyCharSequence string;
78+
79+
MyClass(final MyTemporalAccessor time, final MyCharSequence string) {
80+
this.time = time;
81+
this.string = string;
82+
}
83+
84+
@Override
85+
public String toString() {
86+
return String.format("%s[%s - %s]", getClass().getSimpleName(), string, time);
87+
}
88+
}
89+
90+
static class MyTemporalAccessor implements TemporalAccessor {
91+
92+
private final String string;
93+
private final long value;
94+
private final Instant instant;
95+
private final Duration duration;
96+
97+
MyTemporalAccessor(final String string) {
98+
this.string = string;
99+
this.value = Long.parseLong(string);
100+
this.instant = Instant.ofEpochMilli(value);
101+
this.duration = Duration.between(instant, instant.plusMillis(value));
102+
}
103+
104+
@Override
105+
public long getLong(final TemporalField field) {
106+
return 0;
107+
}
108+
109+
@Override
110+
public boolean isSupported(final TemporalField field) {
111+
return false;
112+
}
113+
114+
@Override
115+
public String toString() {
116+
return String.format("%s[%s - %s - %s]", getClass().getSimpleName(), string, instant, duration);
117+
}
118+
119+
}
120+
121+
@Test
122+
public void testRecursive() {
123+
final MyClass o1 = new MyClass(new MyTemporalAccessor("1"), new MyCharSequence("2"));
124+
// This gives you different instances of MyTemporalAccessor for 1 (and 2) that should be equals by reflection.
125+
final MyClass o1Bis = new MyClass(new MyTemporalAccessor("1"), new MyCharSequence("2"));
126+
final MyClass o2 = new MyClass(new MyTemporalAccessor("3"), new MyCharSequence("4"));
127+
final MyClass o2Bis = new MyClass(new MyTemporalAccessor("3"), new MyCharSequence("4"));
128+
// MyTemporalAccessor
129+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(new MyTemporalAccessor("1"), new MyTemporalAccessor("1")).isEquals());
130+
// MyCharSequence
131+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(new MyCharSequence("1"), new MyCharSequence("1")).isEquals());
132+
// My Class
133+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(o1, o1).isEquals(), o1::toString);
134+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(o1, o1Bis).isEquals(), o1::toString);
135+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(o2, o2).isEquals(), o2::toString);
136+
assertTrue(new EqualsBuilder().setTestRecursive(true).append(o2, o2Bis).isEquals(), o2::toString);
137+
assertFalse(new EqualsBuilder().setTestRecursive(true).append(o1, o2).isEquals());
138+
assertFalse(new EqualsBuilder().setTestRecursive(true).append(o2, o1).isEquals());
139+
}
140+
141+
}

0 commit comments

Comments
 (0)