mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 07:59:21 +08:00
Switch to spotless and format code (#1196)
* Add spotless configuration * Reformat! * Add copyright config for build.gradle.kts files * Add toeholds for headers
This commit is contained in:
@@ -23,14 +23,16 @@ import java.util.Date;
|
||||
* The new class is {@code com.squareup.moshi.adapters.Rfc3339DateJsonAdapter}.
|
||||
*/
|
||||
public final class Rfc3339DateJsonAdapter extends JsonAdapter<Date> {
|
||||
private final com.squareup.moshi.adapters.Rfc3339DateJsonAdapter delegate
|
||||
= new com.squareup.moshi.adapters.Rfc3339DateJsonAdapter();
|
||||
private final com.squareup.moshi.adapters.Rfc3339DateJsonAdapter delegate =
|
||||
new com.squareup.moshi.adapters.Rfc3339DateJsonAdapter();
|
||||
|
||||
@Override public Date fromJson(JsonReader reader) throws IOException {
|
||||
@Override
|
||||
public Date fromJson(JsonReader reader) throws IOException {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, Date value) throws IOException {
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, Date value) throws IOException {
|
||||
delegate.toJson(writer, value);
|
||||
}
|
||||
}
|
||||
|
@@ -29,12 +29,11 @@ import javax.annotation.Nullable;
|
||||
* not match any enum value. To use, add this as an adapter for your enum type on your {@link
|
||||
* com.squareup.moshi.Moshi.Builder Moshi.Builder}:
|
||||
*
|
||||
* <pre> {@code
|
||||
*
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(CurrencyCode.class, EnumJsonAdapter.create(CurrencyCode.class)
|
||||
* .withUnknownFallback(CurrencyCode.USD))
|
||||
* .build();
|
||||
* <pre>{@code
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(CurrencyCode.class, EnumJsonAdapter.create(CurrencyCode.class)
|
||||
* .withUnknownFallback(CurrencyCode.USD))
|
||||
* .build();
|
||||
* }</pre>
|
||||
*/
|
||||
public final class EnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {
|
||||
@@ -78,15 +77,21 @@ public final class EnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
@Override
|
||||
public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
int index = reader.selectString(options);
|
||||
if (index != -1) return constants[index];
|
||||
|
||||
String path = reader.getPath();
|
||||
if (!useFallbackValue) {
|
||||
String name = reader.nextString();
|
||||
throw new JsonDataException("Expected one of "
|
||||
+ Arrays.asList(nameStrings) + " but was " + name + " at path " + path);
|
||||
throw new JsonDataException(
|
||||
"Expected one of "
|
||||
+ Arrays.asList(nameStrings)
|
||||
+ " but was "
|
||||
+ name
|
||||
+ " at path "
|
||||
+ path);
|
||||
}
|
||||
if (reader.peek() != JsonReader.Token.STRING) {
|
||||
throw new JsonDataException(
|
||||
@@ -96,7 +101,8 @@ public final class EnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
if (value == null) {
|
||||
throw new NullPointerException(
|
||||
"value was null! Wrap in .nullSafe() to write nullable values.");
|
||||
@@ -104,7 +110,8 @@ public final class EnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {
|
||||
writer.value(nameStrings[value.ordinal()]);
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EnumJsonAdapter(" + enumType.getName() + ")";
|
||||
}
|
||||
}
|
||||
|
@@ -26,11 +26,12 @@ import java.util.TimeZone;
|
||||
* Jackson’s date formatter, pruned to Moshi's needs. Forked from this file:
|
||||
* https://github.com/FasterXML/jackson-databind/blob/67ebf7305f492285a8f9f4de31545f5f16fc7c3a/src/main/java/com/fasterxml/jackson/databind/util/ISO8601Utils.java
|
||||
*
|
||||
* Utilities methods for manipulating dates in iso8601 format. This is much much faster and GC
|
||||
* <p>Utilities methods for manipulating dates in iso8601 format. This is much much faster and GC
|
||||
* friendly than using SimpleDateFormat so highly suitable if you (un)serialize lots of date
|
||||
* objects.
|
||||
*
|
||||
* Supported parse format: [yyyy-MM-dd|yyyyMMdd][T(hh:mm[:ss[.sss]]|hhmm[ss[.sss]])]?[Z|[+-]hh[:]mm]]
|
||||
* <p>Supported parse format:
|
||||
* [yyyy-MM-dd|yyyyMMdd][T(hh:mm[:ss[.sss]]|hhmm[ss[.sss]])]?[Z|[+-]hh[:]mm]]
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/NOTE-datetime">this specification</a>
|
||||
*/
|
||||
@@ -167,8 +168,11 @@ final class Iso8601Utils {
|
||||
*/
|
||||
String cleaned = act.replace(":", "");
|
||||
if (!cleaned.equals(timezoneId)) {
|
||||
throw new IndexOutOfBoundsException("Mismatching time zone indicator: "
|
||||
+ timezoneId + " given, resolves to " + timezone.getID());
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Mismatching time zone indicator: "
|
||||
+ timezoneId
|
||||
+ " given, resolves to "
|
||||
+ timezone.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,8 +263,7 @@ final class Iso8601Utils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first character in the string that is not a digit, starting at
|
||||
* offset.
|
||||
* Returns the index of the first character in the string that is not a digit, starting at offset.
|
||||
*/
|
||||
private static int indexOfNonDigit(String string, int offset) {
|
||||
for (int i = offset; i < string.length(); i++) {
|
||||
|
@@ -38,50 +38,47 @@ import javax.annotation.Nullable;
|
||||
*
|
||||
* <p>Suppose we have an interface, its implementations, and a class that uses them:
|
||||
*
|
||||
* <pre> {@code
|
||||
* <pre>{@code
|
||||
* interface HandOfCards {
|
||||
* }
|
||||
*
|
||||
* interface HandOfCards {
|
||||
* }
|
||||
* class BlackjackHand implements HandOfCards {
|
||||
* Card hidden_card;
|
||||
* List<Card> visible_cards;
|
||||
* }
|
||||
*
|
||||
* class BlackjackHand implements HandOfCards {
|
||||
* Card hidden_card;
|
||||
* List<Card> visible_cards;
|
||||
* }
|
||||
* class HoldemHand implements HandOfCards {
|
||||
* Set<Card> hidden_cards;
|
||||
* }
|
||||
*
|
||||
* class HoldemHand implements HandOfCards {
|
||||
* Set<Card> hidden_cards;
|
||||
* }
|
||||
*
|
||||
* class Player {
|
||||
* String name;
|
||||
* HandOfCards hand;
|
||||
* }
|
||||
* class Player {
|
||||
* String name;
|
||||
* HandOfCards hand;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>We want to decode the following JSON into the player model above:
|
||||
*
|
||||
* <pre> {@code
|
||||
*
|
||||
* {
|
||||
* "name": "Jesse",
|
||||
* "hand": {
|
||||
* "hand_type": "blackjack",
|
||||
* "hidden_card": "9D",
|
||||
* "visible_cards": ["8H", "4C"]
|
||||
* }
|
||||
* <pre>{@code
|
||||
* {
|
||||
* "name": "Jesse",
|
||||
* "hand": {
|
||||
* "hand_type": "blackjack",
|
||||
* "hidden_card": "9D",
|
||||
* "visible_cards": ["8H", "4C"]
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Left unconfigured, Moshi would incorrectly attempt to decode the hand object to the abstract
|
||||
* {@code HandOfCards} interface. We configure it to use the appropriate subtype instead:
|
||||
*
|
||||
* <pre> {@code
|
||||
*
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(PolymorphicJsonAdapterFactory.of(HandOfCards.class, "hand_type")
|
||||
* .withSubtype(BlackjackHand.class, "blackjack")
|
||||
* .withSubtype(HoldemHand.class, "holdem"))
|
||||
* .build();
|
||||
* <pre>{@code
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(PolymorphicJsonAdapterFactory.of(HandOfCards.class, "hand_type")
|
||||
* .withSubtype(BlackjackHand.class, "blackjack")
|
||||
* .withSubtype(HoldemHand.class, "holdem"))
|
||||
* .build();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This class imposes strict requirements on its use:
|
||||
@@ -95,23 +92,25 @@ import javax.annotation.Nullable;
|
||||
* <li>Each type identifier must be unique.
|
||||
* </ul>
|
||||
*
|
||||
* <p>For best performance type information should be the first field in the object. Otherwise
|
||||
* Moshi must reprocess the JSON stream once it knows the object's type.
|
||||
* <p>For best performance type information should be the first field in the object. Otherwise Moshi
|
||||
* must reprocess the JSON stream once it knows the object's type.
|
||||
*
|
||||
* <p>If an unknown subtype is encountered when decoding:
|
||||
* <ul>
|
||||
* <li>If {@link #withDefaultValue(Object)} is used, then {@code defaultValue} will be returned.
|
||||
* <li>If {@link #withFallbackJsonAdapter(JsonAdapter)} is used, then the
|
||||
* {@code fallbackJsonAdapter.fromJson(reader)} result will be returned.
|
||||
* <li>Otherwise a {@link JsonDataException} will be thrown.
|
||||
* </ul>
|
||||
*
|
||||
* <ul>
|
||||
* <li>If {@link #withDefaultValue(Object)} is used, then {@code defaultValue} will be returned.
|
||||
* <li>If {@link #withFallbackJsonAdapter(JsonAdapter)} is used, then the {@code
|
||||
* fallbackJsonAdapter.fromJson(reader)} result will be returned.
|
||||
* <li>Otherwise a {@link JsonDataException} will be thrown.
|
||||
* </ul>
|
||||
*
|
||||
* <p>If an unknown type is encountered when encoding:
|
||||
* <ul>
|
||||
* <li>If {@link #withFallbackJsonAdapter(JsonAdapter)} is used, then the
|
||||
* {@code fallbackJsonAdapter.toJson(writer, value)} result will be returned.
|
||||
* <li>Otherwise a {@link IllegalArgumentException} will be thrown.
|
||||
* </ul>
|
||||
*
|
||||
* <ul>
|
||||
* <li>If {@link #withFallbackJsonAdapter(JsonAdapter)} is used, then the {@code
|
||||
* fallbackJsonAdapter.toJson(writer, value)} result will be returned.
|
||||
* <li>Otherwise a {@link IllegalArgumentException} will be thrown.
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the same subtype has multiple labels the first one is used when encoding.
|
||||
*/
|
||||
@@ -145,16 +144,10 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
if (baseType == null) throw new NullPointerException("baseType == null");
|
||||
if (labelKey == null) throw new NullPointerException("labelKey == null");
|
||||
return new PolymorphicJsonAdapterFactory<>(
|
||||
baseType,
|
||||
labelKey,
|
||||
Collections.<String>emptyList(),
|
||||
Collections.<Type>emptyList(),
|
||||
null);
|
||||
baseType, labelKey, Collections.<String>emptyList(), Collections.<Type>emptyList(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new factory that decodes instances of {@code subtype}.
|
||||
*/
|
||||
/** Returns a new factory that decodes instances of {@code subtype}. */
|
||||
public PolymorphicJsonAdapterFactory<T> withSubtype(Class<? extends T> subtype, String label) {
|
||||
if (subtype == null) throw new NullPointerException("subtype == null");
|
||||
if (label == null) throw new NullPointerException("label == null");
|
||||
@@ -165,27 +158,21 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
newLabels.add(label);
|
||||
List<Type> newSubtypes = new ArrayList<>(subtypes);
|
||||
newSubtypes.add(subtype);
|
||||
return new PolymorphicJsonAdapterFactory<>(baseType,
|
||||
labelKey,
|
||||
newLabels,
|
||||
newSubtypes,
|
||||
fallbackJsonAdapter);
|
||||
return new PolymorphicJsonAdapterFactory<>(
|
||||
baseType, labelKey, newLabels, newSubtypes, fallbackJsonAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new factory that with default to {@code fallbackJsonAdapter.fromJson(reader)}
|
||||
* upon decoding of unrecognized labels.
|
||||
* Returns a new factory that with default to {@code fallbackJsonAdapter.fromJson(reader)} upon
|
||||
* decoding of unrecognized labels.
|
||||
*
|
||||
* <p>The {@link JsonReader} instance will not be automatically consumed, so sure to consume it
|
||||
* within your implementation of {@link JsonAdapter#fromJson(JsonReader)}
|
||||
*/
|
||||
public PolymorphicJsonAdapterFactory<T> withFallbackJsonAdapter(
|
||||
@Nullable JsonAdapter<Object> fallbackJsonAdapter) {
|
||||
return new PolymorphicJsonAdapterFactory<>(baseType,
|
||||
labelKey,
|
||||
labels,
|
||||
subtypes,
|
||||
fallbackJsonAdapter);
|
||||
return new PolymorphicJsonAdapterFactory<>(
|
||||
baseType, labelKey, labels, subtypes, fallbackJsonAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,14 +185,22 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
|
||||
private JsonAdapter<Object> buildFallbackJsonAdapter(final T defaultValue) {
|
||||
return new JsonAdapter<Object>() {
|
||||
@Override public @Nullable Object fromJson(JsonReader reader) throws IOException {
|
||||
@Override
|
||||
public @Nullable Object fromJson(JsonReader reader) throws IOException {
|
||||
reader.skipValue();
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
throw new IllegalArgumentException("Expected one of " + subtypes + " but found " + value
|
||||
+ ", a " + value.getClass() + ". Register this subtype.");
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
throw new IllegalArgumentException(
|
||||
"Expected one of "
|
||||
+ subtypes
|
||||
+ " but found "
|
||||
+ value
|
||||
+ ", a "
|
||||
+ value.getClass()
|
||||
+ ". Register this subtype.");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -221,12 +216,8 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
jsonAdapters.add(moshi.adapter(subtypes.get(i)));
|
||||
}
|
||||
|
||||
return new PolymorphicJsonAdapter(labelKey,
|
||||
labels,
|
||||
subtypes,
|
||||
jsonAdapters,
|
||||
fallbackJsonAdapter
|
||||
).nullSafe();
|
||||
return new PolymorphicJsonAdapter(labelKey, labels, subtypes, jsonAdapters, fallbackJsonAdapter)
|
||||
.nullSafe();
|
||||
}
|
||||
|
||||
static final class PolymorphicJsonAdapter extends JsonAdapter<Object> {
|
||||
@@ -241,7 +232,8 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
/** Corresponds to subtypes. */
|
||||
final JsonReader.Options labelOptions;
|
||||
|
||||
PolymorphicJsonAdapter(String labelKey,
|
||||
PolymorphicJsonAdapter(
|
||||
String labelKey,
|
||||
List<String> labels,
|
||||
List<Type> subtypes,
|
||||
List<JsonAdapter<Object>> jsonAdapters,
|
||||
@@ -256,7 +248,8 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
this.labelOptions = JsonReader.Options.of(labels.toArray(new String[0]));
|
||||
}
|
||||
|
||||
@Override public Object fromJson(JsonReader reader) throws IOException {
|
||||
@Override
|
||||
public Object fromJson(JsonReader reader) throws IOException {
|
||||
JsonReader peeked = reader.peekJson();
|
||||
peeked.setFailOnUnknown(false);
|
||||
int labelIndex;
|
||||
@@ -283,8 +276,14 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
|
||||
int labelIndex = reader.selectString(labelOptions);
|
||||
if (labelIndex == -1 && this.fallbackJsonAdapter == null) {
|
||||
throw new JsonDataException("Expected one of " + labels + " for key '" + labelKey
|
||||
+ "' but found '" + reader.nextString() + "'. Register a subtype for this label.");
|
||||
throw new JsonDataException(
|
||||
"Expected one of "
|
||||
+ labels
|
||||
+ " for key '"
|
||||
+ labelKey
|
||||
+ "' but found '"
|
||||
+ reader.nextString()
|
||||
+ "'. Register a subtype for this label.");
|
||||
}
|
||||
return labelIndex;
|
||||
}
|
||||
@@ -292,14 +291,21 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
throw new JsonDataException("Missing label for " + labelKey);
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
Class<?> type = value.getClass();
|
||||
int labelIndex = subtypes.indexOf(type);
|
||||
final JsonAdapter<Object> adapter;
|
||||
if (labelIndex == -1) {
|
||||
if (fallbackJsonAdapter == null) {
|
||||
throw new IllegalArgumentException("Expected one of " + subtypes + " but found " + value
|
||||
+ ", a " + value.getClass() + ". Register this subtype.");
|
||||
throw new IllegalArgumentException(
|
||||
"Expected one of "
|
||||
+ subtypes
|
||||
+ " but found "
|
||||
+ value
|
||||
+ ", a "
|
||||
+ value.getClass()
|
||||
+ ". Register this subtype.");
|
||||
}
|
||||
adapter = fallbackJsonAdapter;
|
||||
} else {
|
||||
@@ -316,7 +322,8 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PolymorphicJsonAdapter(" + labelKey + ")";
|
||||
}
|
||||
}
|
||||
|
@@ -26,15 +26,15 @@ import java.util.Date;
|
||||
* formatted like {@code 2015-09-26T18:23:50.250Z}. This adapter is null-safe. To use, add this as
|
||||
* an adapter for {@code Date.class} on your {@link com.squareup.moshi.Moshi.Builder Moshi.Builder}:
|
||||
*
|
||||
* <pre> {@code
|
||||
*
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(Date.class, new Rfc3339DateJsonAdapter())
|
||||
* .build();
|
||||
* <pre>{@code
|
||||
* Moshi moshi = new Moshi.Builder()
|
||||
* .add(Date.class, new Rfc3339DateJsonAdapter())
|
||||
* .build();
|
||||
* }</pre>
|
||||
*/
|
||||
public final class Rfc3339DateJsonAdapter extends JsonAdapter<Date> {
|
||||
@Override public synchronized Date fromJson(JsonReader reader) throws IOException {
|
||||
@Override
|
||||
public synchronized Date fromJson(JsonReader reader) throws IOException {
|
||||
if (reader.peek() == JsonReader.Token.NULL) {
|
||||
return reader.nextNull();
|
||||
}
|
||||
@@ -42,7 +42,8 @@ public final class Rfc3339DateJsonAdapter extends JsonAdapter<Date> {
|
||||
return Iso8601Utils.parse(string);
|
||||
}
|
||||
|
||||
@Override public synchronized void toJson(JsonWriter writer, Date value) throws IOException {
|
||||
@Override
|
||||
public synchronized void toJson(JsonWriter writer, Date value) throws IOException {
|
||||
if (value == null) {
|
||||
writer.nullValue();
|
||||
} else {
|
||||
|
@@ -15,53 +15,57 @@
|
||||
*/
|
||||
package com.squareup.moshi.adapters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.squareup.moshi.Json;
|
||||
import com.squareup.moshi.JsonDataException;
|
||||
import com.squareup.moshi.JsonReader;
|
||||
import okio.Buffer;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@SuppressWarnings("CheckReturnValue")
|
||||
public final class EnumJsonAdapterTest {
|
||||
@Test public void toAndFromJson() throws Exception {
|
||||
@Test
|
||||
public void toAndFromJson() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter = EnumJsonAdapter.create(Roshambo.class);
|
||||
assertThat(adapter.fromJson("\"ROCK\"")).isEqualTo(Roshambo.ROCK);
|
||||
assertThat(adapter.toJson(Roshambo.PAPER)).isEqualTo("\"PAPER\"");
|
||||
}
|
||||
|
||||
@Test public void withJsonName() throws Exception {
|
||||
@Test
|
||||
public void withJsonName() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter = EnumJsonAdapter.create(Roshambo.class);
|
||||
assertThat(adapter.fromJson("\"scr\"")).isEqualTo(Roshambo.SCISSORS);
|
||||
assertThat(adapter.toJson(Roshambo.SCISSORS)).isEqualTo("\"scr\"");
|
||||
}
|
||||
|
||||
@Test public void withoutFallbackValue() throws Exception {
|
||||
@Test
|
||||
public void withoutFallbackValue() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter = EnumJsonAdapter.create(Roshambo.class);
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8("\"SPOCK\""));
|
||||
try {
|
||||
adapter.fromJson(reader);
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected one of [ROCK, PAPER, scr] but was SPOCK at path $");
|
||||
assertThat(expected).hasMessage("Expected one of [ROCK, PAPER, scr] but was SPOCK at path $");
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void withFallbackValue() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter = EnumJsonAdapter.create(Roshambo.class)
|
||||
.withUnknownFallback(Roshambo.ROCK);
|
||||
@Test
|
||||
public void withFallbackValue() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter =
|
||||
EnumJsonAdapter.create(Roshambo.class).withUnknownFallback(Roshambo.ROCK);
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8("\"SPOCK\""));
|
||||
assertThat(adapter.fromJson(reader)).isEqualTo(Roshambo.ROCK);
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void withNullFallbackValue() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter = EnumJsonAdapter.create(Roshambo.class)
|
||||
.withUnknownFallback(null);
|
||||
@Test
|
||||
public void withNullFallbackValue() throws Exception {
|
||||
EnumJsonAdapter<Roshambo> adapter =
|
||||
EnumJsonAdapter.create(Roshambo.class).withUnknownFallback(null);
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8("\"SPOCK\""));
|
||||
assertThat(adapter.fromJson(reader)).isNull();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
@@ -70,6 +74,7 @@ public final class EnumJsonAdapterTest {
|
||||
enum Roshambo {
|
||||
ROCK,
|
||||
PAPER,
|
||||
@Json(name = "scr") SCISSORS
|
||||
@Json(name = "scr")
|
||||
SCISSORS
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.squareup.moshi.adapters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.JsonDataException;
|
||||
import com.squareup.moshi.JsonReader;
|
||||
@@ -27,17 +30,17 @@ import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@SuppressWarnings("CheckReturnValue")
|
||||
public final class PolymorphicJsonAdapterFactoryTest {
|
||||
@Test public void fromJson() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void fromJson() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
assertThat(adapter.fromJson("{\"type\":\"success\",\"value\":\"Okay!\"}"))
|
||||
@@ -46,12 +49,15 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
.isEqualTo(new Error(Collections.<String, Object>singletonMap("order", 66d)));
|
||||
}
|
||||
|
||||
@Test public void toJson() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void toJson() {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
assertThat(adapter.toJson(new Success("Okay!")))
|
||||
@@ -60,12 +66,15 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
.isEqualTo("{\"type\":\"error\",\"error_logs\":{\"order\":66}}");
|
||||
}
|
||||
|
||||
@Test public void unregisteredLabelValue() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void unregisteredLabelValue() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
JsonReader reader =
|
||||
@@ -74,61 +83,74 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
adapter.fromJson(reader);
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Expected one of [success, error] for key 'type' but found"
|
||||
+ " 'data'. Register a subtype for this label.");
|
||||
assertThat(expected)
|
||||
.hasMessage(
|
||||
"Expected one of [success, error] for key 'type' but found"
|
||||
+ " 'data'. Register a subtype for this label.");
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.BEGIN_OBJECT);
|
||||
}
|
||||
|
||||
@Test public void specifiedFallbackSubtype() throws IOException {
|
||||
@Test
|
||||
public void specifiedFallbackSubtype() throws IOException {
|
||||
Error fallbackError = new Error(Collections.<String, Object>emptyMap());
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(fallbackError))
|
||||
.build();
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(fallbackError))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
Message message = adapter.fromJson("{\"type\":\"data\",\"value\":\"Okay!\"}");
|
||||
assertThat(message).isSameAs(fallbackError);
|
||||
}
|
||||
|
||||
@Test public void specifiedNullFallbackSubtype() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(null))
|
||||
.build();
|
||||
@Test
|
||||
public void specifiedNullFallbackSubtype() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(null))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
Message message = adapter.fromJson("{\"type\":\"data\",\"value\":\"Okay!\"}");
|
||||
assertThat(message).isNull();
|
||||
}
|
||||
|
||||
@Test public void specifiedFallbackJsonAdapter() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withFallbackJsonAdapter(new JsonAdapter<Object>() {
|
||||
@Override public Object fromJson(JsonReader reader) throws IOException {
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("type");
|
||||
assertThat(reader.nextString()).isEqualTo("data");
|
||||
assertThat(reader.nextName()).isEqualTo("value");
|
||||
assertThat(reader.nextString()).isEqualTo("Okay!");
|
||||
reader.endObject();
|
||||
return new EmptyMessage();
|
||||
}
|
||||
@Test
|
||||
public void specifiedFallbackJsonAdapter() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withFallbackJsonAdapter(
|
||||
new JsonAdapter<Object>() {
|
||||
@Override
|
||||
public Object fromJson(JsonReader reader) throws IOException {
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("type");
|
||||
assertThat(reader.nextString()).isEqualTo("data");
|
||||
assertThat(reader.nextName()).isEqualTo("value");
|
||||
assertThat(reader.nextString()).isEqualTo("Okay!");
|
||||
reader.endObject();
|
||||
return new EmptyMessage();
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, @Nullable Object value) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
})
|
||||
)
|
||||
.build();
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, @Nullable Object value) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
JsonReader reader =
|
||||
@@ -139,75 +161,95 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void unregisteredSubtype() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void unregisteredSubtype() {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
try {
|
||||
adapter.toJson(new EmptyMessage());
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("Expected one of [class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Success, class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Error] but found"
|
||||
+ " EmptyMessage, a class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$EmptyMessage. Register"
|
||||
+ " this subtype.");
|
||||
assertThat(expected)
|
||||
.hasMessage(
|
||||
"Expected one of [class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Success, class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Error] but found"
|
||||
+ " EmptyMessage, a class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$EmptyMessage. Register"
|
||||
+ " this subtype.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unregisteredSubtypeWithDefaultValue() {
|
||||
@Test
|
||||
public void unregisteredSubtypeWithDefaultValue() {
|
||||
Error fallbackError = new Error(Collections.<String, Object>emptyMap());
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(fallbackError))
|
||||
.build();
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withDefaultValue(fallbackError))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
try {
|
||||
adapter.toJson(new EmptyMessage());
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertThat(expected).hasMessage("Expected one of [class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Success, class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Error] but found"
|
||||
+ " EmptyMessage, a class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$EmptyMessage. Register"
|
||||
+ " this subtype.");
|
||||
assertThat(expected)
|
||||
.hasMessage(
|
||||
"Expected one of [class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Success, class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$Error] but found"
|
||||
+ " EmptyMessage, a class"
|
||||
+ " com.squareup.moshi.adapters.PolymorphicJsonAdapterFactoryTest$EmptyMessage. Register"
|
||||
+ " this subtype.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unregisteredSubtypeWithFallbackJsonAdapter() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withFallbackJsonAdapter(new JsonAdapter<Object>() {
|
||||
@Override public Object fromJson(JsonReader reader) {
|
||||
throw new RuntimeException("Not implemented as not needed for the test");
|
||||
}
|
||||
@Test
|
||||
public void unregisteredSubtypeWithFallbackJsonAdapter() {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error")
|
||||
.withFallbackJsonAdapter(
|
||||
new JsonAdapter<Object>() {
|
||||
@Override
|
||||
public Object fromJson(JsonReader reader) {
|
||||
throw new RuntimeException(
|
||||
"Not implemented as not needed for the test");
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
writer.name("type").value("injected by fallbackJsonAdapter");
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
writer.name("type").value("injected by fallbackJsonAdapter");
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
String json = adapter.toJson(new EmptyMessage());
|
||||
assertThat(json).isEqualTo("{\"type\":\"injected by fallbackJsonAdapter\"}");
|
||||
}
|
||||
|
||||
@Test public void nonStringLabelValue() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void nonStringLabelValue() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
try {
|
||||
@@ -218,12 +260,15 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nonObjectDoesNotConsume() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void nonObjectDoesNotConsume() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8("\"Failure\""));
|
||||
@@ -237,13 +282,16 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void nonUniqueSubtypes() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Success.class, "data")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void nonUniqueSubtypes() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Success.class, "data")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
@@ -257,10 +305,10 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
.isEqualTo("{\"type\":\"success\",\"value\":\"Data!\"}");
|
||||
}
|
||||
|
||||
@Test public void uniqueLabels() {
|
||||
@Test
|
||||
public void uniqueLabels() {
|
||||
PolymorphicJsonAdapterFactory<Message> factory =
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "data");
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type").withSubtype(Success.class, "data");
|
||||
try {
|
||||
factory.withSubtype(Error.class, "data");
|
||||
fail();
|
||||
@@ -269,12 +317,15 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nullSafe() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
@Test
|
||||
public void nullSafe() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(Success.class, "success")
|
||||
.withSubtype(Error.class, "error"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
JsonReader reader = JsonReader.of(new Buffer().writeUtf8("null"));
|
||||
@@ -286,34 +337,40 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
* Longs that do not have an exact double representation are problematic for JSON. It is a bad
|
||||
* idea to use JSON for these values! But Moshi tries to retain long precision where possible.
|
||||
*/
|
||||
@Test public void unportableTypes() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(MessageWithUnportableTypes.class, "unportable"))
|
||||
.build();
|
||||
@Test
|
||||
public void unportableTypes() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(MessageWithUnportableTypes.class, "unportable"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class);
|
||||
|
||||
assertThat(adapter.toJson(new MessageWithUnportableTypes(9007199254740993L)))
|
||||
.isEqualTo("{\"type\":\"unportable\",\"long_value\":9007199254740993}");
|
||||
MessageWithUnportableTypes decoded = (MessageWithUnportableTypes) adapter.fromJson(
|
||||
"{\"type\":\"unportable\",\"long_value\":9007199254740993}");
|
||||
MessageWithUnportableTypes decoded =
|
||||
(MessageWithUnportableTypes)
|
||||
adapter.fromJson("{\"type\":\"unportable\",\"long_value\":9007199254740993}");
|
||||
assertThat(decoded.long_value).isEqualTo(9007199254740993L);
|
||||
}
|
||||
|
||||
@Test public void failOnUnknownMissingTypeLabel() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(MessageWithType.class, "success"))
|
||||
.build();
|
||||
@Test
|
||||
public void failOnUnknownMissingTypeLabel() throws IOException {
|
||||
Moshi moshi =
|
||||
new Moshi.Builder()
|
||||
.add(
|
||||
PolymorphicJsonAdapterFactory.of(Message.class, "type")
|
||||
.withSubtype(MessageWithType.class, "success"))
|
||||
.build();
|
||||
JsonAdapter<Message> adapter = moshi.adapter(Message.class).failOnUnknown();
|
||||
|
||||
MessageWithType decoded = (MessageWithType) adapter.fromJson(
|
||||
"{\"value\":\"Okay!\",\"type\":\"success\"}");
|
||||
MessageWithType decoded =
|
||||
(MessageWithType) adapter.fromJson("{\"value\":\"Okay!\",\"type\":\"success\"}");
|
||||
assertThat(decoded.value).isEqualTo("Okay!");
|
||||
}
|
||||
|
||||
interface Message {
|
||||
}
|
||||
interface Message {}
|
||||
|
||||
static final class Success implements Message {
|
||||
final String value;
|
||||
@@ -322,14 +379,16 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Success)) return false;
|
||||
Success success = (Success) o;
|
||||
return value.equals(success.value);
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -341,20 +400,23 @@ public final class PolymorphicJsonAdapterFactoryTest {
|
||||
this.error_logs = error_logs;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Error)) return false;
|
||||
Error error = (Error) o;
|
||||
return error_logs.equals(error.error_logs);
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return error_logs.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
static final class EmptyMessage implements Message {
|
||||
@Override public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EmptyMessage";
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.squareup.moshi.adapters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@@ -23,17 +25,17 @@ import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public final class Rfc3339DateJsonAdapterTest {
|
||||
private final JsonAdapter<Date> adapter = new Rfc3339DateJsonAdapter().lenient();
|
||||
|
||||
@Test public void fromJsonWithTwoDigitMillis() throws Exception {
|
||||
@Test
|
||||
public void fromJsonWithTwoDigitMillis() throws Exception {
|
||||
assertThat(adapter.fromJson("\"1985-04-12T23:20:50.52Z\""))
|
||||
.isEqualTo(newDate(1985, 4, 12, 23, 20, 50, 520, 0));
|
||||
}
|
||||
|
||||
@Test public void fromJson() throws Exception {
|
||||
@Test
|
||||
public void fromJson() throws Exception {
|
||||
assertThat(adapter.fromJson("\"1970-01-01T00:00:00.000Z\""))
|
||||
.isEqualTo(newDate(1970, 1, 1, 0, 0, 0, 0, 0));
|
||||
assertThat(adapter.fromJson("\"1985-04-12T23:20:50.520Z\""))
|
||||
@@ -48,7 +50,8 @@ public final class Rfc3339DateJsonAdapterTest {
|
||||
.isEqualTo(newDate(1937, 1, 1, 12, 0, 27, 870, 20));
|
||||
}
|
||||
|
||||
@Test public void toJson() throws Exception {
|
||||
@Test
|
||||
public void toJson() throws Exception {
|
||||
assertThat(adapter.toJson(newDate(1970, 1, 1, 0, 0, 0, 0, 0)))
|
||||
.isEqualTo("\"1970-01-01T00:00:00.000Z\"");
|
||||
assertThat(adapter.toJson(newDate(1985, 4, 12, 23, 20, 50, 520, 0)))
|
||||
@@ -63,7 +66,8 @@ public final class Rfc3339DateJsonAdapterTest {
|
||||
.isEqualTo("\"1937-01-01T11:40:27.870Z\"");
|
||||
}
|
||||
|
||||
@Test public void nullSafety() throws Exception {
|
||||
@Test
|
||||
public void nullSafety() throws Exception {
|
||||
assertThat(adapter.toJson(null)).isEqualTo("null");
|
||||
assertThat(adapter.fromJson("null")).isNull();
|
||||
}
|
||||
|
Reference in New Issue
Block a user