Skip to content

Commit

Permalink
Work on #268: convert androidrecord (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder authored Jan 18, 2025
1 parent d34c221 commit 0f590b9
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 44 deletions.
10 changes: 8 additions & 2 deletions android-record/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@
<artifactId>jackson-databind</artifactId>
</dependency>

<!-- Test dependencies: -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.fasterxml.jackson.module.androidrecord;

import org.junit.jupiter.api.Test;

import com.android.tools.r8.RecordTag;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;

public class AbstractRecordMemberTest extends BaseMapTest {
import com.fasterxml.jackson.annotation.*;

static final class RootRecord extends RecordTag {
import com.fasterxml.jackson.databind.ObjectMapper;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class AbstractRecordMemberTest extends BaseMapTest
{
static final class RootRecord extends RecordTag
{
private final AbstractMember member;

public RootRecord(AbstractMember member) {
Expand Down Expand Up @@ -65,6 +69,8 @@ public int getVal() {
/* https://github.com/FasterXML/jackson-modules-base/issues/248
/**********************************************************************
*/

@Test
public void testDeserializeRecordWithAbstractMember() throws Exception {
RootRecord value = MAPPER.readValue("{\"member\":{\"@class\":\"string\",\"val\":\"Hello, abstract member!\"}}",
RootRecord.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
package com.fasterxml.jackson.module.androidrecord;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.jupiter.api.Test;

import com.android.tools.r8.RecordTag;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import junit.framework.TestCase;
import org.junit.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Inner test classes simulate Android-desugared records.
*
* @author Eran Leshem
**/
public class AndroidRecordTest extends TestCase {
public class AndroidRecordTest
extends BaseMapTest
{
static final class Simple extends RecordTag {
static int si = 7;
private final int i;
Expand Down Expand Up @@ -129,16 +132,17 @@ public String s() {
}
}


private final ObjectMapper _objectMapper = JsonMapper.builder()
.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.addModule(new AndroidRecordModule()).build();

@Test
public void testSimple() throws JsonProcessingException {
Simple simple = new Simple(9, 3, "foo", Arrays.asList("bar", "baz"), new AtomicInteger(8));
assertEquals(simple, _objectMapper.readValue(_objectMapper.writeValueAsString(simple), Simple.class));
}

@Test
public void testMultipleConstructors() throws JsonProcessingException {
List<String> l = Arrays.asList("bar", "baz");
assertEquals(9, _objectMapper.readValue(_objectMapper.writeValueAsString(new MultipleConstructors(9, l)),
Expand All @@ -151,8 +155,9 @@ public void testMultipleConstructors() throws JsonProcessingException {
new MultipleConstructors(Arrays.asList(1, 2), 9)), MultipleConstructors.class).i());
}

@Test
public void testConflictingConstructors() {
Assert.assertThrows(InvalidDefinitionException.class,
assertThrows(InvalidDefinitionException.class,
() -> _objectMapper.readValue(_objectMapper.writeValueAsString(
new ConflictingConstructors(9, "foo")), ConflictingConstructors.class));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public abstract class BaseMapTest
extends BaseTest
{
protected static ObjectMapper newJsonMapper() {
return new JsonMapper().registerModule(new AndroidRecordModule());
return JsonMapper.builder()
.addModule(new AndroidRecordModule())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.fasterxml.jackson.module.androidrecord;

import junit.framework.TestCase;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.fail;

public abstract class BaseTest
extends TestCase
{
/**
* @param e Exception to check
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package com.fasterxml.jackson.module.androidrecord;

import java.util.*;

import org.junit.jupiter.api.Test;

import com.android.tools.r8.RecordTag;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
import org.junit.Assert;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.*;

public class RecordBasicsTest extends BaseMapTest {
public class RecordBasicsTest extends BaseMapTest
{
static final class EmptyRecord extends RecordTag {
@Override
public boolean equals(Object o) {
Expand Down Expand Up @@ -327,13 +330,15 @@ public String toString() {
/**********************************************************************
*/

@Test
public void testClassUtil() {
assertFalse(AndroidRecordModule.isDesugaredRecordClass(getClass()));
assertTrue(AndroidRecordModule.isDesugaredRecordClass(SimpleRecord.class));
assertTrue(AndroidRecordModule.isDesugaredRecordClass(RecordOfRecord.class));
assertTrue(AndroidRecordModule.isDesugaredRecordClass(RecordWithRename.class));
}

@Test
public void testRecordJavaType() {
assertFalse(AndroidRecordModule.isDesugaredRecordClass(MAPPER.constructType(getClass()).getRawClass()));
assertTrue(AndroidRecordModule.isDesugaredRecordClass(MAPPER.constructType(SimpleRecord.class).getRawClass()));
Expand All @@ -347,26 +352,31 @@ public void testRecordJavaType() {
/**********************************************************************
*/

@Test
public void testSerializeSimpleRecord() throws Exception {
String json = MAPPER.writeValueAsString(new SimpleRecord(123, "Bob"));
final Object EXP = map("id", Integer.valueOf(123), "name", "Bob");
assertEquals(EXP, MAPPER.readValue(json, Object.class));
}

@Test
public void testDeserializeSimpleRecord() throws Exception {
assertEquals(new SimpleRecord(123, "Bob"),
MAPPER.readValue("{\"id\":123,\"name\":\"Bob\"}", SimpleRecord.class));
}

@Test
public void testSerializeEmptyRecord() throws Exception {
assertEquals("{}", MAPPER.writeValueAsString(new EmptyRecord()));
}

@Test
public void testDeserializeEmptyRecord() throws Exception {
assertEquals(new EmptyRecord(),
MAPPER.readValue("{}", EmptyRecord.class));
}

@Test
public void testSerializeRecordOfRecord() throws Exception {
RecordOfRecord record = new RecordOfRecord(new SimpleRecord(123, "Bob"));
String json = MAPPER.writeValueAsString(record);
Expand All @@ -375,6 +385,7 @@ public void testSerializeRecordOfRecord() throws Exception {
assertEquals(EXP, MAPPER.readValue(json, Object.class));
}

@Test
public void testDeserializeRecordOfRecord() throws Exception {
assertEquals(new RecordOfRecord(new SimpleRecord(123, "Bob")),
MAPPER.readValue("{\"record\":{\"id\":123,\"name\":\"Bob\"}}",
Expand All @@ -387,6 +398,7 @@ public void testDeserializeRecordOfRecord() throws Exception {
/**********************************************************************
*/

@Test
public void testSerializeSimpleRecord_DisableAnnotationIntrospector() throws Exception {
SimpleRecord record = new SimpleRecord(123, "Bob");

Expand All @@ -398,12 +410,14 @@ public void testSerializeSimpleRecord_DisableAnnotationIntrospector() throws Exc
assertEquals("{\"id\":123,\"name\":\"Bob\"}", json);
}

@Test
public void testDeserializeSimpleRecord_DisableAnnotationIntrospector() throws Exception {
JsonMapper mapper = JsonMapper.builder().addModule(new AndroidRecordModule())
.configure(MapperFeature.USE_ANNOTATIONS, false)
.build();

Assert.assertThrows(InvalidDefinitionException.class, () -> mapper.readValue("{\"id\":123,\"name\":\"Bob\"}", SimpleRecord.class));
assertThrows(InvalidDefinitionException.class,
() -> mapper.readValue("{\"id\":123,\"name\":\"Bob\"}", SimpleRecord.class));
}

/*
Expand All @@ -412,18 +426,21 @@ public void testDeserializeSimpleRecord_DisableAnnotationIntrospector() throws E
/**********************************************************************
*/

@Test
public void testSerializeJsonRename() throws Exception {
String json = MAPPER.writeValueAsString(new RecordWithRename(123, "Bob"));
final Object EXP = map("id", Integer.valueOf(123), "rename", "Bob");
assertEquals(EXP, MAPPER.readValue(json, Object.class));
}

@Test
public void testDeserializeJsonRename() throws Exception {
RecordWithRename value = MAPPER.readValue("{\"id\":123,\"rename\":\"Bob\"}",
RecordWithRename.class);
assertEquals(new RecordWithRename(123, "Bob"), value);
}

@Test
public void testDeserializeConstructorInjectRecord() throws Exception {
MAPPER.setInjectableValues(new InjectableValues.Std().addValue(String.class, "Bob"));

Expand All @@ -438,6 +455,7 @@ public void testDeserializeConstructorInjectRecord() throws Exception {
*/

// [databind#2992]
@Test
public void testNamingStrategy() throws Exception {
SnakeRecord input = new SnakeRecord("123", "value");

Expand All @@ -454,25 +472,29 @@ public void testNamingStrategy() throws Exception {
/**********************************************************************
*/

@Test
public void testSerialize_SingleWriteOnlyParameter() throws Exception {
String json = MAPPER.writeValueAsString(new RecordSingleWriteOnly(123));

assertEquals("{}", json);
}

// [databind#3897]
@Test
public void testDeserialize_SingleWriteOnlyParameter() throws Exception {
RecordSingleWriteOnly value = MAPPER.readValue("{\"id\":123}", RecordSingleWriteOnly.class);

assertEquals(new RecordSingleWriteOnly(123), value);
}

@Test
public void testSerialize_SomeWriteOnlyParameter() throws Exception {
String json = MAPPER.writeValueAsString(new RecordSomeWriteOnly(123, "Bob", "[email protected]"));

assertEquals("{\"email\":\"[email protected]\"}", json);
}

@Test
public void testDeserialize_SomeWriteOnlyParameter() throws Exception {
RecordSomeWriteOnly value = MAPPER.readValue(
"{\"id\":123,\"name\":\"Bob\",\"email\":\"[email protected]\"}",
Expand All @@ -481,12 +503,14 @@ public void testDeserialize_SomeWriteOnlyParameter() throws Exception {
assertEquals(new RecordSomeWriteOnly(123, "Bob", "[email protected]"), value);
}

@Test
public void testSerialize_AllWriteOnlyParameter() throws Exception {
String json = MAPPER.writeValueAsString(new RecordAllWriteOnly(123, "Bob", "[email protected]"));

assertEquals("{}", json);
}

@Test
public void testDeserialize_AllWriteOnlyParameter() throws Exception {
RecordAllWriteOnly value = MAPPER.readValue(
"{\"id\":123,\"name\":\"Bob\",\"email\":\"[email protected]\"}",
Expand All @@ -502,6 +526,7 @@ public void testDeserialize_AllWriteOnlyParameter() throws Exception {
*/

// Fails: converter not applied
@Test
public void testDeserializeJsonDeserializeRecord() throws Exception {
RecordWithJsonDeserialize value = MAPPER.readValue("{\"id\":123,\"name\":\" Bob \"}",
RecordWithJsonDeserialize.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.fasterxml.jackson.module.androidrecord;

import org.junit.jupiter.api.Test;

import com.android.tools.r8.RecordTag;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class RecordCreatorsTest extends BaseMapTest
{
static final class RecordWithCanonicalCtorOverride extends RecordTag {
Expand Down Expand Up @@ -56,6 +61,7 @@ public String accessValueForTest() {
/**********************************************************************
*/

@Test
public void testDeserializeWithCanonicalCtorOverride() throws Exception {
RecordWithCanonicalCtorOverride value = MAPPER.readValue("{\"id\":123,\"name\":\"Bob\"}",
RecordWithCanonicalCtorOverride.class);
Expand All @@ -64,6 +70,7 @@ public void testDeserializeWithCanonicalCtorOverride() throws Exception {
}

// [databind#2980]
@Test
public void testDeserializeWithDelegatingCtor() throws Exception {
RecordWithDelegation value = MAPPER.readValue(q("foobar"),
RecordWithDelegation.class);
Expand Down
Loading

0 comments on commit 0f590b9

Please sign in to comment.