Skip to content

Commit d020e4a

Browse files
authored
Fix couple of minor bugs (#343)
1 parent 5731cfe commit d020e4a

8 files changed

Lines changed: 107 additions & 11 deletions

File tree

src/main/java/com/fasterxml/jackson/annotation/JsonFormat.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -484,18 +484,24 @@ public Features withOverrides(Features overrides) {
484484

485485
public Features with(Feature...features) {
486486
int e = _enabled;
487+
int d = _disabled;
487488
for (Feature f : features) {
488-
e |= (1 << f.ordinal());
489+
int mask = (1 << f.ordinal());
490+
e |= mask;
491+
d &= ~mask;
489492
}
490-
return (e == _enabled) ? this : new Features(e, _disabled);
493+
return (e == _enabled && d == _disabled) ? this : new Features(e, d);
491494
}
492495

493496
public Features without(Feature...features) {
497+
int e = _enabled;
494498
int d = _disabled;
495499
for (Feature f : features) {
496-
d |= (1 << f.ordinal());
500+
int mask = (1 << f.ordinal());
501+
d |= mask;
502+
e &= ~mask;
497503
}
498-
return (d == _disabled) ? this : new Features(_enabled, d);
504+
return (d == _disabled && e == _enabled) ? this : new Features(e, d);
499505
}
500506

501507
public Boolean get(Feature f) {
@@ -822,7 +828,7 @@ public Value withLocale(Locale l) {
822828
*/
823829
public Value withTimeZone(TimeZone tz) {
824830
return new Value(_pattern, _shape, _locale, null, tz,
825-
_features, _lenient);
831+
_features, _lenient, _radix);
826832
}
827833

828834
/**
@@ -1020,6 +1026,7 @@ public int hashCode() {
10201026
hash += _locale.hashCode();
10211027
}
10221028
hash ^= _features.hashCode();
1029+
hash += _radix;
10231030
return hash;
10241031
}
10251032

@@ -1037,9 +1044,8 @@ public boolean equals(Object o) {
10371044
return Objects.equals(_lenient, other._lenient)
10381045
&& Objects.equals(_timezoneStr, other._timezoneStr)
10391046
&& Objects.equals(_pattern, other._pattern)
1040-
&& Objects.equals(_timezone, other._timezone)
10411047
&& Objects.equals(_locale, other._locale)
1042-
&& Objects.equals(_radix, other._radix);
1048+
&& (_radix == other._radix);
10431049
}
10441050
}
10451051
}

src/main/java/com/fasterxml/jackson/annotation/JsonIgnoreProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ public String toString() {
384384

385385
@Override
386386
public int hashCode() {
387-
return (_ignored.size())
387+
return _ignored.hashCode()
388388
+ (_ignoreUnknown ? 1 : -3)
389389
+ (_allowGetters ? 3 : -7)
390390
+ (_allowSetters ? 7 : -11)

src/main/java/com/fasterxml/jackson/annotation/JsonInclude.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ public Value withOverrides(Value overrides) {
448448

449449
boolean viDiff = (vi != _valueInclusion) && (vi != Include.USE_DEFAULTS);
450450
boolean ciDiff = (ci != _contentInclusion) && (ci != Include.USE_DEFAULTS);
451-
boolean filterDiff = (vf != _valueFilter) || (cf != _valueFilter);
451+
boolean filterDiff = (vf != _valueFilter) || (cf != _contentFilter);
452452

453453
if (viDiff) {
454454
if (ciDiff) {
@@ -619,7 +619,9 @@ public String toString() {
619619
@Override
620620
public int hashCode() {
621621
return (_valueInclusion.hashCode() << 2)
622-
+ _contentInclusion.hashCode();
622+
+ _contentInclusion.hashCode()
623+
+ ((_valueFilter == null) ? 0 : _valueFilter.hashCode())
624+
+ ((_contentFilter == null) ? 0 : _contentFilter.hashCode());
623625
}
624626

625627
@Override

src/main/java/com/fasterxml/jackson/annotation/JsonIncludeProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public String toString() {
181181

182182
@Override
183183
public int hashCode() {
184-
return ((_included == null) ? 0 : _included.size())
184+
return ((_included == null) ? 0 : _included.hashCode())
185185
+ (Boolean.TRUE.equals(_ordered) ? 1 : 0);
186186
}
187187

src/test/java/com/fasterxml/jackson/annotation/JsonFormatTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,54 @@ public void testFeatures() {
263263
assertEquals(Boolean.TRUE, f4.get(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS));
264264
}
265265

266+
@Test
267+
void testFeaturesWithClearsDisabled() {
268+
// with() after without() on same feature should result in enabled
269+
JsonFormat.Features f = JsonFormat.Features.empty()
270+
.without(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
271+
.with(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
272+
assertEquals(Boolean.TRUE, f.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
273+
}
274+
275+
@Test
276+
void testFeaturesWithoutClearsEnabled() {
277+
// without() after with() on same feature should result in disabled
278+
JsonFormat.Features f = JsonFormat.Features.empty()
279+
.with(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
280+
.without(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
281+
assertEquals(Boolean.FALSE, f.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
282+
}
283+
284+
@Test
285+
void testEqualsIgnoresTransientTimezone() {
286+
// Two Values created from same timezone string should be equal
287+
// regardless of whether getTimeZone() has been called
288+
JsonFormat.Value v1 = new JsonFormat.Value("", Shape.ANY, "", "UTC",
289+
JsonFormat.Features.empty(), null, DEFAULT_RADIX);
290+
JsonFormat.Value v2 = new JsonFormat.Value("", Shape.ANY, "", "UTC",
291+
JsonFormat.Features.empty(), null, DEFAULT_RADIX);
292+
// Force lazy _timezone population on v1 only
293+
v1.getTimeZone();
294+
assertEquals(v1, v2);
295+
}
296+
297+
@Test
298+
void testWithTimeZonePreservesRadix() {
299+
int binaryRadix = 2;
300+
JsonFormat.Value v = JsonFormat.Value.forRadix(binaryRadix);
301+
JsonFormat.Value withTz = v.withTimeZone(java.util.TimeZone.getTimeZone("UTC"));
302+
assertEquals(binaryRadix, withTz.getRadix());
303+
}
304+
305+
@Test
306+
void testRadixInHashCode() {
307+
JsonFormat.Value v1 = JsonFormat.Value.forRadix(2);
308+
JsonFormat.Value v2 = JsonFormat.Value.forRadix(16);
309+
// Not equal, so hashCodes should (very likely) differ
310+
assertNotEquals(v1, v2);
311+
assertNotEquals(v1.hashCode(), v2.hashCode());
312+
}
313+
266314
@Test
267315
void testRadix() {
268316
//Non-Default radix overrides the default

src/test/java/com/fasterxml/jackson/annotation/JsonIgnorePropertiesTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ public void testMergeIgnoreProperties()
149149
assertTrue(all.contains("c"));
150150
}
151151

152+
@Test
153+
public void testHashCodeIncludesIgnoredContents() {
154+
JsonIgnoreProperties.Value v1 = EMPTY.withIgnored("a", "b");
155+
JsonIgnoreProperties.Value v2 = EMPTY.withIgnored("c", "d");
156+
assertNotEquals(v1, v2);
157+
assertNotEquals(v1.hashCode(), v2.hashCode());
158+
}
159+
152160
@Test
153161
public void testToString() {
154162
assertEquals(

src/test/java/com/fasterxml/jackson/annotation/JsonIncludePropertiesTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ public void testFromAnnotationOrdered()
9494
assertEquals(Boolean.TRUE, v.getOrdered());
9595
}
9696

97+
@Test
98+
public void testHashCodeIncludesContents() {
99+
JsonIncludeProperties.Value v1 = new JsonIncludeProperties.Value(_set("a", "b"), null);
100+
JsonIncludeProperties.Value v2 = new JsonIncludeProperties.Value(_set("c", "d"), null);
101+
assertNotEquals(v1, v2);
102+
assertNotEquals(v1.hashCode(), v2.hashCode());
103+
}
104+
97105
@Test
98106
public void testOrderedEquality()
99107
{

src/test/java/com/fasterxml/jackson/annotation/JsonIncludeTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,30 @@ public void testContentMerge76()
136136
assertEquals(JsonInclude.Include.NON_ABSENT, v21.getValueInclusion());
137137
}
138138

139+
@Test
140+
public void testHashCodeIncludesFilters()
141+
{
142+
JsonInclude.Value v1 = new JsonInclude.Value(Include.CUSTOM, Include.CUSTOM,
143+
Integer.class, Long.class);
144+
JsonInclude.Value v2 = new JsonInclude.Value(Include.CUSTOM, Include.CUSTOM,
145+
String.class, Double.class);
146+
assertNotEquals(v1, v2);
147+
assertNotEquals(v1.hashCode(), v2.hashCode());
148+
}
149+
150+
// Verify that withOverrides() properly detects content filter changes
151+
@Test
152+
public void testWithOverridesContentFilter()
153+
{
154+
JsonInclude.Value base = new JsonInclude.Value(Include.NON_EMPTY, Include.NON_EMPTY,
155+
null, null);
156+
JsonInclude.Value overrideContentFilter = new JsonInclude.Value(
157+
Include.USE_DEFAULTS, Include.USE_DEFAULTS, null, Long.class);
158+
159+
JsonInclude.Value merged = base.withOverrides(overrideContentFilter);
160+
assertEquals(Long.class, merged.getContentFilter());
161+
}
162+
139163
@Test
140164
public void testFilters()
141165
{

0 commit comments

Comments
 (0)